diff --git a/src/config.rs b/src/config.rs index 2d08283..f7bdf1a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -290,6 +290,18 @@ impl Config { config_map!(self, opts => ::internal::deserialize_from(reader, opts)) } + /// Deserializes an object directly from a `Read`er with state `seed` using this configuration + /// + /// If this returns an `Error`, `reader` may be in an invalid state. + #[inline(always)] + pub fn deserialize_from_seed<'a, R: Read, T: serde::de::DeserializeSeed<'a>>( + &self, + seed: T, + reader: R, + ) -> Result { + config_map!(self, opts => ::internal::deserialize_from_seed(seed, reader, opts)) + } + /// Deserializes an object from a custom `BincodeRead`er using the default configuration. /// It is highly recommended to use `deserialize_from` unless you need to implement /// `BincodeRead` for performance reasons. @@ -303,6 +315,24 @@ impl Config { config_map!(self, opts => ::internal::deserialize_from_custom(reader, opts)) } + /// Deserializes an object from a custom `BincodeRead`er with state `seed` using the default + /// configuration. It is highly recommended to use `deserialize_from` unless you need to + /// implement `BincodeRead` for performance reasons. + /// + /// If this returns an `Error`, `reader` may be in an invalid state. + #[inline(always)] + pub fn deserialize_from_custom_seed< + 'a, + R: BincodeRead<'a>, + T: serde::de::DeserializeSeed<'a>, + >( + &self, + seed: T, + reader: R, + ) -> Result { + config_map!(self, opts => ::internal::deserialize_from_custom_seed(seed, reader, opts)) + } + /// Executes the acceptor with a serde::Deserializer instance. /// NOT A PART OF THE STABLE PUBLIC API #[doc(hidden)] diff --git a/src/de/read.rs b/src/de/read.rs index 45aa5d7..f18f789 100644 --- a/src/de/read.rs +++ b/src/de/read.rs @@ -150,13 +150,13 @@ where } } -impl BincodeRead<'static> for IoReader +impl<'a, R> BincodeRead<'a> for IoReader where R: io::Read, { fn forward_read_str(&mut self, length: usize, visitor: V) -> Result where - V: serde::de::Visitor<'static>, + V: serde::de::Visitor<'a>, { self.fill_buffer(length)?; @@ -176,7 +176,7 @@ where fn forward_read_bytes(&mut self, length: usize, visitor: V) -> Result where - V: serde::de::Visitor<'static>, + V: serde::de::Visitor<'a>, { self.fill_buffer(length)?; let r = visitor.visit_bytes(&self.temp_buffer[..]); diff --git a/src/internal.rs b/src/internal.rs index c614781..968950a 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -1,5 +1,6 @@ use serde; use std::io::{Read, Write}; +use std::marker::PhantomData; use config::{Options, OptionsExt}; use de::read::BincodeRead; @@ -77,10 +78,18 @@ where R: Read, T: serde::de::DeserializeOwned, O: Options, +{ + deserialize_from_seed(PhantomData, reader, options) +} + +pub(crate) fn deserialize_from_seed<'a, R, T, O>(seed: T, reader: R, options: O) -> Result +where + R: Read, + T: serde::de::DeserializeSeed<'a>, + O: Options, { let reader = ::de::read::IoReader::new(reader); - let mut deserializer = ::de::Deserializer::<_, O>::new(reader, options); - serde::Deserialize::deserialize(&mut deserializer) + deserialize_from_custom_seed(seed, reader, options) } pub(crate) fn deserialize_from_custom<'a, R, T, O>(reader: R, options: O) -> Result @@ -88,9 +97,22 @@ where R: BincodeRead<'a>, T: serde::de::DeserializeOwned, O: Options, +{ + deserialize_from_custom_seed(PhantomData, reader, options) +} + +pub(crate) fn deserialize_from_custom_seed<'a, R, T, O>( + seed: T, + reader: R, + options: O, +) -> Result +where + R: BincodeRead<'a>, + T: serde::de::DeserializeSeed<'a>, + O: Options, { let mut deserializer = ::de::Deserializer::<_, O>::new(reader, options); - serde::Deserialize::deserialize(&mut deserializer) + seed.deserialize(&mut deserializer) } pub(crate) fn deserialize_in_place<'a, R, T, O>(reader: R, options: O, place: &mut T) -> Result<()> @@ -108,10 +130,7 @@ where T: serde::de::Deserialize<'a>, O: Options, { - let reader = ::de::read::SliceReader::new(bytes); - let options = ::config::WithOtherLimit::new(options, Infinite); - let mut deserializer = ::de::Deserializer::new(reader, options); - serde::Deserialize::deserialize(&mut deserializer) + deserialize_seed(PhantomData, bytes, options) } pub(crate) fn deserialize_seed<'a, T, O>(seed: T, bytes: &'a [u8], options: O) -> Result @@ -121,8 +140,7 @@ where { let reader = ::de::read::SliceReader::new(bytes); let options = ::config::WithOtherLimit::new(options, Infinite); - let mut deserializer = ::de::Deserializer::new(reader, options); - seed.deserialize(&mut deserializer) + deserialize_from_custom_seed(seed, reader, options) } pub(crate) trait SizeLimit: Clone {