diff --git a/serde/Cargo.toml b/serde/Cargo.toml index 3675479db..094d18a2f 100644 --- a/serde/Cargo.toml +++ b/serde/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde" -version = "1.0.69" # remember to update html_root_url +version = "1.0.999" # remember to update html_root_url authors = ["Erick Tryzelaar ", "David Tolnay "] license = "MIT/Apache-2.0" description = "A generic serialization/deserialization framework" @@ -27,7 +27,7 @@ serde_derive = { version = "1.0", path = "../serde_derive" } ### FEATURES ################################################################# [features] -default = ["std"] +default = ["std", "state"] # Re-export the derive(Serialize, Deserialize) macros. This is intended for # library crates that provide optional Serde impls behind a Cargo cfg of their @@ -78,3 +78,9 @@ alloc = ["unstable"] # does not preserve identity and may result in multiple copies of the same data. # Be sure that this is what you want before enabling this feature. rc = [] + +# Enables the state support. This feature is on by default but can be removed +# to disable states. If states are enabled serializers can carry state information +# around. If this feature is disabled any attempt to store data in the state will +# silently do nothing. +state = [] diff --git a/serde/build.rs b/serde/build.rs index a187cf85c..3d4f7646d 100644 --- a/serde/build.rs +++ b/serde/build.rs @@ -24,6 +24,12 @@ fn main() { println!("cargo:rustc-cfg=de_rc_dst"); } + // drop_types_in_const was stabilized in 1.22: + // https://blog.rust-lang.org/2017/11/22/Rust-1.22.html + if minor >= 22 { + println!("cargo:rustc-cfg=de_state"); + } + // Duration available in core since Rust 1.25: // https://blog.rust-lang.org/2018/03/29/Rust-1.25.html#library-stabilizations if minor >= 25 { diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 84a659a23..d51a15470 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -129,8 +129,10 @@ mod from_primitive; mod ignored_any; mod impls; mod utf8; +mod state; pub use self::ignored_any::IgnoredAny; +pub use self::state::State; //////////////////////////////////////////////////////////////////////////////// @@ -1203,6 +1205,12 @@ pub trait Deserializer<'de>: Sized { fn is_human_readable(&self) -> bool { true } + + /// Returns the current state. + #[inline] + fn state(&self) -> &State { + State::empty() + } } //////////////////////////////////////////////////////////////////////////////// @@ -2235,6 +2243,16 @@ pub trait IntoDeserializer<'de, E: Error = value::Error> { /// Convert this value into a deserializer. fn into_deserializer(self) -> Self::Deserializer; + + /// Convert this value into a deserializer and attach state. + fn into_deserializer_with_state(self, state: State) -> Self::Deserializer + where Self: Sized + { + if !state.is_empty() { + panic!("This deserializer does not support state"); + } + IntoDeserializer::into_deserializer(self) + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/serde/src/de/state.rs b/serde/src/de/state.rs new file mode 100644 index 000000000..b2d87bfc4 --- /dev/null +++ b/serde/src/de/state.rs @@ -0,0 +1,136 @@ +use lib::*; + +/// A copy on write structure for deserializer state. +/// +/// Deserializers can hold arbitrary state that the `Deserializer` trait +/// can access. From the outside state can only be read not modified +/// (not counting interior mutability). Any static type can be added +/// to the state. +/// +/// This for instance can be used to notify types about location +/// information or associated metadata. If the `state` feature is +/// disabled in serde this becomes a zero sized type that does not +/// do anything instead. +/// +/// Internally the structure is a reasonably efficient copy on write +/// structure. It can be cheaply cloned which effectively just bumps +/// some refcounts. Internally it is implemented as a vector. +/// +/// This requires Rust 1.22 or later and the `state` feature to be +/// enabled. Otherwise the state type is read-only and does not +/// provide the `set` and `remove` methods. +#[derive(Clone, Default)] +pub struct State { + #[cfg(all(feature = "state", de_state))] + map: Option>)>>>, +} + +impl State { + /// Returns the static reference to the empty state. + /// + /// The state is normally non `Send` but the read only empty state + /// can be safely accessed from multiple threads. To modify the + /// state it needs to be cloned first. + /// + /// ``` + /// # use serde::de::State; + /// struct MyInfo(i32); + /// let mut state = State::empty().clone(); + /// state.set(MyInfo(42)); + /// ``` + #[inline] + pub fn empty() -> &'static State { + // we could use `const EMPTY_STATE: State` here for newer rust + // versions which would avoid the unsafe. The end result is + // about the same though. + #[cfg(all(feature = "state", de_state))] { + const EMPTY_STATE: State = State { + map: None + }; + &EMPTY_STATE + } + #[cfg(not(all(feature = "state", de_state)))] { + static mut EMPTY_STATE: State = State {}; + unsafe { &EMPTY_STATE } + } + } + + /// Checks if the state is empty. + pub fn is_empty(&self) -> bool { + #[cfg(all(feature = "state", de_state))] { + match self.map { + Some(ref map) => map.is_empty(), + None => true, + } + } + #[cfg(not(all(feature = "state", de_state)))] { + true + } + } + + /// Looks up an item. + /// + /// This function is always available even if the state feature is + /// disabled. In that case the state just always returns `None`. + pub fn get(&self) -> Option<&T> { + #[cfg(all(feature = "state", de_state))] { + if let Some(ref map) = self.map { + for &(type_id, ref boxed_rc) in map.iter() { + if type_id == TypeId::of::() { + return (&***boxed_rc as &(Any + 'static)).downcast_ref(); + } + } + } + } + None + } + + /// Inserts or replaces a type in the state map. + #[cfg(all(feature = "state", de_state))] + pub fn set(&mut self, val: T) { + self.map = Some(Rc::new(self.map + .as_ref() + .map_or(&[][..], |x| &x[..]) + .iter() + .filter_map(|&(type_id, ref boxed_rc)| { + if type_id == TypeId::of::() { + None + } else { + Some((type_id, boxed_rc.clone())) + } + }) + .chain(iter::once((TypeId::of::(), Rc::new(Box::new(val) as Box)))) + .collect())); + } + + /// Removes a type from the state map. + #[cfg(all(feature = "state", de_state))] + pub fn remove(&mut self) { + let new_map = { + let mut iter = self.map + .as_ref() + .map_or(&[][..], |x| &x[..]) + .iter() + .filter_map(|&(type_id, ref boxed_rc)| { + if type_id == TypeId::of::() { + None + } else { + Some((type_id, boxed_rc.clone())) + } + }) + .peekable(); + if iter.peek().is_some() { + Some(iter.collect()) + } else { + None + } + }; + self.map = new_map.map(Rc::new); + } +} + +impl fmt::Debug for State { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("State").finish() + } +} diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index fe097042b..37b27ee80 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -38,28 +38,12 @@ use lib::*; use self::private::{First, Second}; -use de::{self, Expected, IntoDeserializer, SeqAccess}; +use de::{self, Expected, IntoDeserializer, SeqAccess, State}; use private::de::size_hint; use ser; //////////////////////////////////////////////////////////////////////////////// -// For structs that contain a PhantomData. We do not want the trait -// bound `E: Clone` inferred by derive(Clone). -macro_rules! impl_copy_clone { - ($ty:ident $(<$lifetime:tt>)*) => { - impl<$($lifetime,)* E> Copy for $ty<$($lifetime,)* E> {} - - impl<$($lifetime,)* E> Clone for $ty<$($lifetime,)* E> { - fn clone(&self) -> Self { - *self - } - } - }; -} - -//////////////////////////////////////////////////////////////////////////////// - /// A minimal representation of all possible errors that can occur using the /// `IntoDeserializer` trait. #[derive(Clone, Debug, PartialEq)] @@ -135,6 +119,7 @@ where fn into_deserializer(self) -> UnitDeserializer { UnitDeserializer { marker: PhantomData, + state: State::default(), } } } @@ -143,9 +128,17 @@ where #[derive(Debug)] pub struct UnitDeserializer { marker: PhantomData, + state: State, } -impl_copy_clone!(UnitDeserializer); +impl Clone for UnitDeserializer { + fn clone(&self) -> Self { + UnitDeserializer { + marker: PhantomData, + state: self.state.clone(), + } + } +} impl<'de, E> de::Deserializer<'de> for UnitDeserializer where @@ -153,6 +146,8 @@ where { type Error = E; + forward_deserializer_state_to_field!(); + forward_to_deserialize_any! { bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string bytes byte_buf unit unit_struct newtype_struct seq tuple tuple_struct @@ -225,10 +220,19 @@ macro_rules! primitive_deserializer { #[derive(Debug)] pub struct $name { value: $ty, + state: State, marker: PhantomData } - impl_copy_clone!($name); + impl Clone for $name { + fn clone(&self) -> Self { + $name { + value: self.value, + state: self.state.clone(), + marker: PhantomData, + } + } + } impl<'de, E> IntoDeserializer<'de, E> for $ty where @@ -239,6 +243,7 @@ macro_rules! primitive_deserializer { fn into_deserializer(self) -> $name { $name { value: self, + state: State::default(), marker: PhantomData, } } @@ -256,6 +261,8 @@ macro_rules! primitive_deserializer { tuple tuple_struct map struct enum identifier ignored_any } + forward_deserializer_state_to_field!(); + fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, @@ -289,10 +296,19 @@ serde_if_integer128! { #[derive(Debug)] pub struct U32Deserializer { value: u32, + state: State, marker: PhantomData, } -impl_copy_clone!(U32Deserializer); +impl Clone for U32Deserializer { + fn clone(&self) -> Self { + U32Deserializer { + value: self.value, + state: self.state.clone(), + marker: PhantomData, + } + } +} impl<'de, E> IntoDeserializer<'de, E> for u32 where @@ -303,6 +319,7 @@ where fn into_deserializer(self) -> U32Deserializer { U32Deserializer { value: self, + state: State::default(), marker: PhantomData, } } @@ -314,6 +331,8 @@ where { type Error = E; + forward_deserializer_state_to_field!(); + forward_to_deserialize_any! { bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string bytes byte_buf option unit unit_struct newtype_struct seq tuple @@ -363,10 +382,19 @@ where #[derive(Debug)] pub struct StrDeserializer<'a, E> { value: &'a str, + state: State, marker: PhantomData, } -impl_copy_clone!(StrDeserializer<'de>); +impl<'de, E> Clone for StrDeserializer<'de, E> { + fn clone(&self) -> Self { + StrDeserializer { + value: self.value, + state: self.state.clone(), + marker: PhantomData, + } + } +} impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a str where @@ -377,6 +405,7 @@ where fn into_deserializer(self) -> StrDeserializer<'a, E> { StrDeserializer { value: self, + state: State::default(), marker: PhantomData, } } @@ -388,6 +417,8 @@ where { type Error = E; + forward_deserializer_state_to_field!(); + fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, @@ -438,16 +469,31 @@ where #[derive(Debug)] pub struct BorrowedStrDeserializer<'de, E> { value: &'de str, + state: State, marker: PhantomData, } -impl_copy_clone!(BorrowedStrDeserializer<'de>); +impl<'de, E> Clone for BorrowedStrDeserializer<'de, E> { + fn clone(&self) -> Self { + BorrowedStrDeserializer { + value: self.value, + state: self.state.clone(), + marker: PhantomData, + } + } +} impl<'de, E> BorrowedStrDeserializer<'de, E> { /// Create a new borrowed deserializer from the given string. pub fn new(value: &'de str) -> BorrowedStrDeserializer<'de, E> { + Self::new_with_state(value, State::default()) + } + + /// Create a new borrowed deserializer from the given string and state. + pub fn new_with_state(value: &'de str, new_state: State) -> BorrowedStrDeserializer<'de, E> { BorrowedStrDeserializer { value: value, + state: new_state, marker: PhantomData, } } @@ -459,6 +505,8 @@ where { type Error = E; + forward_deserializer_state_to_field!(); + fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, @@ -509,6 +557,7 @@ where #[derive(Debug)] pub struct StringDeserializer { value: String, + state: State, marker: PhantomData, } @@ -517,6 +566,7 @@ impl Clone for StringDeserializer { fn clone(&self) -> Self { StringDeserializer { value: self.value.clone(), + state: State::default(), marker: PhantomData, } } @@ -532,6 +582,7 @@ where fn into_deserializer(self) -> StringDeserializer { StringDeserializer { value: self, + state: State::default(), marker: PhantomData, } } @@ -544,6 +595,8 @@ where { type Error = E; + forward_deserializer_state_to_field!(); + fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, @@ -595,6 +648,7 @@ where #[derive(Debug)] pub struct CowStrDeserializer<'a, E> { value: Cow<'a, str>, + state: State, marker: PhantomData, } @@ -603,6 +657,7 @@ impl<'a, E> Clone for CowStrDeserializer<'a, E> { fn clone(&self) -> Self { CowStrDeserializer { value: self.value.clone(), + state: self.state.clone(), marker: PhantomData, } } @@ -618,6 +673,7 @@ where fn into_deserializer(self) -> CowStrDeserializer<'a, E> { CowStrDeserializer { value: self, + state: State::default(), marker: PhantomData, } } @@ -630,6 +686,8 @@ where { type Error = E; + forward_deserializer_state_to_field!(); + fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, @@ -684,16 +742,31 @@ where #[derive(Debug)] pub struct BorrowedBytesDeserializer<'de, E> { value: &'de [u8], + state: State, marker: PhantomData, } -impl_copy_clone!(BorrowedBytesDeserializer<'de>); +impl<'de, E> Clone for BorrowedBytesDeserializer<'de, E> { + fn clone(&self) -> Self { + BorrowedBytesDeserializer { + value: self.value, + state: self.state.clone(), + marker: PhantomData, + } + } +} impl<'de, E> BorrowedBytesDeserializer<'de, E> { /// Create a new borrowed deserializer from the given byte slice. pub fn new(value: &'de [u8]) -> BorrowedBytesDeserializer<'de, E> { + Self::new_with_state(value, State::default()) + } + + /// Create a new borrowed deserializer from the given byte slice and state. + pub fn new_with_state(value: &'de [u8], new_state: State) -> BorrowedBytesDeserializer<'de, E> { BorrowedBytesDeserializer { value: value, + state: new_state, marker: PhantomData, } } @@ -705,6 +778,8 @@ where { type Error = E; + forward_deserializer_state_to_field!(); + fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, @@ -727,6 +802,7 @@ pub struct SeqDeserializer { iter: iter::Fuse, count: usize, marker: PhantomData, + state: State, } impl SeqDeserializer @@ -735,10 +811,16 @@ where { /// Construct a new `SeqDeserializer`. pub fn new(iter: I) -> Self { + Self::new_with_state(iter, State::default()) + } + + /// Construct a new `SeqDeserializer` and state. + pub fn new_with_state(iter: I, state: State) -> Self { SeqDeserializer { iter: iter.fuse(), count: 0, marker: PhantomData, + state: state, } } } @@ -773,6 +855,8 @@ where { type Error = E; + forward_deserializer_state_to_field!(); + fn deserialize_any(mut self, visitor: V) -> Result where V: de::Visitor<'de>, @@ -804,7 +888,7 @@ where match self.iter.next() { Some(value) => { self.count += 1; - seed.deserialize(value.into_deserializer()).map(Some) + seed.deserialize(value.into_deserializer_with_state(self.state.clone())).map(Some) } None => Ok(None), } @@ -875,12 +959,18 @@ where #[derive(Clone, Debug)] pub struct SeqAccessDeserializer { seq: A, + state: State, } impl SeqAccessDeserializer { /// Construct a new `SeqAccessDeserializer`. pub fn new(seq: A) -> Self { - SeqAccessDeserializer { seq: seq } + Self::new_with_state(seq, State::default()) + } + + /// Construct a new `SeqAccessDeserializer` with state. + pub fn new_with_state(seq: A, state: State) -> Self { + SeqAccessDeserializer { seq: seq, state: state } } } @@ -890,6 +980,8 @@ where { type Error = A::Error; + forward_deserializer_state_to_field!(); + fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, @@ -916,6 +1008,7 @@ where value: Option>, count: usize, lifetime: PhantomData<&'de ()>, + state: State, error: PhantomData, } @@ -926,11 +1019,17 @@ where { /// Construct a new `MapDeserializer`. pub fn new(iter: I) -> Self { + Self::new_with_state(iter, State::default()) + } + + /// Construct a new `MapDeserializer` with state. + pub fn new_with_state(iter: I, state: State) -> Self { MapDeserializer { iter: iter.fuse(), value: None, count: 0, lifetime: PhantomData, + state: state, error: PhantomData, } } @@ -985,6 +1084,8 @@ where { type Error = E; + forward_deserializer_state_to_field!(); + fn deserialize_any(mut self, visitor: V) -> Result where V: de::Visitor<'de>, @@ -1035,7 +1136,7 @@ where match self.next_pair() { Some((key, value)) => { self.value = Some(value); - seed.deserialize(key.into_deserializer()).map(Some) + seed.deserialize(key.into_deserializer_with_state(self.state.clone())).map(Some) } None => Ok(None), } @@ -1049,7 +1150,7 @@ where // Panic because this indicates a bug in the program rather than an // expected failure. let value = value.expect("MapAccess::visit_value called before visit_key"); - seed.deserialize(value.into_deserializer()) + seed.deserialize(value.into_deserializer_with_state(self.state.clone())) } fn next_entry_seed( @@ -1063,8 +1164,8 @@ where { match self.next_pair() { Some((key, value)) => { - let key = try!(kseed.deserialize(key.into_deserializer())); - let value = try!(vseed.deserialize(value.into_deserializer())); + let key = try!(kseed.deserialize(key.into_deserializer_with_state(self.state.clone()))); + let value = try!(vseed.deserialize(value.into_deserializer_with_state(self.state.clone()))); Ok(Some((key, value))) } None => Ok(None), @@ -1092,7 +1193,7 @@ where { match self.next_pair() { Some((k, v)) => { - let de = PairDeserializer(k, v, PhantomData); + let de = PairDeserializer(k, v, self.state.clone(), PhantomData); seed.deserialize(de).map(Some) } None => Ok(None), @@ -1117,6 +1218,7 @@ where value: self.value.clone(), count: self.count, lifetime: self.lifetime, + state: self.state.clone(), error: self.error, } } @@ -1143,7 +1245,7 @@ where // Used in the `impl SeqAccess for MapDeserializer` to visit the map as a // sequence of pairs. -struct PairDeserializer(A, B, PhantomData); +struct PairDeserializer(A, B, State, PhantomData); impl<'de, A, B, E> de::Deserializer<'de> for PairDeserializer where @@ -1170,7 +1272,7 @@ where where V: de::Visitor<'de>, { - let mut pair_visitor = PairVisitor(Some(self.0), Some(self.1), PhantomData); + let mut pair_visitor = PairVisitor(Some(self.0), Some(self.1), self.2.clone(), PhantomData); let pair = try!(visitor.visit_seq(&mut pair_visitor)); if pair_visitor.1.is_none() { Ok(pair) @@ -1196,7 +1298,7 @@ where } } -struct PairVisitor(Option, Option, PhantomData); +struct PairVisitor(Option, Option, State, PhantomData); impl<'de, A, B, E> de::SeqAccess<'de> for PairVisitor where @@ -1211,9 +1313,9 @@ where T: de::DeserializeSeed<'de>, { if let Some(k) = self.0.take() { - seed.deserialize(k.into_deserializer()).map(Some) + seed.deserialize(k.into_deserializer_with_state(self.2.clone())).map(Some) } else if let Some(v) = self.1.take() { - seed.deserialize(v.into_deserializer()).map(Some) + seed.deserialize(v.into_deserializer_with_state(self.2.clone())).map(Some) } else { Ok(None) } @@ -1279,12 +1381,18 @@ where #[derive(Clone, Debug)] pub struct MapAccessDeserializer { map: A, + state: State, } impl MapAccessDeserializer { /// Construct a new `MapAccessDeserializer`. pub fn new(map: A) -> Self { - MapAccessDeserializer { map: map } + Self::new_with_state(map, State::default()) + } + + /// Construct a new `MapAccessDeserializer` with state. + pub fn new_with_state(map: A, state: State) -> Self { + MapAccessDeserializer { map: map, state: state } } } @@ -1294,6 +1402,8 @@ where { type Error = A::Error; + forward_deserializer_state_to_field!(); + fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, diff --git a/serde/src/lib.rs b/serde/src/lib.rs index 968fc683e..1e97dbe0b 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -161,6 +161,7 @@ mod lib { pub use self::core::marker::{self, PhantomData}; pub use self::core::option::{self, Option}; pub use self::core::result::{self, Result}; + pub use self::core::any::{Any, TypeId}; #[cfg(all(feature = "alloc", not(feature = "std")))] pub use alloc::borrow::{Cow, ToOwned}; @@ -182,9 +183,9 @@ mod lib { #[cfg(feature = "std")] pub use std::boxed::Box; - #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))] + #[cfg(all(any(feature = "rc", all(feature = "state", de_state)), feature = "alloc", not(feature = "std")))] pub use alloc::rc::{Rc, Weak as RcWeak}; - #[cfg(all(feature = "rc", feature = "std"))] + #[cfg(all(any(feature = "rc", all(feature = "state", de_state)), feature = "std"))] pub use std::rc::{Rc, Weak as RcWeak}; #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))] diff --git a/serde/src/macros.rs b/serde/src/macros.rs index 9d099670a..beb2a0dd4 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -254,3 +254,17 @@ macro_rules! forward_to_deserialize_any_helper { forward_to_deserialize_any_method!{deserialize_ignored_any<$l, $v>()} }; } + +/// Utility macro to forward a deserializer state to a struct field. +#[macro_export] +macro_rules! forward_deserializer_state_to_field { + () => { + forward_deserializer_state_to_field!(state); + }; + ($field:tt) => { + #[inline] + fn state(&self) -> &$crate::de::State { + &self.$field + } + }; +} diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 8fdf6c36f..10cdc3906 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -8,14 +8,14 @@ use lib::*; -use de::{Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, Visitor}; +use de::{Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, Visitor, State}; #[cfg(any(feature = "std", feature = "alloc"))] use de::{MapAccess, Unexpected}; #[cfg(any(feature = "std", feature = "alloc"))] pub use self::content::{ - Content, ContentDeserializer, ContentRefDeserializer, EnumDeserializer, + Content, ContentRepr, ContentDeserializer, ContentRefDeserializer, EnumDeserializer, InternallyTaggedUnitVisitor, TagContentOtherField, TagContentOtherFieldVisitor, TagOrContentField, TagOrContentFieldVisitor, TaggedContentVisitor, UntaggedUnitVisitor, }; @@ -232,7 +232,7 @@ mod content { use super::size_hint; use de::{ self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, MapAccess, - SeqAccess, Unexpected, Visitor, + SeqAccess, Unexpected, Visitor, State, }; /// Used from generated code to buffer the contents of the Deserializer when @@ -240,7 +240,30 @@ mod content { /// /// Not public API. Use serde-value instead. #[derive(Debug)] - pub enum Content<'de> { + pub struct Content<'de> { + repr: ContentRepr<'de>, + state: State, + } + + impl<'de> Content<'de> { + pub fn new(value: ContentRepr<'de>, state: &State) -> Content<'de> { + Content { + repr: value, + state: state.clone(), + } + } + + pub fn repr(&self) -> &ContentRepr { + &self.repr + } + + pub fn state(&self) -> &State { + &self.state + } + } + + #[derive(Debug)] + pub enum ContentRepr<'de> { Bool(bool), U8(u8), @@ -273,39 +296,39 @@ mod content { impl<'de> Content<'de> { pub fn as_str(&self) -> Option<&str> { - match *self { - Content::Str(x) => Some(x), - Content::String(ref x) => Some(x), - Content::Bytes(x) => str::from_utf8(x).ok(), - Content::ByteBuf(ref x) => str::from_utf8(x).ok(), + match self.repr { + ContentRepr::Str(x) => Some(x), + ContentRepr::String(ref x) => Some(x), + ContentRepr::Bytes(x) => str::from_utf8(x).ok(), + ContentRepr::ByteBuf(ref x) => str::from_utf8(x).ok(), _ => None, } } #[cold] fn unexpected(&self) -> Unexpected { - match *self { - Content::Bool(b) => Unexpected::Bool(b), - Content::U8(n) => Unexpected::Unsigned(n as u64), - Content::U16(n) => Unexpected::Unsigned(n as u64), - Content::U32(n) => Unexpected::Unsigned(n as u64), - Content::U64(n) => Unexpected::Unsigned(n), - Content::I8(n) => Unexpected::Signed(n as i64), - Content::I16(n) => Unexpected::Signed(n as i64), - Content::I32(n) => Unexpected::Signed(n as i64), - Content::I64(n) => Unexpected::Signed(n), - Content::F32(f) => Unexpected::Float(f as f64), - Content::F64(f) => Unexpected::Float(f), - Content::Char(c) => Unexpected::Char(c), - Content::String(ref s) => Unexpected::Str(s), - Content::Str(s) => Unexpected::Str(s), - Content::ByteBuf(ref b) => Unexpected::Bytes(b), - Content::Bytes(b) => Unexpected::Bytes(b), - Content::None | Content::Some(_) => Unexpected::Option, - Content::Unit => Unexpected::Unit, - Content::Newtype(_) => Unexpected::NewtypeStruct, - Content::Seq(_) => Unexpected::Seq, - Content::Map(_) => Unexpected::Map, + match self.repr { + ContentRepr::Bool(b) => Unexpected::Bool(b), + ContentRepr::U8(n) => Unexpected::Unsigned(n as u64), + ContentRepr::U16(n) => Unexpected::Unsigned(n as u64), + ContentRepr::U32(n) => Unexpected::Unsigned(n as u64), + ContentRepr::U64(n) => Unexpected::Unsigned(n), + ContentRepr::I8(n) => Unexpected::Signed(n as i64), + ContentRepr::I16(n) => Unexpected::Signed(n as i64), + ContentRepr::I32(n) => Unexpected::Signed(n as i64), + ContentRepr::I64(n) => Unexpected::Signed(n), + ContentRepr::F32(f) => Unexpected::Float(f as f64), + ContentRepr::F64(f) => Unexpected::Float(f), + ContentRepr::Char(c) => Unexpected::Char(c), + ContentRepr::String(ref s) => Unexpected::Str(s), + ContentRepr::Str(s) => Unexpected::Str(s), + ContentRepr::ByteBuf(ref b) => Unexpected::Bytes(b), + ContentRepr::Bytes(b) => Unexpected::Bytes(b), + ContentRepr::None | ContentRepr::Some(_) => Unexpected::Option, + ContentRepr::Unit => Unexpected::Unit, + ContentRepr::Newtype(_) => Unexpected::NewtypeStruct, + ContentRepr::Seq(_) => Unexpected::Seq, + ContentRepr::Map(_) => Unexpected::Map, } } } @@ -317,18 +340,19 @@ mod content { { // Untagged and internally tagged enums are only supported in // self-describing formats. - let visitor = ContentVisitor { value: PhantomData }; + let visitor = ContentVisitor::new(deserializer.state()); deserializer.deserialize_any(visitor) } } struct ContentVisitor<'de> { value: PhantomData>, + state: State, } impl<'de> ContentVisitor<'de> { - fn new() -> Self { - ContentVisitor { value: PhantomData } + fn new(state: &State) -> Self { + ContentVisitor { value: PhantomData, state: state.clone() } } } @@ -343,154 +367,156 @@ mod content { where F: de::Error, { - Ok(Content::Bool(value)) + Ok(Content::new(ContentRepr::Bool(value), &self.state)) } fn visit_i8(self, value: i8) -> Result where F: de::Error, { - Ok(Content::I8(value)) + Ok(Content::new(ContentRepr::I8(value), &self.state)) } fn visit_i16(self, value: i16) -> Result where F: de::Error, { - Ok(Content::I16(value)) + Ok(Content::new(ContentRepr::I16(value), &self.state)) } fn visit_i32(self, value: i32) -> Result where F: de::Error, { - Ok(Content::I32(value)) + Ok(Content::new(ContentRepr::I32(value), &self.state)) } fn visit_i64(self, value: i64) -> Result where F: de::Error, { - Ok(Content::I64(value)) + Ok(Content::new(ContentRepr::I64(value), &self.state)) } fn visit_u8(self, value: u8) -> Result where F: de::Error, { - Ok(Content::U8(value)) + Ok(Content::new(ContentRepr::U8(value), &self.state)) } fn visit_u16(self, value: u16) -> Result where F: de::Error, { - Ok(Content::U16(value)) + Ok(Content::new(ContentRepr::U16(value), &self.state)) } fn visit_u32(self, value: u32) -> Result where F: de::Error, { - Ok(Content::U32(value)) + Ok(Content::new(ContentRepr::U32(value), &self.state)) } fn visit_u64(self, value: u64) -> Result where F: de::Error, { - Ok(Content::U64(value)) + Ok(Content::new(ContentRepr::U64(value), &self.state)) } fn visit_f32(self, value: f32) -> Result where F: de::Error, { - Ok(Content::F32(value)) + Ok(Content::new(ContentRepr::F32(value), &self.state)) } fn visit_f64(self, value: f64) -> Result where F: de::Error, { - Ok(Content::F64(value)) + Ok(Content::new(ContentRepr::F64(value), &self.state)) } fn visit_char(self, value: char) -> Result where F: de::Error, { - Ok(Content::Char(value)) + Ok(Content::new(ContentRepr::Char(value), &self.state)) } fn visit_str(self, value: &str) -> Result where F: de::Error, { - Ok(Content::String(value.into())) + Ok(Content::new(ContentRepr::String(value.into()), &self.state)) } fn visit_borrowed_str(self, value: &'de str) -> Result where F: de::Error, { - Ok(Content::Str(value)) + Ok(Content::new(ContentRepr::Str(value), &self.state)) } fn visit_string(self, value: String) -> Result where F: de::Error, { - Ok(Content::String(value)) + Ok(Content::new(ContentRepr::String(value), &self.state)) } fn visit_bytes(self, value: &[u8]) -> Result where F: de::Error, { - Ok(Content::ByteBuf(value.into())) + Ok(Content::new(ContentRepr::ByteBuf(value.into()), &self.state)) } fn visit_borrowed_bytes(self, value: &'de [u8]) -> Result where F: de::Error, { - Ok(Content::Bytes(value)) + Ok(Content::new(ContentRepr::Bytes(value), &self.state)) } fn visit_byte_buf(self, value: Vec) -> Result where F: de::Error, { - Ok(Content::ByteBuf(value)) + Ok(Content::new(ContentRepr::ByteBuf(value), &self.state)) } fn visit_unit(self) -> Result where F: de::Error, { - Ok(Content::Unit) + Ok(Content::new(ContentRepr::Unit, &self.state)) } fn visit_none(self) -> Result where F: de::Error, { - Ok(Content::None) + Ok(Content::new(ContentRepr::None, &self.state)) } fn visit_some(self, deserializer: D) -> Result where D: Deserializer<'de>, { - Deserialize::deserialize(deserializer).map(|v| Content::Some(Box::new(v))) + Deserialize::deserialize(deserializer) + .map(|v| Content::new(ContentRepr::Some(Box::new(v)), &self.state)) } fn visit_newtype_struct(self, deserializer: D) -> Result where D: Deserializer<'de>, { - Deserialize::deserialize(deserializer).map(|v| Content::Newtype(Box::new(v))) + Deserialize::deserialize(deserializer) + .map(|v| Content::new(ContentRepr::Newtype(Box::new(v)), &self.state)) } fn visit_seq(self, mut visitor: V) -> Result @@ -501,7 +527,7 @@ mod content { while let Some(e) = try!(visitor.next_element()) { vec.push(e); } - Ok(Content::Seq(vec)) + Ok(Content::new(ContentRepr::Seq(vec), &self.state)) } fn visit_map(self, mut visitor: V) -> Result @@ -512,7 +538,7 @@ mod content { while let Some(kv) = try!(visitor.next_entry()) { vec.push(kv); } - Ok(Content::Map(vec)) + Ok(Content::new(ContentRepr::Map(vec), &self.state)) } fn visit_enum(self, _visitor: V) -> Result @@ -536,13 +562,15 @@ mod content { struct TagOrContentVisitor<'de> { name: &'static str, value: PhantomData>, + state: State, } impl<'de> TagOrContentVisitor<'de> { - fn new(name: &'static str) -> Self { + fn new(name: &'static str, state: &State) -> Self { TagOrContentVisitor { name: name, value: PhantomData, + state: state.clone(), } } } @@ -571,7 +599,7 @@ mod content { where F: de::Error, { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_bool(value) .map(TagOrContent::Content) } @@ -580,7 +608,7 @@ mod content { where F: de::Error, { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_i8(value) .map(TagOrContent::Content) } @@ -589,7 +617,7 @@ mod content { where F: de::Error, { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_i16(value) .map(TagOrContent::Content) } @@ -598,7 +626,7 @@ mod content { where F: de::Error, { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_i32(value) .map(TagOrContent::Content) } @@ -607,7 +635,7 @@ mod content { where F: de::Error, { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_i64(value) .map(TagOrContent::Content) } @@ -616,7 +644,7 @@ mod content { where F: de::Error, { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_u8(value) .map(TagOrContent::Content) } @@ -625,7 +653,7 @@ mod content { where F: de::Error, { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_u16(value) .map(TagOrContent::Content) } @@ -634,7 +662,7 @@ mod content { where F: de::Error, { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_u32(value) .map(TagOrContent::Content) } @@ -643,7 +671,7 @@ mod content { where F: de::Error, { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_u64(value) .map(TagOrContent::Content) } @@ -652,7 +680,7 @@ mod content { where F: de::Error, { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_f32(value) .map(TagOrContent::Content) } @@ -661,7 +689,7 @@ mod content { where F: de::Error, { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_f64(value) .map(TagOrContent::Content) } @@ -670,7 +698,7 @@ mod content { where F: de::Error, { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_char(value) .map(TagOrContent::Content) } @@ -682,7 +710,7 @@ mod content { if value == self.name { Ok(TagOrContent::Tag) } else { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_str(value) .map(TagOrContent::Content) } @@ -695,7 +723,7 @@ mod content { if value == self.name { Ok(TagOrContent::Tag) } else { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_borrowed_str(value) .map(TagOrContent::Content) } @@ -708,7 +736,7 @@ mod content { if value == self.name { Ok(TagOrContent::Tag) } else { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_string(value) .map(TagOrContent::Content) } @@ -721,7 +749,7 @@ mod content { if value == self.name.as_bytes() { Ok(TagOrContent::Tag) } else { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_bytes(value) .map(TagOrContent::Content) } @@ -734,7 +762,7 @@ mod content { if value == self.name.as_bytes() { Ok(TagOrContent::Tag) } else { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_borrowed_bytes(value) .map(TagOrContent::Content) } @@ -747,7 +775,7 @@ mod content { if value == self.name.as_bytes() { Ok(TagOrContent::Tag) } else { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_byte_buf(value) .map(TagOrContent::Content) } @@ -757,7 +785,7 @@ mod content { where F: de::Error, { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_unit() .map(TagOrContent::Content) } @@ -766,7 +794,7 @@ mod content { where F: de::Error, { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_none() .map(TagOrContent::Content) } @@ -775,7 +803,7 @@ mod content { where D: Deserializer<'de>, { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_some(deserializer) .map(TagOrContent::Content) } @@ -784,7 +812,7 @@ mod content { where D: Deserializer<'de>, { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_newtype_struct(deserializer) .map(TagOrContent::Content) } @@ -793,7 +821,7 @@ mod content { where V: SeqAccess<'de>, { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_seq(visitor) .map(TagOrContent::Content) } @@ -802,7 +830,7 @@ mod content { where V: MapAccess<'de>, { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_map(visitor) .map(TagOrContent::Content) } @@ -811,7 +839,7 @@ mod content { where V: EnumAccess<'de>, { - ContentVisitor::new() + ContentVisitor::new(&self.state) .visit_enum(visitor) .map(TagOrContent::Content) } @@ -829,15 +857,17 @@ mod content { pub struct TaggedContentVisitor<'de, T> { tag_name: &'static str, value: PhantomData>, + state: State, } impl<'de, T> TaggedContentVisitor<'de, T> { /// Visitor for the content of an internally tagged enum with the given tag /// name. - pub fn new(name: &'static str) -> Self { + pub fn new(name: &'static str, state: State) -> Self { TaggedContentVisitor { tag_name: name, value: PhantomData, + state: state, } } } @@ -878,7 +908,7 @@ mod content { return Err(de::Error::missing_field(self.tag_name)); } }; - let rest = de::value::SeqAccessDeserializer::new(seq); + let rest = de::value::SeqAccessDeserializer::new_with_state(seq, self.state.clone()); Ok(TaggedContent { tag: tag, content: try!(Content::deserialize(rest)), @@ -891,7 +921,7 @@ mod content { { let mut tag = None; let mut vec = Vec::with_capacity(size_hint::cautious(map.size_hint())); - while let Some(k) = try!(map.next_key_seed(TagOrContentVisitor::new(self.tag_name))) { + while let Some(k) = try!(map.next_key_seed(TagOrContentVisitor::new(self.tag_name, &self.state))) { match k { TagOrContent::Tag => { if tag.is_some() { @@ -909,7 +939,7 @@ mod content { None => Err(de::Error::missing_field(self.tag_name)), Some(tag) => Ok(TaggedContent { tag: tag, - content: Content::Map(vec), + content: Content::new(ContentRepr::Map(vec), &self.state), }), } } @@ -1032,27 +1062,27 @@ mod content { where V: Visitor<'de>, { - match self.content { - Content::U8(v) => visitor.visit_u8(v), - Content::U16(v) => visitor.visit_u16(v), - Content::U32(v) => visitor.visit_u32(v), - Content::U64(v) => visitor.visit_u64(v), - Content::I8(v) => visitor.visit_i8(v), - Content::I16(v) => visitor.visit_i16(v), - Content::I32(v) => visitor.visit_i32(v), - Content::I64(v) => visitor.visit_i64(v), + match self.content.repr { + ContentRepr::U8(v) => visitor.visit_u8(v), + ContentRepr::U16(v) => visitor.visit_u16(v), + ContentRepr::U32(v) => visitor.visit_u32(v), + ContentRepr::U64(v) => visitor.visit_u64(v), + ContentRepr::I8(v) => visitor.visit_i8(v), + ContentRepr::I16(v) => visitor.visit_i16(v), + ContentRepr::I32(v) => visitor.visit_i32(v), + ContentRepr::I64(v) => visitor.visit_i64(v), _ => Err(self.invalid_type(&visitor)), } } } - fn visit_content_seq<'de, V, E>(content: Vec>, visitor: V) -> Result + fn visit_content_seq<'de, V, E>(content: Vec>, visitor: V, state: State) -> Result where V: Visitor<'de>, E: de::Error, { let seq = content.into_iter().map(ContentDeserializer::new); - let mut seq_visitor = de::value::SeqDeserializer::new(seq); + let mut seq_visitor = de::value::SeqDeserializer::new_with_state(seq, state); let value = try!(visitor.visit_seq(&mut seq_visitor)); try!(seq_visitor.end()); Ok(value) @@ -1061,6 +1091,7 @@ mod content { fn visit_content_map<'de, V, E>( content: Vec<(Content<'de>, Content<'de>)>, visitor: V, + state: State, ) -> Result where V: Visitor<'de>, @@ -1069,7 +1100,7 @@ mod content { let map = content .into_iter() .map(|(k, v)| (ContentDeserializer::new(k), ContentDeserializer::new(v))); - let mut map_visitor = de::value::MapDeserializer::new(map); + let mut map_visitor = de::value::MapDeserializer::new_with_state(map, state); let value = try!(visitor.visit_map(&mut map_visitor)); try!(map_visitor.end()); Ok(value) @@ -1083,33 +1114,38 @@ mod content { { type Error = E; + #[inline] + fn state(&self) -> &State { + self.content.state() + } + fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de>, { - match self.content { - Content::Bool(v) => visitor.visit_bool(v), - Content::U8(v) => visitor.visit_u8(v), - Content::U16(v) => visitor.visit_u16(v), - Content::U32(v) => visitor.visit_u32(v), - Content::U64(v) => visitor.visit_u64(v), - Content::I8(v) => visitor.visit_i8(v), - Content::I16(v) => visitor.visit_i16(v), - Content::I32(v) => visitor.visit_i32(v), - Content::I64(v) => visitor.visit_i64(v), - Content::F32(v) => visitor.visit_f32(v), - Content::F64(v) => visitor.visit_f64(v), - Content::Char(v) => visitor.visit_char(v), - Content::String(v) => visitor.visit_string(v), - Content::Str(v) => visitor.visit_borrowed_str(v), - Content::ByteBuf(v) => visitor.visit_byte_buf(v), - Content::Bytes(v) => visitor.visit_borrowed_bytes(v), - Content::Unit => visitor.visit_unit(), - Content::None => visitor.visit_none(), - Content::Some(v) => visitor.visit_some(ContentDeserializer::new(*v)), - Content::Newtype(v) => visitor.visit_newtype_struct(ContentDeserializer::new(*v)), - Content::Seq(v) => visit_content_seq(v, visitor), - Content::Map(v) => visit_content_map(v, visitor), + match self.content.repr { + ContentRepr::Bool(v) => visitor.visit_bool(v), + ContentRepr::U8(v) => visitor.visit_u8(v), + ContentRepr::U16(v) => visitor.visit_u16(v), + ContentRepr::U32(v) => visitor.visit_u32(v), + ContentRepr::U64(v) => visitor.visit_u64(v), + ContentRepr::I8(v) => visitor.visit_i8(v), + ContentRepr::I16(v) => visitor.visit_i16(v), + ContentRepr::I32(v) => visitor.visit_i32(v), + ContentRepr::I64(v) => visitor.visit_i64(v), + ContentRepr::F32(v) => visitor.visit_f32(v), + ContentRepr::F64(v) => visitor.visit_f64(v), + ContentRepr::Char(v) => visitor.visit_char(v), + ContentRepr::String(v) => visitor.visit_string(v), + ContentRepr::Str(v) => visitor.visit_borrowed_str(v), + ContentRepr::ByteBuf(v) => visitor.visit_byte_buf(v), + ContentRepr::Bytes(v) => visitor.visit_borrowed_bytes(v), + ContentRepr::Unit => visitor.visit_unit(), + ContentRepr::None => visitor.visit_none(), + ContentRepr::Some(v) => visitor.visit_some(ContentDeserializer::new(*v)), + ContentRepr::Newtype(v) => visitor.visit_newtype_struct(ContentDeserializer::new(*v)), + ContentRepr::Seq(v) => visit_content_seq(v, visitor, self.content.state), + ContentRepr::Map(v) => visit_content_map(v, visitor, self.content.state), } } @@ -1117,8 +1153,8 @@ mod content { where V: Visitor<'de>, { - match self.content { - Content::Bool(v) => visitor.visit_bool(v), + match self.content.repr { + ContentRepr::Bool(v) => visitor.visit_bool(v), _ => Err(self.invalid_type(&visitor)), } } @@ -1183,11 +1219,11 @@ mod content { where V: Visitor<'de>, { - match self.content { - Content::F32(v) => visitor.visit_f32(v), - Content::F64(v) => visitor.visit_f64(v), - Content::U64(v) => visitor.visit_u64(v), - Content::I64(v) => visitor.visit_i64(v), + match self.content.repr { + ContentRepr::F32(v) => visitor.visit_f32(v), + ContentRepr::F64(v) => visitor.visit_f64(v), + ContentRepr::U64(v) => visitor.visit_u64(v), + ContentRepr::I64(v) => visitor.visit_i64(v), _ => Err(self.invalid_type(&visitor)), } } @@ -1196,10 +1232,10 @@ mod content { where V: Visitor<'de>, { - match self.content { - Content::F64(v) => visitor.visit_f64(v), - Content::U64(v) => visitor.visit_u64(v), - Content::I64(v) => visitor.visit_i64(v), + match self.content.repr { + ContentRepr::F64(v) => visitor.visit_f64(v), + ContentRepr::U64(v) => visitor.visit_u64(v), + ContentRepr::I64(v) => visitor.visit_i64(v), _ => Err(self.invalid_type(&visitor)), } } @@ -1208,10 +1244,10 @@ mod content { where V: Visitor<'de>, { - match self.content { - Content::Char(v) => visitor.visit_char(v), - Content::String(v) => visitor.visit_string(v), - Content::Str(v) => visitor.visit_borrowed_str(v), + match self.content.repr { + ContentRepr::Char(v) => visitor.visit_char(v), + ContentRepr::String(v) => visitor.visit_string(v), + ContentRepr::Str(v) => visitor.visit_borrowed_str(v), _ => Err(self.invalid_type(&visitor)), } } @@ -1227,11 +1263,11 @@ mod content { where V: Visitor<'de>, { - match self.content { - Content::String(v) => visitor.visit_string(v), - Content::Str(v) => visitor.visit_borrowed_str(v), - Content::ByteBuf(v) => visitor.visit_byte_buf(v), - Content::Bytes(v) => visitor.visit_borrowed_bytes(v), + match self.content.repr { + ContentRepr::String(v) => visitor.visit_string(v), + ContentRepr::Str(v) => visitor.visit_borrowed_str(v), + ContentRepr::ByteBuf(v) => visitor.visit_byte_buf(v), + ContentRepr::Bytes(v) => visitor.visit_borrowed_bytes(v), _ => Err(self.invalid_type(&visitor)), } } @@ -1247,12 +1283,12 @@ mod content { where V: Visitor<'de>, { - match self.content { - Content::String(v) => visitor.visit_string(v), - Content::Str(v) => visitor.visit_borrowed_str(v), - Content::ByteBuf(v) => visitor.visit_byte_buf(v), - Content::Bytes(v) => visitor.visit_borrowed_bytes(v), - Content::Seq(v) => visit_content_seq(v, visitor), + match self.content.repr { + ContentRepr::String(v) => visitor.visit_string(v), + ContentRepr::Str(v) => visitor.visit_borrowed_str(v), + ContentRepr::ByteBuf(v) => visitor.visit_byte_buf(v), + ContentRepr::Bytes(v) => visitor.visit_borrowed_bytes(v), + ContentRepr::Seq(v) => visit_content_seq(v, visitor, self.content.state), _ => Err(self.invalid_type(&visitor)), } } @@ -1261,10 +1297,10 @@ mod content { where V: Visitor<'de>, { - match self.content { - Content::None => visitor.visit_none(), - Content::Some(v) => visitor.visit_some(ContentDeserializer::new(*v)), - Content::Unit => visitor.visit_unit(), + match self.content.repr { + ContentRepr::None => visitor.visit_none(), + ContentRepr::Some(v) => visitor.visit_some(ContentDeserializer::new(*v)), + ContentRepr::Unit => visitor.visit_unit(), _ => visitor.visit_some(self), } } @@ -1273,8 +1309,8 @@ mod content { where V: Visitor<'de>, { - match self.content { - Content::Unit => visitor.visit_unit(), + match self.content.repr { + ContentRepr::Unit => visitor.visit_unit(), _ => Err(self.invalid_type(&visitor)), } } @@ -1287,7 +1323,7 @@ mod content { where V: Visitor<'de>, { - match self.content { + match self.content.repr { // As a special case, allow deserializing untagged newtype // variant containing unit struct. // @@ -1302,7 +1338,7 @@ mod content { // // We want {"topic":"Info"} to deserialize even though // ordinarily unit structs do not deserialize from empty map. - Content::Map(ref v) if v.is_empty() => visitor.visit_unit(), + ContentRepr::Map(ref v) if v.is_empty() => visitor.visit_unit(), _ => self.deserialize_any(visitor), } } @@ -1315,8 +1351,8 @@ mod content { where V: Visitor<'de>, { - match self.content { - Content::Newtype(v) => visitor.visit_newtype_struct(ContentDeserializer::new(*v)), + match self.content.repr { + ContentRepr::Newtype(v) => visitor.visit_newtype_struct(ContentDeserializer::new(*v)), _ => visitor.visit_newtype_struct(self), } } @@ -1325,8 +1361,8 @@ mod content { where V: Visitor<'de>, { - match self.content { - Content::Seq(v) => visit_content_seq(v, visitor), + match self.content.repr { + ContentRepr::Seq(v) => visit_content_seq(v, visitor, self.content.state), _ => Err(self.invalid_type(&visitor)), } } @@ -1354,8 +1390,8 @@ mod content { where V: Visitor<'de>, { - match self.content { - Content::Map(v) => visit_content_map(v, visitor), + match self.content.repr { + ContentRepr::Map(v) => visit_content_map(v, visitor, self.content.state), _ => Err(self.invalid_type(&visitor)), } } @@ -1369,9 +1405,9 @@ mod content { where V: Visitor<'de>, { - match self.content { - Content::Seq(v) => visit_content_seq(v, visitor), - Content::Map(v) => visit_content_map(v, visitor), + match self.content.repr { + ContentRepr::Seq(v) => visit_content_seq(v, visitor, self.content.state), + ContentRepr::Map(v) => visit_content_map(v, visitor, self.content.state), _ => Err(self.invalid_type(&visitor)), } } @@ -1386,7 +1422,7 @@ mod content { V: Visitor<'de>, { let (variant, value) = match self.content { - Content::Map(value) => { + Content { repr: ContentRepr::Map(value), .. } => { let mut iter = value.into_iter(); let (variant, value) = match iter.next() { Some(v) => v, @@ -1406,7 +1442,8 @@ mod content { } (variant, Some(value)) } - s @ Content::String(_) | s @ Content::Str(_) => (s, None), + s @ Content { repr: ContentRepr::String(_), ..} | + s @ Content { repr: ContentRepr::Str(_), .. } => (s, None), other => { return Err(de::Error::invalid_type( other.unexpected(), @@ -1422,11 +1459,11 @@ mod content { where V: Visitor<'de>, { - match self.content { - Content::String(v) => visitor.visit_string(v), - Content::Str(v) => visitor.visit_borrowed_str(v), - Content::ByteBuf(v) => visitor.visit_byte_buf(v), - Content::Bytes(v) => visitor.visit_borrowed_bytes(v), + match self.content.repr { + ContentRepr::String(v) => visitor.visit_string(v), + ContentRepr::Str(v) => visitor.visit_borrowed_str(v), + ContentRepr::ByteBuf(v) => visitor.visit_byte_buf(v), + ContentRepr::Bytes(v) => visitor.visit_borrowed_bytes(v), _ => Err(self.invalid_type(&visitor)), } } @@ -1531,8 +1568,8 @@ mod content { V: de::Visitor<'de>, { match self.value { - Some(Content::Seq(v)) => { - de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor) + Some(Content { repr: ContentRepr::Seq(v), state }) => { + de::Deserializer::deserialize_any(SeqDeserializer::new(v, state), visitor) } Some(other) => Err(de::Error::invalid_type( other.unexpected(), @@ -1554,11 +1591,11 @@ mod content { V: de::Visitor<'de>, { match self.value { - Some(Content::Map(v)) => { - de::Deserializer::deserialize_any(MapDeserializer::new(v), visitor) + Some(Content { repr: ContentRepr::Map(v), state }) => { + de::Deserializer::deserialize_any(MapDeserializer::new(v, state), visitor) } - Some(Content::Seq(v)) => { - de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor) + Some(Content { repr: ContentRepr::Seq(v), state }) => { + de::Deserializer::deserialize_any(SeqDeserializer::new(v, state), visitor) } Some(other) => Err(de::Error::invalid_type( other.unexpected(), @@ -1577,6 +1614,7 @@ mod content { E: de::Error, { iter: > as IntoIterator>::IntoIter, + state: State, err: PhantomData, } @@ -1584,9 +1622,10 @@ mod content { where E: de::Error, { - fn new(vec: Vec>) -> Self { + fn new(vec: Vec>, state: State) -> Self { SeqDeserializer { iter: vec.into_iter(), + state: state, err: PhantomData, } } @@ -1598,6 +1637,8 @@ mod content { { type Error = E; + forward_deserializer_state_to_field!(); + #[inline] fn deserialize_any(mut self, visitor: V) -> Result where @@ -1651,6 +1692,7 @@ mod content { { iter: , Content<'de>)> as IntoIterator>::IntoIter, value: Option>, + state: State, err: PhantomData, } @@ -1658,10 +1700,11 @@ mod content { where E: de::Error, { - fn new(map: Vec<(Content<'de>, Content<'de>)>) -> Self { + fn new(map: Vec<(Content<'de>, Content<'de>)>, state: State) -> Self { MapDeserializer { iter: map.into_iter(), value: None, + state: state, err: PhantomData, } } @@ -1707,6 +1750,8 @@ mod content { { type Error = E; + forward_deserializer_state_to_field!(); + #[inline] fn deserialize_any(self, visitor: V) -> Result where @@ -1725,6 +1770,7 @@ mod content { /// Not public API. pub struct ContentRefDeserializer<'a, 'de: 'a, E> { content: &'a Content<'de>, + state: State, err: PhantomData, } @@ -1741,15 +1787,15 @@ mod content { where V: Visitor<'de>, { - match *self.content { - Content::U8(v) => visitor.visit_u8(v), - Content::U16(v) => visitor.visit_u16(v), - Content::U32(v) => visitor.visit_u32(v), - Content::U64(v) => visitor.visit_u64(v), - Content::I8(v) => visitor.visit_i8(v), - Content::I16(v) => visitor.visit_i16(v), - Content::I32(v) => visitor.visit_i32(v), - Content::I64(v) => visitor.visit_i64(v), + match self.content.repr { + ContentRepr::U8(v) => visitor.visit_u8(v), + ContentRepr::U16(v) => visitor.visit_u16(v), + ContentRepr::U32(v) => visitor.visit_u32(v), + ContentRepr::U64(v) => visitor.visit_u64(v), + ContentRepr::I8(v) => visitor.visit_i8(v), + ContentRepr::I16(v) => visitor.visit_i16(v), + ContentRepr::I32(v) => visitor.visit_i32(v), + ContentRepr::I64(v) => visitor.visit_i64(v), _ => Err(self.invalid_type(&visitor)), } } @@ -1758,13 +1804,14 @@ mod content { fn visit_content_seq_ref<'a, 'de, V, E>( content: &'a [Content<'de>], visitor: V, + state: State, ) -> Result where V: Visitor<'de>, E: de::Error, { let seq = content.into_iter().map(ContentRefDeserializer::new); - let mut seq_visitor = de::value::SeqDeserializer::new(seq); + let mut seq_visitor = de::value::SeqDeserializer::new_with_state(seq, state); let value = try!(visitor.visit_seq(&mut seq_visitor)); try!(seq_visitor.end()); Ok(value) @@ -1773,6 +1820,7 @@ mod content { fn visit_content_map_ref<'a, 'de, V, E>( content: &'a [(Content<'de>, Content<'de>)], visitor: V, + state: State, ) -> Result where V: Visitor<'de>, @@ -1784,7 +1832,7 @@ mod content { ContentRefDeserializer::new(v), ) }); - let mut map_visitor = de::value::MapDeserializer::new(map); + let mut map_visitor = de::value::MapDeserializer::new_with_state(map, state); let value = try!(visitor.visit_map(&mut map_visitor)); try!(map_visitor.end()); Ok(value) @@ -1798,35 +1846,37 @@ mod content { { type Error = E; + forward_deserializer_state_to_field!(); + fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de>, { - match *self.content { - Content::Bool(v) => visitor.visit_bool(v), - Content::U8(v) => visitor.visit_u8(v), - Content::U16(v) => visitor.visit_u16(v), - Content::U32(v) => visitor.visit_u32(v), - Content::U64(v) => visitor.visit_u64(v), - Content::I8(v) => visitor.visit_i8(v), - Content::I16(v) => visitor.visit_i16(v), - Content::I32(v) => visitor.visit_i32(v), - Content::I64(v) => visitor.visit_i64(v), - Content::F32(v) => visitor.visit_f32(v), - Content::F64(v) => visitor.visit_f64(v), - Content::Char(v) => visitor.visit_char(v), - Content::String(ref v) => visitor.visit_str(v), - Content::Str(v) => visitor.visit_borrowed_str(v), - Content::ByteBuf(ref v) => visitor.visit_bytes(v), - Content::Bytes(v) => visitor.visit_borrowed_bytes(v), - Content::Unit => visitor.visit_unit(), - Content::None => visitor.visit_none(), - Content::Some(ref v) => visitor.visit_some(ContentRefDeserializer::new(v)), - Content::Newtype(ref v) => { + match self.content.repr { + ContentRepr::Bool(v) => visitor.visit_bool(v), + ContentRepr::U8(v) => visitor.visit_u8(v), + ContentRepr::U16(v) => visitor.visit_u16(v), + ContentRepr::U32(v) => visitor.visit_u32(v), + ContentRepr::U64(v) => visitor.visit_u64(v), + ContentRepr::I8(v) => visitor.visit_i8(v), + ContentRepr::I16(v) => visitor.visit_i16(v), + ContentRepr::I32(v) => visitor.visit_i32(v), + ContentRepr::I64(v) => visitor.visit_i64(v), + ContentRepr::F32(v) => visitor.visit_f32(v), + ContentRepr::F64(v) => visitor.visit_f64(v), + ContentRepr::Char(v) => visitor.visit_char(v), + ContentRepr::String(ref v) => visitor.visit_str(v), + ContentRepr::Str(v) => visitor.visit_borrowed_str(v), + ContentRepr::ByteBuf(ref v) => visitor.visit_bytes(v), + ContentRepr::Bytes(v) => visitor.visit_borrowed_bytes(v), + ContentRepr::Unit => visitor.visit_unit(), + ContentRepr::None => visitor.visit_none(), + ContentRepr::Some(ref v) => visitor.visit_some(ContentRefDeserializer::new(v)), + ContentRepr::Newtype(ref v) => { visitor.visit_newtype_struct(ContentRefDeserializer::new(v)) } - Content::Seq(ref v) => visit_content_seq_ref(v, visitor), - Content::Map(ref v) => visit_content_map_ref(v, visitor), + ContentRepr::Seq(ref v) => visit_content_seq_ref(v, visitor, self.content.state.clone()), + ContentRepr::Map(ref v) => visit_content_map_ref(v, visitor, self.content.state.clone()), } } @@ -1834,8 +1884,8 @@ mod content { where V: Visitor<'de>, { - match *self.content { - Content::Bool(v) => visitor.visit_bool(v), + match self.content.repr { + ContentRepr::Bool(v) => visitor.visit_bool(v), _ => Err(self.invalid_type(&visitor)), } } @@ -1900,11 +1950,11 @@ mod content { where V: Visitor<'de>, { - match *self.content { - Content::F32(v) => visitor.visit_f32(v), - Content::F64(v) => visitor.visit_f64(v), - Content::U64(v) => visitor.visit_u64(v), - Content::I64(v) => visitor.visit_i64(v), + match self.content.repr { + ContentRepr::F32(v) => visitor.visit_f32(v), + ContentRepr::F64(v) => visitor.visit_f64(v), + ContentRepr::U64(v) => visitor.visit_u64(v), + ContentRepr::I64(v) => visitor.visit_i64(v), _ => Err(self.invalid_type(&visitor)), } } @@ -1913,10 +1963,10 @@ mod content { where V: Visitor<'de>, { - match *self.content { - Content::F64(v) => visitor.visit_f64(v), - Content::U64(v) => visitor.visit_u64(v), - Content::I64(v) => visitor.visit_i64(v), + match self.content.repr { + ContentRepr::F64(v) => visitor.visit_f64(v), + ContentRepr::U64(v) => visitor.visit_u64(v), + ContentRepr::I64(v) => visitor.visit_i64(v), _ => Err(self.invalid_type(&visitor)), } } @@ -1925,10 +1975,10 @@ mod content { where V: Visitor<'de>, { - match *self.content { - Content::Char(v) => visitor.visit_char(v), - Content::String(ref v) => visitor.visit_str(v), - Content::Str(v) => visitor.visit_borrowed_str(v), + match self.content.repr { + ContentRepr::Char(v) => visitor.visit_char(v), + ContentRepr::String(ref v) => visitor.visit_str(v), + ContentRepr::Str(v) => visitor.visit_borrowed_str(v), _ => Err(self.invalid_type(&visitor)), } } @@ -1937,11 +1987,11 @@ mod content { where V: Visitor<'de>, { - match *self.content { - Content::String(ref v) => visitor.visit_str(v), - Content::Str(v) => visitor.visit_borrowed_str(v), - Content::ByteBuf(ref v) => visitor.visit_bytes(v), - Content::Bytes(v) => visitor.visit_borrowed_bytes(v), + match self.content.repr { + ContentRepr::String(ref v) => visitor.visit_str(v), + ContentRepr::Str(v) => visitor.visit_borrowed_str(v), + ContentRepr::ByteBuf(ref v) => visitor.visit_bytes(v), + ContentRepr::Bytes(v) => visitor.visit_borrowed_bytes(v), _ => Err(self.invalid_type(&visitor)), } } @@ -1957,12 +2007,12 @@ mod content { where V: Visitor<'de>, { - match *self.content { - Content::String(ref v) => visitor.visit_str(v), - Content::Str(v) => visitor.visit_borrowed_str(v), - Content::ByteBuf(ref v) => visitor.visit_bytes(v), - Content::Bytes(v) => visitor.visit_borrowed_bytes(v), - Content::Seq(ref v) => visit_content_seq_ref(v, visitor), + match self.content.repr { + ContentRepr::String(ref v) => visitor.visit_str(v), + ContentRepr::Str(v) => visitor.visit_borrowed_str(v), + ContentRepr::ByteBuf(ref v) => visitor.visit_bytes(v), + ContentRepr::Bytes(v) => visitor.visit_borrowed_bytes(v), + ContentRepr::Seq(ref v) => visit_content_seq_ref(v, visitor, self.content.state.clone()), _ => Err(self.invalid_type(&visitor)), } } @@ -1978,10 +2028,10 @@ mod content { where V: Visitor<'de>, { - match *self.content { - Content::None => visitor.visit_none(), - Content::Some(ref v) => visitor.visit_some(ContentRefDeserializer::new(v)), - Content::Unit => visitor.visit_unit(), + match self.content.repr { + ContentRepr::None => visitor.visit_none(), + ContentRepr::Some(ref v) => visitor.visit_some(ContentRefDeserializer::new(v)), + ContentRepr::Unit => visitor.visit_unit(), _ => visitor.visit_some(self), } } @@ -1990,8 +2040,8 @@ mod content { where V: Visitor<'de>, { - match *self.content { - Content::Unit => visitor.visit_unit(), + match self.content.repr { + ContentRepr::Unit => visitor.visit_unit(), _ => Err(self.invalid_type(&visitor)), } } @@ -2011,8 +2061,8 @@ mod content { where V: Visitor<'de>, { - match *self.content { - Content::Newtype(ref v) => { + match self.content.repr { + ContentRepr::Newtype(ref v) => { visitor.visit_newtype_struct(ContentRefDeserializer::new(v)) } _ => visitor.visit_newtype_struct(self), @@ -2023,8 +2073,8 @@ mod content { where V: Visitor<'de>, { - match *self.content { - Content::Seq(ref v) => visit_content_seq_ref(v, visitor), + match self.content.repr { + ContentRepr::Seq(ref v) => visit_content_seq_ref(v, visitor, self.content.state.clone()), _ => Err(self.invalid_type(&visitor)), } } @@ -2052,8 +2102,8 @@ mod content { where V: Visitor<'de>, { - match *self.content { - Content::Map(ref v) => visit_content_map_ref(v, visitor), + match self.content.repr { + ContentRepr::Map(ref v) => visit_content_map_ref(v, visitor, self.content.state.clone()), _ => Err(self.invalid_type(&visitor)), } } @@ -2067,9 +2117,9 @@ mod content { where V: Visitor<'de>, { - match *self.content { - Content::Seq(ref v) => visit_content_seq_ref(v, visitor), - Content::Map(ref v) => visit_content_map_ref(v, visitor), + match self.content.repr { + ContentRepr::Seq(ref v) => visit_content_seq_ref(v, visitor, self.content.state.clone()), + ContentRepr::Map(ref v) => visit_content_map_ref(v, visitor, self.content.state.clone()), _ => Err(self.invalid_type(&visitor)), } } @@ -2083,8 +2133,8 @@ mod content { where V: Visitor<'de>, { - let (variant, value) = match *self.content { - Content::Map(ref value) => { + let (variant, value) = match self.content { + &Content { repr: ContentRepr::Map(ref value), ..} => { let mut iter = value.into_iter(); let &(ref variant, ref value) = match iter.next() { Some(v) => v, @@ -2104,7 +2154,8 @@ mod content { } (variant, Some(value)) } - ref s @ Content::String(_) | ref s @ Content::Str(_) => (s, None), + ref s @ &Content { repr: ContentRepr::String(_), ..} | + ref s @ &Content { repr: ContentRepr::Str(_), ..} => (*s, None), ref other => { return Err(de::Error::invalid_type( other.unexpected(), @@ -2124,11 +2175,11 @@ mod content { where V: Visitor<'de>, { - match *self.content { - Content::String(ref v) => visitor.visit_str(v), - Content::Str(v) => visitor.visit_borrowed_str(v), - Content::ByteBuf(ref v) => visitor.visit_bytes(v), - Content::Bytes(v) => visitor.visit_borrowed_bytes(v), + match self.content.repr { + ContentRepr::String(ref v) => visitor.visit_str(v), + ContentRepr::Str(v) => visitor.visit_borrowed_str(v), + ContentRepr::ByteBuf(ref v) => visitor.visit_bytes(v), + ContentRepr::Bytes(v) => visitor.visit_borrowed_bytes(v), _ => Err(self.invalid_type(&visitor)), } } @@ -2146,6 +2197,7 @@ mod content { pub fn new(content: &'a Content<'de>) -> Self { ContentRefDeserializer { content: content, + state: content.state().clone(), err: PhantomData, } } @@ -2219,8 +2271,8 @@ mod content { V: de::Visitor<'de>, { match self.value { - Some(&Content::Seq(ref v)) => { - de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor) + Some(&Content { repr: ContentRepr::Seq(ref v), ref state }) => { + de::Deserializer::deserialize_any(SeqRefDeserializer::new(v, state.clone()), visitor) } Some(other) => Err(de::Error::invalid_type( other.unexpected(), @@ -2242,11 +2294,11 @@ mod content { V: de::Visitor<'de>, { match self.value { - Some(&Content::Map(ref v)) => { - de::Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor) + Some(&Content { repr: ContentRepr::Map(ref v), ref state }) => { + de::Deserializer::deserialize_any(MapRefDeserializer::new(v, state.clone()), visitor) } - Some(&Content::Seq(ref v)) => { - de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor) + Some(&Content { repr: ContentRepr::Seq(ref v), ref state }) => { + de::Deserializer::deserialize_any(SeqRefDeserializer::new(v, state.clone()), visitor) } Some(other) => Err(de::Error::invalid_type( other.unexpected(), @@ -2265,6 +2317,7 @@ mod content { E: de::Error, { iter: <&'a [Content<'de>] as IntoIterator>::IntoIter, + state: State, err: PhantomData, } @@ -2272,9 +2325,10 @@ mod content { where E: de::Error, { - fn new(vec: &'a [Content<'de>]) -> Self { + fn new(vec: &'a [Content<'de>], state: State) -> Self { SeqRefDeserializer { iter: vec.into_iter(), + state: state, err: PhantomData, } } @@ -2286,6 +2340,8 @@ mod content { { type Error = E; + forward_deserializer_state_to_field!(); + #[inline] fn deserialize_any(mut self, visitor: V) -> Result where @@ -2341,6 +2397,7 @@ mod content { { iter: <&'a [(Content<'de>, Content<'de>)] as IntoIterator>::IntoIter, value: Option<&'a Content<'de>>, + state: State, err: PhantomData, } @@ -2348,10 +2405,11 @@ mod content { where E: de::Error, { - fn new(map: &'a [(Content<'de>, Content<'de>)]) -> Self { + fn new(map: &'a [(Content<'de>, Content<'de>)], state: State) -> Self { MapRefDeserializer { iter: map.into_iter(), value: None, + state: state, err: PhantomData, } } @@ -2397,6 +2455,8 @@ mod content { { type Error = E; + forward_deserializer_state_to_field!(); + #[inline] fn deserialize_any(self, visitor: V) -> Result where @@ -2421,6 +2481,13 @@ mod content { fn into_deserializer(self) -> Self { self } + + fn into_deserializer_with_state(self, state: State) -> Self { + // do not use the state passed in but keep the one that we have already + // on the content. + let _state = state; + self + } } impl<'de, 'a, E> de::IntoDeserializer<'de, E> for ContentRefDeserializer<'a, 'de, E> @@ -2432,6 +2499,13 @@ mod content { fn into_deserializer(self) -> Self { self } + + fn into_deserializer_with_state(self, state: State) -> Self { + // do not use the state passed in but keep the one that we have already + // on the content. + let _state = state; + self + } } /// Visitor for deserializing an internally tagged unit variant. @@ -2532,6 +2606,15 @@ pub trait IdentifierDeserializer<'de, E: Error> { type Deserializer: Deserializer<'de, Error = E>; fn from(self) -> Self::Deserializer; + + fn from_with_state(self, new_state: State) -> Self::Deserializer + where Self: Sized + { + if !new_state.is_empty() { + panic!("This identfier deserializer does not support state"); + } + IdentifierDeserializer::from(self) + } } impl<'de, E> IdentifierDeserializer<'de, E> for u32 @@ -2543,10 +2626,15 @@ where fn from(self) -> Self::Deserializer { self.into_deserializer() } + + fn from_with_state(self, state: State) -> Self::Deserializer { + self.into_deserializer_with_state(state) + } } pub struct StrDeserializer<'a, E> { value: &'a str, + state: State, marker: PhantomData, } @@ -2557,8 +2645,13 @@ where type Deserializer = StrDeserializer<'a, E>; fn from(self) -> Self::Deserializer { + Self::from_with_state(self, State::default()) + } + + fn from_with_state(self, state: State) -> Self::Deserializer { StrDeserializer { value: self, + state: state, marker: PhantomData, } } @@ -2570,6 +2663,8 @@ where { type Error = E; + forward_deserializer_state_to_field!(); + fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de>, @@ -2586,6 +2681,7 @@ where pub struct BytesDeserializer<'a, E> { value: &'a [u8], + state: State, marker: PhantomData, } @@ -2596,8 +2692,13 @@ where type Deserializer = BytesDeserializer<'a, E>; fn from(self) -> Self::Deserializer { + Self::from_with_state(self, State::default()) + } + + fn from_with_state(self, state: State) -> Self::Deserializer { BytesDeserializer { value: self, + state: state, marker: PhantomData, } } @@ -2609,6 +2710,8 @@ where { type Error = E; + forward_deserializer_state_to_field!(); + fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de>, @@ -2644,6 +2747,7 @@ where #[cfg(any(feature = "std", feature = "alloc"))] pub struct FlatMapDeserializer<'a, 'de: 'a, E>( pub &'a mut Vec, Content<'de>)>>, + pub State, pub PhantomData, ); @@ -2678,6 +2782,8 @@ where { type Error = E; + forward_deserializer_state_to_field!(1); + fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de>, diff --git a/serde_derive/Cargo.toml b/serde_derive/Cargo.toml index cf19fbecb..a05a2f4cb 100644 --- a/serde_derive/Cargo.toml +++ b/serde_derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde_derive" -version = "1.0.69" # remember to update html_root_url +version = "1.0.999" # remember to update html_root_url authors = ["Erick Tryzelaar ", "David Tolnay "] license = "MIT/Apache-2.0" description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 10177a85c..80e48340a 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -401,7 +401,9 @@ fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fra let expecting = format!("unit struct {}", params.type_name()); quote_block! { - struct __Visitor; + struct __Visitor { + state: _serde::de::State, + } impl<'de> _serde::de::Visitor<'de> for __Visitor { type Value = #this; @@ -419,7 +421,10 @@ fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fra } } - _serde::Deserializer::deserialize_unit_struct(__deserializer, #type_name, __Visitor) + let __state = _serde::Deserializer::state(&__deserializer).clone(); + _serde::Deserializer::deserialize_unit_struct(__deserializer, #type_name, __Visitor { + state: __state, + }) } } @@ -473,18 +478,31 @@ fn deserialize_tuple( __Visitor { marker: _serde::export::PhantomData::<#this #ty_generics>, lifetime: _serde::export::PhantomData, + state: __state, } }; - let dispatch = if let Some(deserializer) = deserializer { - quote!(_serde::Deserializer::deserialize_tuple(#deserializer, #nfields, #visitor_expr)) + let (state_expr, dispatch) = if deserializer.is_some() { + ( + quote!(_serde::Deserializer::state(&__other_deserializer).clone()), + quote!(_serde::Deserializer::deserialize_tuple(__other_deserializer, #nfields, #visitor_expr)) + ) } else if is_enum { - quote!(_serde::de::VariantAccess::tuple_variant(__variant, #nfields, #visitor_expr)) + ( + quote!(self.state.clone()), + quote!(_serde::de::VariantAccess::tuple_variant(__variant, #nfields, #visitor_expr)) + ) } else if nfields == 1 { let type_name = cattrs.name().deserialize_name(); - quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr)) + ( + quote!(_serde::Deserializer::state(&__deserializer).clone()), + quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr)) + ) } else { let type_name = cattrs.name().deserialize_name(); - quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #nfields, #visitor_expr)) + ( + quote!(_serde::Deserializer::state(&__deserializer).clone()), + quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #nfields, #visitor_expr)) + ) }; let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); @@ -494,10 +512,17 @@ fn deserialize_tuple( quote!(mut __seq) }; + let init_deserializer = deserializer.map(|deserializer| { + quote! { + let __other_deserializer = #deserializer; + } + }); + quote_block! { struct __Visitor #de_impl_generics #where_clause { marker: _serde::export::PhantomData<#this #ty_generics>, lifetime: _serde::export::PhantomData<&#delife ()>, + state: _serde::de::State, } impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause { @@ -518,6 +543,8 @@ fn deserialize_tuple( } } + #init_deserializer + let __state = #state_expr; #dispatch } } @@ -557,19 +584,32 @@ fn deserialize_tuple_in_place( __Visitor { place: __place, lifetime: _serde::export::PhantomData, + state: __state, } }; - let dispatch = if let Some(deserializer) = deserializer { - quote!(_serde::Deserializer::deserialize_tuple(#deserializer, #nfields, #visitor_expr)) + let (state_expr, dispatch) = if deserializer.is_some() { + ( + quote!(_serde::Deserializer::state(&__other_deserializer).clone()), + quote!(_serde::Deserializer::deserialize_tuple(__other_deserializer, #nfields, #visitor_expr)) + ) } else if is_enum { - quote!(_serde::de::VariantAccess::tuple_variant(__variant, #nfields, #visitor_expr)) + ( + quote!(self.state.clone()), + quote!(_serde::de::VariantAccess::tuple_variant(__variant, #nfields, #visitor_expr)) + ) } else if nfields == 1 { let type_name = cattrs.name().deserialize_name(); - quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr)) + ( + quote!(_serde::Deserializer::state(&__deserializer).clone()), + quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr)) + ) } else { let type_name = cattrs.name().deserialize_name(); - quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #nfields, #visitor_expr)) + ( + quote!(_serde::Deserializer::state(&__deserializer).clone()), + quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #nfields, #visitor_expr)) + ) }; let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); @@ -579,6 +619,12 @@ fn deserialize_tuple_in_place( quote!(mut __seq) }; + let init_deserializer = deserializer.map(|deserializer| { + quote! { + let __other_deserializer = #deserializer; + } + }); + let in_place_impl_generics = de_impl_generics.in_place(); let in_place_ty_generics = de_ty_generics.in_place(); let place_life = place_lifetime(); @@ -587,6 +633,7 @@ fn deserialize_tuple_in_place( struct __Visitor #in_place_impl_generics #where_clause { place: &#place_life mut #this #ty_generics, lifetime: _serde::export::PhantomData<&#delife ()>, + state: _serde::de::State, } impl #in_place_impl_generics _serde::de::Visitor<#delife> for __Visitor #in_place_ty_generics #where_clause { @@ -607,6 +654,8 @@ fn deserialize_tuple_in_place( } } + #init_deserializer + let __state = #state_expr; #dispatch } } @@ -907,29 +956,45 @@ fn deserialize_struct( __Visitor { marker: _serde::export::PhantomData::<#this #ty_generics>, lifetime: _serde::export::PhantomData, + state: __state, } }; - let dispatch = if let Some(deserializer) = deserializer { - quote! { - _serde::Deserializer::deserialize_any(#deserializer, #visitor_expr) - } + let (state_expr, dispatch) = if deserializer.is_some() { + ( + quote!(_serde::Deserializer::state(&__other_deserializer).clone()), + quote! { + _serde::Deserializer::deserialize_any(__other_deserializer, #visitor_expr) + } + ) } else if is_enum && cattrs.has_flatten() { - quote! { - _serde::de::VariantAccess::newtype_variant_seed(__variant, #visitor_expr) - } + ( + quote!(self.state.clone()), + quote! { + _serde::de::VariantAccess::newtype_variant_seed(__variant, #visitor_expr) + } + ) } else if is_enum { - quote! { - _serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr) - } + ( + quote!(self.state.clone()), + quote! { + _serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr) + } + ) } else if cattrs.has_flatten() { - quote! { - _serde::Deserializer::deserialize_map(__deserializer, #visitor_expr) - } + ( + quote!(_serde::Deserializer::state(&__deserializer).clone()), + quote! { + _serde::Deserializer::deserialize_map(__deserializer, #visitor_expr) + } + ) } else { let type_name = cattrs.name().deserialize_name(); - quote! { - _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr) - } + ( + quote!(_serde::Deserializer::state(&__deserializer).clone()), + quote! { + _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr) + } + ) }; let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); @@ -939,6 +1004,12 @@ fn deserialize_struct( quote!(mut __seq) }; + let init_deserializer = deserializer.map(|deserializer| { + quote! { + let __other_deserializer = #deserializer; + } + }); + // untagged struct variants do not get a visit_seq method. The same applies to structs that // only have a map representation. let visit_seq = match *untagged { @@ -977,6 +1048,7 @@ fn deserialize_struct( struct __Visitor #de_impl_generics #where_clause { marker: _serde::export::PhantomData<#this #ty_generics>, lifetime: _serde::export::PhantomData<&#delife ()>, + state: _serde::de::State, } impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause { @@ -993,6 +1065,7 @@ fn deserialize_struct( where __A: _serde::de::MapAccess<#delife>, { + let __state = &self.state; #visit_map } } @@ -1000,6 +1073,8 @@ fn deserialize_struct( #visitor_seed #fields_stmt + #init_deserializer + let __state = #state_expr; #dispatch } @@ -1044,21 +1119,31 @@ fn deserialize_struct_in_place( __Visitor { place: __place, lifetime: _serde::export::PhantomData, + state: __state, } }; - let dispatch = if let Some(deserializer) = deserializer { - quote! { - _serde::Deserializer::deserialize_any(#deserializer, #visitor_expr) - } + let (state_expr, dispatch) = if deserializer.is_some() { + ( + quote!(_serde::Deserializer::state(&__other_deserializer).clone()), + quote! { + _serde::Deserializer::deserialize_any(__other_deserializer, #visitor_expr) + } + ) } else if is_enum { - quote! { - _serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr) - } + ( + quote!(self.state.clone()), + quote! { + _serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr) + } + ) } else { let type_name = cattrs.name().deserialize_name(); - quote! { - _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr) - } + ( + quote!(_serde::Deserializer::state(&__deserializer).clone()), + quote! { + _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr) + } + ) }; let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); @@ -1068,6 +1153,12 @@ fn deserialize_struct_in_place( quote!(mut __seq) }; + let init_deserializer = deserializer.map(|deserializer| { + quote! { + let __other_deserializer = #deserializer; + } + }); + let visit_seq = quote! { #[inline] fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result @@ -1088,6 +1179,7 @@ fn deserialize_struct_in_place( struct __Visitor #in_place_impl_generics #where_clause { place: &#place_life mut #this #ty_generics, lifetime: _serde::export::PhantomData<&#delife ()>, + state: _serde::de::State, } impl #in_place_impl_generics _serde::de::Visitor<#delife> for __Visitor #in_place_ty_generics #where_clause { @@ -1109,6 +1201,8 @@ fn deserialize_struct_in_place( } #fields_stmt + #init_deserializer + let __state = #state_expr; #dispatch }) @@ -1211,6 +1305,7 @@ fn deserialize_externally_tagged_enum( struct __Visitor #de_impl_generics #where_clause { marker: _serde::export::PhantomData<#this #ty_generics>, lifetime: _serde::export::PhantomData<&#delife ()>, + state: _serde::de::State, } impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause { @@ -1230,10 +1325,12 @@ fn deserialize_externally_tagged_enum( #variants_stmt + let __state = _serde::Deserializer::state(&__deserializer).clone(); _serde::Deserializer::deserialize_enum(__deserializer, #type_name, VARIANTS, __Visitor { marker: _serde::export::PhantomData::<#this #ty_generics>, lifetime: _serde::export::PhantomData, + state: __state, }) } } @@ -1291,9 +1388,10 @@ fn deserialize_internally_tagged_enum( #variants_stmt + let __state = _serde::Deserializer::state(&__deserializer).clone(); let __tagged = try!(_serde::Deserializer::deserialize_any( __deserializer, - _serde::private::de::TaggedContentVisitor::<__Field>::new(#tag))); + _serde::private::de::TaggedContentVisitor::<__Field>::new(#tag, __state))); match __tagged.tag { #(#variant_arms)* @@ -1499,6 +1597,7 @@ fn deserialize_adjacently_tagged_enum( struct __Visitor #de_impl_generics #where_clause { marker: _serde::export::PhantomData<#this #ty_generics>, lifetime: _serde::export::PhantomData<&#delife ()>, + state: _serde::de::State, } impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause { @@ -1597,10 +1696,12 @@ fn deserialize_adjacently_tagged_enum( } const FIELDS: &'static [&'static str] = &[#tag, #content]; + let __state = _serde::Deserializer::state(&__deserializer).clone(); _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, __Visitor { marker: _serde::export::PhantomData::<#this #ty_generics>, lifetime: _serde::export::PhantomData, + state: __state, }) } } @@ -1635,6 +1736,7 @@ fn deserialize_untagged_enum( quote_block! { let __content = try!(<_serde::private::de::Content as _serde::Deserialize>::deserialize(__deserializer)); + let __state = __content.state().clone(); #( if let _serde::export::Ok(__ok) = #attempts { @@ -1876,7 +1978,9 @@ fn deserialize_generated_identifier( #ignore_variant } - struct __FieldVisitor; + struct __FieldVisitor { + state: _serde::de::State, + } impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { type Value = __Field #lifetime; @@ -1890,7 +1994,10 @@ fn deserialize_generated_identifier( where __D: _serde::Deserializer<'de>, { - _serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor) + let __state = _serde::Deserializer::state(&__deserializer).clone(); + _serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor { + state: __state, + }) } } } @@ -1918,7 +2025,7 @@ fn deserialize_custom_identifier( (ordinary, Some(fallthrough)) } else if let Style::Newtype = last.style { let ordinary = &variants[..variants.len() - 1]; - let deserializer = quote!(_serde::private::de::IdentifierDeserializer::from(__value)); + let deserializer = quote!(_serde::private::de::IdentifierDeserializer::from_with_state(__value, self.state.clone())); let fallthrough = quote! { _serde::export::Result::map( _serde::Deserialize::deserialize(#deserializer), @@ -1975,6 +2082,7 @@ fn deserialize_custom_identifier( struct __FieldVisitor #de_impl_generics #where_clause { marker: _serde::export::PhantomData<#this #ty_generics>, lifetime: _serde::export::PhantomData<&#delife ()>, + state: _serde::de::State, } impl #de_impl_generics _serde::de::Visitor<#delife> for __FieldVisitor #de_ty_generics #where_clause { @@ -1986,6 +2094,7 @@ fn deserialize_custom_identifier( let __visitor = __FieldVisitor { marker: _serde::export::PhantomData::<#this #ty_generics>, lifetime: _serde::export::PhantomData, + state: _serde::Deserializer::state(&__deserializer).clone(), }; _serde::Deserializer::deserialize_identifier(__deserializer, __visitor) } @@ -2036,16 +2145,16 @@ fn deserialize_identifier( ) = if collect_other_fields { ( Some(quote! { - let __value = _serde::private::de::Content::String(__value.to_string()); + let __value = _serde::private::de::Content::new(_serde::private::de::ContentRepr::String(__value.to_string()), &self.state); }), Some(quote! { - let __value = _serde::private::de::Content::Str(__value); + let __value = _serde::private::de::Content::new(_serde::private::de::ContentRepr::Str(__value), &self.state); }), Some(quote! { - let __value = _serde::private::de::Content::ByteBuf(__value.to_vec()); + let __value = _serde::private::de::Content::new(_serde::private::de::ContentRepr::ByteBuf(__value.to_vec()), &self.state); }), Some(quote! { - let __value = _serde::private::de::Content::Bytes(__value); + let __value = _serde::private::de::Content::new(_serde::private::de::ContentRepr::Bytes(__value), &self.state); }), ) } else { @@ -2072,91 +2181,91 @@ fn deserialize_identifier( where __E: _serde::de::Error, { - _serde::export::Ok(__Field::__other(_serde::private::de::Content::Bool(__value))) + _serde::export::Ok(__Field::__other(_serde::private::de::Content::new(_serde::private::de::ContentRepr::Bool(__value), &self.state))) } fn visit_i8<__E>(self, __value: i8) -> _serde::export::Result where __E: _serde::de::Error, { - _serde::export::Ok(__Field::__other(_serde::private::de::Content::I8(__value))) + _serde::export::Ok(__Field::__other(_serde::private::de::Content::new(_serde::private::de::ContentRepr::I8(__value), &self.state))) } fn visit_i16<__E>(self, __value: i16) -> _serde::export::Result where __E: _serde::de::Error, { - _serde::export::Ok(__Field::__other(_serde::private::de::Content::I16(__value))) + _serde::export::Ok(__Field::__other(_serde::private::de::Content::new(_serde::private::de::ContentRepr::I16(__value), &self.state))) } fn visit_i32<__E>(self, __value: i32) -> _serde::export::Result where __E: _serde::de::Error, { - _serde::export::Ok(__Field::__other(_serde::private::de::Content::I32(__value))) + _serde::export::Ok(__Field::__other(_serde::private::de::Content::new(_serde::private::de::ContentRepr::I32(__value), &self.state))) } fn visit_i64<__E>(self, __value: i64) -> _serde::export::Result where __E: _serde::de::Error, { - _serde::export::Ok(__Field::__other(_serde::private::de::Content::I64(__value))) + _serde::export::Ok(__Field::__other(_serde::private::de::Content::new(_serde::private::de::ContentRepr::I64(__value), &self.state))) } fn visit_u8<__E>(self, __value: u8) -> _serde::export::Result where __E: _serde::de::Error, { - _serde::export::Ok(__Field::__other(_serde::private::de::Content::U8(__value))) + _serde::export::Ok(__Field::__other(_serde::private::de::Content::new(_serde::private::de::ContentRepr::U8(__value), &self.state))) } fn visit_u16<__E>(self, __value: u16) -> _serde::export::Result where __E: _serde::de::Error, { - _serde::export::Ok(__Field::__other(_serde::private::de::Content::U16(__value))) + _serde::export::Ok(__Field::__other(_serde::private::de::Content::new(_serde::private::de::ContentRepr::U16(__value), &self.state))) } fn visit_u32<__E>(self, __value: u32) -> _serde::export::Result where __E: _serde::de::Error, { - _serde::export::Ok(__Field::__other(_serde::private::de::Content::U32(__value))) + _serde::export::Ok(__Field::__other(_serde::private::de::Content::new(_serde::private::de::ContentRepr::U32(__value), &self.state))) } fn visit_u64<__E>(self, __value: u64) -> _serde::export::Result where __E: _serde::de::Error, { - _serde::export::Ok(__Field::__other(_serde::private::de::Content::U64(__value))) + _serde::export::Ok(__Field::__other(_serde::private::de::Content::new(_serde::private::de::ContentRepr::U64(__value), &self.state))) } fn visit_f32<__E>(self, __value: f32) -> _serde::export::Result where __E: _serde::de::Error, { - _serde::export::Ok(__Field::__other(_serde::private::de::Content::F32(__value))) + _serde::export::Ok(__Field::__other(_serde::private::de::Content::new(_serde::private::de::ContentRepr::F32(__value), &self.state))) } fn visit_f64<__E>(self, __value: f64) -> _serde::export::Result where __E: _serde::de::Error, { - _serde::export::Ok(__Field::__other(_serde::private::de::Content::F64(__value))) + _serde::export::Ok(__Field::__other(_serde::private::de::Content::new(_serde::private::de::ContentRepr::F64(__value), &self.state))) } fn visit_char<__E>(self, __value: char) -> _serde::export::Result where __E: _serde::de::Error, { - _serde::export::Ok(__Field::__other(_serde::private::de::Content::Char(__value))) + _serde::export::Ok(__Field::__other(_serde::private::de::Content::new(_serde::private::de::ContentRepr::Char(__value), &self.state))) } fn visit_unit<__E>(self) -> _serde::export::Result where __E: _serde::de::Error, { - _serde::export::Ok(__Field::__other(_serde::private::de::Content::Unit)) + _serde::export::Ok(__Field::__other(_serde::private::de::Content::new(_serde::private::de::ContentRepr::Unit, &self.state))) } fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::export::Result @@ -2432,6 +2541,7 @@ fn deserialize_map( let #name: #field_ty = try!(#func( _serde::private::de::FlatMapDeserializer( &mut __collect, + __state.clone(), _serde::export::PhantomData))); } }); diff --git a/serde_test/Cargo.toml b/serde_test/Cargo.toml index f049b8ce2..3a97eb1f1 100644 --- a/serde_test/Cargo.toml +++ b/serde_test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde_test" -version = "1.0.69" # remember to update html_root_url +version = "1.0.999" # remember to update html_root_url authors = ["Erick Tryzelaar ", "David Tolnay "] license = "MIT/Apache-2.0" description = "Token De/Serializer for testing De/Serialize implementations" diff --git a/test_suite/tests/test_value.rs b/test_suite/tests/test_value.rs index d2d9e67c0..428beccfd 100644 --- a/test_suite/tests/test_value.rs +++ b/test_suite/tests/test_value.rs @@ -32,13 +32,13 @@ fn test_integer128() { let de_i128 = IntoDeserializer::::into_deserializer(1i128); // u128 to u128 - assert_eq!(1u128, u128::deserialize(de_u128).unwrap()); + assert_eq!(1u128, u128::deserialize(de_u128.clone()).unwrap()); // u128 to i128 assert_eq!(1i128, i128::deserialize(de_u128).unwrap()); // i128 to u128 - assert_eq!(1u128, u128::deserialize(de_i128).unwrap()); + assert_eq!(1u128, u128::deserialize(de_i128.clone()).unwrap()); // i128 to i128 assert_eq!(1i128, i128::deserialize(de_i128).unwrap());