From d3a2f5e268228558b3c8882144b98ada1554e591 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 26 Mar 2017 22:56:58 -0700 Subject: [PATCH 001/177] Add a 'de lifetime to the deserialize traits --- serde/src/bytes.rs | 8 +- serde/src/de/content.rs | 142 ++++++------ serde/src/de/impls.rs | 324 ++++++++++++++------------- serde/src/de/mod.rs | 212 +++++++++++------- serde/src/de/private.rs | 10 +- serde/src/de/value.rs | 238 ++++++++++---------- serde/src/macros.rs | 4 +- serde_derive/src/bound.rs | 24 +- serde_derive/src/de.rs | 140 ++++++++---- serde_test/src/assert.rs | 12 +- serde_test/src/de.rs | 56 ++--- test_suite/tests/test_annotations.rs | 12 +- test_suite/tests/test_gen.rs | 21 +- 13 files changed, 640 insertions(+), 563 deletions(-) diff --git a/serde/src/bytes.rs b/serde/src/bytes.rs index d1ea0189..b6b6d02a 100644 --- a/serde/src/bytes.rs +++ b/serde/src/bytes.rs @@ -237,7 +237,7 @@ mod bytebuf { /// This type implements the `serde::de::Visitor` trait for a `ByteBuf`. pub struct ByteBufVisitor; - impl de::Visitor for ByteBufVisitor { + impl<'de> de::Visitor<'de> for ByteBufVisitor { type Value = ByteBuf; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -253,7 +253,7 @@ mod bytebuf { #[inline] fn visit_seq(self, mut visitor: V) -> Result - where V: de::SeqVisitor + where V: de::SeqVisitor<'de> { let len = cmp::min(visitor.size_hint().0, 4096); let mut values = Vec::with_capacity(len); @@ -292,10 +292,10 @@ mod bytebuf { } } - impl de::Deserialize for ByteBuf { + impl<'de> de::Deserialize<'de> for ByteBuf { #[inline] fn deserialize(deserializer: D) -> Result - where D: de::Deserializer + where D: de::Deserializer<'de> { deserializer.deserialize_byte_buf(ByteBufVisitor) } diff --git a/serde/src/de/content.rs b/serde/src/de/content.rs index e784b4ec..62f71d10 100644 --- a/serde/src/de/content.rs +++ b/serde/src/de/content.rs @@ -83,8 +83,10 @@ impl Content { } } -impl Deserialize for Content { - fn deserialize(deserializer: D) -> Result { +impl<'de> Deserialize<'de> for Content { + fn deserialize(deserializer: D) -> Result + where D: Deserializer<'de> + { // Untagged and internally tagged enums are only supported in // self-describing formats. deserializer.deserialize(ContentVisitor) @@ -93,7 +95,7 @@ impl Deserialize for Content { struct ContentVisitor; -impl Visitor for ContentVisitor { +impl<'de> Visitor<'de> for ContentVisitor { type Value = Content; fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result { @@ -209,19 +211,19 @@ impl Visitor for ContentVisitor { } fn visit_some(self, deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { Deserialize::deserialize(deserializer).map(|v| Content::Some(Box::new(v))) } fn visit_newtype_struct(self, deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { Deserialize::deserialize(deserializer).map(|v| Content::Newtype(Box::new(v))) } fn visit_seq(self, mut visitor: V) -> Result - where V: SeqVisitor + where V: SeqVisitor<'de> { let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); while let Some(e) = try!(visitor.visit()) { @@ -231,7 +233,7 @@ impl Visitor for ContentVisitor { } fn visit_map(self, mut visitor: V) -> Result - where V: MapVisitor + where V: MapVisitor<'de> { let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); while let Some(kv) = try!(visitor.visit()) { @@ -241,7 +243,7 @@ impl Visitor for ContentVisitor { } fn visit_enum(self, _visitor: V) -> Result - where V: EnumVisitor + where V: EnumVisitor<'de> { Err(de::Error::custom("untagged and internally tagged enums do not support enum input")) } @@ -265,11 +267,11 @@ impl TagOrContentVisitor { } } -impl DeserializeSeed for TagOrContentVisitor { +impl<'de> DeserializeSeed<'de> for TagOrContentVisitor { type Value = TagOrContent; fn deserialize(self, deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { // Internally tagged enums are only supported in self-describing // formats. @@ -277,7 +279,7 @@ impl DeserializeSeed for TagOrContentVisitor { } } -impl Visitor for TagOrContentVisitor { +impl<'de> Visitor<'de> for TagOrContentVisitor { type Value = TagOrContent; fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result { @@ -409,31 +411,31 @@ impl Visitor for TagOrContentVisitor { } fn visit_some(self, deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { ContentVisitor.visit_some(deserializer).map(TagOrContent::Content) } fn visit_newtype_struct(self, deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { ContentVisitor.visit_newtype_struct(deserializer).map(TagOrContent::Content) } fn visit_seq(self, visitor: V) -> Result - where V: SeqVisitor + where V: SeqVisitor<'de> { ContentVisitor.visit_seq(visitor).map(TagOrContent::Content) } fn visit_map(self, visitor: V) -> Result - where V: MapVisitor + where V: MapVisitor<'de> { ContentVisitor.visit_map(visitor).map(TagOrContent::Content) } fn visit_enum(self, visitor: V) -> Result - where V: EnumVisitor + where V: EnumVisitor<'de> { ContentVisitor.visit_enum(visitor).map(TagOrContent::Content) } @@ -464,13 +466,13 @@ impl TaggedContentVisitor { } } -impl DeserializeSeed for TaggedContentVisitor - where T: Deserialize +impl<'de, T> DeserializeSeed<'de> for TaggedContentVisitor + where T: Deserialize<'de> { type Value = TaggedContent; fn deserialize(self, deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { // Internally tagged enums are only supported in self-describing // formats. @@ -478,8 +480,8 @@ impl DeserializeSeed for TaggedContentVisitor } } -impl Visitor for TaggedContentVisitor - where T: Deserialize +impl<'de, T> Visitor<'de> for TaggedContentVisitor + where T: Deserialize<'de> { type Value = TaggedContent; @@ -488,7 +490,7 @@ impl Visitor for TaggedContentVisitor } fn visit_map(self, mut visitor: V) -> Result - where V: MapVisitor + where V: MapVisitor<'de> { let mut tag = None; let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); @@ -532,17 +534,17 @@ pub struct TagOrContentFieldVisitor { pub content: &'static str, } -impl DeserializeSeed for TagOrContentFieldVisitor { +impl<'de> DeserializeSeed<'de> for TagOrContentFieldVisitor { type Value = TagOrContentField; fn deserialize(self, deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { deserializer.deserialize_str(self) } } -impl Visitor for TagOrContentFieldVisitor { +impl<'de> Visitor<'de> for TagOrContentFieldVisitor { type Value = TagOrContentField; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -570,13 +572,13 @@ pub struct ContentDeserializer { /// Used when deserializing an internally tagged enum because the content will /// be used exactly once. -impl Deserializer for ContentDeserializer +impl<'de, E> Deserializer<'de> for ContentDeserializer where E: de::Error { type Error = E; fn deserialize(self, visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { match self.content { Content::Bool(v) => visitor.visit_bool(v), @@ -618,7 +620,7 @@ impl Deserializer for ContentDeserializer } fn deserialize_option(self, visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { match self.content { Content::None => visitor.visit_none(), @@ -629,7 +631,7 @@ impl Deserializer for ContentDeserializer } fn deserialize_newtype_struct(self, _name: &str, visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { visitor.visit_newtype_struct(self) } @@ -639,7 +641,7 @@ impl Deserializer for ContentDeserializer _variants: &'static [&'static str], visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { let (variant, value) = match self.content { Content::Map(value) => { @@ -696,7 +698,7 @@ struct EnumDeserializer err: PhantomData, } -impl de::EnumVisitor for EnumDeserializer +impl<'de, E> de::EnumVisitor<'de> for EnumDeserializer where E: de::Error { type Error = E; @@ -705,7 +707,7 @@ impl de::EnumVisitor for EnumDeserializer fn visit_variant_seed(self, seed: V) -> Result<(V::Value, VariantDeserializer), Self::Error> - where V: de::DeserializeSeed + where V: de::DeserializeSeed<'de> { let visitor = VariantDeserializer { value: self.value, @@ -722,7 +724,7 @@ struct VariantDeserializer err: PhantomData, } -impl de::VariantVisitor for VariantDeserializer +impl<'de, E> de::VariantVisitor<'de> for VariantDeserializer where E: de::Error { type Error = E; @@ -735,7 +737,7 @@ impl de::VariantVisitor for VariantDeserializer } fn visit_newtype_seed(self, seed: T) -> Result - where T: de::DeserializeSeed + where T: de::DeserializeSeed<'de> { match self.value { Some(value) => seed.deserialize(ContentDeserializer::new(value)), @@ -744,7 +746,7 @@ impl de::VariantVisitor for VariantDeserializer } fn visit_tuple(self, _len: usize, visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { match self.value { Some(Content::Seq(v)) => { @@ -759,7 +761,7 @@ impl de::VariantVisitor for VariantDeserializer _fields: &'static [&'static str], visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { match self.value { Some(Content::Map(v)) => { @@ -789,14 +791,14 @@ impl SeqDeserializer } } -impl de::Deserializer for SeqDeserializer +impl<'de, E> de::Deserializer<'de> for SeqDeserializer where E: de::Error { type Error = E; #[inline] fn deserialize(mut self, visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { let len = self.iter.len(); if len == 0 { @@ -819,13 +821,13 @@ impl de::Deserializer for SeqDeserializer } } -impl de::SeqVisitor for SeqDeserializer +impl<'de, E> de::SeqVisitor<'de> for SeqDeserializer where E: de::Error { type Error = E; fn visit_seed(&mut self, seed: T) -> Result, Self::Error> - where T: de::DeserializeSeed + where T: de::DeserializeSeed<'de> { match self.iter.next() { Some(value) => seed.deserialize(ContentDeserializer::new(value)).map(Some), @@ -858,13 +860,13 @@ impl MapDeserializer } } -impl de::MapVisitor for MapDeserializer +impl<'de, E> de::MapVisitor<'de> for MapDeserializer where E: de::Error { type Error = E; fn visit_key_seed(&mut self, seed: T) -> Result, Self::Error> - where T: de::DeserializeSeed + where T: de::DeserializeSeed<'de> { match self.iter.next() { Some((key, value)) => { @@ -876,7 +878,7 @@ impl de::MapVisitor for MapDeserializer } fn visit_value_seed(&mut self, seed: T) -> Result - where T: de::DeserializeSeed + where T: de::DeserializeSeed<'de> { match self.value.take() { Some(value) => seed.deserialize(ContentDeserializer::new(value)), @@ -889,14 +891,14 @@ impl de::MapVisitor for MapDeserializer } } -impl de::Deserializer for MapDeserializer +impl<'de, E> de::Deserializer<'de> for MapDeserializer where E: de::Error { type Error = E; #[inline] fn deserialize(self, visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { visitor.visit_map(self) } @@ -917,13 +919,13 @@ pub struct ContentRefDeserializer<'a, E> { /// Used when deserializing an untagged enum because the content may need to be /// used more than once. -impl<'a, E> Deserializer for ContentRefDeserializer<'a, E> +impl<'de, 'a, E> Deserializer<'de> for ContentRefDeserializer<'a, E> where E: de::Error { type Error = E; fn deserialize(self, visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { match *self.content { Content::Bool(v) => visitor.visit_bool(v), @@ -965,7 +967,7 @@ impl<'a, E> Deserializer for ContentRefDeserializer<'a, E> } fn deserialize_option(self, visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { match *self.content { Content::None => visitor.visit_none(), @@ -976,7 +978,7 @@ impl<'a, E> Deserializer for ContentRefDeserializer<'a, E> } fn deserialize_newtype_struct(self, _name: &str, visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { visitor.visit_newtype_struct(self) } @@ -986,7 +988,7 @@ impl<'a, E> Deserializer for ContentRefDeserializer<'a, E> _variants: &'static [&'static str], visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { let (variant, value) = match *self.content { Content::Map(ref value) => { @@ -1043,14 +1045,14 @@ struct EnumRefDeserializer<'a, E> err: PhantomData, } -impl<'a, E> de::EnumVisitor for EnumRefDeserializer<'a, E> +impl<'de, 'a, E> de::EnumVisitor<'de> for EnumRefDeserializer<'a, E> where E: de::Error { type Error = E; type Variant = VariantRefDeserializer<'a, Self::Error>; fn visit_variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> - where V: de::DeserializeSeed + where V: de::DeserializeSeed<'de> { let visitor = VariantRefDeserializer { value: self.value, @@ -1067,7 +1069,7 @@ struct VariantRefDeserializer<'a, E> err: PhantomData, } -impl<'a, E> de::VariantVisitor for VariantRefDeserializer<'a, E> +impl<'de, 'a, E> de::VariantVisitor<'de> for VariantRefDeserializer<'a, E> where E: de::Error { type Error = E; @@ -1080,7 +1082,7 @@ impl<'a, E> de::VariantVisitor for VariantRefDeserializer<'a, E> } fn visit_newtype_seed(self, seed: T) -> Result - where T: de::DeserializeSeed + where T: de::DeserializeSeed<'de> { match self.value { Some(value) => seed.deserialize(ContentRefDeserializer::new(value)), @@ -1089,7 +1091,7 @@ impl<'a, E> de::VariantVisitor for VariantRefDeserializer<'a, E> } fn visit_tuple(self, _len: usize, visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { match self.value { Some(&Content::Seq(ref v)) => { @@ -1104,7 +1106,7 @@ impl<'a, E> de::VariantVisitor for VariantRefDeserializer<'a, E> _fields: &'static [&'static str], visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { match self.value { Some(&Content::Map(ref v)) => { @@ -1134,14 +1136,14 @@ impl<'a, E> SeqRefDeserializer<'a, E> } } -impl<'a, E> de::Deserializer for SeqRefDeserializer<'a, E> +impl<'de, 'a, E> de::Deserializer<'de> for SeqRefDeserializer<'a, E> where E: de::Error { type Error = E; #[inline] fn deserialize(mut self, visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { let len = self.iter.len(); if len == 0 { @@ -1164,13 +1166,13 @@ impl<'a, E> de::Deserializer for SeqRefDeserializer<'a, E> } } -impl<'a, E> de::SeqVisitor for SeqRefDeserializer<'a, E> +impl<'de, 'a, E> de::SeqVisitor<'de> for SeqRefDeserializer<'a, E> where E: de::Error { type Error = E; fn visit_seed(&mut self, seed: T) -> Result, Self::Error> - where T: de::DeserializeSeed + where T: de::DeserializeSeed<'de> { match self.iter.next() { Some(value) => seed.deserialize(ContentRefDeserializer::new(value)).map(Some), @@ -1203,13 +1205,13 @@ impl<'a, E> MapRefDeserializer<'a, E> } } -impl<'a, E> de::MapVisitor for MapRefDeserializer<'a, E> +impl<'de, 'a, E> de::MapVisitor<'de> for MapRefDeserializer<'a, E> where E: de::Error { type Error = E; fn visit_key_seed(&mut self, seed: T) -> Result, Self::Error> - where T: de::DeserializeSeed + where T: de::DeserializeSeed<'de> { match self.iter.next() { Some(&(ref key, ref value)) => { @@ -1221,7 +1223,7 @@ impl<'a, E> de::MapVisitor for MapRefDeserializer<'a, E> } fn visit_value_seed(&mut self, seed: T) -> Result - where T: de::DeserializeSeed + where T: de::DeserializeSeed<'de> { match self.value.take() { Some(value) => seed.deserialize(ContentRefDeserializer::new(value)), @@ -1234,14 +1236,14 @@ impl<'a, E> de::MapVisitor for MapRefDeserializer<'a, E> } } -impl<'a, E> de::Deserializer for MapRefDeserializer<'a, E> +impl<'de, 'a, E> de::Deserializer<'de> for MapRefDeserializer<'a, E> where E: de::Error { type Error = E; #[inline] fn deserialize(self, visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { visitor.visit_map(self) } @@ -1253,7 +1255,7 @@ impl<'a, E> de::Deserializer for MapRefDeserializer<'a, E> } } -impl de::value::ValueDeserializer for ContentDeserializer +impl<'de, E> de::value::ValueDeserializer<'de, E> for ContentDeserializer where E: de::Error { type Deserializer = Self; @@ -1263,7 +1265,7 @@ impl de::value::ValueDeserializer for ContentDeserializer } } -impl<'a, E> de::value::ValueDeserializer for ContentRefDeserializer<'a, E> +impl<'de, 'a, E> de::value::ValueDeserializer<'de, E> for ContentRefDeserializer<'a, E> where E: de::Error { type Deserializer = Self; @@ -1291,7 +1293,7 @@ impl<'a> InternallyTaggedUnitVisitor<'a> { } } -impl<'a> Visitor for InternallyTaggedUnitVisitor<'a> { +impl<'de, 'a> Visitor<'de> for InternallyTaggedUnitVisitor<'a> { type Value = (); fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -1299,7 +1301,7 @@ impl<'a> Visitor for InternallyTaggedUnitVisitor<'a> { } fn visit_map(self, _: V) -> Result<(), V::Error> - where V: MapVisitor + where V: MapVisitor<'de> { Ok(()) } @@ -1323,7 +1325,7 @@ impl<'a> UntaggedUnitVisitor<'a> { } } -impl<'a> Visitor for UntaggedUnitVisitor<'a> { +impl<'de, 'a> Visitor<'de> for UntaggedUnitVisitor<'a> { type Value = (); fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 7bffab32..fc61dac1 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -68,7 +68,7 @@ use bytes::ByteBuf; /// A visitor that produces a `()`. pub struct UnitVisitor; -impl Visitor for UnitVisitor { +impl<'de> Visitor<'de> for UnitVisitor { type Value = (); fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -82,15 +82,15 @@ impl Visitor for UnitVisitor { } fn visit_seq(self, _: V) -> Result<(), V::Error> - where V: SeqVisitor + where V: SeqVisitor<'de> { Ok(()) } } -impl Deserialize for () { +impl<'de> Deserialize<'de> for () { fn deserialize(deserializer: D) -> Result<(), D::Error> - where D: Deserializer + where D: Deserializer<'de> { deserializer.deserialize_unit(UnitVisitor) } @@ -101,7 +101,7 @@ impl Deserialize for () { /// A visitor that produces a `bool`. pub struct BoolVisitor; -impl Visitor for BoolVisitor { +impl<'de> Visitor<'de> for BoolVisitor { type Value = bool; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -125,9 +125,9 @@ impl Visitor for BoolVisitor { } } -impl Deserialize for bool { +impl<'de> Deserialize<'de> for bool { fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { deserializer.deserialize_bool(BoolVisitor) } @@ -151,14 +151,14 @@ macro_rules! impl_deserialize_num_method { macro_rules! impl_deserialize_num { ($ty:ident, $method:ident) => { - impl Deserialize for $ty { + impl<'de> Deserialize<'de> for $ty { #[inline] fn deserialize(deserializer: D) -> Result<$ty, D::Error> - where D: Deserializer, + where D: Deserializer<'de>, { struct PrimitiveVisitor; - impl Visitor for PrimitiveVisitor { + impl<'de> Visitor<'de> for PrimitiveVisitor { type Value = $ty; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -209,7 +209,7 @@ impl_deserialize_num!(f64, deserialize_f64); struct CharVisitor; -impl Visitor for CharVisitor { +impl<'de> Visitor<'de> for CharVisitor { type Value = char; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -235,10 +235,10 @@ impl Visitor for CharVisitor { } } -impl Deserialize for char { +impl<'de> Deserialize<'de> for char { #[inline] fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { deserializer.deserialize_char(CharVisitor) } @@ -250,7 +250,7 @@ impl Deserialize for char { struct StringVisitor; #[cfg(any(feature = "std", feature = "collections"))] -impl Visitor for StringVisitor { +impl<'de> Visitor<'de> for StringVisitor { type Value = String; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -295,9 +295,9 @@ impl Visitor for StringVisitor { } #[cfg(any(feature = "std", feature = "collections"))] -impl Deserialize for String { +impl<'de> Deserialize<'de> for String { fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { deserializer.deserialize_string(StringVisitor) } @@ -306,9 +306,9 @@ impl Deserialize for String { /////////////////////////////////////////////////////////////////////////////// #[cfg(all(feature = "std", feature="unstable"))] -impl Deserialize for Box { +impl<'de> Deserialize<'de> for Box { fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { let s = try!(CString::deserialize(deserializer)); Ok(s.into_boxed_c_str()) @@ -316,9 +316,9 @@ impl Deserialize for Box { } #[cfg(feature = "std")] -impl Deserialize for CString { +impl<'de> Deserialize<'de> for CString { fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { let bytes = try!(ByteBuf::deserialize(deserializer)); CString::new(bytes).map_err(Error::custom) @@ -331,7 +331,9 @@ struct OptionVisitor { marker: PhantomData, } -impl Visitor for OptionVisitor { +impl<'de, T> Visitor<'de> for OptionVisitor + where T: Deserialize<'de> +{ type Value = Option; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -354,17 +356,17 @@ impl Visitor for OptionVisitor { #[inline] fn visit_some(self, deserializer: D) -> Result, D::Error> - where D: Deserializer + where D: Deserializer<'de> { Ok(Some(try!(Deserialize::deserialize(deserializer)))) } } -impl Deserialize for Option - where T: Deserialize +impl<'de, T> Deserialize<'de> for Option + where T: Deserialize<'de> { fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer + where D: Deserializer<'de> { deserializer.deserialize_option(OptionVisitor { marker: PhantomData }) } @@ -377,7 +379,7 @@ pub struct PhantomDataVisitor { marker: PhantomData, } -impl Visitor for PhantomDataVisitor { +impl<'de, T> Visitor<'de> for PhantomDataVisitor { type Value = PhantomData; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -392,9 +394,9 @@ impl Visitor for PhantomDataVisitor { } } -impl Deserialize for PhantomData { +impl<'de, T> Deserialize<'de> for PhantomData { fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer + where D: Deserializer<'de> { let visitor = PhantomDataVisitor { marker: PhantomData }; deserializer.deserialize_unit_struct("PhantomData", visitor) @@ -405,21 +407,19 @@ impl Deserialize for PhantomData { macro_rules! seq_impl { ( - $ty:ty, - $visitor_ty:ident < $($typaram:ident : $bound1:ident $(+ $bound2:ident)*),* >, + $ty:ident < T $(, $typaram:ident)* >, + $visitor_ty:ident $( < $($boundparam:ident : $bound1:ident $(+ $bound2:ident)*),* > )*, $visitor:ident, $ctor:expr, $with_capacity:expr, $insert:expr ) => { /// A visitor that produces a sequence. - pub struct $visitor_ty<$($typaram),*> { - marker: PhantomData<$ty>, + pub struct $visitor_ty { + marker: PhantomData<$ty>, } - impl<$($typaram),*> $visitor_ty<$($typaram),*> - where $($typaram: $bound1 $(+ $bound2)*),* - { + impl $visitor_ty { /// Construct a new sequence visitor. pub fn new() -> Self { $visitor_ty { @@ -428,25 +428,26 @@ macro_rules! seq_impl { } } - impl<$($typaram),*> Visitor for $visitor_ty<$($typaram),*> - where $($typaram: $bound1 $(+ $bound2)*),* + impl<'de, T $(, $typaram)*> Visitor<'de> for $visitor_ty + where T: Deserialize<'de>, + $($($boundparam: $bound1 $(+ $bound2)*),*)* { - type Value = $ty; + type Value = $ty; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a sequence") } #[inline] - fn visit_unit(self) -> Result<$ty, E> + fn visit_unit(self) -> Result where E: Error, { Ok($ctor) } #[inline] - fn visit_seq(self, mut $visitor: V) -> Result<$ty, V::Error> - where V: SeqVisitor, + fn visit_seq(self, mut $visitor: V) -> Result + where V: SeqVisitor<'de>, { let mut values = $with_capacity; @@ -458,11 +459,12 @@ macro_rules! seq_impl { } } - impl<$($typaram),*> Deserialize for $ty - where $($typaram: $bound1 $(+ $bound2)*),* + impl<'de, T $(, $typaram)*> Deserialize<'de> for $ty + where T: Deserialize<'de>, + $($($boundparam: $bound1 $(+ $bound2)*),*)* { - fn deserialize(deserializer: D) -> Result<$ty, D::Error> - where D: Deserializer, + fn deserialize(deserializer: D) -> Result + where D: Deserializer<'de>, { deserializer.deserialize_seq($visitor_ty::new()) } @@ -473,7 +475,7 @@ macro_rules! seq_impl { #[cfg(any(feature = "std", feature = "collections"))] seq_impl!( BinaryHeap, - BinaryHeapVisitor, + BinaryHeapVisitor, visitor, BinaryHeap::new(), BinaryHeap::with_capacity(cmp::min(visitor.size_hint().0, 4096)), @@ -482,7 +484,7 @@ seq_impl!( #[cfg(any(feature = "std", feature = "collections"))] seq_impl!( BTreeSet, - BTreeSetVisitor, + BTreeSetVisitor, visitor, BTreeSet::new(), BTreeSet::new(), @@ -491,7 +493,7 @@ seq_impl!( #[cfg(any(feature = "std", feature = "collections"))] seq_impl!( LinkedList, - LinkedListVisitor, + LinkedListVisitor, visitor, LinkedList::new(), LinkedList::new(), @@ -500,7 +502,7 @@ seq_impl!( #[cfg(feature = "std")] seq_impl!( HashSet, - HashSetVisitor, visitor, HashSet::with_hasher(S::default()), @@ -510,7 +512,7 @@ seq_impl!( #[cfg(any(feature = "std", feature = "collections"))] seq_impl!( Vec, - VecVisitor, + VecVisitor, visitor, Vec::new(), Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)), @@ -519,7 +521,7 @@ seq_impl!( #[cfg(any(feature = "std", feature = "collections"))] seq_impl!( VecDeque, - VecDequeVisitor, + VecDequeVisitor, visitor, VecDeque::new(), VecDeque::with_capacity(cmp::min(visitor.size_hint().0, 4096)), @@ -537,8 +539,8 @@ impl ArrayVisitor { } } -impl Visitor for ArrayVisitor<[T; 0]> - where T: Deserialize +impl<'de, T> Visitor<'de> for ArrayVisitor<[T; 0]> + where T: Deserialize<'de> { type Value = [T; 0]; @@ -555,17 +557,17 @@ impl Visitor for ArrayVisitor<[T; 0]> #[inline] fn visit_seq(self, _: V) -> Result<[T; 0], V::Error> - where V: SeqVisitor + where V: SeqVisitor<'de> { Ok([]) } } -impl Deserialize for [T; 0] - where T: Deserialize +impl<'de, T> Deserialize<'de> for [T; 0] + where T: Deserialize<'de> { fn deserialize(deserializer: D) -> Result<[T; 0], D::Error> - where D: Deserializer + where D: Deserializer<'de> { deserializer.deserialize_seq_fixed_size(0, ArrayVisitor::<[T; 0]>::new()) } @@ -574,7 +576,9 @@ impl Deserialize for [T; 0] macro_rules! array_impls { ($($len:expr => ($($n:tt $name:ident)+))+) => { $( - impl Visitor for ArrayVisitor<[T; $len]> where T: Deserialize { + impl<'de, T> Visitor<'de> for ArrayVisitor<[T; $len]> + where T: Deserialize<'de> + { type Value = [T; $len]; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -583,7 +587,7 @@ macro_rules! array_impls { #[inline] fn visit_seq(self, mut visitor: V) -> Result<[T; $len], V::Error> - where V: SeqVisitor, + where V: SeqVisitor<'de>, { $( let $name = match try!(visitor.visit()) { @@ -596,11 +600,11 @@ macro_rules! array_impls { } } - impl Deserialize for [T; $len] - where T: Deserialize, + impl<'de, T> Deserialize<'de> for [T; $len] + where T: Deserialize<'de>, { fn deserialize(deserializer: D) -> Result<[T; $len], D::Error> - where D: Deserializer, + where D: Deserializer<'de>, { deserializer.deserialize_seq_fixed_size($len, ArrayVisitor::<[T; $len]>::new()) } @@ -654,14 +658,14 @@ macro_rules! tuple_impls { marker: PhantomData<($($name,)+)>, } - impl<$($name: Deserialize,)+> $visitor<$($name,)+> { + impl<$($name,)+> $visitor<$($name,)+> { /// Construct a `TupleVisitor*`. pub fn new() -> Self { $visitor { marker: PhantomData } } } - impl<$($name: Deserialize),+> Visitor for $visitor<$($name,)+> { + impl<'de, $($name: Deserialize<'de>),+> Visitor<'de> for $visitor<$($name,)+> { type Value = ($($name,)+); fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -671,7 +675,7 @@ macro_rules! tuple_impls { #[inline] #[allow(non_snake_case)] fn visit_seq(self, mut visitor: V) -> Result<($($name,)+), V::Error> - where V: SeqVisitor, + where V: SeqVisitor<'de>, { $( let $name = match try!(visitor.visit()) { @@ -684,10 +688,10 @@ macro_rules! tuple_impls { } } - impl<$($name: Deserialize),+> Deserialize for ($($name,)+) { + impl<'de, $($name: Deserialize<'de>),+> Deserialize<'de> for ($($name,)+) { #[inline] fn deserialize(deserializer: D) -> Result<($($name,)+), D::Error> - where D: Deserializer, + where D: Deserializer<'de>, { deserializer.deserialize_tuple($len, $visitor::new()) } @@ -719,20 +723,18 @@ tuple_impls! { macro_rules! map_impl { ( - $ty:ty, - $visitor_ty:ident < $($typaram:ident : $bound1:ident $(+ $bound2:ident)*),* >, + $ty:ident < K, V $(, $typaram:ident)* >, + $visitor_ty:ident < $($boundparam:ident : $bound1:ident $(+ $bound2:ident)*),* >, $visitor:ident, $ctor:expr, $with_capacity:expr ) => { /// A visitor that produces a map. - pub struct $visitor_ty<$($typaram),*> { - marker: PhantomData<$ty>, + pub struct $visitor_ty { + marker: PhantomData<$ty>, } - impl<$($typaram),*> $visitor_ty<$($typaram),*> - where $($typaram: $bound1 $(+ $bound2)*),* - { + impl $visitor_ty { /// Construct a `MapVisitor*`. pub fn new() -> Self { $visitor_ty { @@ -741,25 +743,27 @@ macro_rules! map_impl { } } - impl<$($typaram),*> Visitor for $visitor_ty<$($typaram),*> - where $($typaram: $bound1 $(+ $bound2)*),* + impl<'de, K, V $(, $typaram)*> Visitor<'de> for $visitor_ty + where K: Deserialize<'de>, + V: Deserialize<'de>, + $($boundparam: $bound1 $(+ $bound2)*),* { - type Value = $ty; + type Value = $ty; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a map") } #[inline] - fn visit_unit(self) -> Result<$ty, E> + fn visit_unit(self) -> Result where E: Error, { Ok($ctor) } #[inline] - fn visit_map(self, mut $visitor: Visitor) -> Result<$ty, Visitor::Error> - where Visitor: MapVisitor, + fn visit_map(self, mut $visitor: Visitor) -> Result + where Visitor: MapVisitor<'de>, { let mut values = $with_capacity; @@ -771,11 +775,13 @@ macro_rules! map_impl { } } - impl<$($typaram),*> Deserialize for $ty - where $($typaram: $bound1 $(+ $bound2)*),* + impl<'de, K, V $(, $typaram)*> Deserialize<'de> for $ty + where K: Deserialize<'de>, + V: Deserialize<'de>, + $($boundparam: $bound1 $(+ $bound2)*),* { - fn deserialize(deserializer: D) -> Result<$ty, D::Error> - where D: Deserializer, + fn deserialize(deserializer: D) -> Result + where D: Deserializer<'de>, { deserializer.deserialize_map($visitor_ty::new()) } @@ -786,8 +792,7 @@ macro_rules! map_impl { #[cfg(any(feature = "std", feature = "collections"))] map_impl!( BTreeMap, - BTreeMapVisitor, + BTreeMapVisitor, visitor, BTreeMap::new(), BTreeMap::new()); @@ -795,8 +800,7 @@ map_impl!( #[cfg(feature = "std")] map_impl!( HashMap, - HashMapVisitor, visitor, HashMap::with_hasher(S::default()), @@ -805,9 +809,9 @@ map_impl!( /////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "std")] -impl Deserialize for net::IpAddr { +impl<'de> Deserialize<'de> for net::IpAddr { fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { let s = try!(String::deserialize(deserializer)); match s.parse() { @@ -818,9 +822,9 @@ impl Deserialize for net::IpAddr { } #[cfg(feature = "std")] -impl Deserialize for net::Ipv4Addr { +impl<'de> Deserialize<'de> for net::Ipv4Addr { fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { let s = try!(String::deserialize(deserializer)); match s.parse() { @@ -831,9 +835,9 @@ impl Deserialize for net::Ipv4Addr { } #[cfg(feature = "std")] -impl Deserialize for net::Ipv6Addr { +impl<'de> Deserialize<'de> for net::Ipv6Addr { fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { let s = try!(String::deserialize(deserializer)); match s.parse() { @@ -846,9 +850,9 @@ impl Deserialize for net::Ipv6Addr { /////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "std")] -impl Deserialize for net::SocketAddr { +impl<'de> Deserialize<'de> for net::SocketAddr { fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { let s = try!(String::deserialize(deserializer)); match s.parse() { @@ -859,9 +863,9 @@ impl Deserialize for net::SocketAddr { } #[cfg(feature = "std")] -impl Deserialize for net::SocketAddrV4 { +impl<'de> Deserialize<'de> for net::SocketAddrV4 { fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { let s = try!(String::deserialize(deserializer)); match s.parse() { @@ -872,9 +876,9 @@ impl Deserialize for net::SocketAddrV4 { } #[cfg(feature = "std")] -impl Deserialize for net::SocketAddrV6 { +impl<'de> Deserialize<'de> for net::SocketAddrV6 { fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { let s = try!(String::deserialize(deserializer)); match s.parse() { @@ -890,7 +894,7 @@ impl Deserialize for net::SocketAddrV6 { struct PathBufVisitor; #[cfg(feature = "std")] -impl Visitor for PathBufVisitor { +impl<'de> Visitor<'de> for PathBufVisitor { type Value = path::PathBuf; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -912,9 +916,9 @@ impl Visitor for PathBufVisitor { #[cfg(feature = "std")] -impl Deserialize for path::PathBuf { +impl<'de> Deserialize<'de> for path::PathBuf { fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { deserializer.deserialize_string(PathBufVisitor) } @@ -932,13 +936,13 @@ enum OsStringKind { static OSSTR_VARIANTS: &'static [&'static str] = &["Unix", "Windows"]; #[cfg(all(feature = "std", any(unix, windows)))] -impl Deserialize for OsStringKind { +impl<'de> Deserialize<'de> for OsStringKind { fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { struct KindVisitor; - impl Visitor for KindVisitor { + impl<'de> Visitor<'de> for KindVisitor { type Value = OsStringKind; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -991,7 +995,7 @@ impl Deserialize for OsStringKind { struct OsStringVisitor; #[cfg(all(feature = "std", any(unix, windows)))] -impl Visitor for OsStringVisitor { +impl<'de> Visitor<'de> for OsStringVisitor { type Value = OsString; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -1000,7 +1004,7 @@ impl Visitor for OsStringVisitor { #[cfg(unix)] fn visit_enum(self, visitor: V) -> Result - where V: EnumVisitor, + where V: EnumVisitor<'de>, { use std::os::unix::ffi::OsStringExt; @@ -1016,9 +1020,9 @@ impl Visitor for OsStringVisitor { } #[cfg(all(feature = "std", any(unix, windows)))] -impl Deserialize for OsString { +impl<'de> Deserialize<'de> for OsString { fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { deserializer.deserialize_enum("OsString", OSSTR_VARIANTS, OsStringVisitor) } @@ -1027,9 +1031,9 @@ impl Deserialize for OsString { /////////////////////////////////////////////////////////////////////////////// #[cfg(any(feature = "std", feature = "alloc"))] -impl Deserialize for Box { +impl<'de, T: Deserialize<'de>> Deserialize<'de> for Box { fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer + where D: Deserializer<'de> { let val = try!(Deserialize::deserialize(deserializer)); Ok(Box::new(val)) @@ -1037,9 +1041,9 @@ impl Deserialize for Box { } #[cfg(any(feature = "std", feature = "collections"))] -impl Deserialize for Box<[T]> { +impl<'de, T: Deserialize<'de>> Deserialize<'de> for Box<[T]> { fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer + where D: Deserializer<'de> { let v: Vec = try!(Deserialize::deserialize(deserializer)); Ok(v.into_boxed_slice()) @@ -1047,9 +1051,9 @@ impl Deserialize for Box<[T]> { } #[cfg(any(feature = "std", feature = "collections"))] -impl Deserialize for Box { +impl<'de> Deserialize<'de> for Box { fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { let s = try!(String::deserialize(deserializer)); Ok(s.into_boxed_str()) @@ -1057,9 +1061,9 @@ impl Deserialize for Box { } #[cfg(any(feature = "std", feature = "alloc"))] -impl Deserialize for Arc { +impl<'de, T: Deserialize<'de>> Deserialize<'de> for Arc { fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer + where D: Deserializer<'de> { let val = try!(Deserialize::deserialize(deserializer)); Ok(Arc::new(val)) @@ -1067,9 +1071,9 @@ impl Deserialize for Arc { } #[cfg(any(feature = "std", feature = "alloc"))] -impl Deserialize for Rc { +impl<'de, T: Deserialize<'de>> Deserialize<'de> for Rc { fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer + where D: Deserializer<'de> { let val = try!(Deserialize::deserialize(deserializer)); Ok(Rc::new(val)) @@ -1077,13 +1081,13 @@ impl Deserialize for Rc { } #[cfg(any(feature = "std", feature = "collections"))] -impl<'a, T: ?Sized> Deserialize for Cow<'a, T> +impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T> where T: ToOwned, - T::Owned: Deserialize + T::Owned: Deserialize<'de> { #[inline] fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer + where D: Deserializer<'de> { let val = try!(Deserialize::deserialize(deserializer)); Ok(Cow::Owned(val)) @@ -1101,22 +1105,22 @@ impl<'a, T: ?Sized> Deserialize for Cow<'a, T> // nanos: u32, // } #[cfg(feature = "std")] -impl Deserialize for Duration { +impl<'de> Deserialize<'de> for Duration { fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { enum Field { Secs, Nanos, }; - impl Deserialize for Field { + impl<'de> Deserialize<'de> for Field { fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { struct FieldVisitor; - impl Visitor for FieldVisitor { + impl<'de> Visitor<'de> for FieldVisitor { type Value = Field; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -1153,7 +1157,7 @@ impl Deserialize for Duration { struct DurationVisitor; - impl Visitor for DurationVisitor { + impl<'de> Visitor<'de> for DurationVisitor { type Value = Duration; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -1161,7 +1165,7 @@ impl Deserialize for Duration { } fn visit_seq(self, mut visitor: V) -> Result - where V: SeqVisitor + where V: SeqVisitor<'de> { let secs: u64 = match try!(visitor.visit()) { Some(value) => value, @@ -1179,7 +1183,7 @@ impl Deserialize for Duration { } fn visit_map(self, mut visitor: V) -> Result - where V: MapVisitor + where V: MapVisitor<'de> { let mut secs: Option = None; let mut nanos: Option = None; @@ -1227,22 +1231,22 @@ impl Deserialize for Duration { // end: u32, // } #[cfg(feature = "std")] -impl Deserialize for std::ops::Range { +impl<'de, Idx: Deserialize<'de>> Deserialize<'de> for std::ops::Range { fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { enum Field { Start, End, }; - impl Deserialize for Field { + impl<'de> Deserialize<'de> for Field { fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { struct FieldVisitor; - impl Visitor for FieldVisitor { + impl<'de> Visitor<'de> for FieldVisitor { type Value = Field; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -1281,7 +1285,7 @@ impl Deserialize for std::ops::Range { phantom: PhantomData, } - impl Visitor for RangeVisitor { + impl<'de, Idx: Deserialize<'de>> Visitor<'de> for RangeVisitor { type Value = std::ops::Range; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -1289,7 +1293,7 @@ impl Deserialize for std::ops::Range { } fn visit_seq(self, mut visitor: V) -> Result, V::Error> - where V: SeqVisitor + where V: SeqVisitor<'de> { let start: Idx = match try!(visitor.visit()) { Some(value) => value, @@ -1307,7 +1311,7 @@ impl Deserialize for std::ops::Range { } fn visit_map(self, mut visitor: V) -> Result, V::Error> - where V: MapVisitor + where V: MapVisitor<'de> { let mut start: Option = None; let mut end: Option = None; @@ -1351,11 +1355,11 @@ impl Deserialize for std::ops::Range { #[cfg(feature = "unstable")] #[allow(deprecated)] // num::Zero is deprecated but there is no replacement -impl Deserialize for NonZero - where T: Deserialize + PartialEq + Zeroable + Zero +impl<'de, T> Deserialize<'de> for NonZero + where T: Deserialize<'de> + PartialEq + Zeroable + Zero { fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer + where D: Deserializer<'de> { let value = try!(Deserialize::deserialize(deserializer)); if value == Zero::zero() { @@ -1368,26 +1372,26 @@ impl Deserialize for NonZero /////////////////////////////////////////////////////////////////////////////// -impl Deserialize for Result - where T: Deserialize, - E: Deserialize +impl<'de, T, E> Deserialize<'de> for Result + where T: Deserialize<'de>, + E: Deserialize<'de> { fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer + where D: Deserializer<'de> { enum Field { Ok, Err, } - impl Deserialize for Field { + impl<'de> Deserialize<'de> for Field { #[inline] fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { struct FieldVisitor; - impl Visitor for FieldVisitor { + impl<'de> Visitor<'de> for FieldVisitor { type Value = Field; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -1440,9 +1444,9 @@ impl Deserialize for Result struct ResultVisitor(PhantomData>); - impl Visitor for ResultVisitor - where T: Deserialize, - E: Deserialize + impl<'de, T, E> Visitor<'de> for ResultVisitor + where T: Deserialize<'de>, + E: Deserialize<'de> { type Value = Result; @@ -1451,7 +1455,7 @@ impl Deserialize for Result } fn visit_enum(self, visitor: V) -> Result, V::Error> - where V: EnumVisitor + where V: EnumVisitor<'de> { match try!(visitor.visit_variant()) { (Field::Ok, variant) => variant.visit_newtype().map(Ok), @@ -1472,14 +1476,14 @@ impl Deserialize for Result /// Deserialize and silently eats data given to it. pub struct IgnoredAny; -impl Deserialize for IgnoredAny { +impl<'de> Deserialize<'de> for IgnoredAny { #[inline] fn deserialize(deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { struct IgnoredAnyVisitor; - impl Visitor for IgnoredAnyVisitor { + impl<'de> Visitor<'de> for IgnoredAnyVisitor { type Value = IgnoredAny; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -1520,14 +1524,14 @@ impl Deserialize for IgnoredAny { #[inline] fn visit_some(self, _: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { Ok(IgnoredAny) } #[inline] fn visit_newtype_struct(self, _: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { Ok(IgnoredAny) } @@ -1539,7 +1543,7 @@ impl Deserialize for IgnoredAny { #[inline] fn visit_seq(self, mut visitor: V) -> Result - where V: SeqVisitor + where V: SeqVisitor<'de> { while let Some(_) = try!(visitor.visit::()) { // Gobble @@ -1549,7 +1553,7 @@ impl Deserialize for IgnoredAny { #[inline] fn visit_map(self, mut visitor: V) -> Result - where V: MapVisitor + where V: MapVisitor<'de> { while let Some((_, _)) = try!(visitor.visit::()) { // Gobble diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 334ef2ab..359df584 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -405,8 +405,8 @@ pub trait Expected { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result; } -impl Expected for T - where T: Visitor +impl<'de, T> Expected for T + where T: Visitor<'de> { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { self.expecting(formatter) @@ -451,16 +451,36 @@ impl<'a> Display for Expected + 'a { /// [de]: https://docs.serde.rs/serde/de/index.html /// [codegen]: https://serde.rs/codegen.html /// [impl-deserialize]: https://serde.rs/impl-deserialize.html -pub trait Deserialize: Sized { +pub trait Deserialize<'de>: Sized { /// Deserialize this value from the given Serde deserializer. /// /// See the [Implementing `Deserialize`][impl-deserialize] section of the /// manual for more information about how to implement this method. /// /// [impl-deserialize]: https://serde.rs/impl-deserialize.html - fn deserialize(deserializer: D) -> Result where D: Deserializer; + fn deserialize(deserializer: D) -> Result + where D: Deserializer<'de>; } +/// A data structure that can be deserialized without borrowing any data from +/// the deserializer. +/// +/// This is primarily useful for trait bounds on functions. For example a +/// `from_str` function may be able to deserialize a data structure that borrows +/// from the input string, but a `from_reader` function may only deserialize +/// owned data. +/// +/// ```rust,ignore +/// pub fn from_str<'a, T>(s: &'a str) -> Result +/// where T: Deserialize<'a>; +/// +/// pub fn from_reader(rdr: R) -> Result +/// where R: Read, +/// T: DeserializeOwned; +/// ``` +pub trait DeserializeOwned: for<'de> Deserialize<'de> {} +impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} + /// `DeserializeSeed` is the stateful form of the `Deserialize` trait. If you /// ever find yourself looking for a way to pass data into a `Deserialize` impl, /// this trait is the way to do it. @@ -600,23 +620,24 @@ pub trait Deserialize: Sized { /// # let _ = flattened; /// # Ok(()) } /// ``` -pub trait DeserializeSeed: Sized { +pub trait DeserializeSeed<'de>: Sized { /// The type produced by using this seed. type Value; /// Equivalent to the more common `Deserialize::deserialize` method, except /// with some initial piece of data (the seed) passed in. - fn deserialize(self, deserializer: D) -> Result where D: Deserializer; + fn deserialize(self, deserializer: D) -> Result + where D: Deserializer<'de>; } -impl DeserializeSeed for PhantomData - where T: Deserialize +impl<'de, T> DeserializeSeed<'de> for PhantomData + where T: Deserialize<'de> { type Value = T; #[inline] fn deserialize(self, deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { T::deserialize(deserializer) } @@ -705,7 +726,7 @@ impl DeserializeSeed for PhantomData /// what type is in the input. Know that relying on `Deserializer::deserialize` /// means your data type will be able to deserialize from self-describing /// formats only, ruling out Bincode and many others. -pub trait Deserializer: Sized { +pub trait Deserializer<'de>: Sized { /// The error type that can be returned if some error occurs during /// deserialization. type Error: Error; @@ -719,43 +740,43 @@ pub trait Deserializer: Sized { /// `Deserializer::deserialize` means your data type will be able to /// deserialize from self-describing formats only, ruling out Bincode and /// many others. - fn deserialize(self, visitor: V) -> Result where V: Visitor; + fn deserialize(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a `bool` value. - fn deserialize_bool(self, visitor: V) -> Result where V: Visitor; + fn deserialize_bool(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a `u8` value. - fn deserialize_u8(self, visitor: V) -> Result where V: Visitor; + fn deserialize_u8(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a `u16` value. - fn deserialize_u16(self, visitor: V) -> Result where V: Visitor; + fn deserialize_u16(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a `u32` value. - fn deserialize_u32(self, visitor: V) -> Result where V: Visitor; + fn deserialize_u32(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a `u64` value. - fn deserialize_u64(self, visitor: V) -> Result where V: Visitor; + fn deserialize_u64(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting an `i8` value. - fn deserialize_i8(self, visitor: V) -> Result where V: Visitor; + fn deserialize_i8(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting an `i16` value. - fn deserialize_i16(self, visitor: V) -> Result where V: Visitor; + fn deserialize_i16(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting an `i32` value. - fn deserialize_i32(self, visitor: V) -> Result where V: Visitor; + fn deserialize_i32(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting an `i64` value. - fn deserialize_i64(self, visitor: V) -> Result where V: Visitor; + fn deserialize_i64(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a `f32` value. - fn deserialize_f32(self, visitor: V) -> Result where V: Visitor; + fn deserialize_f32(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a `f64` value. - fn deserialize_f64(self, visitor: V) -> Result where V: Visitor; + fn deserialize_f64(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a `char` value. - fn deserialize_char(self, visitor: V) -> Result where V: Visitor; + fn deserialize_char(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a string value and does /// not benefit from taking ownership of buffered data owned by the @@ -764,7 +785,7 @@ pub trait Deserializer: Sized { /// If the `Visitor` would benefit from taking ownership of `String` data, /// indiciate this to the `Deserializer` by using `deserialize_string` /// instead. - fn deserialize_str(self, visitor: V) -> Result where V: Visitor; + fn deserialize_str(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a string value and would /// benefit from taking ownership of buffered data owned by the @@ -773,7 +794,7 @@ pub trait Deserializer: Sized { /// If the `Visitor` would not benefit from taking ownership of `String` /// data, indicate that to the `Deserializer` by using `deserialize_str` /// instead. - fn deserialize_string(self, visitor: V) -> Result where V: Visitor; + fn deserialize_string(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a byte array and does not /// benefit from taking ownership of buffered data owned by the @@ -782,7 +803,7 @@ pub trait Deserializer: Sized { /// If the `Visitor` would benefit from taking ownership of `Vec` data, /// indicate this to the `Deserializer` by using `deserialize_byte_buf` /// instead. - fn deserialize_bytes(self, visitor: V) -> Result where V: Visitor; + fn deserialize_bytes(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a byte array and would /// benefit from taking ownership of buffered data owned by the @@ -791,17 +812,17 @@ pub trait Deserializer: Sized { /// If the `Visitor` would not benefit from taking ownership of `Vec` /// data, indicate that to the `Deserializer` by using `deserialize_bytes` /// instead. - fn deserialize_byte_buf(self, visitor: V) -> Result where V: Visitor; + fn deserialize_byte_buf(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting an optional value. /// /// This allows deserializers that encode an optional value as a nullable /// value to convert the null value into `None` and a regular value into /// `Some(value)`. - fn deserialize_option(self, visitor: V) -> Result where V: Visitor; + fn deserialize_option(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a unit value. - fn deserialize_unit(self, visitor: V) -> Result where V: Visitor; + fn deserialize_unit(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a unit struct with a /// particular name. @@ -809,7 +830,7 @@ pub trait Deserializer: Sized { name: &'static str, visitor: V) -> Result - where V: Visitor; + where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a newtype struct with a /// particular name. @@ -817,10 +838,10 @@ pub trait Deserializer: Sized { name: &'static str, visitor: V) -> Result - where V: Visitor; + where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a sequence of values. - fn deserialize_seq(self, visitor: V) -> Result where V: Visitor; + fn deserialize_seq(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a sequence of values and /// knows how many values there are without looking at the serialized data. @@ -828,12 +849,12 @@ pub trait Deserializer: Sized { len: usize, visitor: V) -> Result - where V: Visitor; + where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a tuple value with a /// particular number of elements. fn deserialize_tuple(self, len: usize, visitor: V) -> Result - where V: Visitor; + where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a tuple struct with a /// particular name and number of fields. @@ -842,10 +863,10 @@ pub trait Deserializer: Sized { len: usize, visitor: V) -> Result - where V: Visitor; + where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a map of key-value pairs. - fn deserialize_map(self, visitor: V) -> Result where V: Visitor; + fn deserialize_map(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a struct with a particular /// name and fields. @@ -854,12 +875,12 @@ pub trait Deserializer: Sized { fields: &'static [&'static str], visitor: V) -> Result - where V: Visitor; + where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting the name of a struct /// field. fn deserialize_struct_field(self, visitor: V) -> Result - where V: Visitor; + where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting an enum value with a /// particular name and possible variants. @@ -868,14 +889,14 @@ pub trait Deserializer: Sized { variants: &'static [&'static str], visitor: V) -> Result - where V: Visitor; + where V: Visitor<'de>; /// Hint that the `Deserialize` type needs to deserialize a value whose type /// doesn't matter because it is ignored. /// /// Deserializers for non-self-describing formats may not support this mode. fn deserialize_ignored_any(self, visitor: V) -> Result - where V: Visitor; + where V: Visitor<'de>; } /////////////////////////////////////////////////////////////////////////////// @@ -910,7 +931,7 @@ pub trait Deserializer: Sized { /// } /// } /// ``` -pub trait Visitor: Sized { +pub trait Visitor<'de>: Sized { /// The value produced by this visitor. type Value; @@ -1035,6 +1056,21 @@ pub trait Visitor: Sized { Err(Error::invalid_type(Unexpected::Str(v), &self)) } + /// Deserialize a `&str` that is borrowed from the input data. + /// + /// This enables zero-copy deserialization of strings in some formats. For + /// example JSON input containing the JSON string `"borrowed"` can be + /// deserialized with zero copying into a `&'a str` as long as the input + /// data outlives `'a`. + /// + /// The default implementation forwards to `visit_str`. + #[inline] + fn visit_borrowed_str(self, v: &'de str) -> Result + where E: Error + { + self.visit_str(v) + } + /// Deserialize a `String` into a `Value`. /// /// This method allows the `Visitor` to avoid a copy by taking ownership of @@ -1073,7 +1109,7 @@ pub trait Visitor: Sized { /// Deserialize a present optional `Value`. fn visit_some(self, deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { let _ = deserializer; Err(Error::invalid_type(Unexpected::Option, &self)) @@ -1081,7 +1117,7 @@ pub trait Visitor: Sized { /// Deserialize `Value` as a newtype struct. fn visit_newtype_struct(self, deserializer: D) -> Result - where D: Deserializer + where D: Deserializer<'de> { let _ = deserializer; Err(Error::invalid_type(Unexpected::NewtypeStruct, &self)) @@ -1089,7 +1125,7 @@ pub trait Visitor: Sized { /// Deserialize `Value` as a sequence of elements. fn visit_seq(self, visitor: V) -> Result - where V: SeqVisitor + where V: SeqVisitor<'de> { let _ = visitor; Err(Error::invalid_type(Unexpected::Seq, &self)) @@ -1097,7 +1133,7 @@ pub trait Visitor: Sized { /// Deserialize `Value` as a key-value map. fn visit_map(self, visitor: V) -> Result - where V: MapVisitor + where V: MapVisitor<'de> { let _ = visitor; Err(Error::invalid_type(Unexpected::Map, &self)) @@ -1105,7 +1141,7 @@ pub trait Visitor: Sized { /// Deserialize `Value` as an enum. fn visit_enum(self, visitor: V) -> Result - where V: EnumVisitor + where V: EnumVisitor<'de> { let _ = visitor; Err(Error::invalid_type(Unexpected::Enum, &self)) @@ -1128,6 +1164,20 @@ pub trait Visitor: Sized { Err(Error::invalid_type(Unexpected::Bytes(v), &self)) } + /// Deserialize a `&[u8]` that is borrowed from the input data. + /// + /// This enables zero-copy deserialization of bytes in some formats. For + /// example Bincode data containing bytes can be deserialized with zero + /// copying into a `&'a [u8]` as long as the input data outlives `'a`. + /// + /// The default implementation forwards to `visit_bytes`. + #[inline] + fn visit_borrowed_bytes(self, v: &'de [u8]) -> Result + where E: Error + { + self.visit_bytes(v) + } + /// Deserialize a `Vec` into a `Value`. /// /// This method allows the `Visitor` to avoid a copy by taking ownership of @@ -1157,7 +1207,7 @@ pub trait Visitor: Sized { /// /// This is a trait that a `Deserializer` passes to a `Visitor` implementation, /// which deserializes each item in a sequence. -pub trait SeqVisitor { +pub trait SeqVisitor<'de> { /// The error type that can be returned if some error occurs during /// deserialization. type Error: Error; @@ -1168,7 +1218,7 @@ pub trait SeqVisitor { /// `Deserialize` implementations should typically use `SeqVisitor::visit` /// instead. fn visit_seed(&mut self, seed: T) -> Result, Self::Error> - where T: DeserializeSeed; + where T: DeserializeSeed<'de>; /// This returns `Ok(Some(value))` for the next value in the sequence, or /// `Ok(None)` if there are no more remaining items. @@ -1177,7 +1227,7 @@ pub trait SeqVisitor { /// `SeqVisitor` implementations should not override the default behavior. #[inline] fn visit(&mut self) -> Result, Self::Error> - where T: Deserialize + where T: Deserialize<'de> { self.visit_seed(PhantomData) } @@ -1189,21 +1239,21 @@ pub trait SeqVisitor { } } -impl<'a, V> SeqVisitor for &'a mut V - where V: SeqVisitor +impl<'de, 'a, V> SeqVisitor<'de> for &'a mut V + where V: SeqVisitor<'de> { type Error = V::Error; #[inline] fn visit_seed(&mut self, seed: T) -> Result, V::Error> - where T: DeserializeSeed + where T: DeserializeSeed<'de> { (**self).visit_seed(seed) } #[inline] fn visit(&mut self) -> Result, V::Error> - where T: Deserialize + where T: Deserialize<'de> { (**self).visit() } @@ -1219,7 +1269,7 @@ impl<'a, V> SeqVisitor for &'a mut V /// `MapVisitor` visits each item in a sequence. /// /// This is a trait that a `Deserializer` passes to a `Visitor` implementation. -pub trait MapVisitor { +pub trait MapVisitor<'de> { /// The error type that can be returned if some error occurs during /// deserialization. type Error: Error; @@ -1230,14 +1280,14 @@ pub trait MapVisitor { /// `Deserialize` implementations should typically use /// `MapVisitor::visit_key` or `MapVisitor::visit` instead. fn visit_key_seed(&mut self, seed: K) -> Result, Self::Error> - where K: DeserializeSeed; + where K: DeserializeSeed<'de>; /// This returns a `Ok(value)` for the next value in the map. /// /// `Deserialize` implementations should typically use /// `MapVisitor::visit_value` instead. fn visit_value_seed(&mut self, seed: V) -> Result - where V: DeserializeSeed; + where V: DeserializeSeed<'de>; /// This returns `Ok(Some((key, value)))` for the next (key-value) pair in /// the map, or `Ok(None)` if there are no more remaining items. @@ -1252,8 +1302,8 @@ pub trait MapVisitor { kseed: K, vseed: V) -> Result, Self::Error> - where K: DeserializeSeed, - V: DeserializeSeed + where K: DeserializeSeed<'de>, + V: DeserializeSeed<'de> { match try!(self.visit_key_seed(kseed)) { Some(key) => { @@ -1271,7 +1321,7 @@ pub trait MapVisitor { /// `MapVisitor` implementations should not override the default behavior. #[inline] fn visit_key(&mut self) -> Result, Self::Error> - where K: Deserialize + where K: Deserialize<'de> { self.visit_key_seed(PhantomData) } @@ -1282,7 +1332,7 @@ pub trait MapVisitor { /// `MapVisitor` implementations should not override the default behavior. #[inline] fn visit_value(&mut self) -> Result - where V: Deserialize + where V: Deserialize<'de> { self.visit_value_seed(PhantomData) } @@ -1294,8 +1344,8 @@ pub trait MapVisitor { /// `MapVisitor` implementations should not override the default behavior. #[inline] fn visit(&mut self) -> Result, Self::Error> - where K: Deserialize, - V: Deserialize + where K: Deserialize<'de>, + V: Deserialize<'de> { self.visit_seed(PhantomData, PhantomData) } @@ -1307,21 +1357,21 @@ pub trait MapVisitor { } } -impl<'a, V_> MapVisitor for &'a mut V_ - where V_: MapVisitor +impl<'de, 'a, V_> MapVisitor<'de> for &'a mut V_ + where V_: MapVisitor<'de> { type Error = V_::Error; #[inline] fn visit_key_seed(&mut self, seed: K) -> Result, Self::Error> - where K: DeserializeSeed + where K: DeserializeSeed<'de> { (**self).visit_key_seed(seed) } #[inline] fn visit_value_seed(&mut self, seed: V) -> Result - where V: DeserializeSeed + where V: DeserializeSeed<'de> { (**self).visit_value_seed(seed) } @@ -1331,30 +1381,30 @@ impl<'a, V_> MapVisitor for &'a mut V_ kseed: K, vseed: V) -> Result, Self::Error> - where K: DeserializeSeed, - V: DeserializeSeed + where K: DeserializeSeed<'de>, + V: DeserializeSeed<'de> { (**self).visit_seed(kseed, vseed) } #[inline] fn visit(&mut self) -> Result, V_::Error> - where K: Deserialize, - V: Deserialize + where K: Deserialize<'de>, + V: Deserialize<'de> { (**self).visit() } #[inline] fn visit_key(&mut self) -> Result, V_::Error> - where K: Deserialize + where K: Deserialize<'de> { (**self).visit_key() } #[inline] fn visit_value(&mut self) -> Result - where V: Deserialize + where V: Deserialize<'de> { (**self).visit_value() } @@ -1370,20 +1420,20 @@ impl<'a, V_> MapVisitor for &'a mut V_ /// `EnumVisitor` is a visitor that is created by the `Deserializer` and passed /// to the `Deserialize` in order to identify which variant of an enum to /// deserialize. -pub trait EnumVisitor: Sized { +pub trait EnumVisitor<'de>: Sized { /// The error type that can be returned if some error occurs during /// deserialization. type Error: Error; /// The `Visitor` that will be used to deserialize the content of the enum /// variant. - type Variant: VariantVisitor; + type Variant: VariantVisitor<'de, Error = Self::Error>; /// `visit_variant` is called to identify which variant to deserialize. /// /// `Deserialize` implementations should typically use /// `EnumVisitor::visit_variant` instead. fn visit_variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> - where V: DeserializeSeed; + where V: DeserializeSeed<'de>; /// `visit_variant` is called to identify which variant to deserialize. /// @@ -1391,7 +1441,7 @@ pub trait EnumVisitor: Sized { /// `EnumVisitor` implementations should not override the default behavior. #[inline] fn visit_variant(self) -> Result<(V, Self::Variant), Self::Error> - where V: Deserialize + where V: Deserialize<'de> { self.visit_variant_seed(PhantomData) } @@ -1400,7 +1450,7 @@ pub trait EnumVisitor: Sized { /// `VariantVisitor` is a visitor that is created by the `Deserializer` and /// passed to the `Deserialize` to deserialize the content of a particular enum /// variant. -pub trait VariantVisitor: Sized { +pub trait VariantVisitor<'de>: Sized { /// The error type that can be returned if some error occurs during /// deserialization. Must match the error type of our `EnumVisitor`. type Error: Error; @@ -1437,7 +1487,7 @@ pub trait VariantVisitor: Sized { /// } /// ``` fn visit_newtype_seed(self, seed: T) -> Result - where T: DeserializeSeed; + where T: DeserializeSeed<'de>; /// Called when deserializing a variant with a single value. /// @@ -1446,7 +1496,7 @@ pub trait VariantVisitor: Sized { /// behavior. #[inline] fn visit_newtype(self) -> Result - where T: Deserialize + where T: Deserialize<'de> { self.visit_newtype_seed(PhantomData) } @@ -1470,7 +1520,7 @@ pub trait VariantVisitor: Sized { /// } /// ``` fn visit_tuple(self, len: usize, visitor: V) -> Result - where V: Visitor; + where V: Visitor<'de>; /// Called when deserializing a struct-like variant. /// @@ -1494,7 +1544,7 @@ pub trait VariantVisitor: Sized { fields: &'static [&'static str], visitor: V) -> Result - where V: Visitor; + where V: Visitor<'de>; } /////////////////////////////////////////////////////////////////////////////// diff --git a/serde/src/de/private.rs b/serde/src/de/private.rs index 092d66a6..0e001962 100644 --- a/serde/src/de/private.rs +++ b/serde/src/de/private.rs @@ -9,25 +9,25 @@ pub use de::content::{Content, ContentRefDeserializer, ContentDeserializer, Tagg /// If the missing field is of type `Option` then treat is as `None`, /// otherwise it is an error. -pub fn missing_field(field: &'static str) -> Result - where V: Deserialize, +pub fn missing_field<'de, V, E>(field: &'static str) -> Result + where V: Deserialize<'de>, E: Error { struct MissingFieldDeserializer(&'static str, PhantomData); - impl Deserializer for MissingFieldDeserializer + impl<'de, E> Deserializer<'de> for MissingFieldDeserializer where E: Error { type Error = E; fn deserialize(self, _visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { Err(Error::missing_field(self.0)) } fn deserialize_option(self, visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { visitor.visit_none() } diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 00f32d68..13aaaba7 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -83,9 +83,9 @@ impl error::Error for Error { /////////////////////////////////////////////////////////////////////////////// /// This trait converts primitive types into a deserializer. -pub trait ValueDeserializer { +pub trait ValueDeserializer<'de, E: de::Error = Error> { /// The actual deserializer type. - type Deserializer: de::Deserializer; + type Deserializer: de::Deserializer<'de, Error = E>; /// Convert this value into a deserializer. fn into_deserializer(self) -> Self::Deserializer; @@ -93,7 +93,7 @@ pub trait ValueDeserializer { /////////////////////////////////////////////////////////////////////////////// -impl ValueDeserializer for () +impl<'de, E> ValueDeserializer<'de, E> for () where E: de::Error { type Deserializer = UnitDeserializer; @@ -108,7 +108,7 @@ pub struct UnitDeserializer { marker: PhantomData, } -impl de::Deserializer for UnitDeserializer +impl<'de, E> de::Deserializer<'de> for UnitDeserializer where E: de::Error { type Error = E; @@ -120,13 +120,13 @@ impl de::Deserializer for UnitDeserializer } fn deserialize(self, visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { visitor.visit_unit() } fn deserialize_option(self, visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { visitor.visit_none() } @@ -142,7 +142,7 @@ macro_rules! primitive_deserializer { marker: PhantomData } - impl ValueDeserializer for $ty + impl<'de, E> ValueDeserializer<'de, E> for $ty where E: de::Error, { type Deserializer = $name; @@ -155,7 +155,7 @@ macro_rules! primitive_deserializer { } } - impl de::Deserializer for $name + impl<'de, E> de::Deserializer<'de> for $name where E: de::Error, { type Error = E; @@ -167,7 +167,7 @@ macro_rules! primitive_deserializer { } fn deserialize(self, visitor: V) -> Result - where V: de::Visitor, + where V: de::Visitor<'de>, { visitor.$method(self.value $($cast)*) } @@ -195,7 +195,7 @@ pub struct U32Deserializer { marker: PhantomData, } -impl ValueDeserializer for u32 +impl<'de, E> ValueDeserializer<'de, E> for u32 where E: de::Error { type Deserializer = U32Deserializer; @@ -208,7 +208,7 @@ impl ValueDeserializer for u32 } } -impl de::Deserializer for U32Deserializer +impl<'de, E> de::Deserializer<'de> for U32Deserializer where E: de::Error { type Error = E; @@ -220,7 +220,7 @@ impl de::Deserializer for U32Deserializer } fn deserialize(self, visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { visitor.visit_u32(self.value) } @@ -230,20 +230,20 @@ impl de::Deserializer for U32Deserializer _variants: &'static [&'static str], visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { visitor.visit_enum(self) } } -impl de::EnumVisitor for U32Deserializer +impl<'de, E> de::EnumVisitor<'de> for U32Deserializer where E: de::Error { type Error = E; type Variant = private::UnitOnly; fn visit_variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> - where T: de::DeserializeSeed + where T: de::DeserializeSeed<'de> { seed.deserialize(self).map(private::unit_only) } @@ -257,7 +257,7 @@ pub struct StrDeserializer<'a, E> { marker: PhantomData, } -impl<'a, E> ValueDeserializer for &'a str +impl<'de, 'a, E> ValueDeserializer<'de, E> for &'a str where E: de::Error { type Deserializer = StrDeserializer<'a, E>; @@ -270,13 +270,13 @@ impl<'a, E> ValueDeserializer for &'a str } } -impl<'a, E> de::Deserializer for StrDeserializer<'a, E> +impl<'de, 'a, E> de::Deserializer<'de> for StrDeserializer<'a, E> where E: de::Error { type Error = E; fn deserialize(self, visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { visitor.visit_str(self.value) } @@ -286,7 +286,7 @@ impl<'a, E> de::Deserializer for StrDeserializer<'a, E> _variants: &'static [&'static str], visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { visitor.visit_enum(self) } @@ -298,14 +298,14 @@ impl<'a, E> de::Deserializer for StrDeserializer<'a, E> } } -impl<'a, E> de::EnumVisitor for StrDeserializer<'a, E> +impl<'de, 'a, E> de::EnumVisitor<'de> for StrDeserializer<'a, E> where E: de::Error { type Error = E; type Variant = private::UnitOnly; fn visit_variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> - where T: de::DeserializeSeed + where T: de::DeserializeSeed<'de> { seed.deserialize(self).map(private::unit_only) } @@ -321,7 +321,7 @@ pub struct StringDeserializer { } #[cfg(any(feature = "std", feature = "collections"))] -impl ValueDeserializer for String +impl<'de, E> ValueDeserializer<'de, E> for String where E: de::Error { type Deserializer = StringDeserializer; @@ -335,13 +335,13 @@ impl ValueDeserializer for String } #[cfg(any(feature = "std", feature = "collections"))] -impl de::Deserializer for StringDeserializer +impl<'de, E> de::Deserializer<'de> for StringDeserializer where E: de::Error { type Error = E; fn deserialize(self, visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { visitor.visit_string(self.value) } @@ -351,7 +351,7 @@ impl de::Deserializer for StringDeserializer _variants: &'static [&'static str], visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { visitor.visit_enum(self) } @@ -364,14 +364,14 @@ impl de::Deserializer for StringDeserializer } #[cfg(any(feature = "std", feature = "collections"))] -impl<'a, E> de::EnumVisitor for StringDeserializer +impl<'de, 'a, E> de::EnumVisitor<'de> for StringDeserializer where E: de::Error { type Error = E; type Variant = private::UnitOnly; fn visit_variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> - where T: de::DeserializeSeed + where T: de::DeserializeSeed<'de> { seed.deserialize(self).map(private::unit_only) } @@ -387,7 +387,7 @@ pub struct CowStrDeserializer<'a, E> { } #[cfg(any(feature = "std", feature = "collections"))] -impl<'a, E> ValueDeserializer for Cow<'a, str> +impl<'de, 'a, E> ValueDeserializer<'de, E> for Cow<'a, str> where E: de::Error { type Deserializer = CowStrDeserializer<'a, E>; @@ -401,13 +401,13 @@ impl<'a, E> ValueDeserializer for Cow<'a, str> } #[cfg(any(feature = "std", feature = "collections"))] -impl<'a, E> de::Deserializer for CowStrDeserializer<'a, E> +impl<'de, 'a, E> de::Deserializer<'de> for CowStrDeserializer<'a, E> where E: de::Error { type Error = E; fn deserialize(self, visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { match self.value { Cow::Borrowed(string) => visitor.visit_str(string), @@ -420,7 +420,7 @@ impl<'a, E> de::Deserializer for CowStrDeserializer<'a, E> _variants: &'static [&'static str], visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { visitor.visit_enum(self) } @@ -433,14 +433,14 @@ impl<'a, E> de::Deserializer for CowStrDeserializer<'a, E> } #[cfg(any(feature = "std", feature = "collections"))] -impl<'a, E> de::EnumVisitor for CowStrDeserializer<'a, E> +impl<'de, 'a, E> de::EnumVisitor<'de> for CowStrDeserializer<'a, E> where E: de::Error { type Error = E; type Variant = private::UnitOnly; fn visit_variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> - where T: de::DeserializeSeed + where T: de::DeserializeSeed<'de> { seed.deserialize(self).map(private::unit_only) } @@ -485,15 +485,15 @@ impl SeqDeserializer } } -impl de::Deserializer for SeqDeserializer +impl<'de, I, T, E> de::Deserializer<'de> for SeqDeserializer where I: Iterator, - T: ValueDeserializer, + T: ValueDeserializer<'de, E>, E: de::Error { type Error = E; fn deserialize(mut self, visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { let v = try!(visitor.visit_seq(&mut self)); try!(self.end()); @@ -507,15 +507,15 @@ impl de::Deserializer for SeqDeserializer } } -impl de::SeqVisitor for SeqDeserializer +impl<'de, I, T, E> de::SeqVisitor<'de> for SeqDeserializer where I: Iterator, - T: ValueDeserializer, + T: ValueDeserializer<'de, E>, E: de::Error { type Error = E; fn visit_seed(&mut self, seed: V) -> Result, Self::Error> - where V: de::DeserializeSeed + where V: de::DeserializeSeed<'de> { match self.iter.next() { Some(value) => { @@ -546,8 +546,8 @@ impl Expected for ExpectedInSeq { /////////////////////////////////////////////////////////////////////////////// #[cfg(any(feature = "std", feature = "collections"))] -impl ValueDeserializer for Vec - where T: ValueDeserializer, +impl<'de, T, E> ValueDeserializer<'de, E> for Vec + where T: ValueDeserializer<'de, E>, E: de::Error { type Deserializer = SeqDeserializer, E>; @@ -558,8 +558,8 @@ impl ValueDeserializer for Vec } #[cfg(any(feature = "std", feature = "collections"))] -impl ValueDeserializer for BTreeSet - where T: ValueDeserializer + Eq + Ord, +impl<'de, T, E> ValueDeserializer<'de, E> for BTreeSet + where T: ValueDeserializer<'de, E> + Eq + Ord, E: de::Error { type Deserializer = SeqDeserializer, E>; @@ -570,8 +570,8 @@ impl ValueDeserializer for BTreeSet } #[cfg(feature = "std")] -impl ValueDeserializer for HashSet - where T: ValueDeserializer + Eq + Hash, +impl<'de, T, E> ValueDeserializer<'de, E> for HashSet + where T: ValueDeserializer<'de, E> + Eq + Hash, E: de::Error { type Deserializer = SeqDeserializer, E>; @@ -584,31 +584,27 @@ impl ValueDeserializer for HashSet /////////////////////////////////////////////////////////////////////////////// /// A helper deserializer that deserializes a sequence using a `SeqVisitor`. -pub struct SeqVisitorDeserializer { +pub struct SeqVisitorDeserializer { visitor: V_, - marker: PhantomData, } -impl SeqVisitorDeserializer - where V_: de::SeqVisitor, - E: de::Error -{ +impl SeqVisitorDeserializer { /// Construct a new `SeqVisitorDeserializer`. pub fn new(visitor: V_) -> Self { SeqVisitorDeserializer { visitor: visitor, - marker: PhantomData, } } } -impl de::Deserializer for SeqVisitorDeserializer - where V_: de::SeqVisitor, - E: de::Error +impl<'de, V_> de::Deserializer<'de> for SeqVisitorDeserializer + where V_: de::SeqVisitor<'de> { - type Error = E; + type Error = V_::Error; - fn deserialize(self, visitor: V) -> Result { + fn deserialize(self, visitor: V) -> Result + where V: de::Visitor<'de> + { visitor.visit_seq(self.visitor) } @@ -622,24 +618,25 @@ impl de::Deserializer for SeqVisitorDeserializer /////////////////////////////////////////////////////////////////////////////// /// A helper deserializer that deserializes a map. -pub struct MapDeserializer +pub struct MapDeserializer<'de, I, E> where I: Iterator, I::Item: private::Pair, - ::First: ValueDeserializer, - ::Second: ValueDeserializer, + ::First: ValueDeserializer<'de, E>, + ::Second: ValueDeserializer<'de, E>, E: de::Error { iter: iter::Fuse, value: Option<::Second>, count: usize, - marker: PhantomData, + lifetime: PhantomData<&'de ()>, + error: PhantomData, } -impl MapDeserializer +impl<'de, I, E> MapDeserializer<'de, I, E> where I: Iterator, I::Item: private::Pair, - ::First: ValueDeserializer, - ::Second: ValueDeserializer, + ::First: ValueDeserializer<'de, E>, + ::Second: ValueDeserializer<'de, E>, E: de::Error { /// Construct a new `MapDeserializer`. @@ -648,7 +645,8 @@ impl MapDeserializer iter: iter.fuse(), value: None, count: 0, - marker: PhantomData, + lifetime: PhantomData, + error: PhantomData, } } @@ -681,17 +679,17 @@ impl MapDeserializer } } -impl de::Deserializer for MapDeserializer +impl<'de, I, E> de::Deserializer<'de> for MapDeserializer<'de, I, E> where I: Iterator, I::Item: private::Pair, - ::First: ValueDeserializer, - ::Second: ValueDeserializer, + ::First: ValueDeserializer<'de, E>, + ::Second: ValueDeserializer<'de, E>, E: de::Error { type Error = E; fn deserialize(mut self, visitor: V_) -> Result - where V_: de::Visitor + where V_: de::Visitor<'de> { let value = try!(visitor.visit_map(&mut self)); try!(self.end()); @@ -699,7 +697,7 @@ impl de::Deserializer for MapDeserializer } fn deserialize_seq(mut self, visitor: V_) -> Result - where V_: de::Visitor + where V_: de::Visitor<'de> { let value = try!(visitor.visit_seq(&mut self)); try!(self.end()); @@ -710,7 +708,7 @@ impl de::Deserializer for MapDeserializer _len: usize, visitor: V_) -> Result - where V_: de::Visitor + where V_: de::Visitor<'de> { self.deserialize_seq(visitor) } @@ -722,17 +720,17 @@ impl de::Deserializer for MapDeserializer } } -impl de::MapVisitor for MapDeserializer +impl<'de, I, E> de::MapVisitor<'de> for MapDeserializer<'de, I, E> where I: Iterator, I::Item: private::Pair, - ::First: ValueDeserializer, - ::Second: ValueDeserializer, + ::First: ValueDeserializer<'de, E>, + ::Second: ValueDeserializer<'de, E>, E: de::Error { type Error = E; fn visit_key_seed(&mut self, seed: T) -> Result, Self::Error> - where T: de::DeserializeSeed + where T: de::DeserializeSeed<'de> { match self.next_pair() { Some((key, value)) => { @@ -744,7 +742,7 @@ impl de::MapVisitor for MapDeserializer } fn visit_value_seed(&mut self, seed: T) -> Result - where T: de::DeserializeSeed + where T: de::DeserializeSeed<'de> { let value = self.value.take(); // Panic because this indicates a bug in the program rather than an @@ -757,8 +755,8 @@ impl de::MapVisitor for MapDeserializer kseed: TK, vseed: TV) -> Result, Self::Error> - where TK: de::DeserializeSeed, - TV: de::DeserializeSeed + where TK: de::DeserializeSeed<'de>, + TV: de::DeserializeSeed<'de> { match self.next_pair() { Some((key, value)) => { @@ -775,17 +773,17 @@ impl de::MapVisitor for MapDeserializer } } -impl de::SeqVisitor for MapDeserializer +impl<'de, I, E> de::SeqVisitor<'de> for MapDeserializer<'de, I, E> where I: Iterator, I::Item: private::Pair, - ::First: ValueDeserializer, - ::Second: ValueDeserializer, + ::First: ValueDeserializer<'de, E>, + ::Second: ValueDeserializer<'de, E>, E: de::Error { type Error = E; fn visit_seed(&mut self, seed: T) -> Result, Self::Error> - where T: de::DeserializeSeed + where T: de::DeserializeSeed<'de> { match self.next_pair() { Some((k, v)) => { @@ -805,9 +803,9 @@ impl de::SeqVisitor for MapDeserializer // sequence of pairs. struct PairDeserializer(A, B, PhantomData); -impl de::Deserializer for PairDeserializer - where A: ValueDeserializer, - B: ValueDeserializer, +impl<'de, A, B, E> de::Deserializer<'de> for PairDeserializer + where A: ValueDeserializer<'de, E>, + B: ValueDeserializer<'de, E>, E: de::Error { type Error = E; @@ -819,13 +817,13 @@ impl de::Deserializer for PairDeserializer } fn deserialize(self, visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { self.deserialize_seq(visitor) } fn deserialize_seq(self, visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { let mut pair_visitor = PairVisitor(Some(self.0), Some(self.1), PhantomData); let pair = try!(visitor.visit_seq(&mut pair_visitor)); @@ -840,7 +838,7 @@ impl de::Deserializer for PairDeserializer } fn deserialize_seq_fixed_size(self, len: usize, visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { if len == 2 { self.deserialize_seq(visitor) @@ -854,15 +852,15 @@ impl de::Deserializer for PairDeserializer struct PairVisitor(Option, Option, PhantomData); -impl de::SeqVisitor for PairVisitor - where A: ValueDeserializer, - B: ValueDeserializer, +impl<'de, A, B, E> de::SeqVisitor<'de> for PairVisitor + where A: ValueDeserializer<'de, E>, + B: ValueDeserializer<'de, E>, E: de::Error { type Error = E; fn visit_seed(&mut self, seed: T) -> Result, Self::Error> - where T: de::DeserializeSeed + where T: de::DeserializeSeed<'de> { if let Some(k) = self.0.take() { seed.deserialize(k.into_deserializer()).map(Some) @@ -900,12 +898,12 @@ impl Expected for ExpectedInMap { /////////////////////////////////////////////////////////////////////////////// #[cfg(any(feature = "std", feature = "collections"))] -impl ValueDeserializer for BTreeMap - where K: ValueDeserializer + Eq + Ord, - V: ValueDeserializer, +impl<'de, K, V, E> ValueDeserializer<'de, E> for BTreeMap + where K: ValueDeserializer<'de, E> + Eq + Ord, + V: ValueDeserializer<'de, E>, E: de::Error { - type Deserializer = MapDeserializer, E>; + type Deserializer = MapDeserializer<'de, btree_map::IntoIter, E>; fn into_deserializer(self) -> Self::Deserializer { MapDeserializer::new(self.into_iter()) @@ -913,12 +911,12 @@ impl ValueDeserializer for BTreeMap } #[cfg(feature = "std")] -impl ValueDeserializer for HashMap - where K: ValueDeserializer + Eq + Hash, - V: ValueDeserializer, +impl<'de, K, V, E> ValueDeserializer<'de, E> for HashMap + where K: ValueDeserializer<'de, E> + Eq + Hash, + V: ValueDeserializer<'de, E>, E: de::Error { - type Deserializer = MapDeserializer, E>; + type Deserializer = MapDeserializer<'de, hash_map::IntoIter, E>; fn into_deserializer(self) -> Self::Deserializer { MapDeserializer::new(self.into_iter()) @@ -928,31 +926,27 @@ impl ValueDeserializer for HashMap /////////////////////////////////////////////////////////////////////////////// /// A helper deserializer that deserializes a map using a `MapVisitor`. -pub struct MapVisitorDeserializer { +pub struct MapVisitorDeserializer { visitor: V_, - marker: PhantomData, } -impl MapVisitorDeserializer - where V_: de::MapVisitor, - E: de::Error -{ +impl MapVisitorDeserializer { /// Construct a new `MapVisitorDeserializer`. pub fn new(visitor: V_) -> Self { MapVisitorDeserializer { visitor: visitor, - marker: PhantomData, } } } -impl de::Deserializer for MapVisitorDeserializer - where V_: de::MapVisitor, - E: de::Error +impl<'de, V_> de::Deserializer<'de> for MapVisitorDeserializer + where V_: de::MapVisitor<'de> { - type Error = E; + type Error = V_::Error; - fn deserialize(self, visitor: V) -> Result { + fn deserialize(self, visitor: V) -> Result + where V: de::Visitor<'de> + { visitor.visit_map(self.visitor) } @@ -965,7 +959,7 @@ impl de::Deserializer for MapVisitorDeserializer /////////////////////////////////////////////////////////////////////////////// -impl<'a, E> ValueDeserializer for bytes::Bytes<'a> +impl<'de, 'a, E> ValueDeserializer<'de, E> for bytes::Bytes<'a> where E: de::Error { type Deserializer = BytesDeserializer<'a, E>; @@ -984,13 +978,13 @@ pub struct BytesDeserializer<'a, E> { marker: PhantomData, } -impl<'a, E> de::Deserializer for BytesDeserializer<'a, E> +impl<'de, 'a, E> de::Deserializer<'de> for BytesDeserializer<'a, E> where E: de::Error { type Error = E; fn deserialize(self, visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { visitor.visit_bytes(self.value) } @@ -1005,7 +999,7 @@ impl<'a, E> de::Deserializer for BytesDeserializer<'a, E> /////////////////////////////////////////////////////////////////////////////// #[cfg(any(feature = "std", feature = "collections"))] -impl ValueDeserializer for bytes::ByteBuf +impl<'de, E> ValueDeserializer<'de, E> for bytes::ByteBuf where E: de::Error { type Deserializer = ByteBufDeserializer; @@ -1026,13 +1020,13 @@ pub struct ByteBufDeserializer { } #[cfg(any(feature = "std", feature = "collections"))] -impl de::Deserializer for ByteBufDeserializer +impl<'de, E> de::Deserializer<'de> for ByteBufDeserializer where E: de::Error { type Error = E; fn deserialize(self, visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { visitor.visit_byte_buf(self.value) } @@ -1058,7 +1052,7 @@ mod private { (t, UnitOnly { marker: PhantomData }) } - impl de::VariantVisitor for UnitOnly + impl<'de, E> de::VariantVisitor<'de> for UnitOnly where E: de::Error { type Error = E; @@ -1068,13 +1062,13 @@ mod private { } fn visit_newtype_seed(self, _seed: T) -> Result - where T: de::DeserializeSeed + where T: de::DeserializeSeed<'de> { Err(de::Error::invalid_type(Unexpected::UnitVariant, &"newtype variant")) } fn visit_tuple(self, _len: usize, _visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { Err(de::Error::invalid_type(Unexpected::UnitVariant, &"tuple variant")) } @@ -1083,7 +1077,7 @@ mod private { _fields: &'static [&'static str], _visitor: V) -> Result - where V: de::Visitor + where V: de::Visitor<'de> { Err(de::Error::invalid_type(Unexpected::UnitVariant, &"struct variant")) } diff --git a/serde/src/macros.rs b/serde/src/macros.rs index 126c7ec1..42b5accd 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -5,7 +5,7 @@ macro_rules! forward_to_deserialize_method { ($func:ident($($arg:ty),*)) => { #[inline] fn $func<__V>(self, $(_: $arg,)* visitor: __V) -> ::std::result::Result<__V::Value, Self::Error> - where __V: $crate::de::Visitor + where __V: $crate::de::Visitor<'de> { self.deserialize(visitor) } @@ -19,7 +19,7 @@ macro_rules! forward_to_deserialize_method { ($func:ident($($arg:ty),*)) => { #[inline] fn $func<__V>(self, $(_: $arg,)* visitor: __V) -> ::core::result::Result<__V::Value, Self::Error> - where __V: $crate::de::Visitor + where __V: $crate::de::Visitor<'de> { self.deserialize(visitor) } diff --git a/serde_derive/src/bound.rs b/serde_derive/src/bound.rs index 2fe797a1..fe45344f 100644 --- a/serde_derive/src/bound.rs +++ b/serde_derive/src/bound.rs @@ -6,28 +6,8 @@ use internals::ast::Item; use internals::attr; macro_rules! path { - ($first:ident $(:: $rest:ident)*) => { - syn::Path { - global: false, - segments: vec![ - stringify!($first).into(), - $( - stringify!($rest).into(), - )* - ], - } - }; - - (::$first:ident $(:: $rest:ident)*) => { - syn::Path { - global: true, - segments: vec![ - stringify!($first).into(), - $( - stringify!($rest).into(), - )* - ], - } + ($($path:tt)+) => { + syn::parse_path(stringify!($($path)+)).unwrap() }; } diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 637efb51..6ab9f95e 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -1,5 +1,5 @@ use syn::{self, Ident}; -use quote::{self, Tokens}; +use quote::{self, Tokens, ToTokens}; use bound; use fragment::{Fragment, Expr, Stmts, Match}; @@ -17,7 +17,7 @@ pub fn expand_derive_deserialize(item: &syn::DeriveInput) -> Result Result for #ident #ty_generics #where_clause { fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result - where __D: _serde::Deserializer + where __D: _serde::Deserializer<'de> { #body } @@ -60,7 +60,7 @@ fn build_generics(item: &Item) -> syn::Generics { bound::with_bound(item, &generics, needs_deserialize_bound, - &path!(_serde::Deserialize)); + &path!(_serde::Deserialize<'de>)); bound::with_bound(item, &generics, @@ -136,7 +136,7 @@ fn deserialize_unit_struct(ident: &syn::Ident, item_attrs: &attr::Item) -> Fragm quote_block! { struct __Visitor; - impl _serde::de::Visitor for __Visitor { + impl<'de> _serde::de::Visitor<'de> for __Visitor { type Value = #ident; fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { @@ -152,7 +152,7 @@ fn deserialize_unit_struct(ident: &syn::Ident, item_attrs: &attr::Item) -> Fragm #[inline] fn visit_seq<__V>(self, _: __V) -> _serde::export::Result<#ident, __V::Error> - where __V: _serde::de::SeqVisitor + where __V: _serde::de::SeqVisitor<'de> { _serde::export::Ok(#ident) } @@ -169,7 +169,7 @@ fn deserialize_tuple(ident: &syn::Ident, item_attrs: &attr::Item, deserializer: Option) -> Fragment { - let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(generics); let is_enum = variant_ident.is_some(); let type_path = match variant_ident { @@ -192,7 +192,10 @@ fn deserialize_tuple(ident: &syn::Ident, let visit_seq = Stmts(deserialize_seq(ident, &type_path, generics, fields, false, item_attrs)); let visitor_expr = quote! { - __Visitor { marker: _serde::export::PhantomData::<#ident #ty_generics> } + __Visitor { + marker: _serde::export::PhantomData::<#ident #ty_generics>, + lifetime: _serde::export::PhantomData, + } }; let dispatch = if let Some(deserializer) = deserializer { quote!(_serde::Deserializer::deserialize_tuple(#deserializer, #nfields, #visitor_expr)) @@ -214,11 +217,12 @@ fn deserialize_tuple(ident: &syn::Ident, }; quote_block! { - struct __Visitor #impl_generics #where_clause { + struct __Visitor #de_impl_generics #where_clause { marker: _serde::export::PhantomData<#ident #ty_generics>, + lifetime: _serde::export::PhantomData<&'de ()>, } - impl #impl_generics _serde::de::Visitor for __Visitor #ty_generics #where_clause { + impl #de_impl_generics _serde::de::Visitor<'de> for __Visitor #de_ty_generics #where_clause { type Value = #ident #ty_generics; fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { @@ -229,7 +233,7 @@ fn deserialize_tuple(ident: &syn::Ident, #[inline] fn visit_seq<__V>(self, #visitor_var: __V) -> _serde::export::Result - where __V: _serde::de::SeqVisitor + where __V: _serde::de::SeqVisitor<'de> { #visit_seq } @@ -332,7 +336,7 @@ fn deserialize_newtype_struct(ident: &syn::Ident, quote! { #[inline] fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result - where __E: _serde::Deserializer + where __E: _serde::Deserializer<'de> { _serde::export::Ok(#type_path(#value)) } @@ -349,7 +353,7 @@ fn deserialize_struct(ident: &syn::Ident, let is_enum = variant_ident.is_some(); let is_untagged = deserializer.is_some(); - let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(generics); let type_path = match variant_ident { Some(variant_ident) => quote!(#ident::#variant_ident), @@ -369,7 +373,10 @@ fn deserialize_struct(ident: &syn::Ident, let visit_map = Stmts(visit_map); let visitor_expr = quote! { - __Visitor { marker: _serde::export::PhantomData::<#ident #ty_generics> } + __Visitor { + marker: _serde::export::PhantomData::<#ident #ty_generics>, + lifetime: _serde::export::PhantomData, + } }; let dispatch = if let Some(deserializer) = deserializer { quote! { @@ -400,7 +407,7 @@ fn deserialize_struct(ident: &syn::Ident, Some(quote! { #[inline] fn visit_seq<__V>(self, #visitor_var: __V) -> _serde::export::Result - where __V: _serde::de::SeqVisitor + where __V: _serde::de::SeqVisitor<'de> { #visit_seq } @@ -410,11 +417,12 @@ fn deserialize_struct(ident: &syn::Ident, quote_block! { #field_visitor - struct __Visitor #impl_generics #where_clause { + struct __Visitor #de_impl_generics #where_clause { marker: _serde::export::PhantomData<#ident #ty_generics>, + lifetime: _serde::export::PhantomData<&'de ()>, } - impl #generics _serde::de::Visitor for __Visitor #ty_generics #where_clause { + impl #de_impl_generics _serde::de::Visitor<'de> for __Visitor #de_ty_generics #where_clause { type Value = #ident #ty_generics; fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { @@ -425,7 +433,7 @@ fn deserialize_struct(ident: &syn::Ident, #[inline] fn visit_map<__V>(self, mut __visitor: __V) -> _serde::export::Result - where __V: _serde::de::MapVisitor + where __V: _serde::de::MapVisitor<'de> { #visit_map } @@ -472,7 +480,7 @@ fn deserialize_externally_tagged_enum(ident: &syn::Ident, variants: &[Variant], item_attrs: &attr::Item) -> Fragment { - let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(generics); let type_name = item_attrs.name().deserialize_name(); @@ -533,11 +541,12 @@ fn deserialize_externally_tagged_enum(ident: &syn::Ident, quote_block! { #variant_visitor - struct __Visitor #impl_generics #where_clause { + struct __Visitor #de_impl_generics #where_clause { marker: _serde::export::PhantomData<#ident #ty_generics>, + lifetime: _serde::export::PhantomData<&'de ()>, } - impl #generics _serde::de::Visitor for __Visitor #ty_generics #where_clause { + impl #de_impl_generics _serde::de::Visitor<'de> for __Visitor #de_ty_generics #where_clause { type Value = #ident #ty_generics; fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { @@ -545,7 +554,7 @@ fn deserialize_externally_tagged_enum(ident: &syn::Ident, } fn visit_enum<__V>(self, __visitor: __V) -> _serde::export::Result - where __V: _serde::de::EnumVisitor + where __V: _serde::de::EnumVisitor<'de> { #match_variant } @@ -556,6 +565,7 @@ fn deserialize_externally_tagged_enum(ident: &syn::Ident, _serde::Deserializer::deserialize_enum(__deserializer, #type_name, VARIANTS, __Visitor { marker: _serde::export::PhantomData::<#ident #ty_generics>, + lifetime: _serde::export::PhantomData, }) } } @@ -623,7 +633,7 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, tag: &str, content: &str) -> Fragment { - let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(generics); let variant_names_idents: Vec<_> = variants.iter() .enumerate() @@ -724,16 +734,17 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, #variants_stmt - struct __Seed #impl_generics #where_clause { + struct __Seed #de_impl_generics #where_clause { field: __Field, marker: _serde::export::PhantomData<#ident #ty_generics>, + lifetime: _serde::export::PhantomData<&'de ()>, } - impl #impl_generics _serde::de::DeserializeSeed for __Seed #ty_generics #where_clause { + impl #de_impl_generics _serde::de::DeserializeSeed<'de> for __Seed #de_ty_generics #where_clause { type Value = #ident #ty_generics; fn deserialize<__D>(self, __deserializer: __D) -> _serde::export::Result - where __D: _serde::Deserializer + where __D: _serde::Deserializer<'de> { match self.field { #(#variant_arms)* @@ -741,11 +752,12 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, } } - struct __Visitor #impl_generics #where_clause { + struct __Visitor #de_impl_generics #where_clause { marker: _serde::export::PhantomData<#ident #ty_generics>, + lifetime: _serde::export::PhantomData<&'de ()>, } - impl #impl_generics _serde::de::Visitor for __Visitor #ty_generics #where_clause { + impl #de_impl_generics _serde::de::Visitor<'de> for __Visitor #de_ty_generics #where_clause { type Value = #ident #ty_generics; fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { @@ -753,7 +765,7 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, } fn visit_map<__V>(self, mut __visitor: __V) -> _serde::export::Result - where __V: _serde::de::MapVisitor + where __V: _serde::de::MapVisitor<'de> { // Visit the first key. match try!(_serde::de::MapVisitor::visit_key_seed(&mut __visitor, #tag_or_content)) { @@ -769,7 +781,12 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, } // Second key is the content. _serde::export::Some(_serde::de::private::TagOrContentField::Content) => { - let __ret = try!(_serde::de::MapVisitor::visit_value_seed(&mut __visitor, __Seed { field: __field, marker: _serde::export::PhantomData })); + let __ret = try!(_serde::de::MapVisitor::visit_value_seed(&mut __visitor, + __Seed { + field: __field, + marker: _serde::export::PhantomData, + lifetime: _serde::export::PhantomData, + })); // Visit the third key, hopefully there isn't one. #visit_third_key } @@ -812,13 +829,18 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, } fn visit_seq<__V>(self, mut __visitor: __V) -> _serde::export::Result - where __V: _serde::de::SeqVisitor + where __V: _serde::de::SeqVisitor<'de> { // Visit the first element - the tag. match try!(_serde::de::SeqVisitor::visit(&mut __visitor)) { _serde::export::Some(__field) => { // Visit the second element - the content. - match try!(_serde::de::SeqVisitor::visit_seed(&mut __visitor, __Seed { field: __field, marker: _serde::export::PhantomData })) { + match try!(_serde::de::SeqVisitor::visit_seed(&mut __visitor, + __Seed { + field: __field, + marker: _serde::export::PhantomData, + lifetime: _serde::export::PhantomData, + })) { _serde::export::Some(__ret) => _serde::export::Ok(__ret), // There is no second element. _serde::export::None => { @@ -836,7 +858,10 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, const FIELDS: &'static [&'static str] = &[#tag, #content]; _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, - __Visitor { marker: _serde::export::PhantomData::<#ident #ty_generics> }) + __Visitor { + marker: _serde::export::PhantomData::<#ident #ty_generics>, + lifetime: _serde::export::PhantomData, + }) } } @@ -1111,14 +1136,14 @@ fn deserialize_field_visitor(fields: Vec<(String, Ident)>, #ignore_variant } - impl _serde::Deserialize for __Field { + impl<'de> _serde::Deserialize<'de> for __Field { #[inline] fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<__Field, __D::Error> - where __D: _serde::Deserializer + where __D: _serde::Deserializer<'de> { struct __FieldVisitor; - impl _serde::de::Visitor for __FieldVisitor { + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { type Value = __Field; fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { @@ -1334,27 +1359,29 @@ fn wrap_deserialize_with(ident: &syn::Ident, field_ty: &syn::Ty, deserialize_with: &syn::Path) -> (Tokens, Tokens) { - let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(generics); let wrapper = quote! { - struct __DeserializeWith #impl_generics #where_clause { + struct __DeserializeWith #de_impl_generics #where_clause { value: #field_ty, phantom: _serde::export::PhantomData<#ident #ty_generics>, + lifetime: _serde::export::PhantomData<&'de ()>, } - impl #impl_generics _serde::Deserialize for __DeserializeWith #ty_generics #where_clause { + impl #de_impl_generics _serde::Deserialize<'de> for __DeserializeWith #de_ty_generics #where_clause { fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result - where __D: _serde::Deserializer + where __D: _serde::Deserializer<'de> { _serde::export::Ok(__DeserializeWith { value: try!(#deserialize_with(__deserializer)), phantom: _serde::export::PhantomData, + lifetime: _serde::export::PhantomData, }) } } }; - let wrapper_ty = quote!(__DeserializeWith #ty_generics); + let wrapper_ty = quote!(__DeserializeWith #de_ty_generics); (wrapper, wrapper_ty) } @@ -1414,3 +1441,32 @@ fn check_no_str(cx: &internals::Ctxt, item: &Item) { } } } + +struct DeImplGenerics<'a>(&'a syn::Generics); + +impl<'a> ToTokens for DeImplGenerics<'a> { + fn to_tokens(&self, tokens: &mut Tokens) { + let mut generics = self.0.clone(); + generics.lifetimes.insert(0, syn::LifetimeDef::new("'de")); + let (impl_generics, _, _) = generics.split_for_impl(); + impl_generics.to_tokens(tokens); + } +} + +struct DeTyGenerics<'a>(&'a syn::Generics); + +impl<'a> ToTokens for DeTyGenerics<'a> { + fn to_tokens(&self, tokens: &mut Tokens) { + let mut generics = self.0.clone(); + generics.lifetimes.insert(0, syn::LifetimeDef::new("'de")); + let (_, ty_generics, _) = generics.split_for_impl(); + ty_generics.to_tokens(tokens); + } +} + +fn split_with_de_lifetime(generics: &syn::Generics) -> (DeImplGenerics, DeTyGenerics, syn::TyGenerics, &syn::WhereClause) { + let de_impl_generics = DeImplGenerics(generics); + let de_ty_generics = DeTyGenerics(generics); + let (_, ty_generics, where_clause) = generics.split_for_impl(); + (de_impl_generics, de_ty_generics, ty_generics, where_clause) +} diff --git a/serde_test/src/assert.rs b/serde_test/src/assert.rs index 9d281faa..fc33f282 100644 --- a/serde_test/src/assert.rs +++ b/serde_test/src/assert.rs @@ -8,8 +8,8 @@ use token::Token; use std::fmt::Debug; /// Runs both `assert_ser_tokens` and `assert_de_tokens`. -pub fn assert_tokens(value: &T, tokens: &[Token<'static>]) - where T: Serialize + Deserialize + PartialEq + Debug +pub fn assert_tokens<'de, T>(value: &T, tokens: &[Token<'static>]) + where T: Serialize + Deserialize<'de> + PartialEq + Debug { assert_ser_tokens(value, tokens); assert_de_tokens(value, tokens); @@ -35,8 +35,8 @@ pub fn assert_ser_tokens_error(value: &T, tokens: &[Token], error: Error) } /// Asserts that the given `tokens` deserialize into `value`. -pub fn assert_de_tokens(value: &T, tokens: &[Token<'static>]) - where T: Deserialize + PartialEq + Debug +pub fn assert_de_tokens<'de, T>(value: &T, tokens: &[Token<'static>]) + where T: Deserialize<'de> + PartialEq + Debug { let mut de = Deserializer::new(tokens.to_vec().into_iter()); let v: Result = Deserialize::deserialize(&mut de); @@ -45,8 +45,8 @@ pub fn assert_de_tokens(value: &T, tokens: &[Token<'static>]) } /// Asserts that the given `tokens` yield `error` when deserializing. -pub fn assert_de_tokens_error(tokens: &[Token<'static>], error: Error) - where T: Deserialize + PartialEq + Debug +pub fn assert_de_tokens_error<'de, T>(tokens: &[Token<'static>], error: Error) + where T: Deserialize<'de> + PartialEq + Debug { let mut de = Deserializer::new(tokens.to_vec().into_iter()); let v: Result = Deserialize::deserialize(&mut de); diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index e975186d..b2d6dd12 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -41,13 +41,13 @@ impl Deserializer } } - fn visit_seq(&mut self, + fn visit_seq<'de, V>(&mut self, len: Option, sep: Token<'static>, end: Token<'static>, visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { let value = try!(visitor.visit_seq(DeserializerSeqVisitor { de: self, @@ -59,13 +59,13 @@ impl Deserializer Ok(value) } - fn visit_map(&mut self, + fn visit_map<'de, V>(&mut self, len: Option, sep: Token<'static>, end: Token<'static>, visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { let value = try!(visitor.visit_map(DeserializerMapVisitor { de: self, @@ -78,7 +78,7 @@ impl Deserializer } } -impl<'a, I> de::Deserializer for &'a mut Deserializer +impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer where I: Iterator> { type Error = Error; @@ -89,7 +89,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer } fn deserialize(self, visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { match self.tokens.next() { Some(Token::Bool(v)) => visitor.visit_bool(v), @@ -148,7 +148,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer /// Hook into `Option` deserializing so we can treat `Unit` as a /// `None`, or a regular value as `Some(value)`. fn deserialize_option(self, visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { match self.tokens.peek() { Some(&Token::Unit) | @@ -170,7 +170,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer _variants: &'static [&'static str], visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { match self.tokens.peek() { Some(&Token::EnumStart(n)) if name == n => { @@ -193,7 +193,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer } fn deserialize_unit_struct(self, name: &str, visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { match self.tokens.peek() { Some(&Token::UnitStruct(n)) => { @@ -210,7 +210,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer } fn deserialize_newtype_struct(self, name: &str, visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { match self.tokens.peek() { Some(&Token::StructNewType(n)) => { @@ -227,7 +227,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer } fn deserialize_seq_fixed_size(self, len: usize, visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { match self.tokens.peek() { Some(&Token::SeqArrayStart(_)) => { @@ -240,7 +240,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer } fn deserialize_tuple(self, len: usize, visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { match self.tokens.peek() { Some(&Token::Unit) | @@ -277,7 +277,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer len: usize, visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { match self.tokens.peek() { Some(&Token::Unit) => { @@ -325,7 +325,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer fields: &'static [&'static str], visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { match self.tokens.peek() { Some(&Token::StructStart(n, _)) => { @@ -360,13 +360,13 @@ struct DeserializerSeqVisitor<'a, I: 'a> end: Token<'static>, } -impl<'a, I> SeqVisitor for DeserializerSeqVisitor<'a, I> +impl<'de, 'a, I> SeqVisitor<'de> for DeserializerSeqVisitor<'a, I> where I: Iterator> { type Error = Error; fn visit_seed(&mut self, seed: T) -> Result, Error> - where T: DeserializeSeed + where T: DeserializeSeed<'de> { if self.de.tokens.peek() == Some(&self.end) { return Ok(None); @@ -398,13 +398,13 @@ struct DeserializerMapVisitor<'a, I: 'a> end: Token<'static>, } -impl<'a, I> MapVisitor for DeserializerMapVisitor<'a, I> +impl<'de, 'a, I> MapVisitor<'de> for DeserializerMapVisitor<'a, I> where I: Iterator> { type Error = Error; fn visit_key_seed(&mut self, seed: K) -> Result, Error> - where K: DeserializeSeed + where K: DeserializeSeed<'de> { if self.de.tokens.peek() == Some(&self.end) { return Ok(None); @@ -420,7 +420,7 @@ impl<'a, I> MapVisitor for DeserializerMapVisitor<'a, I> } fn visit_value_seed(&mut self, seed: V) -> Result - where V: DeserializeSeed + where V: DeserializeSeed<'de> { seed.deserialize(&mut *self.de) } @@ -439,14 +439,14 @@ struct DeserializerEnumVisitor<'a, I: 'a> de: &'a mut Deserializer, } -impl<'a, I> EnumVisitor for DeserializerEnumVisitor<'a, I> +impl<'de, 'a, I> EnumVisitor<'de> for DeserializerEnumVisitor<'a, I> where I: Iterator> { type Error = Error; type Variant = Self; fn visit_variant_seed(self, seed: V) -> Result<(V::Value, Self), Error> - where V: DeserializeSeed + where V: DeserializeSeed<'de> { match self.de.tokens.peek() { Some(&Token::EnumUnit(_, v)) | @@ -466,7 +466,7 @@ impl<'a, I> EnumVisitor for DeserializerEnumVisitor<'a, I> } } -impl<'a, I> VariantVisitor for DeserializerEnumVisitor<'a, I> +impl<'de, 'a, I> VariantVisitor<'de> for DeserializerEnumVisitor<'a, I> where I: Iterator> { type Error = Error; @@ -483,7 +483,7 @@ impl<'a, I> VariantVisitor for DeserializerEnumVisitor<'a, I> } fn visit_newtype_seed(self, seed: T) -> Result - where T: DeserializeSeed + where T: DeserializeSeed<'de> { match self.de.tokens.peek() { Some(&Token::EnumNewType(_, _)) => { @@ -496,7 +496,7 @@ impl<'a, I> VariantVisitor for DeserializerEnumVisitor<'a, I> } fn visit_tuple(self, len: usize, visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { match self.de.tokens.peek() { Some(&Token::EnumSeqStart(_, _, enum_len)) => { @@ -523,7 +523,7 @@ impl<'a, I> VariantVisitor for DeserializerEnumVisitor<'a, I> } fn visit_struct(self, fields: &'static [&'static str], visitor: V) -> Result - where V: Visitor + where V: Visitor<'de> { match self.de.tokens.peek() { Some(&Token::EnumMapStart(_, _, enum_len)) => { @@ -573,13 +573,13 @@ impl<'a, I: 'a> EnumMapVisitor<'a, I> } } -impl<'a, I: 'a> MapVisitor for EnumMapVisitor<'a, I> +impl<'de, 'a, I: 'a> MapVisitor<'de> for EnumMapVisitor<'a, I> where I: Iterator> { type Error = Error; fn visit_key_seed(&mut self, seed: K) -> Result, Error> - where K: DeserializeSeed + where K: DeserializeSeed<'de> { match self.variant.take() { Some(variant) => seed.deserialize(variant.into_deserializer()).map(Some), @@ -588,7 +588,7 @@ impl<'a, I: 'a> MapVisitor for EnumMapVisitor<'a, I> } fn visit_value_seed(&mut self, seed: V) -> Result - where V: DeserializeSeed + where V: DeserializeSeed<'de> { match self.de.tokens.peek() { Some(&Token::EnumSeqSep) => { diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index af49203b..3bcedd77 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -28,8 +28,8 @@ trait SerializeWith: Sized { } trait DeserializeWith: Sized { - fn deserialize_with(de: D) -> Result - where D: Deserializer; + fn deserialize_with<'de, D>(de: D) -> Result + where D: Deserializer<'de>; } impl MyDefault for i32 { @@ -53,8 +53,8 @@ impl SerializeWith for i32 { } impl DeserializeWith for i32 { - fn deserialize_with(de: D) -> Result - where D: Deserializer + fn deserialize_with<'de, D>(de: D) -> Result + where D: Deserializer<'de> { if try!(Deserialize::deserialize(de)) { Ok(123) @@ -242,8 +242,8 @@ impl Default for NotDeserializeStruct { } impl DeserializeWith for NotDeserializeStruct { - fn deserialize_with(_: D) -> Result - where D: Deserializer + fn deserialize_with<'de, D>(_: D) -> Result + where D: Deserializer<'de> { panic!() } diff --git a/test_suite/tests/test_gen.rs b/test_suite/tests/test_gen.rs index 8cdb254e..68e63505 100644 --- a/test_suite/tests/test_gen.rs +++ b/test_suite/tests/test_gen.rs @@ -9,7 +9,7 @@ extern crate serde_derive; extern crate serde; use self::serde::ser::{Serialize, Serializer}; -use self::serde::de::{Deserialize, Deserializer}; +use self::serde::de::{DeserializeOwned, Deserializer}; use std::borrow::Cow; use std::marker::PhantomData; @@ -64,15 +64,6 @@ fn test_gen() { } assert::>(); - #[derive(Serialize, Deserialize)] - struct Bounds { - t: T, - option: Option, - boxed: Box, - option_boxed: Option>, - } - assert::>(); - #[derive(Serialize, Deserialize)] struct NoBounds { t: T, @@ -206,7 +197,7 @@ fn test_gen() { assert::(); #[derive(Serialize, Deserialize)] - #[serde(bound(deserialize = "T::Owned: Deserialize"))] + #[serde(bound(deserialize = "T::Owned: DeserializeOwned"))] struct CowT<'a, T: ?Sized + 'a + ToOwned>(Cow<'a, T>); assert::>(); @@ -308,7 +299,7 @@ fn test_gen() { ////////////////////////////////////////////////////////////////////////// -fn assert() {} +fn assert() {} fn assert_ser() {} trait SerializeWith { @@ -316,7 +307,7 @@ trait SerializeWith { } trait DeserializeWith: Sized { - fn deserialize_with(_: D) -> StdResult; + fn deserialize_with<'de, D: Deserializer<'de>>(_: D) -> StdResult; } // Implements neither Serialize nor Deserialize @@ -326,7 +317,7 @@ pub fn ser_x(_: &X, _: S) -> StdResult { unimplemented!() } -pub fn de_x(_: D) -> StdResult { +pub fn de_x<'de, D: Deserializer<'de>>(_: D) -> StdResult { unimplemented!() } @@ -341,7 +332,7 @@ impl SerializeWith for X { } impl DeserializeWith for X { - fn deserialize_with(_: D) -> StdResult { + fn deserialize_with<'de, D: Deserializer<'de>>(_: D) -> StdResult { unimplemented!() } } From 4dec5f4de8fe9c8d6a4f46129e46323d751b295f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 30 Mar 2017 22:44:08 -0700 Subject: [PATCH 002/177] Update example code for zero copy --- serde/src/de/mod.rs | 36 ++++++++++++++++++------------------ serde/src/macros.rs | 10 +++++----- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 359df584..ad6944ba 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -147,9 +147,9 @@ pub trait Error: Sized + error::Error { /// # type Err = String; /// # fn from_str(_: &str) -> Result { unimplemented!() } /// # } - /// impl Deserialize for IpAddr { + /// impl<'de> Deserialize<'de> for IpAddr { /// fn deserialize(deserializer: D) -> Result - /// where D: Deserializer + /// where D: Deserializer<'de> /// { /// let s = try!(String::deserialize(deserializer)); /// s.parse().map_err(Error::custom) @@ -256,7 +256,7 @@ pub trait Error: Sized + error::Error { /// # use std::fmt; /// # #[allow(dead_code)] /// # struct Example; -/// # impl Visitor for Example { +/// # impl<'de> Visitor<'de> for Example { /// # type Value = (); /// fn visit_bool(self, v: bool) -> Result /// where E: Error @@ -376,7 +376,7 @@ impl<'a> fmt::Display for Unexpected<'a> { /// # use std::fmt; /// # #[allow(dead_code)] /// # struct Example; -/// # impl Visitor for Example { +/// # impl<'de> Visitor<'de> for Example { /// # type Value = (); /// fn visit_bool(self, v: bool) -> Result /// where E: Error @@ -499,7 +499,7 @@ impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} /// # #[allow(dead_code)] /// # enum Error {} /// # #[allow(dead_code)] -/// fn func() -> Result +/// fn func<'de, T: Deserialize<'de>>() -> Result /// # { unimplemented!() } /// ``` /// @@ -511,7 +511,7 @@ impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} /// # #[allow(dead_code)] /// # enum Error {} /// # #[allow(dead_code)] -/// fn func_seed(seed: T) -> Result +/// fn func_seed<'de, T: DeserializeSeed<'de>>(seed: T) -> Result /// # { /// # let _ = seed; /// # unimplemented!() @@ -543,8 +543,8 @@ impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} /// // appending each integer into the existing Vec. /// struct ExtendVec<'a, T: 'a>(&'a mut Vec); /// -/// impl<'a, T> DeserializeSeed for ExtendVec<'a, T> -/// where T: Deserialize +/// impl<'de, 'a, T> DeserializeSeed<'de> for ExtendVec<'a, T> +/// where T: Deserialize<'de> /// { /// // The return type of the `deserialize` method. This implementation /// // appends onto an existing vector but does not create any new data @@ -552,19 +552,19 @@ impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} /// type Value = (); /// /// fn deserialize(self, deserializer: D) -> Result -/// where D: Deserializer +/// where D: Deserializer<'de> /// { /// // Visitor implementation that will walk an inner array of the JSON /// // input. /// struct ExtendVecVisitor<'a, T: 'a>(&'a mut Vec); /// -/// impl<'a, T> Visitor for ExtendVecVisitor<'a, T> -/// where T: Deserialize +/// impl<'de, 'a, T> Visitor<'de> for ExtendVecVisitor<'a, T> +/// where T: Deserialize<'de> /// { /// type Value = (); /// /// fn visit_seq(self, mut visitor: V) -> Result<(), V::Error> -/// where V: SeqVisitor +/// where V: SeqVisitor<'de> /// { /// // Visit each element in the inner array and push it onto /// // the existing vector. @@ -586,15 +586,15 @@ impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} /// // Visitor implementation that will walk the outer array of the JSON input. /// struct FlattenedVecVisitor(PhantomData); /// -/// impl Visitor for FlattenedVecVisitor -/// where T: Deserialize +/// impl<'de, T> Visitor<'de> for FlattenedVecVisitor +/// where T: Deserialize<'de> /// { /// // This Visitor constructs a single Vec to hold the flattened /// // contents of the inner arrays. /// type Value = Vec; /// /// fn visit_seq(self, mut visitor: V) -> Result, V::Error> -/// where V: SeqVisitor +/// where V: SeqVisitor<'de> /// { /// // Create a single Vec to hold the flattened contents. /// let mut vec = Vec::new(); @@ -614,7 +614,7 @@ impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} /// } /// /// # #[allow(dead_code)] -/// # fn example(deserializer: D) -> Result<(), D::Error> { +/// # fn example<'de, D: Deserializer<'de>>(deserializer: D) -> Result<(), D::Error> { /// let visitor = FlattenedVecVisitor(PhantomData); /// let flattened: Vec = deserializer.deserialize_seq(visitor)?; /// # let _ = flattened; @@ -913,7 +913,7 @@ pub trait Deserializer<'de>: Sized { /// min: usize, /// } /// -/// impl Visitor for LongString { +/// impl<'de> Visitor<'de> for LongString { /// type Value = String; /// /// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -946,7 +946,7 @@ pub trait Visitor<'de>: Sized { /// # use std::fmt; /// # #[allow(dead_code)] /// # struct S { max: usize } - /// # impl serde::de::Visitor for S { + /// # impl<'de> serde::de::Visitor<'de> for S { /// # type Value = (); /// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { /// write!(formatter, "an integer between 0 and {}", self.max) diff --git a/serde/src/macros.rs b/serde/src/macros.rs index 42b5accd..2a64e96d 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -135,15 +135,15 @@ macro_rules! forward_to_deserialize_helper { /// # #[macro_use] extern crate serde; /// # use serde::de::{value, Deserializer, Visitor}; /// # pub struct MyDeserializer; -/// # impl Deserializer for MyDeserializer { +/// # impl<'de> Deserializer<'de> for MyDeserializer { /// # type Error = value::Error; /// # fn deserialize(self, _: V) -> Result -/// # where V: Visitor +/// # where V: Visitor<'de> /// # { unimplemented!() } /// # /// #[inline] /// fn deserialize_bool(self, visitor: V) -> Result -/// where V: Visitor +/// where V: Visitor<'de> /// { /// self.deserialize(visitor) /// } @@ -164,10 +164,10 @@ macro_rules! forward_to_deserialize_helper { /// # #[macro_use] extern crate serde; /// # use serde::de::{value, Deserializer, Visitor}; /// # pub struct MyDeserializer; -/// impl Deserializer for MyDeserializer { +/// impl<'de> Deserializer<'de> for MyDeserializer { /// # type Error = value::Error; /// fn deserialize(self, visitor: V) -> Result -/// where V: Visitor +/// where V: Visitor<'de> /// { /// /* ... */ /// # let _ = visitor; From b6f1a2eb552afa491e19b840f1e6fc19d353d29e Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 30 Mar 2017 23:06:00 -0700 Subject: [PATCH 003/177] Add a note about assuming the deserializer lifetime name --- serde/src/macros.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/serde/src/macros.rs b/serde/src/macros.rs index 2a64e96d..b547f472 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -182,6 +182,10 @@ macro_rules! forward_to_deserialize_helper { /// } /// # fn main() {} /// ``` +/// +/// The macro assumes the convention that your `Deserializer` lifetime parameter +/// is called `'de`. It will not work if the `Deserializer` lifetime parameter +/// is called something different. #[macro_export] macro_rules! forward_to_deserialize { ($($func:ident)*) => { From aa46318425df2ff03cdccf78a75f31425b057fea Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 30 Mar 2017 22:30:31 -0700 Subject: [PATCH 004/177] Deserialize impls for &str and &[u8] --- serde/src/de/impls.rs | 65 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index fc61dac1..41698195 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -305,6 +305,71 @@ impl<'de> Deserialize<'de> for String { /////////////////////////////////////////////////////////////////////////////// +struct StrVisitor; + +impl<'a> Visitor<'a> for StrVisitor { + type Value = &'a str; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a borrowed string") + } + + fn visit_borrowed_str(self, v: &'a str) -> Result + where E: Error + { + Ok(v) // so easy + } + + fn visit_borrowed_bytes(self, v: &'a [u8]) -> Result + where E: Error + { + str::from_utf8(v) + .map_err(|_| Error::invalid_value(Unexpected::Bytes(v), &self)) + } +} + +impl<'a> Deserialize<'a> for &'a str { + fn deserialize(deserializer: D) -> Result + where D: Deserializer<'a> + { + deserializer.deserialize_str(StrVisitor) + } +} + +/////////////////////////////////////////////////////////////////////////////// + +struct BytesVisitor; + +impl<'a> Visitor<'a> for BytesVisitor { + type Value = &'a [u8]; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a borrowed byte array") + } + + fn visit_borrowed_bytes(self, v: &'a [u8]) -> Result + where E: Error + { + Ok(v) + } + + fn visit_borrowed_str(self, v: &'a str) -> Result + where E: Error + { + Ok(v.as_bytes()) + } +} + +impl<'a> Deserialize<'a> for &'a [u8] { + fn deserialize(deserializer: D) -> Result + where D: Deserializer<'a> + { + deserializer.deserialize_bytes(BytesVisitor) + } +} + +/////////////////////////////////////////////////////////////////////////////// + #[cfg(all(feature = "std", feature="unstable"))] impl<'de> Deserialize<'de> for Box { fn deserialize(deserializer: D) -> Result From fb48111e460d1a16f2581f3ca2d0a568f954c583 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 2 Apr 2017 21:42:07 -0700 Subject: [PATCH 005/177] Derive for borrowed fields --- serde/src/de/impls.rs | 8 +- serde/src/de/private.rs | 132 ++++++++++ serde_codegen_internals/Cargo.toml | 3 +- serde_codegen_internals/src/attr.rs | 225 ++++++++++++++++++ serde_codegen_internals/src/lib.rs | 2 + serde_derive/src/de.rs | 179 +++++++------- .../compile-fail/borrow/bad_lifetimes.rs | 10 + .../compile-fail/borrow/duplicate_lifetime.rs | 10 + .../compile-fail/borrow/empty_lifetimes.rs | 10 + .../tests/compile-fail/borrow/no_lifetimes.rs | 10 + .../compile-fail/borrow/wrong_lifetime.rs | 10 + .../tests/compile-fail/str_ref_deser.rs | 9 - 12 files changed, 505 insertions(+), 103 deletions(-) create mode 100644 test_suite/tests/compile-fail/borrow/bad_lifetimes.rs create mode 100644 test_suite/tests/compile-fail/borrow/duplicate_lifetime.rs create mode 100644 test_suite/tests/compile-fail/borrow/empty_lifetimes.rs create mode 100644 test_suite/tests/compile-fail/borrow/no_lifetimes.rs create mode 100644 test_suite/tests/compile-fail/borrow/wrong_lifetime.rs delete mode 100644 test_suite/tests/compile-fail/str_ref_deser.rs diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 41698195..881f0df9 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -328,9 +328,9 @@ impl<'a> Visitor<'a> for StrVisitor { } } -impl<'a> Deserialize<'a> for &'a str { +impl<'de: 'a, 'a> Deserialize<'de> for &'a str { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'a> + where D: Deserializer<'de> { deserializer.deserialize_str(StrVisitor) } @@ -360,9 +360,9 @@ impl<'a> Visitor<'a> for BytesVisitor { } } -impl<'a> Deserialize<'a> for &'a [u8] { +impl<'de: 'a, 'a> Deserialize<'de> for &'a [u8] { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'a> + where D: Deserializer<'de> { deserializer.deserialize_bytes(BytesVisitor) } diff --git a/serde/src/de/private.rs b/serde/src/de/private.rs index 0e001962..a1f3fa70 100644 --- a/serde/src/de/private.rs +++ b/serde/src/de/private.rs @@ -1,7 +1,24 @@ +#[cfg(any(feature = "std", feature = "collections"))] +use core::{fmt, str}; + use core::marker::PhantomData; +#[cfg(feature = "collections")] +use collections::borrow::ToOwned; + +#[cfg(feature = "std")] +use std::borrow::Cow; +#[cfg(all(feature = "collections", not(feature = "std")))] +use collections::borrow::Cow; + +#[cfg(all(feature = "collections", not(feature = "std")))] +use collections::{String, Vec}; + use de::{Deserialize, Deserializer, Error, Visitor}; +#[cfg(any(feature = "std", feature = "collections"))] +use de::Unexpected; + #[cfg(any(feature = "std", feature = "collections"))] pub use de::content::{Content, ContentRefDeserializer, ContentDeserializer, TaggedContentVisitor, TagOrContentField, TagOrContentFieldVisitor, InternallyTaggedUnitVisitor, @@ -42,3 +59,118 @@ pub fn missing_field<'de, V, E>(field: &'static str) -> Result let deserializer = MissingFieldDeserializer(field, PhantomData); Deserialize::deserialize(deserializer) } + +#[cfg(any(feature = "std", feature = "collections"))] +pub fn borrow_cow_str<'de, D>(deserializer: D) -> Result, D::Error> + where D: Deserializer<'de> +{ + struct CowStrVisitor; + + impl<'a> Visitor<'a> for CowStrVisitor { + type Value = Cow<'a, str>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a string") + } + + fn visit_str(self, v: &str) -> Result + where E: Error + { + Ok(Cow::Owned(v.to_owned())) + } + + fn visit_borrowed_str(self, v: &'a str) -> Result + where E: Error + { + Ok(Cow::Borrowed(v)) + } + + fn visit_string(self, v: String) -> Result + where E: Error + { + Ok(Cow::Owned(v)) + } + + fn visit_bytes(self, v: &[u8]) -> Result + where E: Error + { + match str::from_utf8(v) { + Ok(s) => Ok(Cow::Owned(s.to_owned())), + Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)), + } + } + + fn visit_borrowed_bytes(self, v: &'a [u8]) -> Result + where E: Error + { + match str::from_utf8(v) { + Ok(s) => Ok(Cow::Borrowed(s)), + Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)), + } + } + + fn visit_byte_buf(self, v: Vec) -> Result + where E: Error + { + match String::from_utf8(v) { + Ok(s) => Ok(Cow::Owned(s)), + Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self)), + } + } + } + + deserializer.deserialize_str(CowStrVisitor) +} + +#[cfg(any(feature = "std", feature = "collections"))] +pub fn borrow_cow_bytes<'de, D>(deserializer: D) -> Result, D::Error> + where D: Deserializer<'de> +{ + struct CowBytesVisitor; + + impl<'a> Visitor<'a> for CowBytesVisitor { + type Value = Cow<'a, [u8]>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a byte array") + } + + fn visit_str(self, v: &str) -> Result + where E: Error + { + Ok(Cow::Owned(v.as_bytes().to_vec())) + } + + fn visit_borrowed_str(self, v: &'a str) -> Result + where E: Error + { + Ok(Cow::Borrowed(v.as_bytes())) + } + + fn visit_string(self, v: String) -> Result + where E: Error + { + Ok(Cow::Owned(v.into_bytes())) + } + + fn visit_bytes(self, v: &[u8]) -> Result + where E: Error + { + Ok(Cow::Owned(v.to_vec())) + } + + fn visit_borrowed_bytes(self, v: &'a [u8]) -> Result + where E: Error + { + Ok(Cow::Borrowed(v)) + } + + fn visit_byte_buf(self, v: Vec) -> Result + where E: Error + { + Ok(Cow::Owned(v)) + } + } + + deserializer.deserialize_str(CowBytesVisitor) +} diff --git a/serde_codegen_internals/Cargo.toml b/serde_codegen_internals/Cargo.toml index cd167bfe..6f006914 100644 --- a/serde_codegen_internals/Cargo.toml +++ b/serde_codegen_internals/Cargo.toml @@ -12,7 +12,8 @@ readme = "../README.md" include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] [dependencies] -syn = { version = "0.11", default-features = false, features = ["parsing"] } +syn = { version = "0.11.10", default-features = false, features = ["parsing"] } +synom = "0.11" [badges] travis-ci = { repository = "serde-rs/serde" } diff --git a/serde_codegen_internals/src/attr.rs b/serde_codegen_internals/src/attr.rs index 11a2eb2a..13b429b9 100644 --- a/serde_codegen_internals/src/attr.rs +++ b/serde_codegen_internals/src/attr.rs @@ -2,6 +2,8 @@ use Ctxt; use syn; use syn::MetaItem::{List, NameValue, Word}; use syn::NestedMetaItem::{Literal, MetaItem}; +use synom::IResult; +use std::collections::BTreeSet; use std::str::FromStr; // This module handles parsing of `#[serde(...)]` attributes. The entrypoints @@ -528,6 +530,7 @@ pub struct Field { deserialize_with: Option, ser_bound: Option>, de_bound: Option>, + borrowed_lifetimes: BTreeSet, } /// Represents the default to use for a field when deserializing. @@ -554,6 +557,7 @@ impl Field { let mut deserialize_with = Attr::none(cx, "deserialize_with"); let mut ser_bound = Attr::none(cx, "bound"); let mut de_bound = Attr::none(cx, "bound"); + let mut borrowed_lifetimes = Attr::none(cx, "borrow"); let ident = match field.ident { Some(ref ident) => ident.to_string(), @@ -651,6 +655,27 @@ impl Field { } } + // Parse `#[serde(borrow)]` + MetaItem(Word(ref name)) if name == "borrow" => { + if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, &field.ty) { + borrowed_lifetimes.set(borrowable); + } + } + + // Parse `#[serde(borrow = "'a + 'b")]` + MetaItem(NameValue(ref name, ref lit)) if name == "borrow" => { + if let Ok(lifetimes) = parse_lit_into_lifetimes(cx, name.as_ref(), lit) { + if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, &field.ty) { + for lifetime in &lifetimes { + if !borrowable.contains(lifetime) { + cx.error(format!("field `{}` does not have lifetime {}", ident, lifetime.ident)); + } + } + borrowed_lifetimes.set(lifetimes); + } + } + } + MetaItem(ref meta_item) => { cx.error(format!("unknown serde field attribute `{}`", meta_item.name())); } @@ -668,6 +693,30 @@ impl Field { default.set_if_none(Default::Default); } + let mut borrowed_lifetimes = borrowed_lifetimes.get().unwrap_or_default(); + if !borrowed_lifetimes.is_empty() { + // Cow and Cow<[u8]> never borrow by default: + // + // impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T> + // + // A #[serde(borrow)] attribute enables borrowing that corresponds + // roughly to these impls: + // + // impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, str> + // impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, [u8]> + if is_cow(&field.ty, "str") { + let path = syn::parse_path("_serde::de::private::borrow_cow_str").unwrap(); + deserialize_with.set_if_none(path); + } else if is_cow(&field.ty, "[u8]") { + let path = syn::parse_path("_serde::de::private::borrow_cow_bytes").unwrap(); + deserialize_with.set_if_none(path); + } + } else if is_rptr(&field.ty, "str") || is_rptr(&field.ty, "[u8]") { + // Types &str and &[u8] are always implicitly borrowed. No need for + // a #[serde(borrow)]. + borrowed_lifetimes = borrowable_lifetimes(cx, &ident, &field.ty).unwrap(); + } + let ser_name = ser_name.get(); let ser_renamed = ser_name.is_some(); let de_name = de_name.get(); @@ -687,6 +736,7 @@ impl Field { deserialize_with: deserialize_with.get(), ser_bound: ser_bound.get(), de_bound: de_bound.get(), + borrowed_lifetimes: borrowed_lifetimes, } } @@ -734,6 +784,10 @@ impl Field { pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> { self.de_bound.as_ref().map(|vec| &vec[..]) } + + pub fn borrowed_lifetimes(&self) -> &BTreeSet { + &self.borrowed_lifetimes + } } type SerAndDe = (Option, Option); @@ -836,3 +890,174 @@ fn parse_lit_into_ty(cx: &Ctxt, cx.error(format!("failed to parse type: {} = {:?}", attr_name, string)) }) } + +// Parses a string literal like "'a + 'b + 'c" containing a nonempty list of +// lifetimes separated by `+`. +fn parse_lit_into_lifetimes(cx: &Ctxt, + attr_name: &str, + lit: &syn::Lit) + -> Result, ()> { + let string = try!(get_string_from_lit(cx, attr_name, attr_name, lit)); + if string.is_empty() { + cx.error("at least one lifetime must be borrowed"); + return Err(()); + } + + named!(lifetimes -> Vec, + separated_nonempty_list!(punct!("+"), syn::parse::lifetime) + ); + + if let IResult::Done(rest, o) = lifetimes(&string) { + if rest.trim().is_empty() { + let mut set = BTreeSet::new(); + for lifetime in o { + if !set.insert(lifetime.clone()) { + cx.error(format!("duplicate borrowed lifetime `{}`", lifetime.ident)); + } + } + return Ok(set); + } + } + Err(cx.error(format!("failed to parse borrowed lifetimes: {:?}", string))) +} + +// Whether the type looks like it might be `std::borrow::Cow` where elem="T". +// This can have false negatives and false positives. +// +// False negative: +// +// use std::borrow::Cow as Pig; +// +// #[derive(Deserialize)] +// struct S<'a> { +// #[serde(borrow)] +// pig: Pig<'a, str>, +// } +// +// False positive: +// +// type str = [i16]; +// +// #[derive(Deserialize)] +// struct S<'a> { +// #[serde(borrow)] +// cow: Cow<'a, str>, +// } +fn is_cow(ty: &syn::Ty, elem: &str) -> bool { + let path = match *ty { + syn::Ty::Path(None, ref path) => path, + _ => { + return false; + } + }; + let seg = match path.segments.last() { + Some(seg) => seg, + None => { + return false; + } + }; + let params = match seg.parameters { + syn::PathParameters::AngleBracketed(ref params) => params, + _ => { + return false; + } + }; + seg.ident == "Cow" + && params.lifetimes.len() == 1 + && params.types == vec![syn::parse_type(elem).unwrap()] + && params.bindings.is_empty() +} + +// Whether the type looks like it might be `&T` where elem="T". This can have +// false negatives and false positives. +// +// False negative: +// +// type Yarn = str; +// +// #[derive(Deserialize)] +// struct S<'a> { +// r: &'a Yarn, +// } +// +// False positive: +// +// type str = [i16]; +// +// #[derive(Deserialize)] +// struct S<'a> { +// r: &'a str, +// } +fn is_rptr(ty: &syn::Ty, elem: &str) -> bool { + match *ty { + syn::Ty::Rptr(Some(_), ref mut_ty) => { + mut_ty.mutability == syn::Mutability::Immutable + && mut_ty.ty == syn::parse_type(elem).unwrap() + } + _ => false, + } +} + +// All lifetimes that this type could borrow from a Deserializer. +// +// For example a type `S<'a, 'b>` could borrow `'a` and `'b`. On the other hand +// a type `for<'a> fn(&'a str)` could not borrow `'a` from the Deserializer. +// +// This is used when there is an explicit or implicit `#[serde(borrow)]` +// attribute on the field so there must be at least one borrowable lifetime. +fn borrowable_lifetimes(cx: &Ctxt, + name: &str, + ty: &syn::Ty) + -> Result, ()> { + let mut lifetimes = BTreeSet::new(); + collect_lifetimes(ty, &mut lifetimes); + if lifetimes.is_empty() { + Err(cx.error(format!("field `{}` has no lifetimes to borrow", name))) + } else { + Ok(lifetimes) + } +} + +fn collect_lifetimes(ty: &syn::Ty, out: &mut BTreeSet) { + match *ty { + syn::Ty::Slice(ref elem) | + syn::Ty::Array(ref elem, _) | + syn::Ty::Paren(ref elem) => { + collect_lifetimes(elem, out); + } + syn::Ty::Ptr(ref elem) => { + collect_lifetimes(&elem.ty, out); + } + syn::Ty::Rptr(ref lifetime, ref elem) => { + out.extend(lifetime.iter().cloned()); + collect_lifetimes(&elem.ty, out); + } + syn::Ty::Tup(ref elems) => { + for elem in elems { + collect_lifetimes(elem, out); + } + } + syn::Ty::Path(ref qself, ref path) => { + if let Some(ref qself) = *qself { + collect_lifetimes(&qself.ty, out); + } + for seg in &path.segments { + if let syn::PathParameters::AngleBracketed(ref params) = seg.parameters { + out.extend(params.lifetimes.iter().cloned()); + for ty in ¶ms.types { + collect_lifetimes(ty, out); + } + for binding in ¶ms.bindings { + collect_lifetimes(&binding.ty, out); + } + } + } + } + syn::Ty::BareFn(_) | + syn::Ty::Never | + syn::Ty::TraitObject(_) | + syn::Ty::ImplTrait(_) | + syn::Ty::Infer | + syn::Ty::Mac(_) => {} + } +} diff --git a/serde_codegen_internals/src/lib.rs b/serde_codegen_internals/src/lib.rs index c5e8885c..d5baf00b 100644 --- a/serde_codegen_internals/src/lib.rs +++ b/serde_codegen_internals/src/lib.rs @@ -1,4 +1,6 @@ extern crate syn; +#[macro_use] +extern crate synom; pub mod ast; pub mod attr; diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 6ab9f95e..b67ad285 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -6,20 +6,20 @@ use fragment::{Fragment, Expr, Stmts, Match}; use internals::ast::{Body, Field, Item, Style, Variant}; use internals::{self, attr}; +use std::collections::BTreeSet; + pub fn expand_derive_deserialize(item: &syn::DeriveInput) -> Result { - let item = { - let ctxt = internals::Ctxt::new(); - let item = Item::from_ast(&ctxt, item); - check_no_str(&ctxt, &item); - try!(ctxt.check()); - item - }; + let ctxt = internals::Ctxt::new(); + let item = Item::from_ast(&ctxt, item); + try!(ctxt.check()); let ident = &item.ident; let generics = build_generics(&item); - let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(&generics); + let borrowed = borrowed_lifetimes(&item); + let params = Parameters { generics: generics, borrowed: borrowed }; + let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(¶ms); let dummy_const = Ident::new(format!("_IMPL_DESERIALIZE_FOR_{}", ident)); - let body = Stmts(deserialize_body(&item, &generics)); + let body = Stmts(deserialize_body(&item, ¶ms)); Ok(quote! { #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] @@ -37,6 +37,11 @@ pub fn expand_derive_deserialize(item: &syn::DeriveInput) -> Result, +} + // All the generics in the input, plus a bound `T: Deserialize` for each generic // field type that will be deserialized by us, plus a bound `T: Default` for // each generic field type that will be set to a default value. @@ -84,13 +89,27 @@ fn requires_default(attrs: &attr::Field) -> bool { attrs.default() == &attr::Default::Default } -fn deserialize_body(item: &Item, generics: &syn::Generics) -> Fragment { +// The union of lifetimes borrowed by each field of the item. +// +// These turn into bounds on the `'de` lifetime of the Deserialize impl. If +// lifetimes `'a` and `'b` are borrowed but `'c` is not, the impl is: +// +// impl<'de: 'a + 'b, 'a, 'b, 'c> Deserialize<'de> for S<'a, 'b, 'c> +fn borrowed_lifetimes(item: &Item) -> BTreeSet { + let mut lifetimes = BTreeSet::new(); + for field in item.body.all_fields() { + lifetimes.extend(field.attrs.borrowed_lifetimes().iter().cloned()); + } + lifetimes +} + +fn deserialize_body(item: &Item, params: &Parameters) -> Fragment { if let Some(from_type) = item.attrs.from_type() { deserialize_from(from_type) } else { match item.body { Body::Enum(ref variants) => { - deserialize_item_enum(&item.ident, generics, variants, &item.attrs) + deserialize_item_enum(&item.ident, params, variants, &item.attrs) } Body::Struct(Style::Struct, ref fields) => { if fields.iter().any(|field| field.ident.is_none()) { @@ -98,7 +117,7 @@ fn deserialize_body(item: &Item, generics: &syn::Generics) -> Fragment { } deserialize_struct(&item.ident, None, - generics, + params, fields, &item.attrs, None) @@ -110,7 +129,7 @@ fn deserialize_body(item: &Item, generics: &syn::Generics) -> Fragment { } deserialize_tuple(&item.ident, None, - generics, + params, fields, &item.attrs, None) @@ -164,12 +183,12 @@ fn deserialize_unit_struct(ident: &syn::Ident, item_attrs: &attr::Item) -> Fragm fn deserialize_tuple(ident: &syn::Ident, variant_ident: Option<&syn::Ident>, - generics: &syn::Generics, + params: &Parameters, fields: &[Field], item_attrs: &attr::Item, deserializer: Option) -> Fragment { - let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(generics); + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params); let is_enum = variant_ident.is_some(); let type_path = match variant_ident { @@ -184,12 +203,12 @@ fn deserialize_tuple(ident: &syn::Ident, let nfields = fields.len(); let visit_newtype_struct = if !is_enum && nfields == 1 { - Some(deserialize_newtype_struct(ident, &type_path, generics, &fields[0])) + Some(deserialize_newtype_struct(ident, &type_path, params, &fields[0])) } else { None }; - let visit_seq = Stmts(deserialize_seq(ident, &type_path, generics, fields, false, item_attrs)); + let visit_seq = Stmts(deserialize_seq(ident, &type_path, params, fields, false, item_attrs)); let visitor_expr = quote! { __Visitor { @@ -245,7 +264,7 @@ fn deserialize_tuple(ident: &syn::Ident, fn deserialize_seq(ident: &syn::Ident, type_path: &Tokens, - generics: &syn::Generics, + params: &Parameters, fields: &[Field], is_struct: bool, item_attrs: &attr::Item) @@ -273,7 +292,7 @@ fn deserialize_seq(ident: &syn::Ident, } Some(path) => { let (wrapper, wrapper_ty) = wrap_deserialize_with( - ident, generics, field.ty, path); + ident, params, field.ty, path); quote!({ #wrapper _serde::export::Option::map( @@ -314,7 +333,7 @@ fn deserialize_seq(ident: &syn::Ident, fn deserialize_newtype_struct(ident: &syn::Ident, type_path: &Tokens, - generics: &syn::Generics, + params: &Parameters, field: &Field) -> Tokens { let value = match field.attrs.deserialize_with() { @@ -326,7 +345,7 @@ fn deserialize_newtype_struct(ident: &syn::Ident, } Some(path) => { let (wrapper, wrapper_ty) = - wrap_deserialize_with(ident, generics, field.ty, path); + wrap_deserialize_with(ident, params, field.ty, path); quote!({ #wrapper try!(<#wrapper_ty as _serde::Deserialize>::deserialize(__e)).value @@ -345,7 +364,7 @@ fn deserialize_newtype_struct(ident: &syn::Ident, fn deserialize_struct(ident: &syn::Ident, variant_ident: Option<&syn::Ident>, - generics: &syn::Generics, + params: &Parameters, fields: &[Field], item_attrs: &attr::Item, deserializer: Option) @@ -353,7 +372,7 @@ fn deserialize_struct(ident: &syn::Ident, let is_enum = variant_ident.is_some(); let is_untagged = deserializer.is_some(); - let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(generics); + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params); let type_path = match variant_ident { Some(variant_ident) => quote!(#ident::#variant_ident), @@ -364,10 +383,10 @@ fn deserialize_struct(ident: &syn::Ident, None => format!("struct {}", ident), }; - let visit_seq = Stmts(deserialize_seq(ident, &type_path, generics, fields, true, item_attrs)); + let visit_seq = Stmts(deserialize_seq(ident, &type_path, params, fields, true, item_attrs)); let (field_visitor, fields_stmt, visit_map) = - deserialize_struct_visitor(ident, type_path, generics, fields, item_attrs); + deserialize_struct_visitor(ident, type_path, params, fields, item_attrs); let field_visitor = Stmts(field_visitor); let fields_stmt = Stmts(fields_stmt); let visit_map = Stmts(visit_map); @@ -446,41 +465,41 @@ fn deserialize_struct(ident: &syn::Ident, } fn deserialize_item_enum(ident: &syn::Ident, - generics: &syn::Generics, + params: &Parameters, variants: &[Variant], item_attrs: &attr::Item) -> Fragment { match *item_attrs.tag() { attr::EnumTag::External => { - deserialize_externally_tagged_enum(ident, generics, variants, item_attrs) + deserialize_externally_tagged_enum(ident, params, variants, item_attrs) } attr::EnumTag::Internal { ref tag } => { deserialize_internally_tagged_enum(ident, - generics, + params, variants, item_attrs, tag) } attr::EnumTag::Adjacent { ref tag, ref content } => { deserialize_adjacently_tagged_enum(ident, - generics, + params, variants, item_attrs, tag, content) } attr::EnumTag::None => { - deserialize_untagged_enum(ident, generics, variants, item_attrs) + deserialize_untagged_enum(ident, params, variants, item_attrs) } } } fn deserialize_externally_tagged_enum(ident: &syn::Ident, - generics: &syn::Generics, + params: &Parameters, variants: &[Variant], item_attrs: &attr::Item) -> Fragment { - let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(generics); + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params); let type_name = item_attrs.name().deserialize_name(); @@ -509,7 +528,7 @@ fn deserialize_externally_tagged_enum(ident: &syn::Ident, let variant_name = field_i(i); let block = Match(deserialize_externally_tagged_variant(ident, - generics, + params, variant, item_attrs)); @@ -571,7 +590,7 @@ fn deserialize_externally_tagged_enum(ident: &syn::Ident, } fn deserialize_internally_tagged_enum(ident: &syn::Ident, - generics: &syn::Generics, + params: &Parameters, variants: &[Variant], item_attrs: &attr::Item, tag: &str) @@ -600,7 +619,7 @@ fn deserialize_internally_tagged_enum(ident: &syn::Ident, let block = Match(deserialize_internally_tagged_variant( ident, - generics, + params, variant, item_attrs, quote!(_serde::de::private::ContentDeserializer::<__D::Error>::new(__tagged.content)), @@ -627,13 +646,13 @@ fn deserialize_internally_tagged_enum(ident: &syn::Ident, } fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, - generics: &syn::Generics, + params: &Parameters, variants: &[Variant], item_attrs: &attr::Item, tag: &str, content: &str) -> Fragment { - let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(generics); + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params); let variant_names_idents: Vec<_> = variants.iter() .enumerate() @@ -658,7 +677,7 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, let block = Match(deserialize_untagged_variant( ident, - generics, + params, variant, item_attrs, quote!(__deserializer), @@ -866,7 +885,7 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, } fn deserialize_untagged_enum(ident: &syn::Ident, - generics: &syn::Generics, + params: &Parameters, variants: &[Variant], item_attrs: &attr::Item) -> Fragment { @@ -875,7 +894,7 @@ fn deserialize_untagged_enum(ident: &syn::Ident, .map(|variant| { Expr(deserialize_untagged_variant( ident, - generics, + params, variant, item_attrs, quote!(_serde::de::private::ContentRefDeserializer::<__D::Error>::new(&__content)), @@ -904,7 +923,7 @@ fn deserialize_untagged_enum(ident: &syn::Ident, } fn deserialize_externally_tagged_variant(ident: &syn::Ident, - generics: &syn::Generics, + params: &Parameters, variant: &Variant, item_attrs: &attr::Item) -> Fragment { @@ -920,13 +939,13 @@ fn deserialize_externally_tagged_variant(ident: &syn::Ident, Style::Newtype => { deserialize_externally_tagged_newtype_variant(ident, variant_ident, - generics, + params, &variant.fields[0]) } Style::Tuple => { deserialize_tuple(ident, Some(variant_ident), - generics, + params, &variant.fields, item_attrs, None) @@ -934,7 +953,7 @@ fn deserialize_externally_tagged_variant(ident: &syn::Ident, Style::Struct => { deserialize_struct(ident, Some(variant_ident), - generics, + params, &variant.fields, item_attrs, None) @@ -943,7 +962,7 @@ fn deserialize_externally_tagged_variant(ident: &syn::Ident, } fn deserialize_internally_tagged_variant(ident: &syn::Ident, - generics: &syn::Generics, + params: &Parameters, variant: &Variant, item_attrs: &attr::Item, deserializer: Tokens) @@ -961,7 +980,7 @@ fn deserialize_internally_tagged_variant(ident: &syn::Ident, } Style::Newtype | Style::Struct => { deserialize_untagged_variant(ident, - generics, + params, variant, item_attrs, deserializer) @@ -971,7 +990,7 @@ fn deserialize_internally_tagged_variant(ident: &syn::Ident, } fn deserialize_untagged_variant(ident: &syn::Ident, - generics: &syn::Generics, + params: &Parameters, variant: &Variant, item_attrs: &attr::Item, deserializer: Tokens) @@ -994,14 +1013,14 @@ fn deserialize_untagged_variant(ident: &syn::Ident, Style::Newtype => { deserialize_untagged_newtype_variant(ident, variant_ident, - generics, + params, &variant.fields[0], deserializer) } Style::Tuple => { deserialize_tuple(ident, Some(variant_ident), - generics, + params, &variant.fields, item_attrs, Some(deserializer)) @@ -1009,7 +1028,7 @@ fn deserialize_untagged_variant(ident: &syn::Ident, Style::Struct => { deserialize_struct(ident, Some(variant_ident), - generics, + params, &variant.fields, item_attrs, Some(deserializer)) @@ -1019,7 +1038,7 @@ fn deserialize_untagged_variant(ident: &syn::Ident, fn deserialize_externally_tagged_newtype_variant(ident: &syn::Ident, variant_ident: &syn::Ident, - generics: &syn::Generics, + params: &Parameters, field: &Field) -> Fragment { match field.attrs.deserialize_with() { @@ -1033,7 +1052,7 @@ fn deserialize_externally_tagged_newtype_variant(ident: &syn::Ident, } Some(path) => { let (wrapper, wrapper_ty) = - wrap_deserialize_with(ident, generics, field.ty, path); + wrap_deserialize_with(ident, params, field.ty, path); quote_block! { #wrapper _serde::export::Result::map( @@ -1046,7 +1065,7 @@ fn deserialize_externally_tagged_newtype_variant(ident: &syn::Ident, fn deserialize_untagged_newtype_variant(ident: &syn::Ident, variant_ident: &syn::Ident, - generics: &syn::Generics, + params: &Parameters, field: &Field, deserializer: Tokens) -> Fragment { @@ -1061,7 +1080,7 @@ fn deserialize_untagged_newtype_variant(ident: &syn::Ident, } Some(path) => { let (wrapper, wrapper_ty) = - wrap_deserialize_with(ident, generics, field.ty, path); + wrap_deserialize_with(ident, params, field.ty, path); quote_block! { #wrapper _serde::export::Result::map( @@ -1186,7 +1205,7 @@ fn deserialize_field_visitor(fields: Vec<(String, Ident)>, fn deserialize_struct_visitor(ident: &syn::Ident, struct_path: Tokens, - generics: &syn::Generics, + params: &Parameters, fields: &[Field], item_attrs: &attr::Item) -> (Fragment, Fragment, Fragment) { @@ -1205,14 +1224,14 @@ fn deserialize_struct_visitor(ident: &syn::Ident, let field_visitor = deserialize_field_visitor(field_names_idents, item_attrs, false); - let visit_map = deserialize_map(ident, struct_path, generics, fields, item_attrs); + let visit_map = deserialize_map(ident, struct_path, params, fields, item_attrs); (field_visitor, fields_stmt, visit_map) } fn deserialize_map(ident: &syn::Ident, struct_path: Tokens, - generics: &syn::Generics, + params: &Parameters, fields: &[Field], item_attrs: &attr::Item) -> Fragment { @@ -1247,7 +1266,7 @@ fn deserialize_map(ident: &syn::Ident, } Some(path) => { let (wrapper, wrapper_ty) = wrap_deserialize_with( - ident, generics, field.ty, path); + ident, params, field.ty, path); quote!({ #wrapper try!(_serde::de::MapVisitor::visit_value::<#wrapper_ty>(&mut __visitor)).value @@ -1355,11 +1374,11 @@ fn field_i(i: usize) -> Ident { /// This function wraps the expression in `#[serde(deserialize_with="...")]` in /// a trait to prevent it from accessing the internal `Deserialize` state. fn wrap_deserialize_with(ident: &syn::Ident, - generics: &syn::Generics, + params: &Parameters, field_ty: &syn::Ty, deserialize_with: &syn::Path) -> (Tokens, Tokens) { - let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(generics); + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params); let wrapper = quote! { struct __DeserializeWith #de_impl_generics #where_clause { @@ -1420,34 +1439,16 @@ fn expr_is_missing(field: &Field, item_attrs: &attr::Item) -> Fragment { } } -fn check_no_str(cx: &internals::Ctxt, item: &Item) { - let fail = || { - cx.error("Serde does not support deserializing fields of type &str; consider using \ - String instead"); - }; - - for field in item.body.all_fields() { - if field.attrs.skip_deserializing() || field.attrs.deserialize_with().is_some() { - continue; - } - - if let syn::Ty::Rptr(_, ref inner) = *field.ty { - if let syn::Ty::Path(_, ref path) = inner.ty { - if path.segments.len() == 1 && path.segments[0].ident == "str" { - fail(); - return; - } - } - } - } -} - -struct DeImplGenerics<'a>(&'a syn::Generics); +struct DeImplGenerics<'a>(&'a Parameters); impl<'a> ToTokens for DeImplGenerics<'a> { fn to_tokens(&self, tokens: &mut Tokens) { - let mut generics = self.0.clone(); - generics.lifetimes.insert(0, syn::LifetimeDef::new("'de")); + let mut generics = self.0.generics.clone(); + generics.lifetimes.insert(0, syn::LifetimeDef { + attrs: Vec::new(), + lifetime: syn::Lifetime::new("'de"), + bounds: self.0.borrowed.iter().cloned().collect(), + }); let (impl_generics, _, _) = generics.split_for_impl(); impl_generics.to_tokens(tokens); } @@ -1464,9 +1465,9 @@ impl<'a> ToTokens for DeTyGenerics<'a> { } } -fn split_with_de_lifetime(generics: &syn::Generics) -> (DeImplGenerics, DeTyGenerics, syn::TyGenerics, &syn::WhereClause) { - let de_impl_generics = DeImplGenerics(generics); - let de_ty_generics = DeTyGenerics(generics); - let (_, ty_generics, where_clause) = generics.split_for_impl(); +fn split_with_de_lifetime(params: &Parameters) -> (DeImplGenerics, DeTyGenerics, syn::TyGenerics, &syn::WhereClause) { + let de_impl_generics = DeImplGenerics(¶ms); + let de_ty_generics = DeTyGenerics(¶ms.generics); + let (_, ty_generics, where_clause) = params.generics.split_for_impl(); (de_impl_generics, de_ty_generics, ty_generics, where_clause) } diff --git a/test_suite/tests/compile-fail/borrow/bad_lifetimes.rs b/test_suite/tests/compile-fail/borrow/bad_lifetimes.rs new file mode 100644 index 00000000..b4a5e4a3 --- /dev/null +++ b/test_suite/tests/compile-fail/borrow/bad_lifetimes.rs @@ -0,0 +1,10 @@ +#[macro_use] +extern crate serde_derive; + +#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked +struct Test<'a> { + #[serde(borrow = "zzz")] //~^^ HELP: failed to parse borrowed lifetimes: "zzz" + s: &'a str, +} + +fn main() {} diff --git a/test_suite/tests/compile-fail/borrow/duplicate_lifetime.rs b/test_suite/tests/compile-fail/borrow/duplicate_lifetime.rs new file mode 100644 index 00000000..542ddc2a --- /dev/null +++ b/test_suite/tests/compile-fail/borrow/duplicate_lifetime.rs @@ -0,0 +1,10 @@ +#[macro_use] +extern crate serde_derive; + +#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked +struct Test<'a> { + #[serde(borrow = "'a + 'a")] //~^^ HELP: duplicate borrowed lifetime `'a` + s: &'a str, +} + +fn main() {} diff --git a/test_suite/tests/compile-fail/borrow/empty_lifetimes.rs b/test_suite/tests/compile-fail/borrow/empty_lifetimes.rs new file mode 100644 index 00000000..c1d43b57 --- /dev/null +++ b/test_suite/tests/compile-fail/borrow/empty_lifetimes.rs @@ -0,0 +1,10 @@ +#[macro_use] +extern crate serde_derive; + +#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked +struct Test<'a> { + #[serde(borrow = "")] //~^^ HELP: at least one lifetime must be borrowed + s: &'a str, +} + +fn main() {} diff --git a/test_suite/tests/compile-fail/borrow/no_lifetimes.rs b/test_suite/tests/compile-fail/borrow/no_lifetimes.rs new file mode 100644 index 00000000..47b3c0d4 --- /dev/null +++ b/test_suite/tests/compile-fail/borrow/no_lifetimes.rs @@ -0,0 +1,10 @@ +#[macro_use] +extern crate serde_derive; + +#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked +struct Test { + #[serde(borrow)] //~^^ HELP: field `s` has no lifetimes to borrow + s: String, +} + +fn main() {} diff --git a/test_suite/tests/compile-fail/borrow/wrong_lifetime.rs b/test_suite/tests/compile-fail/borrow/wrong_lifetime.rs new file mode 100644 index 00000000..5cf8999f --- /dev/null +++ b/test_suite/tests/compile-fail/borrow/wrong_lifetime.rs @@ -0,0 +1,10 @@ +#[macro_use] +extern crate serde_derive; + +#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked +struct Test<'a> { + #[serde(borrow = "'b")] //~^^ HELP: field `s` does not have lifetime 'b + s: &'a str, +} + +fn main() {} diff --git a/test_suite/tests/compile-fail/str_ref_deser.rs b/test_suite/tests/compile-fail/str_ref_deser.rs deleted file mode 100644 index 51f03f5c..00000000 --- a/test_suite/tests/compile-fail/str_ref_deser.rs +++ /dev/null @@ -1,9 +0,0 @@ -#[macro_use] -extern crate serde_derive; - -#[derive(Serialize, Deserialize)] //~ ERROR: proc-macro derive panicked -struct Test<'a> { - s: &'a str, //~^^ HELP: Serde does not support deserializing fields of type &str -} - -fn main() {} From cee3efbda82a22f9b73a131f39b8a9dfa265f1ca Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 3 Apr 2017 00:54:50 -0700 Subject: [PATCH 006/177] Relax lifetime requirement of the borrow_cow functions --- serde/src/de/private.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/serde/src/de/private.rs b/serde/src/de/private.rs index a1f3fa70..8121ee15 100644 --- a/serde/src/de/private.rs +++ b/serde/src/de/private.rs @@ -61,7 +61,7 @@ pub fn missing_field<'de, V, E>(field: &'static str) -> Result } #[cfg(any(feature = "std", feature = "collections"))] -pub fn borrow_cow_str<'de, D>(deserializer: D) -> Result, D::Error> +pub fn borrow_cow_str<'de: 'a, 'a, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de> { struct CowStrVisitor; @@ -123,7 +123,7 @@ pub fn borrow_cow_str<'de, D>(deserializer: D) -> Result, D::Error } #[cfg(any(feature = "std", feature = "collections"))] -pub fn borrow_cow_bytes<'de, D>(deserializer: D) -> Result, D::Error> +pub fn borrow_cow_bytes<'de: 'a, 'a, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de> { struct CowBytesVisitor; From 211e2bb8d94ffa4b261d40492756cebd1923a861 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 4 Apr 2017 09:56:01 -0700 Subject: [PATCH 007/177] Support borrowed tokens in serde_test --- serde_test/src/de.rs | 2 ++ serde_test/src/token.rs | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index b2d6dd12..2ec45f46 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -105,8 +105,10 @@ impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer Some(Token::F64(v)) => visitor.visit_f64(v), Some(Token::Char(v)) => visitor.visit_char(v), Some(Token::Str(v)) => visitor.visit_str(v), + Some(Token::BorrowedStr(v)) => visitor.visit_borrowed_str(v), Some(Token::String(v)) => visitor.visit_string(v), Some(Token::Bytes(v)) => visitor.visit_bytes(v), + Some(Token::BorrowedBytes(v)) => visitor.visit_borrowed_bytes(v), Some(Token::ByteBuf(v)) => visitor.visit_byte_buf(v), Some(Token::Option(false)) => visitor.visit_none(), Some(Token::Option(true)) => visitor.visit_some(self), diff --git a/serde_test/src/token.rs b/serde_test/src/token.rs index 82ccd9f2..05e15583 100644 --- a/serde_test/src/token.rs +++ b/serde_test/src/token.rs @@ -39,12 +39,18 @@ pub enum Token<'a> { /// A serialized `str`. Str(&'a str), + /// A borrowed `str`. + BorrowedStr(&'a str), + /// A serialized `String`. String(String), /// A serialized `[u8]` Bytes(&'a [u8]), + /// A borrowed `[u8]`. + BorrowedBytes(&'a [u8]), + /// A serialized `ByteBuf` ByteBuf(Vec), From 20ff9ba89b9f167a9b4a3dac96b12f7e017cc9bf Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 4 Apr 2017 10:47:21 -0700 Subject: [PATCH 008/177] Add tests of deserializing borrows --- test_suite/tests/test_borrow.rs | 199 ++++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 test_suite/tests/test_borrow.rs diff --git a/test_suite/tests/test_borrow.rs b/test_suite/tests/test_borrow.rs new file mode 100644 index 00000000..dd75f70b --- /dev/null +++ b/test_suite/tests/test_borrow.rs @@ -0,0 +1,199 @@ +#[macro_use] +extern crate serde_derive; + +extern crate serde; +use serde::{Deserialize, Deserializer}; + +extern crate serde_test; +use serde_test::{ + Error, + Token, + assert_de_tokens, + assert_de_tokens_error, +}; + +use std::borrow::Cow; + +#[test] +fn test_borrowed_str() { + assert_de_tokens( + &"borrowed", + &[ + Token::BorrowedStr("borrowed"), + ] + ); +} + +#[test] +fn test_borrowed_str_from_string() { + assert_de_tokens_error::<&str>( + &[ + Token::String("borrowed".to_owned()), + ], + Error::Message("invalid type: string \"borrowed\", expected a borrowed string".to_owned()), + ); +} + +#[test] +fn test_borrowed_str_from_str() { + assert_de_tokens_error::<&str>( + &[ + Token::Str("borrowed"), + ], + Error::Message("invalid type: string \"borrowed\", expected a borrowed string".to_owned()), + ); +} + +#[test] +fn test_string_from_borrowed_str() { + assert_de_tokens( + &"owned".to_owned(), + &[ + Token::BorrowedStr("owned"), + ] + ); +} + +#[test] +fn test_borrowed_bytes() { + assert_de_tokens( + &&b"borrowed"[..], + &[ + Token::BorrowedBytes(b"borrowed"), + ] + ); +} + +#[test] +fn test_borrowed_bytes_from_bytebuf() { + assert_de_tokens_error::<&[u8]>( + &[ + Token::ByteBuf(b"borrowed".to_vec()), + ], + Error::Message("invalid type: byte array, expected a borrowed byte array".to_owned()), + ); +} + +#[test] +fn test_borrowed_bytes_from_bytes() { + assert_de_tokens_error::<&[u8]>( + &[ + Token::Bytes(b"borrowed"), + ], + Error::Message("invalid type: byte array, expected a borrowed byte array".to_owned()), + ); +} + +#[test] +fn test_tuple() { + assert_de_tokens( + &("str", &b"bytes"[..]), + &[ + Token::TupleStart(2), + + Token::TupleSep, + Token::BorrowedStr("str"), + + Token::TupleSep, + Token::BorrowedBytes(b"bytes"), + + Token::TupleEnd, + ] + ); +} + +#[test] +fn test_struct() { + #[derive(Deserialize, Debug, PartialEq)] + struct Borrowing<'a, 'b> { + bs: &'a str, + bb: &'b [u8], + } + + assert_de_tokens( + &Borrowing { bs: "str", bb: b"bytes" }, + &[ + Token::StructStart("Borrowing", 2), + + Token::StructSep, + Token::BorrowedStr("bs"), + Token::BorrowedStr("str"), + + Token::StructSep, + Token::BorrowedStr("bb"), + Token::BorrowedBytes(b"bytes"), + + Token::StructEnd, + ] + ); +} + +#[test] +fn test_cow() { + #[derive(Deserialize)] + struct Cows<'a, 'b> { + copied: Cow<'a, str>, + + #[serde(borrow)] + borrowed: Cow<'b, str>, + } + + let tokens = vec![ + Token::StructStart("Cows", 2), + + Token::StructSep, + Token::Str("copied"), + Token::BorrowedStr("copied"), + + Token::StructSep, + Token::Str("borrowed"), + Token::BorrowedStr("borrowed"), + + Token::StructEnd, + ]; + + let mut de = serde_test::Deserializer::new(tokens.into_iter()); + let cows = Cows::deserialize(&mut de).unwrap(); + assert_eq!(de.next_token(), None); + + match cows.copied { + Cow::Owned(ref s) if s == "copied" => {} + _ => panic!("expected a copied string"), + } + + match cows.borrowed { + Cow::Borrowed("borrowed") => {} + _ => panic!("expected a borrowed string"), + } +} + +#[test] +fn test_lifetimes() { + #[derive(Deserialize)] + struct Cows<'a, 'b> { + _copied: Cow<'a, str>, + + #[serde(borrow)] + _borrowed: Cow<'b, str>, + } + + // Tests that `'de: 'a` is not required by the Deserialize impl. + fn _cows_lifetimes<'de: 'b, 'a, 'b, D>(deserializer: D) -> Cows<'a, 'b> + where D: Deserializer<'de> + { + Deserialize::deserialize(deserializer).unwrap() + } + + #[derive(Deserialize)] + struct Wrap<'a, 'b> { + #[serde(borrow = "'b")] + _cows: Cows<'a, 'b>, + } + + // Tests that `'de: 'a` is not required by the Deserialize impl. + fn _wrap_lifetimes<'de: 'b, 'a, 'b, D>(deserializer: D) -> Wrap<'a, 'b> + where D: Deserializer<'de> + { + Deserialize::deserialize(deserializer).unwrap() + } +} From 92bc23e484841554f1715825989df32ae9eedc82 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 4 Apr 2017 18:08:36 -0700 Subject: [PATCH 009/177] Deserializing OsString on windows requires a 'de lifetime --- serde/src/de/impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index e29a23d5..9b6f1f5d 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -1085,7 +1085,7 @@ impl<'de> Visitor<'de> for OsStringVisitor { #[cfg(windows)] fn visit_enum(self, visitor: V) -> Result - where V: EnumVisitor, + where V: EnumVisitor<'de>, { use std::os::windows::ffi::OsStringExt; From 2795f0ed9d5dc63b8ab1c2b64368941c42a852c4 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 4 Apr 2017 18:18:47 -0700 Subject: [PATCH 010/177] Remove questionable type conversions --- serde/src/de/impls.rs | 52 ------------------------------------------- serde/src/utils.rs | 24 -------------------- 2 files changed, 76 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 9b6f1f5d..1aa91db5 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -80,12 +80,6 @@ impl<'de> Visitor<'de> for UnitVisitor { { Ok(()) } - - fn visit_seq(self, _: V) -> Result<(), V::Error> - where V: SeqVisitor<'de> - { - Ok(()) - } } impl<'de> Deserialize<'de> for () { @@ -113,16 +107,6 @@ impl<'de> Visitor<'de> for BoolVisitor { { Ok(v) } - - fn visit_str(self, s: &str) -> Result - where E: Error - { - match s.trim_matches(::utils::Pattern_White_Space) { - "true" => Ok(true), - "false" => Ok(false), - _ => Err(Error::invalid_type(Unexpected::Str(s), &self)), - } - } } impl<'de> Deserialize<'de> for bool { @@ -175,15 +159,6 @@ macro_rules! impl_deserialize_num { impl_deserialize_num_method!($ty, u64, visit_u64, from_u64, Unsigned, u64); impl_deserialize_num_method!($ty, f32, visit_f32, from_f32, Float, f64); impl_deserialize_num_method!($ty, f64, visit_f64, from_f64, Float, f64); - - #[inline] - fn visit_str(self, s: &str) -> Result<$ty, E> - where E: Error, - { - str::FromStr::from_str(s.trim_matches(::utils::Pattern_White_Space)).or_else(|_| { - Err(Error::invalid_type(Unexpected::Str(s), &self)) - }) - } } deserializer.$method(PrimitiveVisitor) @@ -269,12 +244,6 @@ impl<'de> Visitor<'de> for StringVisitor { Ok(v) } - fn visit_unit(self) -> Result - where E: Error - { - Ok(String::new()) - } - fn visit_bytes(self, v: &[u8]) -> Result where E: Error { @@ -503,13 +472,6 @@ macro_rules! seq_impl { formatter.write_str("a sequence") } - #[inline] - fn visit_unit(self) -> Result - where E: Error, - { - Ok($ctor) - } - #[inline] fn visit_seq(self, mut $visitor: V) -> Result where V: SeqVisitor<'de>, @@ -613,13 +575,6 @@ impl<'de, T> Visitor<'de> for ArrayVisitor<[T; 0]> formatter.write_str("an empty array") } - #[inline] - fn visit_unit(self) -> Result<[T; 0], E> - where E: Error - { - Ok([]) - } - #[inline] fn visit_seq(self, _: V) -> Result<[T; 0], V::Error> where V: SeqVisitor<'de> @@ -819,13 +774,6 @@ macro_rules! map_impl { formatter.write_str("a map") } - #[inline] - fn visit_unit(self) -> Result - where E: Error, - { - Ok($ctor) - } - #[inline] fn visit_map(self, mut $visitor: Visitor) -> Result where Visitor: MapVisitor<'de>, diff --git a/serde/src/utils.rs b/serde/src/utils.rs index 927d1256..4e81616a 100644 --- a/serde/src/utils.rs +++ b/serde/src/utils.rs @@ -48,27 +48,3 @@ impl EncodeUtf8 { ::core::str::from_utf8(&self.buf[self.pos..]).unwrap() } } - -#[allow(non_upper_case_globals)] -const Pattern_White_Space_table: &'static [(char, char)] = &[('\u{9}', '\u{d}'), - ('\u{20}', '\u{20}'), - ('\u{85}', '\u{85}'), - ('\u{200e}', '\u{200f}'), - ('\u{2028}', '\u{2029}')]; - -fn bsearch_range_table(c: char, r: &'static [(char, char)]) -> bool { - use core::cmp::Ordering::{Equal, Less, Greater}; - r.binary_search_by(|&(lo, hi)| if c < lo { - Greater - } else if hi < c { - Less - } else { - Equal - }) - .is_ok() -} - -#[allow(non_snake_case)] -pub fn Pattern_White_Space(c: char) -> bool { - bsearch_range_table(c, Pattern_White_Space_table) -} From 7a722d506091dc28c541225d441275a110a1dc29 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 4 Apr 2017 18:38:58 -0700 Subject: [PATCH 011/177] Remove questionable conversion tests --- test_suite/tests/test_de.rs | 51 ------------------------------------- 1 file changed, 51 deletions(-) diff --git a/test_suite/tests/test_de.rs b/test_suite/tests/test_de.rs index 8d21844c..ab7b112e 100644 --- a/test_suite/tests/test_de.rs +++ b/test_suite/tests/test_de.rs @@ -245,18 +245,6 @@ declare_tests! { } test_unit { () => &[Token::Unit], - () => &[ - Token::SeqStart(Some(0)), - Token::SeqEnd, - ], - () => &[ - Token::SeqStart(None), - Token::SeqEnd, - ], - () => &[ - Token::TupleStructStart("Anything", 0), - Token::TupleStructEnd, - ], } test_unit_struct { UnitStruct => &[Token::Unit], @@ -272,9 +260,6 @@ declare_tests! { Token::SeqEnd, ], } - test_unit_string { - String::new() => &[Token::Unit], - } test_tuple_struct { TupleStruct(1, 2, 3) => &[ Token::SeqStart(Some(3)), @@ -326,9 +311,6 @@ declare_tests! { ], } test_btreeset { - BTreeSet::::new() => &[ - Token::Unit, - ], BTreeSet::::new() => &[ Token::SeqStart(Some(0)), Token::SeqEnd, @@ -355,18 +337,12 @@ declare_tests! { Token::SeqEnd, Token::SeqEnd, ], - BTreeSet::::new() => &[ - Token::UnitStruct("Anything"), - ], BTreeSet::::new() => &[ Token::TupleStructStart("Anything", 0), Token::TupleStructEnd, ], } test_hashset { - HashSet::::new() => &[ - Token::Unit, - ], HashSet::::new() => &[ Token::SeqStart(Some(0)), Token::SeqEnd, @@ -383,9 +359,6 @@ declare_tests! { Token::I32(3), Token::SeqEnd, ], - HashSet::::new() => &[ - Token::UnitStruct("Anything"), - ], HashSet::::new() => &[ Token::TupleStructStart("Anything", 0), Token::TupleStructEnd, @@ -404,9 +377,6 @@ declare_tests! { ], } test_vec { - Vec::::new() => &[ - Token::Unit, - ], Vec::::new() => &[ Token::SeqStart(Some(0)), Token::SeqEnd, @@ -433,18 +403,12 @@ declare_tests! { Token::SeqEnd, Token::SeqEnd, ], - Vec::::new() => &[ - Token::UnitStruct("Anything"), - ], Vec::::new() => &[ Token::TupleStructStart("Anything", 0), Token::TupleStructEnd, ], } test_array { - [0; 0] => &[ - Token::Unit, - ], [0; 0] => &[ Token::SeqStart(Some(0)), Token::SeqEnd, @@ -497,9 +461,6 @@ declare_tests! { Token::SeqEnd, Token::SeqEnd, ], - [0; 0] => &[ - Token::UnitStruct("Anything"), - ], [0; 0] => &[ Token::TupleStructStart("Anything", 0), Token::TupleStructEnd, @@ -544,9 +505,6 @@ declare_tests! { ], } test_btreemap { - BTreeMap::::new() => &[ - Token::Unit, - ], BTreeMap::::new() => &[ Token::MapStart(Some(0)), Token::MapEnd, @@ -589,18 +547,12 @@ declare_tests! { Token::MapEnd, Token::MapEnd, ], - BTreeMap::::new() => &[ - Token::UnitStruct("Anything"), - ], BTreeMap::::new() => &[ Token::StructStart("Anything", 0), Token::StructEnd, ], } test_hashmap { - HashMap::::new() => &[ - Token::Unit, - ], HashMap::::new() => &[ Token::MapStart(Some(0)), Token::MapEnd, @@ -643,9 +595,6 @@ declare_tests! { Token::MapEnd, Token::MapEnd, ], - HashMap::::new() => &[ - Token::UnitStruct("Anything"), - ], HashMap::::new() => &[ Token::StructStart("Anything", 0), Token::StructEnd, From d03ecda3339aee04cc60fb29ab4d9251015ac984 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 4 Apr 2017 18:50:40 -0700 Subject: [PATCH 012/177] Test that conversions do not happen --- test_suite/tests/test_de.rs | 111 ++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/test_suite/tests/test_de.rs b/test_suite/tests/test_de.rs index ab7b112e..552e58cb 100644 --- a/test_suite/tests/test_de.rs +++ b/test_suite/tests/test_de.rs @@ -1068,4 +1068,115 @@ declare_error_tests! { ], Error::Message("nul byte found in provided data at position: 2".into()), } + test_unit_from_empty_seq<()> { + &[ + Token::SeqStart(Some(0)), + Token::SeqEnd, + ], + Error::Message("invalid type: sequence, expected unit".into()), + } + test_unit_from_empty_seq_without_len<()> { + &[ + Token::SeqStart(None), + Token::SeqEnd, + ], + Error::Message("invalid type: sequence, expected unit".into()), + } + test_unit_from_tuple_struct<()> { + &[ + Token::TupleStructStart("Anything", 0), + Token::TupleStructEnd, + ], + Error::Message("invalid type: sequence, expected unit".into()), + } + test_string_from_unit { + &[ + Token::Unit, + ], + Error::Message("invalid type: unit value, expected a string".into()), + } + test_btreeset_from_unit> { + &[ + Token::Unit, + ], + Error::Message("invalid type: unit value, expected a sequence".into()), + } + test_btreeset_from_unit_struct> { + &[ + Token::UnitStruct("Anything"), + ], + Error::Message("invalid type: unit value, expected a sequence".into()), + } + test_hashset_from_unit> { + &[ + Token::Unit, + ], + Error::Message("invalid type: unit value, expected a sequence".into()), + } + test_hashset_from_unit_struct> { + &[ + Token::UnitStruct("Anything"), + ], + Error::Message("invalid type: unit value, expected a sequence".into()), + } + test_vec_from_unit> { + &[ + Token::Unit, + ], + Error::Message("invalid type: unit value, expected a sequence".into()), + } + test_vec_from_unit_struct> { + &[ + Token::UnitStruct("Anything"), + ], + Error::Message("invalid type: unit value, expected a sequence".into()), + } + test_zero_array_from_unit<[isize; 0]> { + &[ + Token::Unit, + ], + Error::Message("invalid type: unit value, expected an empty array".into()), + } + test_zero_array_from_unit_struct<[isize; 0]> { + &[ + Token::UnitStruct("Anything"), + ], + Error::Message("invalid type: unit value, expected an empty array".into()), + } + test_btreemap_from_unit> { + &[ + Token::Unit, + ], + Error::Message("invalid type: unit value, expected a map".into()), + } + test_btreemap_from_unit_struct> { + &[ + Token::UnitStruct("Anything"), + ], + Error::Message("invalid type: unit value, expected a map".into()), + } + test_hashmap_from_unit> { + &[ + Token::Unit, + ], + Error::Message("invalid type: unit value, expected a map".into()), + } + test_hashmap_from_unit_struct> { + &[ + Token::UnitStruct("Anything"), + ], + Error::Message("invalid type: unit value, expected a map".into()), + } + test_bool_from_string { + &[ + Token::Str("false"), + ], + Error::Message("invalid type: string \"false\", expected a boolean".into()), + } + test_number_from_string { + &[ + Token::Str("1"), + ], + Error::Message("invalid type: string \"1\", expected isize".into()), + } } From 732b91e53d1e3d6799e60e4ea4240b70948869b0 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 4 Apr 2017 18:59:57 -0700 Subject: [PATCH 013/177] Make the built-in visitors private --- serde/src/de/ignored_any.rs | 104 +++++++++++++++++++++++++++ serde/src/de/impls.rs | 135 +++--------------------------------- serde/src/de/mod.rs | 7 +- serde_derive/src/de.rs | 2 +- 4 files changed, 120 insertions(+), 128 deletions(-) create mode 100644 serde/src/de/ignored_any.rs diff --git a/serde/src/de/ignored_any.rs b/serde/src/de/ignored_any.rs new file mode 100644 index 00000000..d51f7386 --- /dev/null +++ b/serde/src/de/ignored_any.rs @@ -0,0 +1,104 @@ +use core::fmt; + +use de::{Deserialize, Deserializer, Visitor, SeqVisitor, MapVisitor, Error}; + +/// A target for deserializers that want to ignore data. Implements Deserialize +/// and silently eats data given to it. +pub struct IgnoredAny; + +impl<'de> Deserialize<'de> for IgnoredAny { + #[inline] + fn deserialize(deserializer: D) -> Result + where D: Deserializer<'de> + { + struct IgnoredAnyVisitor; + + impl<'de> Visitor<'de> for IgnoredAnyVisitor { + type Value = IgnoredAny; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("anything at all") + } + + #[inline] + fn visit_bool(self, _: bool) -> Result { + Ok(IgnoredAny) + } + + #[inline] + fn visit_i64(self, _: i64) -> Result { + Ok(IgnoredAny) + } + + #[inline] + fn visit_u64(self, _: u64) -> Result { + Ok(IgnoredAny) + } + + #[inline] + fn visit_f64(self, _: f64) -> Result { + Ok(IgnoredAny) + } + + #[inline] + fn visit_str(self, _: &str) -> Result + where E: Error + { + Ok(IgnoredAny) + } + + #[inline] + fn visit_none(self) -> Result { + Ok(IgnoredAny) + } + + #[inline] + fn visit_some(self, _: D) -> Result + where D: Deserializer<'de> + { + Ok(IgnoredAny) + } + + #[inline] + fn visit_newtype_struct(self, _: D) -> Result + where D: Deserializer<'de> + { + Ok(IgnoredAny) + } + + #[inline] + fn visit_unit(self) -> Result { + Ok(IgnoredAny) + } + + #[inline] + fn visit_seq(self, mut visitor: V) -> Result + where V: SeqVisitor<'de> + { + while let Some(_) = try!(visitor.visit::()) { + // Gobble + } + Ok(IgnoredAny) + } + + #[inline] + fn visit_map(self, mut visitor: V) -> Result + where V: MapVisitor<'de> + { + while let Some((_, _)) = try!(visitor.visit::()) { + // Gobble + } + Ok(IgnoredAny) + } + + #[inline] + fn visit_bytes(self, _: &[u8]) -> Result + where E: Error + { + Ok(IgnoredAny) + } + } + + deserializer.deserialize_ignored_any(IgnoredAnyVisitor) + } +} diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 9b6f1f5d..8fe9a1a3 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -1,5 +1,3 @@ -//! This module contains `Deserialize` and `Visitor` implementations. - #[cfg(feature = "std")] use std::borrow::Cow; #[cfg(all(feature = "collections", not(feature = "std")))] @@ -65,8 +63,7 @@ use bytes::ByteBuf; /////////////////////////////////////////////////////////////////////////////// -/// A visitor that produces a `()`. -pub struct UnitVisitor; +struct UnitVisitor; impl<'de> Visitor<'de> for UnitVisitor { type Value = (); @@ -98,8 +95,7 @@ impl<'de> Deserialize<'de> for () { /////////////////////////////////////////////////////////////////////////////// -/// A visitor that produces a `bool`. -pub struct BoolVisitor; +struct BoolVisitor; impl<'de> Visitor<'de> for BoolVisitor { type Value = bool; @@ -439,8 +435,7 @@ impl<'de, T> Deserialize<'de> for Option /////////////////////////////////////////////////////////////////////////////// -/// A visitor that produces a `PhantomData`. -pub struct PhantomDataVisitor { +struct PhantomDataVisitor { marker: PhantomData, } @@ -479,14 +474,12 @@ macro_rules! seq_impl { $with_capacity:expr, $insert:expr ) => { - /// A visitor that produces a sequence. - pub struct $visitor_ty { + struct $visitor_ty { marker: PhantomData<$ty>, } impl $visitor_ty { - /// Construct a new sequence visitor. - pub fn new() -> Self { + fn new() -> Self { $visitor_ty { marker: PhantomData, } @@ -599,7 +592,7 @@ struct ArrayVisitor { } impl ArrayVisitor { - pub fn new() -> Self { + fn new() -> Self { ArrayVisitor { marker: PhantomData } } } @@ -718,14 +711,12 @@ array_impls! { macro_rules! tuple_impls { ($($len:expr => $visitor:ident => ($($n:tt $name:ident)+))+) => { $( - /// Construct a tuple visitor. - pub struct $visitor<$($name,)+> { + struct $visitor<$($name,)+> { marker: PhantomData<($($name,)+)>, } impl<$($name,)+> $visitor<$($name,)+> { - /// Construct a `TupleVisitor*`. - pub fn new() -> Self { + fn new() -> Self { $visitor { marker: PhantomData } } } @@ -794,14 +785,12 @@ macro_rules! map_impl { $ctor:expr, $with_capacity:expr ) => { - /// A visitor that produces a map. - pub struct $visitor_ty { + struct $visitor_ty { marker: PhantomData<$ty>, } impl $visitor_ty { - /// Construct a `MapVisitor*`. - pub fn new() -> Self { + fn new() -> Self { $visitor_ty { marker: PhantomData, } @@ -1550,107 +1539,3 @@ impl<'de, T, E> Deserialize<'de> for Result deserializer.deserialize_enum("Result", VARIANTS, ResultVisitor(PhantomData)) } } - -/////////////////////////////////////////////////////////////////////////////// - -/// A target for deserializers that want to ignore data. Implements -/// Deserialize and silently eats data given to it. -pub struct IgnoredAny; - -impl<'de> Deserialize<'de> for IgnoredAny { - #[inline] - fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> - { - struct IgnoredAnyVisitor; - - impl<'de> Visitor<'de> for IgnoredAnyVisitor { - type Value = IgnoredAny; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("anything at all") - } - - #[inline] - fn visit_bool(self, _: bool) -> Result { - Ok(IgnoredAny) - } - - #[inline] - fn visit_i64(self, _: i64) -> Result { - Ok(IgnoredAny) - } - - #[inline] - fn visit_u64(self, _: u64) -> Result { - Ok(IgnoredAny) - } - - #[inline] - fn visit_f64(self, _: f64) -> Result { - Ok(IgnoredAny) - } - - #[inline] - fn visit_str(self, _: &str) -> Result - where E: Error - { - Ok(IgnoredAny) - } - - #[inline] - fn visit_none(self) -> Result { - Ok(IgnoredAny) - } - - #[inline] - fn visit_some(self, _: D) -> Result - where D: Deserializer<'de> - { - Ok(IgnoredAny) - } - - #[inline] - fn visit_newtype_struct(self, _: D) -> Result - where D: Deserializer<'de> - { - Ok(IgnoredAny) - } - - #[inline] - fn visit_unit(self) -> Result { - Ok(IgnoredAny) - } - - #[inline] - fn visit_seq(self, mut visitor: V) -> Result - where V: SeqVisitor<'de> - { - while let Some(_) = try!(visitor.visit::()) { - // Gobble - } - Ok(IgnoredAny) - } - - #[inline] - fn visit_map(self, mut visitor: V) -> Result - where V: MapVisitor<'de> - { - while let Some((_, _)) = try!(visitor.visit::()) { - // Gobble - } - Ok(IgnoredAny) - } - - #[inline] - fn visit_bytes(self, _: &[u8]) -> Result - where E: Error - { - Ok(IgnoredAny) - } - } - - // TODO maybe not necessary with impl specialization - deserializer.deserialize_ignored_any(IgnoredAnyVisitor) - } -} diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index ad6944ba..c9b427f2 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -107,10 +107,11 @@ use core::marker::PhantomData; /////////////////////////////////////////////////////////////////////////////// -#[doc(hidden)] -pub mod impls; pub mod value; + mod from_primitive; +mod ignored_any; +mod impls; // Helpers used by generated code. Not public API. #[doc(hidden)] @@ -118,6 +119,8 @@ pub mod private; #[cfg(any(feature = "std", feature = "collections"))] mod content; +pub use self::ignored_any::IgnoredAny; + /////////////////////////////////////////////////////////////////////////////// /// The `Error` trait allows `Deserialize` implementations to create descriptive diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index b67ad285..84be769b 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -1288,7 +1288,7 @@ fn deserialize_map(ident: &syn::Ident, None } else { Some(quote! { - _ => { let _ = try!(_serde::de::MapVisitor::visit_value::<_serde::de::impls::IgnoredAny>(&mut __visitor)); } + _ => { let _ = try!(_serde::de::MapVisitor::visit_value::<_serde::de::IgnoredAny>(&mut __visitor)); } }) }; From f05368ed24aab0c74d419d7de6a3d545d1da927d Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 4 Apr 2017 19:04:47 -0700 Subject: [PATCH 014/177] Remove the no_std implementation of collect_str --- serde/src/ser/mod.rs | 13 ++++--------- serde/src/ser/private.rs | 7 +++++++ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index ad03b61f..fb9ef2dd 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -654,8 +654,9 @@ pub trait Serializer: Sized { /// Serialize a string produced by an implementation of `Display`. /// - /// The default implementation returns an error unconditionally when - /// compiled with `no_std`. + /// Serializers that use `no_std` are required to provide an implementation + /// of this method. If no more sensible behavior is possible, the + /// implementation is expected to return an error. /// /// ```rust /// # use serde::{Serialize, Serializer}; @@ -676,13 +677,7 @@ pub trait Serializer: Sized { /// ``` #[cfg(not(any(feature = "std", feature = "collections")))] fn collect_str(self, value: &T) -> Result - where T: Display - { - // TODO https://github.com/serde-rs/serde/issues/805 - // Remove this impl and force no_std formats to implement collect_str. - let _ = value; - Err(Error::custom("this no_std format does not support serializing strings with collect_str")) - } + where T: Display; } /// Returned from `Serializer::serialize_seq` and diff --git a/serde/src/ser/private.rs b/serde/src/ser/private.rs index 0297c8ac..6e30cb72 100644 --- a/serde/src/ser/private.rs +++ b/serde/src/ser/private.rs @@ -312,4 +312,11 @@ impl Serializer for TaggedSerializer try!(map.serialize_key(inner_variant)); Ok(SerializeStructVariantAsMapValue::new(map, inner_variant, len)) } + + #[cfg(not(any(feature = "std", feature = "collections")))] + fn collect_str(self, _: &T) -> Result + where T: Display + { + Err(self.bad_type(Unsupported::String)) + } } From 5871fb9ce0ad64e005d2109b2d33b3c1881e802c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 00:17:50 -0700 Subject: [PATCH 015/177] Remove lifetime from serde_test::Token --- serde_test/src/assert.rs | 6 ++-- serde_test/src/de.rs | 48 ++++++++++++------------- serde_test/src/error.rs | 2 +- serde_test/src/ser.rs | 62 ++++++++++++++++++++------------- serde_test/src/token.rs | 34 +++++++++--------- test_suite/tests/test_borrow.rs | 4 +-- test_suite/tests/test_bytes.rs | 8 ++--- test_suite/tests/test_de.rs | 12 +++---- 8 files changed, 95 insertions(+), 81 deletions(-) diff --git a/serde_test/src/assert.rs b/serde_test/src/assert.rs index fc33f282..499330e1 100644 --- a/serde_test/src/assert.rs +++ b/serde_test/src/assert.rs @@ -8,7 +8,7 @@ use token::Token; use std::fmt::Debug; /// Runs both `assert_ser_tokens` and `assert_de_tokens`. -pub fn assert_tokens<'de, T>(value: &T, tokens: &[Token<'static>]) +pub fn assert_tokens<'de, T>(value: &T, tokens: &[Token]) where T: Serialize + Deserialize<'de> + PartialEq + Debug { assert_ser_tokens(value, tokens); @@ -35,7 +35,7 @@ pub fn assert_ser_tokens_error(value: &T, tokens: &[Token], error: Error) } /// Asserts that the given `tokens` deserialize into `value`. -pub fn assert_de_tokens<'de, T>(value: &T, tokens: &[Token<'static>]) +pub fn assert_de_tokens<'de, T>(value: &T, tokens: &[Token]) where T: Deserialize<'de> + PartialEq + Debug { let mut de = Deserializer::new(tokens.to_vec().into_iter()); @@ -45,7 +45,7 @@ pub fn assert_de_tokens<'de, T>(value: &T, tokens: &[Token<'static>]) } /// Asserts that the given `tokens` yield `error` when deserializing. -pub fn assert_de_tokens_error<'de, T>(tokens: &[Token<'static>], error: Error) +pub fn assert_de_tokens_error<'de, T>(tokens: &[Token], error: Error) where T: Deserialize<'de> + PartialEq + Debug { let mut de = Deserializer::new(tokens.to_vec().into_iter()); diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index 2ec45f46..d2441ac1 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -9,13 +9,13 @@ use token::Token; /// A `Deserializer` that reads from a list of tokens. pub struct Deserializer - where I: Iterator> + where I: Iterator { tokens: iter::Peekable, } impl Deserializer - where I: Iterator> + where I: Iterator { /// Creates the deserializer. pub fn new(tokens: I) -> Deserializer { @@ -23,7 +23,7 @@ impl Deserializer } /// Pulls the next token off of the deserializer, ignoring it. - pub fn next_token(&mut self) -> Option> { + pub fn next_token(&mut self) -> Option { self.tokens.next() } @@ -43,8 +43,8 @@ impl Deserializer fn visit_seq<'de, V>(&mut self, len: Option, - sep: Token<'static>, - end: Token<'static>, + sep: Token, + end: Token, visitor: V) -> Result where V: Visitor<'de> @@ -61,8 +61,8 @@ impl Deserializer fn visit_map<'de, V>(&mut self, len: Option, - sep: Token<'static>, - end: Token<'static>, + sep: Token, + end: Token, visitor: V) -> Result where V: Visitor<'de> @@ -79,7 +79,7 @@ impl Deserializer } impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer - where I: Iterator> + where I: Iterator { type Error = Error; @@ -106,10 +106,10 @@ impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer Some(Token::Char(v)) => visitor.visit_char(v), Some(Token::Str(v)) => visitor.visit_str(v), Some(Token::BorrowedStr(v)) => visitor.visit_borrowed_str(v), - Some(Token::String(v)) => visitor.visit_string(v), + Some(Token::String(v)) => visitor.visit_string(v.to_owned()), Some(Token::Bytes(v)) => visitor.visit_bytes(v), Some(Token::BorrowedBytes(v)) => visitor.visit_borrowed_bytes(v), - Some(Token::ByteBuf(v)) => visitor.visit_byte_buf(v), + Some(Token::ByteBuf(v)) => visitor.visit_byte_buf(v.to_vec()), Some(Token::Option(false)) => visitor.visit_none(), Some(Token::Option(true)) => visitor.visit_some(self), Some(Token::Unit) => visitor.visit_unit(), @@ -354,16 +354,16 @@ impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer ////////////////////////////////////////////////////////////////////////// struct DeserializerSeqVisitor<'a, I: 'a> - where I: Iterator> + where I: Iterator { de: &'a mut Deserializer, len: Option, - sep: Token<'static>, - end: Token<'static>, + sep: Token, + end: Token, } impl<'de, 'a, I> SeqVisitor<'de> for DeserializerSeqVisitor<'a, I> - where I: Iterator> + where I: Iterator { type Error = Error; @@ -392,16 +392,16 @@ impl<'de, 'a, I> SeqVisitor<'de> for DeserializerSeqVisitor<'a, I> ////////////////////////////////////////////////////////////////////////// struct DeserializerMapVisitor<'a, I: 'a> - where I: Iterator> + where I: Iterator { de: &'a mut Deserializer, len: Option, - sep: Token<'static>, - end: Token<'static>, + sep: Token, + end: Token, } impl<'de, 'a, I> MapVisitor<'de> for DeserializerMapVisitor<'a, I> - where I: Iterator> + where I: Iterator { type Error = Error; @@ -436,13 +436,13 @@ impl<'de, 'a, I> MapVisitor<'de> for DeserializerMapVisitor<'a, I> ////////////////////////////////////////////////////////////////////////// struct DeserializerEnumVisitor<'a, I: 'a> - where I: Iterator> + where I: Iterator { de: &'a mut Deserializer, } impl<'de, 'a, I> EnumVisitor<'de> for DeserializerEnumVisitor<'a, I> - where I: Iterator> + where I: Iterator { type Error = Error; type Variant = Self; @@ -469,7 +469,7 @@ impl<'de, 'a, I> EnumVisitor<'de> for DeserializerEnumVisitor<'a, I> } impl<'de, 'a, I> VariantVisitor<'de> for DeserializerEnumVisitor<'a, I> - where I: Iterator> + where I: Iterator { type Error = Error; @@ -558,14 +558,14 @@ impl<'de, 'a, I> VariantVisitor<'de> for DeserializerEnumVisitor<'a, I> ////////////////////////////////////////////////////////////////////////// struct EnumMapVisitor<'a, I: 'a> - where I: Iterator> + where I: Iterator { de: &'a mut Deserializer, variant: Option<&'a str>, } impl<'a, I: 'a> EnumMapVisitor<'a, I> - where I: Iterator> + where I: Iterator { fn new(de: &'a mut Deserializer, variant: &'a str) -> Self { EnumMapVisitor { @@ -576,7 +576,7 @@ impl<'a, I: 'a> EnumMapVisitor<'a, I> } impl<'de, 'a, I: 'a> MapVisitor<'de> for EnumMapVisitor<'a, I> - where I: Iterator> + where I: Iterator { type Error = Error; diff --git a/serde_test/src/error.rs b/serde_test/src/error.rs index 507cfd46..2cf5161f 100644 --- a/serde_test/src/error.rs +++ b/serde_test/src/error.rs @@ -15,7 +15,7 @@ pub enum Error { InvalidName(&'static str), /// `Serialize` generated a token that didn't match the test. - UnexpectedToken(Token<'static>), + UnexpectedToken(Token), /// The expected token list was too short. EndOfTokens, diff --git a/serde_test/src/ser.rs b/serde_test/src/ser.rs index 93608a19..c38b1a04 100644 --- a/serde_test/src/ser.rs +++ b/serde_test/src/ser.rs @@ -7,14 +7,14 @@ use token::Token; /// A `Serializer` that ensures that a value serializes to a given list of tokens. pub struct Serializer<'a, I> - where I: Iterator> + where I: Iterator { tokens: I, - phantom: PhantomData<&'a Token<'a>>, + phantom: PhantomData<&'a Token>, } impl<'a, I> Serializer<'a, I> - where I: Iterator> + where I: Iterator { /// Creates the serializer. pub fn new(tokens: I) -> Serializer<'a, I> { @@ -25,13 +25,27 @@ impl<'a, I> Serializer<'a, I> } /// Pulls the next token off of the serializer, ignoring it. - pub fn next_token(&mut self) -> Option<&'a Token<'a>> { + pub fn next_token(&mut self) -> Option<&'a Token> { self.tokens.next() } } +macro_rules! assert_next_token { + ($self:ident, $expected:ident($arg:expr)) => { + match $self.tokens.next() { + Some(&Token::$expected(v)) if v == $arg => {} + Some(other) => { + panic!("expected {}({:?}) but serialized as {:?}", stringify!($expected), $arg, other); + } + None => { + panic!("expected {}({:?}) after end of serialized tokens", stringify!($expected), $arg); + } + } + } +} + impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I> - where I: Iterator> + where I: Iterator { type Ok = (); type Error = Error; @@ -105,12 +119,12 @@ impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I> } fn serialize_str(self, v: &str) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::Str(v))); + assert_next_token!(self, Str(v)); Ok(()) } fn serialize_bytes(self, value: &[u8]) -> Result<(), Self::Error> { - assert_eq!(self.tokens.next(), Some(&Token::Bytes(value))); + assert_next_token!(self, Bytes(value)); Ok(()) } @@ -119,15 +133,15 @@ impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I> Ok(()) } - fn serialize_unit_struct(self, name: &str) -> Result<(), Error> { + fn serialize_unit_struct(self, name: &'static str) -> Result<(), Error> { assert_eq!(self.tokens.next(), Some(&Token::UnitStruct(name))); Ok(()) } fn serialize_unit_variant(self, - name: &str, + name: &'static str, _variant_index: usize, - variant: &str) + variant: &'static str) -> Result<(), Error> { assert_eq!(self.tokens.next(), Some(&Token::EnumUnit(name, variant))); Ok(()) @@ -141,9 +155,9 @@ impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I> } fn serialize_newtype_variant(self, - name: &str, + name: &'static str, _variant_index: usize, - variant: &str, + variant: &'static str, value: &T) -> Result<(), Error> where T: Serialize @@ -186,9 +200,9 @@ impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I> } fn serialize_tuple_variant(self, - name: &str, + name: &'static str, _variant_index: usize, - variant: &str, + variant: &'static str, len: usize) -> Result { assert_eq!(self.tokens.next(), @@ -201,15 +215,15 @@ impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I> Ok(self) } - fn serialize_struct(self, name: &str, len: usize) -> Result { + fn serialize_struct(self, name: &'static str, len: usize) -> Result { assert_eq!(self.tokens.next(), Some(&Token::StructStart(name, len))); Ok(self) } fn serialize_struct_variant(self, - name: &str, + name: &'static str, _variant_index: usize, - variant: &str, + variant: &'static str, len: usize) -> Result { assert_eq!(self.tokens.next(), @@ -219,7 +233,7 @@ impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I> } impl<'s, 'a, I> ser::SerializeSeq for &'s mut Serializer<'a, I> - where I: Iterator> + where I: Iterator { type Ok = (); type Error = Error; @@ -238,7 +252,7 @@ impl<'s, 'a, I> ser::SerializeSeq for &'s mut Serializer<'a, I> } impl<'s, 'a, I> ser::SerializeTuple for &'s mut Serializer<'a, I> - where I: Iterator> + where I: Iterator { type Ok = (); type Error = Error; @@ -257,7 +271,7 @@ impl<'s, 'a, I> ser::SerializeTuple for &'s mut Serializer<'a, I> } impl<'s, 'a, I> ser::SerializeTupleStruct for &'s mut Serializer<'a, I> - where I: Iterator> + where I: Iterator { type Ok = (); type Error = Error; @@ -276,7 +290,7 @@ impl<'s, 'a, I> ser::SerializeTupleStruct for &'s mut Serializer<'a, I> } impl<'s, 'a, I> ser::SerializeTupleVariant for &'s mut Serializer<'a, I> - where I: Iterator> + where I: Iterator { type Ok = (); type Error = Error; @@ -295,7 +309,7 @@ impl<'s, 'a, I> ser::SerializeTupleVariant for &'s mut Serializer<'a, I> } impl<'s, 'a, I> ser::SerializeMap for &'s mut Serializer<'a, I> - where I: Iterator> + where I: Iterator { type Ok = (); type Error = Error; @@ -320,7 +334,7 @@ impl<'s, 'a, I> ser::SerializeMap for &'s mut Serializer<'a, I> } impl<'s, 'a, I> ser::SerializeStruct for &'s mut Serializer<'a, I> - where I: Iterator> + where I: Iterator { type Ok = (); type Error = Error; @@ -343,7 +357,7 @@ impl<'s, 'a, I> ser::SerializeStruct for &'s mut Serializer<'a, I> } impl<'s, 'a, I> ser::SerializeStructVariant for &'s mut Serializer<'a, I> - where I: Iterator> + where I: Iterator { type Ok = (); type Error = Error; diff --git a/serde_test/src/token.rs b/serde_test/src/token.rs index 05e15583..7cc9bbdd 100644 --- a/serde_test/src/token.rs +++ b/serde_test/src/token.rs @@ -1,5 +1,5 @@ -#[derive(Clone, PartialEq, Debug)] -pub enum Token<'a> { +#[derive(Copy, Clone, PartialEq, Debug)] +pub enum Token { /// A serialized `bool`. Bool(bool), @@ -37,22 +37,22 @@ pub enum Token<'a> { Char(char), /// A serialized `str`. - Str(&'a str), + Str(&'static str), /// A borrowed `str`. - BorrowedStr(&'a str), + BorrowedStr(&'static str), /// A serialized `String`. - String(String), + String(&'static str), /// A serialized `[u8]` - Bytes(&'a [u8]), + Bytes(&'static [u8]), /// A borrowed `[u8]`. - BorrowedBytes(&'a [u8]), + BorrowedBytes(&'static [u8]), /// A serialized `ByteBuf` - ByteBuf(Vec), + ByteBuf(&'static [u8]), /// The header to a serialized `Option`. /// @@ -64,13 +64,13 @@ pub enum Token<'a> { Unit, /// A serialized unit struct of the given name. - UnitStruct(&'a str), + UnitStruct(&'static str), /// The header to a serialized newtype struct of the given name. /// /// Newtype structs are serialized with this header, followed by the value contained in the /// newtype struct. - StructNewType(&'a str), + StructNewType(&'static str), /// The header to an enum of the given name. /// @@ -79,19 +79,19 @@ pub enum Token<'a> { /// `assert_tokens` will fail if this token is used. /// /// TODO: Trash this. - EnumStart(&'a str), + EnumStart(&'static str), /// A unit variant of an enum of the given name, of the given name. /// /// The first string represents the name of the enum, and the second represents the name of the /// variant. - EnumUnit(&'a str, &'a str), + EnumUnit(&'static str, &'static str), /// The header to a newtype variant of an enum of the given name, of the given name. /// /// The first string represents the name of the enum, and the second represents the name of the /// variant. The value contained within this enum works the same as `StructNewType`. - EnumNewType(&'a str, &'a str), + EnumNewType(&'static str, &'static str), /// The header to a sequence of the given length. /// @@ -123,7 +123,7 @@ pub enum Token<'a> { TupleEnd, /// The header to a tuple struct of the given name and length. - TupleStructStart(&'a str, usize), + TupleStructStart(&'static str, usize), /// A separator, similar to `TupleSep`. TupleStructSep, @@ -147,7 +147,7 @@ pub enum Token<'a> { MapEnd, /// The header of a struct of the given name and length, similar to `MapStart`. - StructStart(&'a str, usize), + StructStart(&'static str, usize), /// A separator, similar to `MapSep`. StructSep, @@ -156,7 +156,7 @@ pub enum Token<'a> { StructEnd, /// The header to a tuple variant of an enum of the given name, of the given name and length. - EnumSeqStart(&'a str, &'a str, usize), + EnumSeqStart(&'static str, &'static str, usize), /// A separator, similar to `TupleSep`. EnumSeqSep, @@ -166,7 +166,7 @@ pub enum Token<'a> { /// The header of a struct variant of an enum of the given name, of the given name and length, /// similar to `StructStart`. - EnumMapStart(&'a str, &'a str, usize), + EnumMapStart(&'static str, &'static str, usize), /// A separator, similar to `StructSep`. EnumMapSep, diff --git a/test_suite/tests/test_borrow.rs b/test_suite/tests/test_borrow.rs index dd75f70b..f57ebb9c 100644 --- a/test_suite/tests/test_borrow.rs +++ b/test_suite/tests/test_borrow.rs @@ -28,7 +28,7 @@ fn test_borrowed_str() { fn test_borrowed_str_from_string() { assert_de_tokens_error::<&str>( &[ - Token::String("borrowed".to_owned()), + Token::String("borrowed"), ], Error::Message("invalid type: string \"borrowed\", expected a borrowed string".to_owned()), ); @@ -68,7 +68,7 @@ fn test_borrowed_bytes() { fn test_borrowed_bytes_from_bytebuf() { assert_de_tokens_error::<&[u8]>( &[ - Token::ByteBuf(b"borrowed".to_vec()), + Token::ByteBuf(b"borrowed"), ], Error::Message("invalid type: byte array, expected a borrowed byte array".to_owned()), ); diff --git a/test_suite/tests/test_bytes.rs b/test_suite/tests/test_bytes.rs index 28e47d1b..f4ae59dc 100644 --- a/test_suite/tests/test_bytes.rs +++ b/test_suite/tests/test_bytes.rs @@ -18,9 +18,9 @@ fn test_bytes() { fn test_byte_buf() { let empty = ByteBuf::new(); assert_tokens(&empty, &[Token::Bytes(b"")]); - assert_de_tokens(&empty, &[Token::ByteBuf(Vec::new())]); + assert_de_tokens(&empty, &[Token::ByteBuf(b"")]); assert_de_tokens(&empty, &[Token::Str("")]); - assert_de_tokens(&empty, &[Token::String(String::new())]); + assert_de_tokens(&empty, &[Token::String("")]); assert_de_tokens(&empty, &[ Token::SeqStart(None), Token::SeqEnd, @@ -32,9 +32,9 @@ fn test_byte_buf() { let buf = ByteBuf::from(vec![65, 66, 67]); assert_tokens(&buf, &[Token::Bytes(b"ABC")]); - assert_de_tokens(&buf, &[Token::ByteBuf(vec![65, 66, 67])]); + assert_de_tokens(&buf, &[Token::ByteBuf(b"ABC")]); assert_de_tokens(&buf, &[Token::Str("ABC")]); - assert_de_tokens(&buf, &[Token::String("ABC".to_owned())]); + assert_de_tokens(&buf, &[Token::String("ABC")]); assert_de_tokens(&buf, &[ Token::SeqStart(None), Token::SeqSep, diff --git a/test_suite/tests/test_de.rs b/test_suite/tests/test_de.rs index 8d21844c..daeaa4cb 100644 --- a/test_suite/tests/test_de.rs +++ b/test_suite/tests/test_de.rs @@ -137,7 +137,7 @@ macro_rules! declare_error_tests { } } -fn assert_de_tokens_ignore(ignorable_tokens: &[Token<'static>]) { +fn assert_de_tokens_ignore(ignorable_tokens: &[Token]) { #[derive(PartialEq, Debug, Deserialize)] struct IgnoreBase { a: i32, @@ -147,7 +147,7 @@ fn assert_de_tokens_ignore(ignorable_tokens: &[Token<'static>]) { // Embed the tokens to be ignored in the normal token // stream for an IgnoreBase type - let concated_tokens : Vec> = vec![ + let concated_tokens : Vec = vec![ Token::MapStart(Some(2)), Token::MapSep, Token::Str("a"), @@ -215,11 +215,11 @@ declare_tests! { test_char { 'a' => &[Token::Char('a')], 'a' => &[Token::Str("a")], - 'a' => &[Token::String("a".to_owned())], + 'a' => &[Token::String("a")], } test_string { "abc".to_owned() => &[Token::Str("abc")], - "abc".to_owned() => &[Token::String("abc".to_owned())], + "abc".to_owned() => &[Token::String("abc")], "a".to_owned() => &[Token::Char('a')], } test_option { @@ -767,7 +767,7 @@ declare_tests! { Token::StructSep, Token::Str("b"), - Token::String("overwritten".to_string()), + Token::String("overwritten"), Token::StructEnd, ], StructDefault { a: 100, b: "default".to_string() } => &[ @@ -903,7 +903,7 @@ declare_tests! { } test_path_buf { PathBuf::from("/usr/local/lib") => &[ - Token::String("/usr/local/lib".to_owned()), + Token::String("/usr/local/lib"), ], } test_cstring { From b43554fbb1f47db961c7c3befafdae60765881c5 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 00:22:00 -0700 Subject: [PATCH 016/177] Require slice of tokens in serde_test::Deserializer --- serde_test/src/assert.rs | 10 +- serde_test/src/de.rs | 173 ++++++++++++++------------------ test_suite/tests/test_borrow.rs | 4 +- test_suite/tests/test_de.rs | 2 +- 4 files changed, 83 insertions(+), 106 deletions(-) diff --git a/serde_test/src/assert.rs b/serde_test/src/assert.rs index 499330e1..edfadf0d 100644 --- a/serde_test/src/assert.rs +++ b/serde_test/src/assert.rs @@ -8,7 +8,7 @@ use token::Token; use std::fmt::Debug; /// Runs both `assert_ser_tokens` and `assert_de_tokens`. -pub fn assert_tokens<'de, T>(value: &T, tokens: &[Token]) +pub fn assert_tokens<'de, T>(value: &T, tokens: &'de [Token]) where T: Serialize + Deserialize<'de> + PartialEq + Debug { assert_ser_tokens(value, tokens); @@ -35,20 +35,20 @@ pub fn assert_ser_tokens_error(value: &T, tokens: &[Token], error: Error) } /// Asserts that the given `tokens` deserialize into `value`. -pub fn assert_de_tokens<'de, T>(value: &T, tokens: &[Token]) +pub fn assert_de_tokens<'de, T>(value: &T, tokens: &'de [Token]) where T: Deserialize<'de> + PartialEq + Debug { - let mut de = Deserializer::new(tokens.to_vec().into_iter()); + let mut de = Deserializer::new(tokens); let v: Result = Deserialize::deserialize(&mut de); assert_eq!(v.as_ref(), Ok(value)); assert_eq!(de.next_token(), None); } /// Asserts that the given `tokens` yield `error` when deserializing. -pub fn assert_de_tokens_error<'de, T>(tokens: &[Token], error: Error) +pub fn assert_de_tokens_error<'de, T>(tokens: &'de [Token], error: Error) where T: Deserialize<'de> + PartialEq + Debug { - let mut de = Deserializer::new(tokens.to_vec().into_iter()); + let mut de = Deserializer::new(tokens); let v: Result = Deserialize::deserialize(&mut de); assert_eq!(v, Err(error)); // There may be one token left if a peek caused the error diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index d2441ac1..7a0918f6 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -1,5 +1,3 @@ -use std::iter; - use serde::de::{self, Deserialize, DeserializeSeed, EnumVisitor, MapVisitor, SeqVisitor, VariantVisitor, Visitor}; use serde::de::value::{ValueDeserializer, MapVisitorDeserializer, SeqVisitorDeserializer}; @@ -8,28 +6,29 @@ use error::Error; use token::Token; /// A `Deserializer` that reads from a list of tokens. -pub struct Deserializer - where I: Iterator -{ - tokens: iter::Peekable, +pub struct Deserializer<'de> { + tokens: &'de [Token], } -impl Deserializer - where I: Iterator -{ +impl<'de> Deserializer<'de> { /// Creates the deserializer. - pub fn new(tokens: I) -> Deserializer { - Deserializer { tokens: tokens.peekable() } + pub fn new(tokens: &'de [Token]) -> Self { + Deserializer { tokens: tokens } } /// Pulls the next token off of the deserializer, ignoring it. pub fn next_token(&mut self) -> Option { - self.tokens.next() + if let Some((&first, rest)) = self.tokens.split_first() { + self.tokens = rest; + Some(first) + } else { + None + } } /// Pulls the next token off of the deserializer and checks if it matches an expected token. pub fn expect_token(&mut self, expected: Token) -> Result<(), Error> { - match self.tokens.next() { + match self.next_token() { Some(token) => { if expected == token { Ok(()) @@ -41,7 +40,7 @@ impl Deserializer } } - fn visit_seq<'de, V>(&mut self, + fn visit_seq(&mut self, len: Option, sep: Token, end: Token, @@ -59,7 +58,7 @@ impl Deserializer Ok(value) } - fn visit_map<'de, V>(&mut self, + fn visit_map(&mut self, len: Option, sep: Token, end: Token, @@ -78,9 +77,7 @@ impl Deserializer } } -impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer - where I: Iterator -{ +impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { type Error = Error; forward_to_deserialize! { @@ -91,7 +88,7 @@ impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer fn deserialize(self, visitor: V) -> Result where V: Visitor<'de> { - match self.tokens.next() { + match self.next_token() { Some(Token::Bool(v)) => visitor.visit_bool(v), Some(Token::I8(v)) => visitor.visit_i8(v), Some(Token::I16(v)) => visitor.visit_i16(v), @@ -152,14 +149,14 @@ impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer fn deserialize_option(self, visitor: V) -> Result where V: Visitor<'de> { - match self.tokens.peek() { + match self.tokens.first() { Some(&Token::Unit) | Some(&Token::Option(false)) => { - self.tokens.next(); + self.next_token(); visitor.visit_none() } Some(&Token::Option(true)) => { - self.tokens.next(); + self.next_token(); visitor.visit_some(self) } Some(_) => visitor.visit_some(self), @@ -174,9 +171,9 @@ impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer -> Result where V: Visitor<'de> { - match self.tokens.peek() { + match self.tokens.first() { Some(&Token::EnumStart(n)) if name == n => { - self.tokens.next(); + self.next_token(); visitor.visit_enum(DeserializerEnumVisitor { de: self }) } @@ -187,7 +184,7 @@ impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer visitor.visit_enum(DeserializerEnumVisitor { de: self }) } Some(_) => { - let token = self.tokens.next().unwrap(); + let token = self.next_token().unwrap(); Err(Error::UnexpectedToken(token)) } None => Err(Error::EndOfTokens), @@ -197,9 +194,9 @@ impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer fn deserialize_unit_struct(self, name: &str, visitor: V) -> Result where V: Visitor<'de> { - match self.tokens.peek() { + match self.tokens.first() { Some(&Token::UnitStruct(n)) => { - self.tokens.next(); + self.next_token(); if name == n { visitor.visit_unit() } else { @@ -214,9 +211,9 @@ impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer fn deserialize_newtype_struct(self, name: &str, visitor: V) -> Result where V: Visitor<'de> { - match self.tokens.peek() { + match self.tokens.first() { Some(&Token::StructNewType(n)) => { - self.tokens.next(); + self.next_token(); if name == n { visitor.visit_newtype_struct(self) } else { @@ -231,9 +228,9 @@ impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer fn deserialize_seq_fixed_size(self, len: usize, visitor: V) -> Result where V: Visitor<'de> { - match self.tokens.peek() { + match self.tokens.first() { Some(&Token::SeqArrayStart(_)) => { - self.tokens.next(); + self.next_token(); self.visit_seq(Some(len), Token::SeqSep, Token::SeqEnd, visitor) } Some(_) => self.deserialize(visitor), @@ -244,26 +241,26 @@ impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer fn deserialize_tuple(self, len: usize, visitor: V) -> Result where V: Visitor<'de> { - match self.tokens.peek() { + match self.tokens.first() { Some(&Token::Unit) | Some(&Token::UnitStruct(_)) => { - self.tokens.next(); + self.next_token(); visitor.visit_unit() } Some(&Token::SeqStart(_)) => { - self.tokens.next(); + self.next_token(); self.visit_seq(Some(len), Token::SeqSep, Token::SeqEnd, visitor) } Some(&Token::SeqArrayStart(_)) => { - self.tokens.next(); + self.next_token(); self.visit_seq(Some(len), Token::SeqSep, Token::SeqEnd, visitor) } Some(&Token::TupleStart(_)) => { - self.tokens.next(); + self.next_token(); self.visit_seq(Some(len), Token::TupleSep, Token::TupleEnd, visitor) } Some(&Token::TupleStructStart(_, _)) => { - self.tokens.next(); + self.next_token(); self.visit_seq(Some(len), Token::TupleStructSep, Token::TupleStructEnd, @@ -281,13 +278,13 @@ impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer -> Result where V: Visitor<'de> { - match self.tokens.peek() { + match self.tokens.first() { Some(&Token::Unit) => { - self.tokens.next(); + self.next_token(); visitor.visit_unit() } Some(&Token::UnitStruct(n)) => { - self.tokens.next(); + self.next_token(); if name == n { visitor.visit_unit() } else { @@ -295,19 +292,19 @@ impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer } } Some(&Token::SeqStart(_)) => { - self.tokens.next(); + self.next_token(); self.visit_seq(Some(len), Token::SeqSep, Token::SeqEnd, visitor) } Some(&Token::SeqArrayStart(_)) => { - self.tokens.next(); + self.next_token(); self.visit_seq(Some(len), Token::SeqSep, Token::SeqEnd, visitor) } Some(&Token::TupleStart(_)) => { - self.tokens.next(); + self.next_token(); self.visit_seq(Some(len), Token::TupleSep, Token::TupleEnd, visitor) } Some(&Token::TupleStructStart(n, _)) => { - self.tokens.next(); + self.next_token(); if name == n { self.visit_seq(Some(len), Token::TupleStructSep, @@ -329,9 +326,9 @@ impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer -> Result where V: Visitor<'de> { - match self.tokens.peek() { + match self.tokens.first() { Some(&Token::StructStart(n, _)) => { - self.tokens.next(); + self.next_token(); if name == n { self.visit_map(Some(fields.len()), Token::StructSep, @@ -342,7 +339,7 @@ impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer } } Some(&Token::MapStart(_)) => { - self.tokens.next(); + self.next_token(); self.visit_map(Some(fields.len()), Token::MapSep, Token::MapEnd, visitor) } Some(_) => self.deserialize(visitor), @@ -353,27 +350,23 @@ impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer ////////////////////////////////////////////////////////////////////////// -struct DeserializerSeqVisitor<'a, I: 'a> - where I: Iterator -{ - de: &'a mut Deserializer, +struct DeserializerSeqVisitor<'a, 'de: 'a> { + de: &'a mut Deserializer<'de>, len: Option, sep: Token, end: Token, } -impl<'de, 'a, I> SeqVisitor<'de> for DeserializerSeqVisitor<'a, I> - where I: Iterator -{ +impl<'de, 'a> SeqVisitor<'de> for DeserializerSeqVisitor<'a, 'de> { type Error = Error; fn visit_seed(&mut self, seed: T) -> Result, Error> where T: DeserializeSeed<'de> { - if self.de.tokens.peek() == Some(&self.end) { + if self.de.tokens.first() == Some(&self.end) { return Ok(None); } - match self.de.tokens.next() { + match self.de.next_token() { Some(ref token) if *token == self.sep => { self.len = self.len.map(|len| len.saturating_sub(1)); seed.deserialize(&mut *self.de).map(Some) @@ -391,27 +384,23 @@ impl<'de, 'a, I> SeqVisitor<'de> for DeserializerSeqVisitor<'a, I> ////////////////////////////////////////////////////////////////////////// -struct DeserializerMapVisitor<'a, I: 'a> - where I: Iterator -{ - de: &'a mut Deserializer, +struct DeserializerMapVisitor<'a, 'de: 'a> { + de: &'a mut Deserializer<'de>, len: Option, sep: Token, end: Token, } -impl<'de, 'a, I> MapVisitor<'de> for DeserializerMapVisitor<'a, I> - where I: Iterator -{ +impl<'de, 'a> MapVisitor<'de> for DeserializerMapVisitor<'a, 'de> { type Error = Error; fn visit_key_seed(&mut self, seed: K) -> Result, Error> where K: DeserializeSeed<'de> { - if self.de.tokens.peek() == Some(&self.end) { + if self.de.tokens.first() == Some(&self.end) { return Ok(None); } - match self.de.tokens.next() { + match self.de.next_token() { Some(ref token) if *token == self.sep => { self.len = self.len.map(|len| len.saturating_sub(1)); seed.deserialize(&mut *self.de).map(Some) @@ -435,22 +424,18 @@ impl<'de, 'a, I> MapVisitor<'de> for DeserializerMapVisitor<'a, I> ////////////////////////////////////////////////////////////////////////// -struct DeserializerEnumVisitor<'a, I: 'a> - where I: Iterator -{ - de: &'a mut Deserializer, +struct DeserializerEnumVisitor<'a, 'de: 'a> { + de: &'a mut Deserializer<'de>, } -impl<'de, 'a, I> EnumVisitor<'de> for DeserializerEnumVisitor<'a, I> - where I: Iterator -{ +impl<'de, 'a> EnumVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { type Error = Error; type Variant = Self; fn visit_variant_seed(self, seed: V) -> Result<(V::Value, Self), Error> where V: DeserializeSeed<'de> { - match self.de.tokens.peek() { + match self.de.tokens.first() { Some(&Token::EnumUnit(_, v)) | Some(&Token::EnumNewType(_, v)) | Some(&Token::EnumSeqStart(_, v, _)) | @@ -468,15 +453,13 @@ impl<'de, 'a, I> EnumVisitor<'de> for DeserializerEnumVisitor<'a, I> } } -impl<'de, 'a, I> VariantVisitor<'de> for DeserializerEnumVisitor<'a, I> - where I: Iterator -{ +impl<'de, 'a> VariantVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { type Error = Error; fn visit_unit(self) -> Result<(), Error> { - match self.de.tokens.peek() { + match self.de.tokens.first() { Some(&Token::EnumUnit(_, _)) => { - self.de.tokens.next(); + self.de.next_token(); Ok(()) } Some(_) => Deserialize::deserialize(self.de), @@ -487,9 +470,9 @@ impl<'de, 'a, I> VariantVisitor<'de> for DeserializerEnumVisitor<'a, I> fn visit_newtype_seed(self, seed: T) -> Result where T: DeserializeSeed<'de> { - match self.de.tokens.peek() { + match self.de.tokens.first() { Some(&Token::EnumNewType(_, _)) => { - self.de.tokens.next(); + self.de.next_token(); seed.deserialize(self.de) } Some(_) => seed.deserialize(self.de), @@ -500,9 +483,9 @@ impl<'de, 'a, I> VariantVisitor<'de> for DeserializerEnumVisitor<'a, I> fn visit_tuple(self, len: usize, visitor: V) -> Result where V: Visitor<'de> { - match self.de.tokens.peek() { + match self.de.tokens.first() { Some(&Token::EnumSeqStart(_, _, enum_len)) => { - let token = self.de.tokens.next().unwrap(); + let token = self.de.next_token().unwrap(); if len == enum_len { self.de.visit_seq(Some(len), Token::EnumSeqSep, Token::EnumSeqEnd, visitor) @@ -511,7 +494,7 @@ impl<'de, 'a, I> VariantVisitor<'de> for DeserializerEnumVisitor<'a, I> } } Some(&Token::SeqStart(Some(enum_len))) => { - let token = self.de.tokens.next().unwrap(); + let token = self.de.next_token().unwrap(); if len == enum_len { self.de.visit_seq(Some(len), Token::SeqSep, Token::SeqEnd, visitor) @@ -527,9 +510,9 @@ impl<'de, 'a, I> VariantVisitor<'de> for DeserializerEnumVisitor<'a, I> fn visit_struct(self, fields: &'static [&'static str], visitor: V) -> Result where V: Visitor<'de> { - match self.de.tokens.peek() { + match self.de.tokens.first() { Some(&Token::EnumMapStart(_, _, enum_len)) => { - let token = self.de.tokens.next().unwrap(); + let token = self.de.next_token().unwrap(); if fields.len() == enum_len { self.de.visit_map(Some(fields.len()), @@ -541,7 +524,7 @@ impl<'de, 'a, I> VariantVisitor<'de> for DeserializerEnumVisitor<'a, I> } } Some(&Token::MapStart(Some(enum_len))) => { - let token = self.de.tokens.next().unwrap(); + let token = self.de.next_token().unwrap(); if fields.len() == enum_len { self.de.visit_map(Some(fields.len()), Token::MapSep, Token::MapEnd, visitor) @@ -557,17 +540,13 @@ impl<'de, 'a, I> VariantVisitor<'de> for DeserializerEnumVisitor<'a, I> ////////////////////////////////////////////////////////////////////////// -struct EnumMapVisitor<'a, I: 'a> - where I: Iterator -{ - de: &'a mut Deserializer, +struct EnumMapVisitor<'a, 'de: 'a> { + de: &'a mut Deserializer<'de>, variant: Option<&'a str>, } -impl<'a, I: 'a> EnumMapVisitor<'a, I> - where I: Iterator -{ - fn new(de: &'a mut Deserializer, variant: &'a str) -> Self { +impl<'a, 'de> EnumMapVisitor<'a, 'de> { + fn new(de: &'a mut Deserializer<'de>, variant: &'a str) -> Self { EnumMapVisitor { de: de, variant: Some(variant), @@ -575,9 +554,7 @@ impl<'a, I: 'a> EnumMapVisitor<'a, I> } } -impl<'de, 'a, I: 'a> MapVisitor<'de> for EnumMapVisitor<'a, I> - where I: Iterator -{ +impl<'de, 'a> MapVisitor<'de> for EnumMapVisitor<'a, 'de> { type Error = Error; fn visit_key_seed(&mut self, seed: K) -> Result, Error> @@ -592,7 +569,7 @@ impl<'de, 'a, I: 'a> MapVisitor<'de> for EnumMapVisitor<'a, I> fn visit_value_seed(&mut self, seed: V) -> Result where V: DeserializeSeed<'de> { - match self.de.tokens.peek() { + match self.de.tokens.first() { Some(&Token::EnumSeqSep) => { let value = { let visitor = DeserializerSeqVisitor { diff --git a/test_suite/tests/test_borrow.rs b/test_suite/tests/test_borrow.rs index f57ebb9c..4749456e 100644 --- a/test_suite/tests/test_borrow.rs +++ b/test_suite/tests/test_borrow.rs @@ -138,7 +138,7 @@ fn test_cow() { borrowed: Cow<'b, str>, } - let tokens = vec![ + let tokens = &[ Token::StructStart("Cows", 2), Token::StructSep, @@ -152,7 +152,7 @@ fn test_cow() { Token::StructEnd, ]; - let mut de = serde_test::Deserializer::new(tokens.into_iter()); + let mut de = serde_test::Deserializer::new(tokens); let cows = Cows::deserialize(&mut de).unwrap(); assert_eq!(de.next_token(), None); diff --git a/test_suite/tests/test_de.rs b/test_suite/tests/test_de.rs index daeaa4cb..1344355a 100644 --- a/test_suite/tests/test_de.rs +++ b/test_suite/tests/test_de.rs @@ -163,7 +163,7 @@ fn assert_de_tokens_ignore(ignorable_tokens: &[Token]) { ].into_iter()) .collect(); - let mut de = serde_test::Deserializer::new(concated_tokens.into_iter()); + let mut de = serde_test::Deserializer::new(&concated_tokens); let v: Result = Deserialize::deserialize(&mut de); // We run this test on every token stream for convenience, but From 93860d064331c1c22ece53d3278ca7b1c2a5014a Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 00:27:30 -0700 Subject: [PATCH 017/177] Require slice of tokens in serde_test::Serializer --- serde_test/src/assert.rs | 4 +- serde_test/src/ser.rs | 141 +++++++++++++++++---------------------- 2 files changed, 63 insertions(+), 82 deletions(-) diff --git a/serde_test/src/assert.rs b/serde_test/src/assert.rs index edfadf0d..ccfa4c26 100644 --- a/serde_test/src/assert.rs +++ b/serde_test/src/assert.rs @@ -19,7 +19,7 @@ pub fn assert_tokens<'de, T>(value: &T, tokens: &'de [Token]) pub fn assert_ser_tokens(value: &T, tokens: &[Token]) where T: Serialize { - let mut ser = Serializer::new(tokens.iter()); + let mut ser = Serializer::new(tokens); assert_eq!(Serialize::serialize(value, &mut ser), Ok(())); assert_eq!(ser.next_token(), None); } @@ -28,7 +28,7 @@ pub fn assert_ser_tokens(value: &T, tokens: &[Token]) pub fn assert_ser_tokens_error(value: &T, tokens: &[Token], error: Error) where T: Serialize + PartialEq + Debug { - let mut ser = Serializer::new(tokens.iter()); + let mut ser = Serializer::new(tokens); let v: Result<(), Error> = Serialize::serialize(value, &mut ser); assert_eq!(v.as_ref(), Err(&error)); assert_eq!(ser.next_token(), None); diff --git a/serde_test/src/ser.rs b/serde_test/src/ser.rs index c38b1a04..2ad6ffce 100644 --- a/serde_test/src/ser.rs +++ b/serde_test/src/ser.rs @@ -1,38 +1,35 @@ -use std::marker::PhantomData; - use serde::{ser, Serialize}; use error::Error; use token::Token; /// A `Serializer` that ensures that a value serializes to a given list of tokens. -pub struct Serializer<'a, I> - where I: Iterator -{ - tokens: I, - phantom: PhantomData<&'a Token>, +pub struct Serializer<'a> { + tokens: &'a [Token], } -impl<'a, I> Serializer<'a, I> - where I: Iterator -{ +impl<'a> Serializer<'a> { /// Creates the serializer. - pub fn new(tokens: I) -> Serializer<'a, I> { + pub fn new(tokens: &'a [Token]) -> Self { Serializer { tokens: tokens, - phantom: PhantomData, } } /// Pulls the next token off of the serializer, ignoring it. - pub fn next_token(&mut self) -> Option<&'a Token> { - self.tokens.next() + pub fn next_token(&mut self) -> Option<&Token> { + if let Some((first, rest)) = self.tokens.split_first() { + self.tokens = rest; + Some(first) + } else { + None + } } } macro_rules! assert_next_token { ($self:ident, $expected:ident($arg:expr)) => { - match $self.tokens.next() { + match $self.next_token() { Some(&Token::$expected(v)) if v == $arg => {} Some(other) => { panic!("expected {}({:?}) but serialized as {:?}", stringify!($expected), $arg, other); @@ -44,9 +41,7 @@ macro_rules! assert_next_token { } } -impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I> - where I: Iterator -{ +impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { type Ok = (); type Error = Error; @@ -59,62 +54,62 @@ impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I> type SerializeStructVariant = Self; fn serialize_bool(self, v: bool) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::Bool(v))); + assert_eq!(self.next_token(), Some(&Token::Bool(v))); Ok(()) } fn serialize_i8(self, v: i8) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::I8(v))); + assert_eq!(self.next_token(), Some(&Token::I8(v))); Ok(()) } fn serialize_i16(self, v: i16) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::I16(v))); + assert_eq!(self.next_token(), Some(&Token::I16(v))); Ok(()) } fn serialize_i32(self, v: i32) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::I32(v))); + assert_eq!(self.next_token(), Some(&Token::I32(v))); Ok(()) } fn serialize_i64(self, v: i64) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::I64(v))); + assert_eq!(self.next_token(), Some(&Token::I64(v))); Ok(()) } fn serialize_u8(self, v: u8) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::U8(v))); + assert_eq!(self.next_token(), Some(&Token::U8(v))); Ok(()) } fn serialize_u16(self, v: u16) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::U16(v))); + assert_eq!(self.next_token(), Some(&Token::U16(v))); Ok(()) } fn serialize_u32(self, v: u32) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::U32(v))); + assert_eq!(self.next_token(), Some(&Token::U32(v))); Ok(()) } fn serialize_u64(self, v: u64) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::U64(v))); + assert_eq!(self.next_token(), Some(&Token::U64(v))); Ok(()) } fn serialize_f32(self, v: f32) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::F32(v))); + assert_eq!(self.next_token(), Some(&Token::F32(v))); Ok(()) } fn serialize_f64(self, v: f64) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::F64(v))); + assert_eq!(self.next_token(), Some(&Token::F64(v))); Ok(()) } fn serialize_char(self, v: char) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::Char(v))); + assert_eq!(self.next_token(), Some(&Token::Char(v))); Ok(()) } @@ -129,12 +124,12 @@ impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I> } fn serialize_unit(self) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::Unit)); + assert_eq!(self.next_token(), Some(&Token::Unit)); Ok(()) } fn serialize_unit_struct(self, name: &'static str) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::UnitStruct(name))); + assert_eq!(self.next_token(), Some(&Token::UnitStruct(name))); Ok(()) } @@ -143,14 +138,14 @@ impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I> _variant_index: usize, variant: &'static str) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::EnumUnit(name, variant))); + assert_eq!(self.next_token(), Some(&Token::EnumUnit(name, variant))); Ok(()) } fn serialize_newtype_struct(self, name: &'static str, value: &T) -> Result<(), Error> where T: Serialize { - assert_eq!(self.tokens.next(), Some(&Token::StructNewType(name))); + assert_eq!(self.next_token(), Some(&Token::StructNewType(name))); value.serialize(self) } @@ -162,39 +157,39 @@ impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I> -> Result<(), Error> where T: Serialize { - assert_eq!(self.tokens.next(), Some(&Token::EnumNewType(name, variant))); + assert_eq!(self.next_token(), Some(&Token::EnumNewType(name, variant))); value.serialize(self) } fn serialize_none(self) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::Option(false))); + assert_eq!(self.next_token(), Some(&Token::Option(false))); Ok(()) } fn serialize_some(self, value: &T) -> Result<(), Error> where T: Serialize { - assert_eq!(self.tokens.next(), Some(&Token::Option(true))); + assert_eq!(self.next_token(), Some(&Token::Option(true))); value.serialize(self) } fn serialize_seq(self, len: Option) -> Result { - assert_eq!(self.tokens.next(), Some(&Token::SeqStart(len))); + assert_eq!(self.next_token(), Some(&Token::SeqStart(len))); Ok(self) } fn serialize_seq_fixed_size(self, len: usize) -> Result { - assert_eq!(self.tokens.next(), Some(&Token::SeqArrayStart(len))); + assert_eq!(self.next_token(), Some(&Token::SeqArrayStart(len))); Ok(self) } fn serialize_tuple(self, len: usize) -> Result { - assert_eq!(self.tokens.next(), Some(&Token::TupleStart(len))); + assert_eq!(self.next_token(), Some(&Token::TupleStart(len))); Ok(self) } fn serialize_tuple_struct(self, name: &'static str, len: usize) -> Result { - assert_eq!(self.tokens.next(), + assert_eq!(self.next_token(), Some(&Token::TupleStructStart(name, len))); Ok(self) } @@ -205,18 +200,18 @@ impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I> variant: &'static str, len: usize) -> Result { - assert_eq!(self.tokens.next(), + assert_eq!(self.next_token(), Some(&Token::EnumSeqStart(name, variant, len))); Ok(self) } fn serialize_map(self, len: Option) -> Result { - assert_eq!(self.tokens.next(), Some(&Token::MapStart(len))); + assert_eq!(self.next_token(), Some(&Token::MapStart(len))); Ok(self) } fn serialize_struct(self, name: &'static str, len: usize) -> Result { - assert_eq!(self.tokens.next(), Some(&Token::StructStart(name, len))); + assert_eq!(self.next_token(), Some(&Token::StructStart(name, len))); Ok(self) } @@ -226,98 +221,88 @@ impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I> variant: &'static str, len: usize) -> Result { - assert_eq!(self.tokens.next(), + assert_eq!(self.next_token(), Some(&Token::EnumMapStart(name, variant, len))); Ok(self) } } -impl<'s, 'a, I> ser::SerializeSeq for &'s mut Serializer<'a, I> - where I: Iterator -{ +impl<'s, 'a> ser::SerializeSeq for &'s mut Serializer<'a> { type Ok = (); type Error = Error; fn serialize_element(&mut self, value: &T) -> Result<(), Error> where T: Serialize { - assert_eq!(self.tokens.next(), Some(&Token::SeqSep)); + assert_eq!(self.next_token(), Some(&Token::SeqSep)); value.serialize(&mut **self) } fn end(self) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::SeqEnd)); + assert_eq!(self.next_token(), Some(&Token::SeqEnd)); Ok(()) } } -impl<'s, 'a, I> ser::SerializeTuple for &'s mut Serializer<'a, I> - where I: Iterator -{ +impl<'s, 'a> ser::SerializeTuple for &'s mut Serializer<'a> { type Ok = (); type Error = Error; fn serialize_element(&mut self, value: &T) -> Result<(), Error> where T: Serialize { - assert_eq!(self.tokens.next(), Some(&Token::TupleSep)); + assert_eq!(self.next_token(), Some(&Token::TupleSep)); value.serialize(&mut **self) } fn end(self) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::TupleEnd)); + assert_eq!(self.next_token(), Some(&Token::TupleEnd)); Ok(()) } } -impl<'s, 'a, I> ser::SerializeTupleStruct for &'s mut Serializer<'a, I> - where I: Iterator -{ +impl<'s, 'a> ser::SerializeTupleStruct for &'s mut Serializer<'a> { type Ok = (); type Error = Error; fn serialize_field(&mut self, value: &T) -> Result<(), Error> where T: Serialize { - assert_eq!(self.tokens.next(), Some(&Token::TupleStructSep)); + assert_eq!(self.next_token(), Some(&Token::TupleStructSep)); value.serialize(&mut **self) } fn end(self) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::TupleStructEnd)); + assert_eq!(self.next_token(), Some(&Token::TupleStructEnd)); Ok(()) } } -impl<'s, 'a, I> ser::SerializeTupleVariant for &'s mut Serializer<'a, I> - where I: Iterator -{ +impl<'s, 'a> ser::SerializeTupleVariant for &'s mut Serializer<'a> { type Ok = (); type Error = Error; fn serialize_field(&mut self, value: &T) -> Result<(), Error> where T: Serialize { - assert_eq!(self.tokens.next(), Some(&Token::EnumSeqSep)); + assert_eq!(self.next_token(), Some(&Token::EnumSeqSep)); value.serialize(&mut **self) } fn end(self) -> Result<(), Error> { - assert_eq!(self.tokens.next(), Some(&Token::EnumSeqEnd)); + assert_eq!(self.next_token(), Some(&Token::EnumSeqEnd)); Ok(()) } } -impl<'s, 'a, I> ser::SerializeMap for &'s mut Serializer<'a, I> - where I: Iterator -{ +impl<'s, 'a> ser::SerializeMap for &'s mut Serializer<'a> { type Ok = (); type Error = Error; fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> where T: Serialize { - assert_eq!(self.tokens.next(), Some(&Token::MapSep)); + assert_eq!(self.next_token(), Some(&Token::MapSep)); key.serialize(&mut **self) } @@ -328,14 +313,12 @@ impl<'s, 'a, I> ser::SerializeMap for &'s mut Serializer<'a, I> } fn end(self) -> Result<(), Self::Error> { - assert_eq!(self.tokens.next(), Some(&Token::MapEnd)); + assert_eq!(self.next_token(), Some(&Token::MapEnd)); Ok(()) } } -impl<'s, 'a, I> ser::SerializeStruct for &'s mut Serializer<'a, I> - where I: Iterator -{ +impl<'s, 'a> ser::SerializeStruct for &'s mut Serializer<'a> { type Ok = (); type Error = Error; @@ -345,20 +328,18 @@ impl<'s, 'a, I> ser::SerializeStruct for &'s mut Serializer<'a, I> -> Result<(), Self::Error> where T: Serialize { - assert_eq!(self.tokens.next(), Some(&Token::StructSep)); + assert_eq!(self.next_token(), Some(&Token::StructSep)); try!(key.serialize(&mut **self)); value.serialize(&mut **self) } fn end(self) -> Result<(), Self::Error> { - assert_eq!(self.tokens.next(), Some(&Token::StructEnd)); + assert_eq!(self.next_token(), Some(&Token::StructEnd)); Ok(()) } } -impl<'s, 'a, I> ser::SerializeStructVariant for &'s mut Serializer<'a, I> - where I: Iterator -{ +impl<'s, 'a> ser::SerializeStructVariant for &'s mut Serializer<'a> { type Ok = (); type Error = Error; @@ -368,13 +349,13 @@ impl<'s, 'a, I> ser::SerializeStructVariant for &'s mut Serializer<'a, I> -> Result<(), Self::Error> where T: Serialize { - assert_eq!(self.tokens.next(), Some(&Token::EnumMapSep)); + assert_eq!(self.next_token(), Some(&Token::EnumMapSep)); try!(key.serialize(&mut **self)); value.serialize(&mut **self) } fn end(self) -> Result<(), Self::Error> { - assert_eq!(self.tokens.next(), Some(&Token::EnumMapEnd)); + assert_eq!(self.next_token(), Some(&Token::EnumMapEnd)); Ok(()) } } From afaab12b66f8047a1e28979ae534b6d97951ddbc Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 01:06:42 -0700 Subject: [PATCH 018/177] Improve assert_ser_tokens error messages --- serde_test/src/ser.rs | 110 ++++++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 51 deletions(-) diff --git a/serde_test/src/ser.rs b/serde_test/src/ser.rs index 2ad6ffce..1a105f33 100644 --- a/serde_test/src/ser.rs +++ b/serde_test/src/ser.rs @@ -17,8 +17,8 @@ impl<'a> Serializer<'a> { } /// Pulls the next token off of the serializer, ignoring it. - pub fn next_token(&mut self) -> Option<&Token> { - if let Some((first, rest)) = self.tokens.split_first() { + pub fn next_token(&mut self) -> Option { + if let Some((&first, rest)) = self.tokens.split_first() { self.tokens = rest; Some(first) } else { @@ -28,17 +28,28 @@ impl<'a> Serializer<'a> { } macro_rules! assert_next_token { - ($self:ident, $expected:ident($arg:expr)) => { + ($self:ident, $expected:ident($a:expr)) => { + assert_next_token!($self, $expected { a: $a }); + }; + ($self:ident, $expected:ident($a:expr, $b:expr)) => { + assert_next_token!($self, $expected { a: $a, b: $b }); + }; + ($self:ident, $expected:ident($a:expr, $b:expr, $c:expr)) => { + assert_next_token!($self, $expected { a: $a, b: $b, c: $c }); + }; + ($self:ident, $expected:ident $({ $($n:ident: $v:expr),* })*) => { match $self.next_token() { - Some(&Token::$expected(v)) if v == $arg => {} + Some(Token::$expected $(($($n),*))*) $(if $($n == $v)&&*)* => {} Some(other) => { - panic!("expected {}({:?}) but serialized as {:?}", stringify!($expected), $arg, other); + panic!("expected Token::{} but serialized as {:?}", + stringify!($expected), other); } None => { - panic!("expected {}({:?}) after end of serialized tokens", stringify!($expected), $arg); + panic!("expected Token::{} after end of serialized tokens", + stringify!($expected)); } } - } + }; } impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { @@ -54,62 +65,62 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { type SerializeStructVariant = Self; fn serialize_bool(self, v: bool) -> Result<(), Error> { - assert_eq!(self.next_token(), Some(&Token::Bool(v))); + assert_next_token!(self, Bool(v)); Ok(()) } fn serialize_i8(self, v: i8) -> Result<(), Error> { - assert_eq!(self.next_token(), Some(&Token::I8(v))); + assert_next_token!(self, I8(v)); Ok(()) } fn serialize_i16(self, v: i16) -> Result<(), Error> { - assert_eq!(self.next_token(), Some(&Token::I16(v))); + assert_next_token!(self, I16(v)); Ok(()) } fn serialize_i32(self, v: i32) -> Result<(), Error> { - assert_eq!(self.next_token(), Some(&Token::I32(v))); + assert_next_token!(self, I32(v)); Ok(()) } fn serialize_i64(self, v: i64) -> Result<(), Error> { - assert_eq!(self.next_token(), Some(&Token::I64(v))); + assert_next_token!(self, I64(v)); Ok(()) } fn serialize_u8(self, v: u8) -> Result<(), Error> { - assert_eq!(self.next_token(), Some(&Token::U8(v))); + assert_next_token!(self, U8(v)); Ok(()) } fn serialize_u16(self, v: u16) -> Result<(), Error> { - assert_eq!(self.next_token(), Some(&Token::U16(v))); + assert_next_token!(self, U16(v)); Ok(()) } fn serialize_u32(self, v: u32) -> Result<(), Error> { - assert_eq!(self.next_token(), Some(&Token::U32(v))); + assert_next_token!(self, U32(v)); Ok(()) } fn serialize_u64(self, v: u64) -> Result<(), Error> { - assert_eq!(self.next_token(), Some(&Token::U64(v))); + assert_next_token!(self, U64(v)); Ok(()) } fn serialize_f32(self, v: f32) -> Result<(), Error> { - assert_eq!(self.next_token(), Some(&Token::F32(v))); + assert_next_token!(self, F32(v)); Ok(()) } fn serialize_f64(self, v: f64) -> Result<(), Error> { - assert_eq!(self.next_token(), Some(&Token::F64(v))); + assert_next_token!(self, F64(v)); Ok(()) } fn serialize_char(self, v: char) -> Result<(), Error> { - assert_eq!(self.next_token(), Some(&Token::Char(v))); + assert_next_token!(self, Char(v)); Ok(()) } @@ -124,12 +135,12 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { } fn serialize_unit(self) -> Result<(), Error> { - assert_eq!(self.next_token(), Some(&Token::Unit)); + assert_next_token!(self, Unit); Ok(()) } fn serialize_unit_struct(self, name: &'static str) -> Result<(), Error> { - assert_eq!(self.next_token(), Some(&Token::UnitStruct(name))); + assert_next_token!(self, UnitStruct(name)); Ok(()) } @@ -138,14 +149,14 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { _variant_index: usize, variant: &'static str) -> Result<(), Error> { - assert_eq!(self.next_token(), Some(&Token::EnumUnit(name, variant))); + assert_next_token!(self, EnumUnit(name, variant)); Ok(()) } fn serialize_newtype_struct(self, name: &'static str, value: &T) -> Result<(), Error> where T: Serialize { - assert_eq!(self.next_token(), Some(&Token::StructNewType(name))); + assert_next_token!(self, StructNewType(name)); value.serialize(self) } @@ -157,40 +168,39 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { -> Result<(), Error> where T: Serialize { - assert_eq!(self.next_token(), Some(&Token::EnumNewType(name, variant))); + assert_next_token!(self, EnumNewType(name, variant)); value.serialize(self) } fn serialize_none(self) -> Result<(), Error> { - assert_eq!(self.next_token(), Some(&Token::Option(false))); + assert_next_token!(self, Option(false)); Ok(()) } fn serialize_some(self, value: &T) -> Result<(), Error> where T: Serialize { - assert_eq!(self.next_token(), Some(&Token::Option(true))); + assert_next_token!(self, Option(true)); value.serialize(self) } fn serialize_seq(self, len: Option) -> Result { - assert_eq!(self.next_token(), Some(&Token::SeqStart(len))); + assert_next_token!(self, SeqStart(len)); Ok(self) } fn serialize_seq_fixed_size(self, len: usize) -> Result { - assert_eq!(self.next_token(), Some(&Token::SeqArrayStart(len))); + assert_next_token!(self, SeqArrayStart(len)); Ok(self) } fn serialize_tuple(self, len: usize) -> Result { - assert_eq!(self.next_token(), Some(&Token::TupleStart(len))); + assert_next_token!(self, TupleStart(len)); Ok(self) } fn serialize_tuple_struct(self, name: &'static str, len: usize) -> Result { - assert_eq!(self.next_token(), - Some(&Token::TupleStructStart(name, len))); + assert_next_token!(self, TupleStructStart(name, len)); Ok(self) } @@ -200,18 +210,17 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { variant: &'static str, len: usize) -> Result { - assert_eq!(self.next_token(), - Some(&Token::EnumSeqStart(name, variant, len))); + assert_next_token!(self, EnumSeqStart(name, variant, len)); Ok(self) } fn serialize_map(self, len: Option) -> Result { - assert_eq!(self.next_token(), Some(&Token::MapStart(len))); + assert_next_token!(self, MapStart(len)); Ok(self) } fn serialize_struct(self, name: &'static str, len: usize) -> Result { - assert_eq!(self.next_token(), Some(&Token::StructStart(name, len))); + assert_next_token!(self, StructStart(name, len)); Ok(self) } @@ -221,8 +230,7 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { variant: &'static str, len: usize) -> Result { - assert_eq!(self.next_token(), - Some(&Token::EnumMapStart(name, variant, len))); + assert_next_token!(self, EnumMapStart(name, variant, len)); Ok(self) } } @@ -234,12 +242,12 @@ impl<'s, 'a> ser::SerializeSeq for &'s mut Serializer<'a> { fn serialize_element(&mut self, value: &T) -> Result<(), Error> where T: Serialize { - assert_eq!(self.next_token(), Some(&Token::SeqSep)); + assert_next_token!(self, SeqSep); value.serialize(&mut **self) } fn end(self) -> Result<(), Error> { - assert_eq!(self.next_token(), Some(&Token::SeqEnd)); + assert_next_token!(self, SeqEnd); Ok(()) } } @@ -251,12 +259,12 @@ impl<'s, 'a> ser::SerializeTuple for &'s mut Serializer<'a> { fn serialize_element(&mut self, value: &T) -> Result<(), Error> where T: Serialize { - assert_eq!(self.next_token(), Some(&Token::TupleSep)); + assert_next_token!(self, TupleSep); value.serialize(&mut **self) } fn end(self) -> Result<(), Error> { - assert_eq!(self.next_token(), Some(&Token::TupleEnd)); + assert_next_token!(self, TupleEnd); Ok(()) } } @@ -268,12 +276,12 @@ impl<'s, 'a> ser::SerializeTupleStruct for &'s mut Serializer<'a> { fn serialize_field(&mut self, value: &T) -> Result<(), Error> where T: Serialize { - assert_eq!(self.next_token(), Some(&Token::TupleStructSep)); + assert_next_token!(self, TupleStructSep); value.serialize(&mut **self) } fn end(self) -> Result<(), Error> { - assert_eq!(self.next_token(), Some(&Token::TupleStructEnd)); + assert_next_token!(self, TupleStructEnd); Ok(()) } } @@ -285,12 +293,12 @@ impl<'s, 'a> ser::SerializeTupleVariant for &'s mut Serializer<'a> { fn serialize_field(&mut self, value: &T) -> Result<(), Error> where T: Serialize { - assert_eq!(self.next_token(), Some(&Token::EnumSeqSep)); + assert_next_token!(self, EnumSeqSep); value.serialize(&mut **self) } fn end(self) -> Result<(), Error> { - assert_eq!(self.next_token(), Some(&Token::EnumSeqEnd)); + assert_next_token!(self, EnumSeqEnd); Ok(()) } } @@ -302,7 +310,7 @@ impl<'s, 'a> ser::SerializeMap for &'s mut Serializer<'a> { fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> where T: Serialize { - assert_eq!(self.next_token(), Some(&Token::MapSep)); + assert_next_token!(self, MapSep); key.serialize(&mut **self) } @@ -313,7 +321,7 @@ impl<'s, 'a> ser::SerializeMap for &'s mut Serializer<'a> { } fn end(self) -> Result<(), Self::Error> { - assert_eq!(self.next_token(), Some(&Token::MapEnd)); + assert_next_token!(self, MapEnd); Ok(()) } } @@ -328,13 +336,13 @@ impl<'s, 'a> ser::SerializeStruct for &'s mut Serializer<'a> { -> Result<(), Self::Error> where T: Serialize { - assert_eq!(self.next_token(), Some(&Token::StructSep)); + assert_next_token!(self, StructSep); try!(key.serialize(&mut **self)); value.serialize(&mut **self) } fn end(self) -> Result<(), Self::Error> { - assert_eq!(self.next_token(), Some(&Token::StructEnd)); + assert_next_token!(self, StructEnd); Ok(()) } } @@ -349,13 +357,13 @@ impl<'s, 'a> ser::SerializeStructVariant for &'s mut Serializer<'a> { -> Result<(), Self::Error> where T: Serialize { - assert_eq!(self.next_token(), Some(&Token::EnumMapSep)); + assert_next_token!(self, EnumMapSep); try!(key.serialize(&mut **self)); value.serialize(&mut **self) } fn end(self) -> Result<(), Self::Error> { - assert_eq!(self.next_token(), Some(&Token::EnumMapEnd)); + assert_next_token!(self, EnumMapEnd); Ok(()) } } From 21adee8f408b71add3f65f3f19bc49a88c8ae800 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 01:15:42 -0700 Subject: [PATCH 019/177] Partial support for EnumStart in assert_ser_tokens --- serde_test/src/ser.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/serde_test/src/ser.rs b/serde_test/src/ser.rs index 1a105f33..e8af6ee9 100644 --- a/serde_test/src/ser.rs +++ b/serde_test/src/ser.rs @@ -149,7 +149,13 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { _variant_index: usize, variant: &'static str) -> Result<(), Error> { - assert_next_token!(self, EnumUnit(name, variant)); + if self.tokens.first() == Some(&Token::EnumStart(name)) { + self.next_token(); + assert_next_token!(self, Str(variant)); + assert_next_token!(self, Unit); + } else { + assert_next_token!(self, EnumUnit(name, variant)); + } Ok(()) } @@ -168,7 +174,12 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { -> Result<(), Error> where T: Serialize { - assert_next_token!(self, EnumNewType(name, variant)); + if self.tokens.first() == Some(&Token::EnumStart(name)) { + self.next_token(); + assert_next_token!(self, Str(variant)); + } else { + assert_next_token!(self, EnumNewType(name, variant)); + } value.serialize(self) } From b2377d4c0b012573f54772990bcb0a653e3a8688 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 08:54:30 -0700 Subject: [PATCH 020/177] Allow enums in ignored map value in serde_test --- serde_test/src/de.rs | 64 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index 7a0918f6..5437ffa2 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -132,12 +132,35 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { Some(Token::StructStart(_, len)) => { self.visit_map(Some(len), Token::StructSep, Token::StructEnd, visitor) } + Some(Token::EnumStart(_)) => { + let variant = self.next_token().ok_or(Error::EndOfTokens)?; + let next = *self.tokens.first().ok_or(Error::EndOfTokens)?; + match (variant, next) { + (Token::Str(variant), Token::Unit) => { + self.next_token(); + visitor.visit_str(variant) + } + (Token::Bytes(variant), Token::Unit) => { + self.next_token(); + visitor.visit_bytes(variant) + } + (Token::U32(variant), Token::Unit) => { + self.next_token(); + visitor.visit_u32(variant) + } + (variant, Token::Unit) => { + Err(Error::UnexpectedToken(variant)) + } + (variant, _) => { + visitor.visit_map(EnumMapVisitor::new(self, variant)) + } + } + } Some(Token::EnumUnit(_, variant)) => visitor.visit_str(variant), - Some(Token::EnumStart(variant)) | Some(Token::EnumNewType(_, variant)) | Some(Token::EnumSeqStart(_, variant, _)) | Some(Token::EnumMapStart(_, variant, _)) => { - visitor.visit_map(EnumMapVisitor::new(self, variant)) + visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant))) } Some(token) => Err(Error::UnexpectedToken(token)), None => Err(Error::EndOfTokens), @@ -542,11 +565,11 @@ impl<'de, 'a> VariantVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { struct EnumMapVisitor<'a, 'de: 'a> { de: &'a mut Deserializer<'de>, - variant: Option<&'a str>, + variant: Option, } impl<'a, 'de> EnumMapVisitor<'a, 'de> { - fn new(de: &'a mut Deserializer<'de>, variant: &'a str) -> Self { + fn new(de: &'a mut Deserializer<'de>, variant: Token) -> Self { EnumMapVisitor { de: de, variant: Some(variant), @@ -561,7 +584,18 @@ impl<'de, 'a> MapVisitor<'de> for EnumMapVisitor<'a, 'de> { where K: DeserializeSeed<'de> { match self.variant.take() { - Some(variant) => seed.deserialize(variant.into_deserializer()).map(Some), + Some(Token::Str(variant)) => { + seed.deserialize(variant.into_deserializer()).map(Some) + } + Some(Token::Bytes(variant)) => { + seed.deserialize(BytesDeserializer { value: variant }).map(Some) + } + Some(Token::U32(variant)) => { + seed.deserialize(variant.into_deserializer()).map(Some) + } + Some(other) => { + Err(Error::UnexpectedToken(other)) + } None => Ok(None), } } @@ -600,3 +634,23 @@ impl<'de, 'a> MapVisitor<'de> for EnumMapVisitor<'a, 'de> { } } } + +struct BytesDeserializer { + value: &'static [u8], +} + +impl<'de> de::Deserializer<'de> for BytesDeserializer { + type Error = Error; + + fn deserialize(self, visitor: V) -> Result + where V: de::Visitor<'de> + { + visitor.visit_bytes(self.value) + } + + forward_to_deserialize! { + bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option + seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct + struct struct_field tuple enum ignored_any byte_buf + } +} From c3d9b42cdf402bf249a1b3f272451694cdf21182 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 09:19:22 -0700 Subject: [PATCH 021/177] Fix handling of option and newtype in IgnoredAny --- serde/src/de/ignored_any.rs | 8 ++++---- serde_test/src/de.rs | 3 ++- test_suite/tests/test_de.rs | 17 +++++++++-------- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/serde/src/de/ignored_any.rs b/serde/src/de/ignored_any.rs index d51f7386..3ee68433 100644 --- a/serde/src/de/ignored_any.rs +++ b/serde/src/de/ignored_any.rs @@ -53,17 +53,17 @@ impl<'de> Deserialize<'de> for IgnoredAny { } #[inline] - fn visit_some(self, _: D) -> Result + fn visit_some(self, deserializer: D) -> Result where D: Deserializer<'de> { - Ok(IgnoredAny) + IgnoredAny::deserialize(deserializer) } #[inline] - fn visit_newtype_struct(self, _: D) -> Result + fn visit_newtype_struct(self, deserializer: D) -> Result where D: Deserializer<'de> { - Ok(IgnoredAny) + IgnoredAny::deserialize(deserializer) } #[inline] diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index 5437ffa2..28989187 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -111,6 +111,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { Some(Token::Option(true)) => visitor.visit_some(self), Some(Token::Unit) => visitor.visit_unit(), Some(Token::UnitStruct(_name)) => visitor.visit_unit(), + Some(Token::StructNewType(_name)) => visitor.visit_newtype_struct(self), Some(Token::SeqStart(len)) => { self.visit_seq(len, Token::SeqSep, Token::SeqEnd, visitor) } @@ -182,7 +183,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { self.next_token(); visitor.visit_some(self) } - Some(_) => visitor.visit_some(self), + Some(_) => self.deserialize(visitor), None => Err(Error::EndOfTokens), } } diff --git a/test_suite/tests/test_de.rs b/test_suite/tests/test_de.rs index f5817f2b..2d012259 100644 --- a/test_suite/tests/test_de.rs +++ b/test_suite/tests/test_de.rs @@ -35,6 +35,9 @@ mod macros; #[derive(Copy, Clone, PartialEq, Debug, Deserialize)] struct UnitStruct; +#[derive(PartialEq, Debug, Deserialize)] +struct NewtypeStruct(i32); + #[derive(PartialEq, Debug, Deserialize)] struct TupleStruct(i32, i32, i32); @@ -166,13 +169,6 @@ fn assert_de_tokens_ignore(ignorable_tokens: &[Token]) { let mut de = serde_test::Deserializer::new(&concated_tokens); let v: Result = Deserialize::deserialize(&mut de); - // We run this test on every token stream for convenience, but - // some token streams don't make sense embedded as a map value, - // so we ignore those. SyntaxError is the real sign of trouble. - if let Err(Error::UnexpectedToken(_)) = v { - return; - } - assert_eq!(v.as_ref(), Ok(&expected)); assert_eq!(de.next_token(), None); } @@ -225,7 +221,6 @@ declare_tests! { test_option { None:: => &[Token::Unit], None:: => &[Token::Option(false)], - Some(1) => &[Token::I32(1)], Some(1) => &[ Token::Option(true), Token::I32(1), @@ -260,6 +255,12 @@ declare_tests! { Token::SeqEnd, ], } + test_newtype_struct { + NewtypeStruct(1) => &[ + Token::StructNewType("NewtypeStruct"), + Token::I32(1), + ], + } test_tuple_struct { TupleStruct(1, 2, 3) => &[ Token::SeqStart(Some(3)), From 67ed7a0eddb77d0278fafff95239e1d4cf29b84a Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 09:42:24 -0700 Subject: [PATCH 022/177] Eliminate Sep tokens in serde_test --- serde_test/src/de.rs | 95 +++++++--------- serde_test/src/ser.rs | 7 -- serde_test/src/token.rs | 26 ----- test_suite/tests/test_annotations.rs | 71 +----------- test_suite/tests/test_borrow.rs | 9 -- test_suite/tests/test_bytes.rs | 6 -- test_suite/tests/test_de.rs | 156 +-------------------------- test_suite/tests/test_macros.rs | 142 ------------------------ test_suite/tests/test_ser.rs | 54 ---------- 9 files changed, 47 insertions(+), 519 deletions(-) diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index 28989187..2811241e 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -42,7 +42,6 @@ impl<'de> Deserializer<'de> { fn visit_seq(&mut self, len: Option, - sep: Token, end: Token, visitor: V) -> Result @@ -51,7 +50,6 @@ impl<'de> Deserializer<'de> { let value = try!(visitor.visit_seq(DeserializerSeqVisitor { de: self, len: len, - sep: sep, end: end.clone(), })); try!(self.expect_token(end)); @@ -60,7 +58,6 @@ impl<'de> Deserializer<'de> { fn visit_map(&mut self, len: Option, - sep: Token, end: Token, visitor: V) -> Result @@ -69,7 +66,6 @@ impl<'de> Deserializer<'de> { let value = try!(visitor.visit_map(DeserializerMapVisitor { de: self, len: len, - sep: sep, end: end.clone(), })); try!(self.expect_token(end)); @@ -113,25 +109,24 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { Some(Token::UnitStruct(_name)) => visitor.visit_unit(), Some(Token::StructNewType(_name)) => visitor.visit_newtype_struct(self), Some(Token::SeqStart(len)) => { - self.visit_seq(len, Token::SeqSep, Token::SeqEnd, visitor) + self.visit_seq(len, Token::SeqEnd, visitor) } Some(Token::SeqArrayStart(len)) => { - self.visit_seq(Some(len), Token::SeqSep, Token::SeqEnd, visitor) + self.visit_seq(Some(len), Token::SeqEnd, visitor) } Some(Token::TupleStart(len)) => { - self.visit_seq(Some(len), Token::TupleSep, Token::TupleEnd, visitor) + self.visit_seq(Some(len), Token::TupleEnd, visitor) } Some(Token::TupleStructStart(_, len)) => { self.visit_seq(Some(len), - Token::TupleStructSep, Token::TupleStructEnd, visitor) } Some(Token::MapStart(len)) => { - self.visit_map(len, Token::MapSep, Token::MapEnd, visitor) + self.visit_map(len, Token::MapEnd, visitor) } Some(Token::StructStart(_, len)) => { - self.visit_map(Some(len), Token::StructSep, Token::StructEnd, visitor) + self.visit_map(Some(len), Token::StructEnd, visitor) } Some(Token::EnumStart(_)) => { let variant = self.next_token().ok_or(Error::EndOfTokens)?; @@ -153,15 +148,19 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { Err(Error::UnexpectedToken(variant)) } (variant, _) => { - visitor.visit_map(EnumMapVisitor::new(self, variant)) + visitor.visit_map(EnumMapVisitor::new(self, variant, EnumFormat::Any)) } } } Some(Token::EnumUnit(_, variant)) => visitor.visit_str(variant), - Some(Token::EnumNewType(_, variant)) | - Some(Token::EnumSeqStart(_, variant, _)) | + Some(Token::EnumNewType(_, variant)) => { + visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Any)) + } + Some(Token::EnumSeqStart(_, variant, _)) => { + visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Seq)) + } Some(Token::EnumMapStart(_, variant, _)) => { - visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant))) + visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Map)) } Some(token) => Err(Error::UnexpectedToken(token)), None => Err(Error::EndOfTokens), @@ -255,7 +254,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { match self.tokens.first() { Some(&Token::SeqArrayStart(_)) => { self.next_token(); - self.visit_seq(Some(len), Token::SeqSep, Token::SeqEnd, visitor) + self.visit_seq(Some(len), Token::SeqEnd, visitor) } Some(_) => self.deserialize(visitor), None => Err(Error::EndOfTokens), @@ -273,20 +272,19 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } Some(&Token::SeqStart(_)) => { self.next_token(); - self.visit_seq(Some(len), Token::SeqSep, Token::SeqEnd, visitor) + self.visit_seq(Some(len), Token::SeqEnd, visitor) } Some(&Token::SeqArrayStart(_)) => { self.next_token(); - self.visit_seq(Some(len), Token::SeqSep, Token::SeqEnd, visitor) + self.visit_seq(Some(len), Token::SeqEnd, visitor) } Some(&Token::TupleStart(_)) => { self.next_token(); - self.visit_seq(Some(len), Token::TupleSep, Token::TupleEnd, visitor) + self.visit_seq(Some(len), Token::TupleEnd, visitor) } Some(&Token::TupleStructStart(_, _)) => { self.next_token(); self.visit_seq(Some(len), - Token::TupleStructSep, Token::TupleStructEnd, visitor) } @@ -317,21 +315,20 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } Some(&Token::SeqStart(_)) => { self.next_token(); - self.visit_seq(Some(len), Token::SeqSep, Token::SeqEnd, visitor) + self.visit_seq(Some(len), Token::SeqEnd, visitor) } Some(&Token::SeqArrayStart(_)) => { self.next_token(); - self.visit_seq(Some(len), Token::SeqSep, Token::SeqEnd, visitor) + self.visit_seq(Some(len), Token::SeqEnd, visitor) } Some(&Token::TupleStart(_)) => { self.next_token(); - self.visit_seq(Some(len), Token::TupleSep, Token::TupleEnd, visitor) + self.visit_seq(Some(len), Token::TupleEnd, visitor) } Some(&Token::TupleStructStart(n, _)) => { self.next_token(); if name == n { self.visit_seq(Some(len), - Token::TupleStructSep, Token::TupleStructEnd, visitor) } else { @@ -355,7 +352,6 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { self.next_token(); if name == n { self.visit_map(Some(fields.len()), - Token::StructSep, Token::StructEnd, visitor) } else { @@ -364,7 +360,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } Some(&Token::MapStart(_)) => { self.next_token(); - self.visit_map(Some(fields.len()), Token::MapSep, Token::MapEnd, visitor) + self.visit_map(Some(fields.len()), Token::MapEnd, visitor) } Some(_) => self.deserialize(visitor), None => Err(Error::EndOfTokens), @@ -377,7 +373,6 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { struct DeserializerSeqVisitor<'a, 'de: 'a> { de: &'a mut Deserializer<'de>, len: Option, - sep: Token, end: Token, } @@ -390,14 +385,8 @@ impl<'de, 'a> SeqVisitor<'de> for DeserializerSeqVisitor<'a, 'de> { if self.de.tokens.first() == Some(&self.end) { return Ok(None); } - match self.de.next_token() { - Some(ref token) if *token == self.sep => { - self.len = self.len.map(|len| len.saturating_sub(1)); - seed.deserialize(&mut *self.de).map(Some) - } - Some(other) => Err(Error::UnexpectedToken(other)), - None => Err(Error::EndOfTokens), - } + self.len = self.len.map(|len| len.saturating_sub(1)); + seed.deserialize(&mut *self.de).map(Some) } fn size_hint(&self) -> (usize, Option) { @@ -411,7 +400,6 @@ impl<'de, 'a> SeqVisitor<'de> for DeserializerSeqVisitor<'a, 'de> { struct DeserializerMapVisitor<'a, 'de: 'a> { de: &'a mut Deserializer<'de>, len: Option, - sep: Token, end: Token, } @@ -424,14 +412,8 @@ impl<'de, 'a> MapVisitor<'de> for DeserializerMapVisitor<'a, 'de> { if self.de.tokens.first() == Some(&self.end) { return Ok(None); } - match self.de.next_token() { - Some(ref token) if *token == self.sep => { - self.len = self.len.map(|len| len.saturating_sub(1)); - seed.deserialize(&mut *self.de).map(Some) - } - Some(other) => Err(Error::UnexpectedToken(other)), - None => Err(Error::EndOfTokens), - } + self.len = self.len.map(|len| len.saturating_sub(1)); + seed.deserialize(&mut *self.de).map(Some) } fn visit_value_seed(&mut self, seed: V) -> Result @@ -512,7 +494,7 @@ impl<'de, 'a> VariantVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { let token = self.de.next_token().unwrap(); if len == enum_len { - self.de.visit_seq(Some(len), Token::EnumSeqSep, Token::EnumSeqEnd, visitor) + self.de.visit_seq(Some(len), Token::EnumSeqEnd, visitor) } else { Err(Error::UnexpectedToken(token)) } @@ -521,7 +503,7 @@ impl<'de, 'a> VariantVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { let token = self.de.next_token().unwrap(); if len == enum_len { - self.de.visit_seq(Some(len), Token::SeqSep, Token::SeqEnd, visitor) + self.de.visit_seq(Some(len), Token::SeqEnd, visitor) } else { Err(Error::UnexpectedToken(token)) } @@ -540,7 +522,6 @@ impl<'de, 'a> VariantVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { if fields.len() == enum_len { self.de.visit_map(Some(fields.len()), - Token::EnumMapSep, Token::EnumMapEnd, visitor) } else { @@ -551,7 +532,7 @@ impl<'de, 'a> VariantVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { let token = self.de.next_token().unwrap(); if fields.len() == enum_len { - self.de.visit_map(Some(fields.len()), Token::MapSep, Token::MapEnd, visitor) + self.de.visit_map(Some(fields.len()), Token::MapEnd, visitor) } else { Err(Error::UnexpectedToken(token)) } @@ -567,13 +548,21 @@ impl<'de, 'a> VariantVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { struct EnumMapVisitor<'a, 'de: 'a> { de: &'a mut Deserializer<'de>, variant: Option, + format: EnumFormat, +} + +enum EnumFormat { + Seq, + Map, + Any, } impl<'a, 'de> EnumMapVisitor<'a, 'de> { - fn new(de: &'a mut Deserializer<'de>, variant: Token) -> Self { + fn new(de: &'a mut Deserializer<'de>, variant: Token, format: EnumFormat) -> Self { EnumMapVisitor { de: de, variant: Some(variant), + format: format, } } } @@ -604,13 +593,12 @@ impl<'de, 'a> MapVisitor<'de> for EnumMapVisitor<'a, 'de> { fn visit_value_seed(&mut self, seed: V) -> Result where V: DeserializeSeed<'de> { - match self.de.tokens.first() { - Some(&Token::EnumSeqSep) => { + match self.format { + EnumFormat::Seq => { let value = { let visitor = DeserializerSeqVisitor { de: self.de, len: None, - sep: Token::EnumSeqSep, end: Token::EnumSeqEnd, }; try!(seed.deserialize(SeqVisitorDeserializer::new(visitor))) @@ -618,12 +606,11 @@ impl<'de, 'a> MapVisitor<'de> for EnumMapVisitor<'a, 'de> { try!(self.de.expect_token(Token::EnumSeqEnd)); Ok(value) } - Some(&Token::EnumMapSep) => { + EnumFormat::Map => { let value = { let visitor = DeserializerMapVisitor { de: self.de, len: None, - sep: Token::EnumMapSep, end: Token::EnumMapEnd, }; try!(seed.deserialize(MapVisitorDeserializer::new(visitor))) @@ -631,7 +618,7 @@ impl<'de, 'a> MapVisitor<'de> for EnumMapVisitor<'a, 'de> { try!(self.de.expect_token(Token::EnumMapEnd)); Ok(value) } - _ => seed.deserialize(&mut *self.de), + EnumFormat::Any => seed.deserialize(&mut *self.de), } } } diff --git a/serde_test/src/ser.rs b/serde_test/src/ser.rs index e8af6ee9..919565b1 100644 --- a/serde_test/src/ser.rs +++ b/serde_test/src/ser.rs @@ -253,7 +253,6 @@ impl<'s, 'a> ser::SerializeSeq for &'s mut Serializer<'a> { fn serialize_element(&mut self, value: &T) -> Result<(), Error> where T: Serialize { - assert_next_token!(self, SeqSep); value.serialize(&mut **self) } @@ -270,7 +269,6 @@ impl<'s, 'a> ser::SerializeTuple for &'s mut Serializer<'a> { fn serialize_element(&mut self, value: &T) -> Result<(), Error> where T: Serialize { - assert_next_token!(self, TupleSep); value.serialize(&mut **self) } @@ -287,7 +285,6 @@ impl<'s, 'a> ser::SerializeTupleStruct for &'s mut Serializer<'a> { fn serialize_field(&mut self, value: &T) -> Result<(), Error> where T: Serialize { - assert_next_token!(self, TupleStructSep); value.serialize(&mut **self) } @@ -304,7 +301,6 @@ impl<'s, 'a> ser::SerializeTupleVariant for &'s mut Serializer<'a> { fn serialize_field(&mut self, value: &T) -> Result<(), Error> where T: Serialize { - assert_next_token!(self, EnumSeqSep); value.serialize(&mut **self) } @@ -321,7 +317,6 @@ impl<'s, 'a> ser::SerializeMap for &'s mut Serializer<'a> { fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> where T: Serialize { - assert_next_token!(self, MapSep); key.serialize(&mut **self) } @@ -347,7 +342,6 @@ impl<'s, 'a> ser::SerializeStruct for &'s mut Serializer<'a> { -> Result<(), Self::Error> where T: Serialize { - assert_next_token!(self, StructSep); try!(key.serialize(&mut **self)); value.serialize(&mut **self) } @@ -368,7 +362,6 @@ impl<'s, 'a> ser::SerializeStructVariant for &'s mut Serializer<'a> { -> Result<(), Self::Error> where T: Serialize { - assert_next_token!(self, EnumMapSep); try!(key.serialize(&mut **self)); value.serialize(&mut **self) } diff --git a/serde_test/src/token.rs b/serde_test/src/token.rs index 7cc9bbdd..5e9cead0 100644 --- a/serde_test/src/token.rs +++ b/serde_test/src/token.rs @@ -105,29 +105,18 @@ pub enum Token { /// header is a list of elements, followed by `SeqEnd`. SeqArrayStart(usize), - /// A separator, which occurs *before* every element in a sequence. - /// - /// Elements in sequences are represented by a `SeqSep`, followed by the value of the element. - SeqSep, - /// An indicator of the end of a sequence. SeqEnd, /// The header to a tuple of the given length, similar to `SeqArrayStart`. TupleStart(usize), - /// A separator, similar to `SeqSep`. - TupleSep, - /// An indicator of the end of a tuple, similar to `SeqEnd`. TupleEnd, /// The header to a tuple struct of the given name and length. TupleStructStart(&'static str, usize), - /// A separator, similar to `TupleSep`. - TupleStructSep, - /// An indicator of the end of a tuple struct, similar to `TupleEnd`. TupleStructEnd, @@ -137,30 +126,18 @@ pub enum Token { /// is a list of key-value pairs, followed by `MapEnd`. MapStart(Option), - /// A separator, which occurs *before* every key-value pair in a map. - /// - /// Elements in maps are represented by a `MapSep`, followed by a serialized key, followed - /// by a serialized value. - MapSep, - /// An indicator of the end of a map. MapEnd, /// The header of a struct of the given name and length, similar to `MapStart`. StructStart(&'static str, usize), - /// A separator, similar to `MapSep`. - StructSep, - /// An indicator of the end of a struct, similar to `MapEnd`. StructEnd, /// The header to a tuple variant of an enum of the given name, of the given name and length. EnumSeqStart(&'static str, &'static str, usize), - /// A separator, similar to `TupleSep`. - EnumSeqSep, - /// An indicator of the end of a tuple variant, similar to `TupleEnd`. EnumSeqEnd, @@ -168,9 +145,6 @@ pub enum Token { /// similar to `StructStart`. EnumMapStart(&'static str, &'static str, usize), - /// A separator, similar to `StructSep`. - EnumMapSep, - /// An indicator of the end of a struct, similar to `StructEnd`. EnumMapEnd, } diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index 3bcedd77..1eef647c 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -87,23 +87,18 @@ fn test_default_struct() { &[ Token::StructStart("DefaultStruct", 3), - Token::StructSep, Token::Str("a1"), Token::I32(1), - Token::StructSep, Token::Str("a2"), Token::I32(2), - Token::StructSep, Token::Str("a3"), Token::I32(3), - Token::StructSep, Token::Str("a4"), Token::I32(4), - Token::StructSep, Token::Str("a5"), Token::I32(5), @@ -116,7 +111,6 @@ fn test_default_struct() { &[ Token::StructStart("DefaultStruct", 1), - Token::StructSep, Token::Str("a1"), Token::I32(1), @@ -150,23 +144,18 @@ fn test_default_enum() { &[ Token::EnumMapStart("DefaultEnum", "Struct", 3), - Token::EnumMapSep, Token::Str("a1"), Token::I32(1), - Token::EnumMapSep, Token::Str("a2"), Token::I32(2), - Token::EnumMapSep, Token::Str("a3"), Token::I32(3), - Token::EnumMapSep, Token::Str("a4"), Token::I32(4), - Token::EnumMapSep, Token::Str("a5"), Token::I32(5), @@ -179,7 +168,6 @@ fn test_default_enum() { &[ Token::EnumMapStart("DefaultEnum", "Struct", 3), - Token::EnumMapSep, Token::Str("a1"), Token::I32(1), @@ -221,7 +209,6 @@ fn test_no_std_default() { &[ Token::StructStart("ContainsNoStdDefault", 1), - Token::StructSep, Token::Str("a"), Token::StructNewType("NoStdDefault"), Token::I8(8), @@ -304,30 +291,23 @@ fn test_ignore_unknown() { &[ Token::StructStart("DefaultStruct", 5), - Token::StructSep, Token::Str("whoops1"), Token::I32(2), - Token::StructSep, Token::Str("a1"), Token::I32(1), - Token::StructSep, Token::Str("whoops2"), Token::SeqStart(Some(1)), - Token::SeqSep, Token::I32(2), Token::SeqEnd, - Token::StructSep, Token::Str("a2"), Token::I32(2), - Token::StructSep, Token::Str("whoops3"), Token::I32(2), - Token::StructSep, Token::Str("a3"), Token::I32(3), @@ -339,11 +319,9 @@ fn test_ignore_unknown() { &[ Token::StructStart("DenyUnknown", 2), - Token::StructSep, Token::Str("a1"), Token::I32(1), - Token::StructSep, Token::Str("whoops"), ], Error::Message("unknown field `whoops`, expected `a1`".to_owned()) @@ -373,11 +351,9 @@ fn test_rename_struct() { &[ Token::StructStart("Superhero", 2), - Token::StructSep, Token::Str("a1"), Token::I32(1), - Token::StructSep, Token::Str("a3"), Token::I32(2), @@ -390,11 +366,9 @@ fn test_rename_struct() { &[ Token::StructStart("SuperheroSer", 2), - Token::StructSep, Token::Str("a1"), Token::I32(1), - Token::StructSep, Token::Str("a4"), Token::I32(2), @@ -407,11 +381,9 @@ fn test_rename_struct() { &[ Token::StructStart("SuperheroDe", 2), - Token::StructSep, Token::Str("a1"), Token::I32(1), - Token::StructSep, Token::Str("a5"), Token::I32(2), @@ -469,13 +441,8 @@ fn test_rename_enum() { &RenameEnum::WonderWoman(0, 1), &[ Token::EnumSeqStart("Superhero", "diana_prince", 2), - - Token::EnumSeqSep, Token::I8(0), - - Token::EnumSeqSep, Token::I8(1), - Token::EnumSeqEnd, ] ); @@ -485,7 +452,6 @@ fn test_rename_enum() { &[ Token::EnumMapStart("Superhero", "barry_allan", 1), - Token::EnumMapSep, Token::Str("b"), Token::I32(1), @@ -501,11 +467,9 @@ fn test_rename_enum() { &[ Token::EnumMapStart("SuperheroSer", "dick_grayson", 2), - Token::EnumMapSep, Token::Str("a"), Token::I8(0), - Token::EnumMapSep, Token::Str("c"), Token::Str(""), @@ -521,11 +485,9 @@ fn test_rename_enum() { &[ Token::EnumMapStart("SuperheroDe", "jason_todd", 2), - Token::EnumMapSep, Token::Str("a"), Token::I8(0), - Token::EnumMapSep, Token::Str("d"), Token::Str(""), @@ -555,11 +517,9 @@ fn test_skip_serializing_struct() { &[ Token::StructStart("SkipSerializingStruct", 2), - Token::StructSep, Token::Str("a"), Token::I8(1), - Token::StructSep, Token::Str("c"), Token::I32(3), @@ -576,7 +536,6 @@ fn test_skip_serializing_struct() { &[ Token::StructStart("SkipSerializingStruct", 1), - Token::StructSep, Token::Str("a"), Token::I8(1), @@ -608,11 +567,9 @@ fn test_skip_serializing_enum() { &[ Token::EnumMapStart("SkipSerializingEnum", "Struct", 2), - Token::EnumMapSep, Token::Str("a"), Token::I8(1), - Token::EnumMapSep, Token::Str("c"), Token::I32(3), @@ -629,7 +586,6 @@ fn test_skip_serializing_enum() { &[ Token::EnumMapStart("SkipSerializingEnum", "Struct", 1), - Token::EnumMapSep, Token::Str("a"), Token::I8(1), @@ -676,12 +632,10 @@ fn test_elt_not_serialize() { &[ Token::StructStart("ContainsNotSerialize", 2), - Token::StructSep, Token::Str("a"), Token::Option(true), Token::I8(1), - Token::StructSep, Token::Str("d"), Token::Str("trouble"), @@ -708,11 +662,9 @@ fn test_serialize_with_struct() { &[ Token::StructStart("SerializeWithStruct", 2), - Token::StructSep, Token::Str("a"), Token::I8(1), - Token::StructSep, Token::Str("b"), Token::Bool(false), @@ -728,11 +680,9 @@ fn test_serialize_with_struct() { &[ Token::StructStart("SerializeWithStruct", 2), - Token::StructSep, Token::Str("a"), Token::I8(1), - Token::StructSep, Token::Str("b"), Token::Bool(true), @@ -761,11 +711,9 @@ fn test_serialize_with_enum() { &[ Token::EnumMapStart("SerializeWithEnum", "Struct", 2), - Token::EnumMapSep, Token::Str("a"), Token::I8(1), - Token::EnumMapSep, Token::Str("b"), Token::Bool(false), @@ -781,11 +729,9 @@ fn test_serialize_with_enum() { &[ Token::EnumMapStart("SerializeWithEnum", "Struct", 2), - Token::EnumMapSep, Token::Str("a"), Token::I8(1), - Token::EnumMapSep, Token::Str("b"), Token::Bool(true), @@ -811,11 +757,9 @@ fn test_deserialize_with_struct() { &[ Token::StructStart("DeserializeWithStruct", 2), - Token::StructSep, Token::Str("a"), Token::I8(1), - Token::StructSep, Token::Str("b"), Token::Bool(false), @@ -831,11 +775,9 @@ fn test_deserialize_with_struct() { &[ Token::StructStart("DeserializeWithStruct", 2), - Token::StructSep, Token::Str("a"), Token::I8(1), - Token::StructSep, Token::Str("b"), Token::Bool(true), @@ -863,11 +805,9 @@ fn test_deserialize_with_enum() { &[ Token::EnumMapStart("DeserializeWithEnum", "Struct", 2), - Token::EnumMapSep, Token::Str("a"), Token::I8(1), - Token::EnumMapSep, Token::Str("b"), Token::Bool(false), @@ -883,11 +823,9 @@ fn test_deserialize_with_enum() { &[ Token::EnumMapStart("DeserializeWithEnum", "Struct", 2), - Token::EnumMapSep, Token::Str("a"), Token::I8(1), - Token::EnumMapSep, Token::Str("b"), Token::Bool(true), @@ -902,7 +840,6 @@ fn test_missing_renamed_field_struct() { &[ Token::StructStart("Superhero", 2), - Token::StructSep, Token::Str("a1"), Token::I32(1), @@ -915,7 +852,6 @@ fn test_missing_renamed_field_struct() { &[ Token::StructStart("SuperheroDe", 2), - Token::StructSep, Token::Str("a1"), Token::I32(1), @@ -940,7 +876,6 @@ fn test_missing_renamed_field_enum() { &[ Token::EnumMapStart("SuperheroDe", "jason_todd", 2), - Token::EnumMapSep, Token::Str("a"), Token::I8(0), @@ -961,8 +896,7 @@ fn test_invalid_length_enum() { assert_de_tokens_error::( &[ Token::EnumSeqStart("InvalidLengthEnum", "A", 3), - Token::EnumSeqSep, - Token::I32(1), + Token::I32(1), Token::EnumSeqEnd, ], Error::Message("invalid length 1, expected tuple of 3 elements".to_owned()), @@ -970,8 +904,7 @@ fn test_invalid_length_enum() { assert_de_tokens_error::( &[ Token::EnumSeqStart("InvalidLengthEnum", "B", 3), - Token::EnumSeqSep, - Token::I32(1), + Token::I32(1), Token::EnumSeqEnd, ], Error::Message("invalid length 1, expected tuple of 2 elements".to_owned()), diff --git a/test_suite/tests/test_borrow.rs b/test_suite/tests/test_borrow.rs index 4749456e..c12bcdcd 100644 --- a/test_suite/tests/test_borrow.rs +++ b/test_suite/tests/test_borrow.rs @@ -90,13 +90,8 @@ fn test_tuple() { &("str", &b"bytes"[..]), &[ Token::TupleStart(2), - - Token::TupleSep, Token::BorrowedStr("str"), - - Token::TupleSep, Token::BorrowedBytes(b"bytes"), - Token::TupleEnd, ] ); @@ -115,11 +110,9 @@ fn test_struct() { &[ Token::StructStart("Borrowing", 2), - Token::StructSep, Token::BorrowedStr("bs"), Token::BorrowedStr("str"), - Token::StructSep, Token::BorrowedStr("bb"), Token::BorrowedBytes(b"bytes"), @@ -141,11 +134,9 @@ fn test_cow() { let tokens = &[ Token::StructStart("Cows", 2), - Token::StructSep, Token::Str("copied"), Token::BorrowedStr("copied"), - Token::StructSep, Token::Str("borrowed"), Token::BorrowedStr("borrowed"), diff --git a/test_suite/tests/test_bytes.rs b/test_suite/tests/test_bytes.rs index f4ae59dc..3cc941d3 100644 --- a/test_suite/tests/test_bytes.rs +++ b/test_suite/tests/test_bytes.rs @@ -37,21 +37,15 @@ fn test_byte_buf() { assert_de_tokens(&buf, &[Token::String("ABC")]); assert_de_tokens(&buf, &[ Token::SeqStart(None), - Token::SeqSep, Token::U8(65), - Token::SeqSep, Token::U8(66), - Token::SeqSep, Token::U8(67), Token::SeqEnd, ]); assert_de_tokens(&buf, &[ Token::SeqStart(Some(3)), - Token::SeqSep, Token::U8(65), - Token::SeqSep, Token::U8(66), - Token::SeqSep, Token::U8(67), Token::SeqEnd, ]); diff --git a/test_suite/tests/test_de.rs b/test_suite/tests/test_de.rs index 2d012259..5fe900e1 100644 --- a/test_suite/tests/test_de.rs +++ b/test_suite/tests/test_de.rs @@ -152,11 +152,9 @@ fn assert_de_tokens_ignore(ignorable_tokens: &[Token]) { // stream for an IgnoreBase type let concated_tokens : Vec = vec![ Token::MapStart(Some(2)), - Token::MapSep, Token::Str("a"), Token::I32(1), - Token::MapSep, Token::Str("ignored") ] .into_iter() @@ -264,49 +262,29 @@ declare_tests! { test_tuple_struct { TupleStruct(1, 2, 3) => &[ Token::SeqStart(Some(3)), - Token::SeqSep, Token::I32(1), - - Token::SeqSep, Token::I32(2), - - Token::SeqSep, Token::I32(3), Token::SeqEnd, ], TupleStruct(1, 2, 3) => &[ Token::SeqStart(None), - Token::SeqSep, Token::I32(1), - - Token::SeqSep, Token::I32(2), - - Token::SeqSep, Token::I32(3), Token::SeqEnd, ], TupleStruct(1, 2, 3) => &[ Token::TupleStructStart("TupleStruct", 3), - Token::TupleStructSep, Token::I32(1), - - Token::TupleStructSep, Token::I32(2), - - Token::TupleStructSep, Token::I32(3), Token::TupleStructEnd, ], TupleStruct(1, 2, 3) => &[ Token::TupleStructStart("TupleStruct", 3), - Token::TupleStructSep, Token::I32(1), - - Token::TupleStructSep, Token::I32(2), - - Token::TupleStructSep, Token::I32(3), Token::TupleStructEnd, ], @@ -318,22 +296,15 @@ declare_tests! { ], btreeset![btreeset![], btreeset![1], btreeset![2, 3]] => &[ Token::SeqStart(Some(3)), - Token::SeqSep, Token::SeqStart(Some(0)), Token::SeqEnd, - Token::SeqSep, Token::SeqStart(Some(1)), - Token::SeqSep, Token::I32(1), Token::SeqEnd, - Token::SeqSep, Token::SeqStart(Some(2)), - Token::SeqSep, Token::I32(2), - - Token::SeqSep, Token::I32(3), Token::SeqEnd, Token::SeqEnd, @@ -350,13 +321,8 @@ declare_tests! { ], hashset![1, 2, 3] => &[ Token::SeqStart(Some(3)), - Token::SeqSep, Token::I32(1), - - Token::SeqSep, Token::I32(2), - - Token::SeqSep, Token::I32(3), Token::SeqEnd, ], @@ -366,13 +332,8 @@ declare_tests! { ], hashset![FnvHasher @ 1, 2, 3] => &[ Token::SeqStart(Some(3)), - Token::SeqSep, Token::I32(1), - - Token::SeqSep, Token::I32(2), - - Token::SeqSep, Token::I32(3), Token::SeqEnd, ], @@ -384,22 +345,15 @@ declare_tests! { ], vec![vec![], vec![1], vec![2, 3]] => &[ Token::SeqStart(Some(3)), - Token::SeqSep, Token::SeqStart(Some(0)), Token::SeqEnd, - Token::SeqSep, Token::SeqStart(Some(1)), - Token::SeqSep, Token::I32(1), Token::SeqEnd, - Token::SeqSep, Token::SeqStart(Some(2)), - Token::SeqSep, Token::I32(2), - - Token::SeqSep, Token::I32(3), Token::SeqEnd, Token::SeqEnd, @@ -420,44 +374,30 @@ declare_tests! { ], ([0; 0], [1], [2, 3]) => &[ Token::SeqStart(Some(3)), - Token::SeqSep, Token::SeqStart(Some(0)), Token::SeqEnd, - Token::SeqSep, Token::SeqStart(Some(1)), - Token::SeqSep, Token::I32(1), Token::SeqEnd, - Token::SeqSep, Token::SeqStart(Some(2)), - Token::SeqSep, Token::I32(2), - - Token::SeqSep, Token::I32(3), Token::SeqEnd, Token::SeqEnd, ], ([0; 0], [1], [2, 3]) => &[ Token::SeqArrayStart(3), - Token::SeqSep, Token::SeqArrayStart(0), Token::SeqEnd, - Token::SeqSep, Token::SeqArrayStart(1), - Token::SeqSep, Token::I32(1), Token::SeqEnd, - Token::SeqSep, Token::SeqArrayStart(2), - Token::SeqSep, Token::I32(2), - - Token::SeqSep, Token::I32(3), Token::SeqEnd, Token::SeqEnd, @@ -470,37 +410,25 @@ declare_tests! { test_tuple { (1,) => &[ Token::SeqStart(Some(1)), - Token::SeqSep, Token::I32(1), Token::SeqEnd, ], (1, 2, 3) => &[ Token::SeqStart(Some(3)), - Token::SeqSep, Token::I32(1), - - Token::SeqSep, Token::I32(2), - - Token::SeqSep, Token::I32(3), Token::SeqEnd, ], (1,) => &[ Token::TupleStart(1), - Token::TupleSep, Token::I32(1), Token::TupleEnd, ], (1, 2, 3) => &[ Token::TupleStart(3), - Token::TupleSep, Token::I32(1), - - Token::TupleSep, Token::I32(2), - - Token::TupleSep, Token::I32(3), Token::TupleEnd, ], @@ -512,37 +440,30 @@ declare_tests! { ], btreemap![1 => 2] => &[ Token::MapStart(Some(1)), - Token::MapSep, Token::I32(1), Token::I32(2), Token::MapEnd, ], btreemap![1 => 2, 3 => 4] => &[ Token::MapStart(Some(2)), - Token::MapSep, Token::I32(1), Token::I32(2), - Token::MapSep, Token::I32(3), Token::I32(4), Token::MapEnd, ], btreemap![1 => btreemap![], 2 => btreemap![3 => 4, 5 => 6]] => &[ Token::MapStart(Some(2)), - Token::MapSep, Token::I32(1), Token::MapStart(Some(0)), Token::MapEnd, - Token::MapSep, Token::I32(2), Token::MapStart(Some(2)), - Token::MapSep, Token::I32(3), Token::I32(4), - Token::MapSep, Token::I32(5), Token::I32(6), Token::MapEnd, @@ -560,37 +481,30 @@ declare_tests! { ], hashmap![1 => 2] => &[ Token::MapStart(Some(1)), - Token::MapSep, Token::I32(1), Token::I32(2), Token::MapEnd, ], hashmap![1 => 2, 3 => 4] => &[ Token::MapStart(Some(2)), - Token::MapSep, Token::I32(1), Token::I32(2), - Token::MapSep, Token::I32(3), Token::I32(4), Token::MapEnd, ], hashmap![1 => hashmap![], 2 => hashmap![3 => 4, 5 => 6]] => &[ Token::MapStart(Some(2)), - Token::MapSep, Token::I32(1), Token::MapStart(Some(0)), Token::MapEnd, - Token::MapSep, Token::I32(2), Token::MapStart(Some(2)), - Token::MapSep, Token::I32(3), Token::I32(4), - Token::MapSep, Token::I32(5), Token::I32(6), Token::MapEnd, @@ -602,11 +516,9 @@ declare_tests! { ], hashmap![FnvHasher @ 1 => 2, 3 => 4] => &[ Token::MapStart(Some(2)), - Token::MapSep, Token::I32(1), Token::I32(2), - Token::MapSep, Token::I32(3), Token::I32(4), Token::MapEnd, @@ -615,32 +527,25 @@ declare_tests! { test_struct { Struct { a: 1, b: 2, c: 0 } => &[ Token::MapStart(Some(3)), - Token::MapSep, Token::Str("a"), Token::I32(1), - Token::MapSep, Token::Str("b"), Token::I32(2), Token::MapEnd, ], Struct { a: 1, b: 2, c: 0 } => &[ Token::StructStart("Struct", 3), - Token::StructSep, Token::Str("a"), Token::I32(1), - Token::StructSep, Token::Str("b"), Token::I32(2), Token::StructEnd, ], Struct { a: 1, b: 2, c: 0 } => &[ Token::SeqStart(Some(3)), - Token::SeqSep, Token::I32(1), - - Token::SeqSep, Token::I32(2), Token::SeqEnd, ], @@ -648,38 +553,30 @@ declare_tests! { test_struct_with_skip { Struct { a: 1, b: 2, c: 0 } => &[ Token::MapStart(Some(3)), - Token::MapSep, Token::Str("a"), Token::I32(1), - Token::MapSep, Token::Str("b"), Token::I32(2), - Token::MapSep, Token::Str("c"), Token::I32(3), - Token::MapSep, Token::Str("d"), Token::I32(4), Token::MapEnd, ], Struct { a: 1, b: 2, c: 0 } => &[ Token::StructStart("Struct", 3), - Token::StructSep, Token::Str("a"), Token::I32(1), - Token::StructSep, Token::Str("b"), Token::I32(2), - Token::StructSep, Token::Str("c"), Token::I32(3), - Token::StructSep, Token::Str("d"), Token::I32(4), Token::StructEnd, @@ -692,11 +589,9 @@ declare_tests! { ], StructSkipAll { a: 0 } => &[ Token::StructStart("StructSkipAll", 1), - Token::StructSep, Token::Str("a"), Token::I32(1), - Token::StructSep, Token::Str("b"), Token::I32(2), Token::StructEnd, @@ -711,11 +606,9 @@ declare_tests! { test_struct_default { StructDefault { a: 50, b: "overwritten".to_string() } => &[ Token::StructStart("StructDefault", 1), - Token::StructSep, Token::Str("a"), Token::I32(50), - Token::StructSep, Token::Str("b"), Token::String("overwritten"), Token::StructEnd, @@ -739,13 +632,8 @@ declare_tests! { test_enum_seq { Enum::Seq(1, 2, 3) => &[ Token::EnumSeqStart("Enum", "Seq", 3), - Token::EnumSeqSep, Token::I32(1), - - Token::EnumSeqSep, Token::I32(2), - - Token::EnumSeqSep, Token::I32(3), Token::EnumSeqEnd, ], @@ -753,15 +641,12 @@ declare_tests! { test_enum_map { Enum::Map { a: 1, b: 2, c: 3 } => &[ Token::EnumMapStart("Enum", "Map", 3), - Token::EnumMapSep, Token::Str("a"), Token::I32(1), - Token::EnumMapSep, Token::Str("b"), Token::I32(2), - Token::EnumMapSep, Token::Str("c"), Token::I32(3), Token::EnumMapEnd, @@ -787,11 +672,8 @@ declare_tests! { test_boxed_slice { Box::new([0, 1, 2]) => &[ Token::SeqStart(Some(3)), - Token::SeqSep, Token::I32(0), - Token::SeqSep, Token::I32(1), - Token::SeqSep, Token::I32(2), Token::SeqEnd, ], @@ -799,21 +681,16 @@ declare_tests! { test_duration { Duration::new(1, 2) => &[ Token::StructStart("Duration", 2), - Token::StructSep, Token::Str("secs"), Token::U64(1), - Token::StructSep, Token::Str("nanos"), Token::U32(2), Token::StructEnd, ], Duration::new(1, 2) => &[ Token::SeqStart(Some(2)), - Token::SeqSep, Token::I64(1), - - Token::SeqSep, Token::I64(2), Token::SeqEnd, ], @@ -821,21 +698,16 @@ declare_tests! { test_range { 1u32..2u32 => &[ Token::StructStart("Range", 2), - Token::StructSep, Token::Str("start"), Token::U32(1), - Token::StructSep, Token::Str("end"), Token::U32(2), Token::StructEnd, ], 1u32..2u32 => &[ Token::SeqStart(Some(2)), - Token::SeqSep, Token::U64(1), - - Token::SeqSep, Token::U64(2), Token::SeqEnd, ], @@ -873,13 +745,8 @@ fn test_osstring() { Token::EnumStart("OsString"), Token::Str("Unix"), Token::SeqStart(Some(2)), - Token::SeqSep, Token::U8(1), - - Token::SeqSep, Token::U8(2), - - Token::SeqSep, Token::U8(3), Token::SeqEnd, ]; @@ -898,13 +765,8 @@ fn test_osstring() { Token::EnumStart("OsString"), Token::Str("Windows"), Token::SeqStart(Some(2)), - Token::SeqSep, Token::U16(1), - - Token::SeqSep, Token::U16(2), - - Token::SeqSep, Token::U16(3), Token::SeqEnd, ]; @@ -955,11 +817,9 @@ declare_error_tests! { test_unknown_field { &[ Token::StructStart("StructDenyUnknown", 2), - Token::StructSep, Token::Str("a"), Token::I32(0), - Token::StructSep, Token::Str("d"), ], Error::Message("unknown field `d`, expected `a`".to_owned()), @@ -967,7 +827,6 @@ declare_error_tests! { test_skipped_field_is_unknown { &[ Token::StructStart("StructDenyUnknown", 2), - Token::StructSep, Token::Str("b"), ], Error::Message("unknown field `b`, expected `a`".to_owned()), @@ -975,7 +834,6 @@ declare_error_tests! { test_skip_all_deny_unknown { &[ Token::StructStart("StructSkipAllDenyUnknown", 1), - Token::StructSep, Token::Str("a"), ], Error::Message("unknown field `a`, there are no fields".to_owned()), @@ -1001,20 +859,18 @@ declare_error_tests! { test_struct_seq_too_long { &[ Token::SeqStart(Some(4)), - Token::SeqSep, Token::I32(1), - Token::SeqSep, Token::I32(2), - Token::SeqSep, Token::I32(3), + Token::I32(1), + Token::I32(2), + Token::I32(3), ], - Error::UnexpectedToken(Token::SeqSep), + Error::UnexpectedToken(Token::I32(3)), } test_duplicate_field_struct { &[ Token::MapStart(Some(3)), - Token::MapSep, Token::Str("a"), Token::I32(1), - Token::MapSep, Token::Str("a"), ], Error::Message("duplicate field `a`".to_owned()), @@ -1022,11 +878,9 @@ declare_error_tests! { test_duplicate_field_enum { &[ Token::EnumMapStart("Enum", "Map", 3), - Token::EnumMapSep, Token::Str("a"), Token::I32(1), - Token::EnumMapSep, Token::Str("a"), ], Error::Message("duplicate field `a`".to_owned()), @@ -1042,7 +896,6 @@ declare_error_tests! { test_short_tuple<(u8, u8, u8)> { &[ Token::TupleStart(1), - Token::TupleSep, Token::U8(1), Token::TupleEnd, ], @@ -1051,7 +904,6 @@ declare_error_tests! { test_short_array<[u8; 3]> { &[ Token::SeqStart(Some(1)), - Token::SeqSep, Token::U8(1), Token::SeqEnd, ], diff --git a/test_suite/tests/test_macros.rs b/test_suite/tests/test_macros.rs index 43fe0980..f739e860 100644 --- a/test_suite/tests/test_macros.rs +++ b/test_suite/tests/test_macros.rs @@ -165,15 +165,9 @@ fn test_ser_named_tuple() { &SerNamedTuple(&a, &mut b, c), &[ Token::TupleStructStart("SerNamedTuple", 3), - Token::TupleStructSep, Token::I32(5), - - Token::TupleStructSep, Token::I32(6), - - Token::TupleStructSep, Token::I32(7), - Token::TupleStructEnd, ], ); @@ -185,15 +179,9 @@ fn test_de_named_tuple() { &DeNamedTuple(5, 6, 7), &[ Token::SeqStart(Some(3)), - Token::SeqSep, Token::I32(5), - - Token::SeqSep, Token::I32(6), - - Token::SeqSep, Token::I32(7), - Token::SeqEnd, ] ); @@ -202,15 +190,9 @@ fn test_de_named_tuple() { &DeNamedTuple(5, 6, 7), &[ Token::TupleStructStart("DeNamedTuple", 3), - Token::TupleStructSep, Token::I32(5), - - Token::TupleStructSep, Token::I32(6), - - Token::TupleStructSep, Token::I32(7), - Token::TupleStructEnd, ] ); @@ -231,15 +213,12 @@ fn test_ser_named_map() { &[ Token::StructStart("SerNamedMap", 3), - Token::StructSep, Token::Str("a"), Token::I32(5), - Token::StructSep, Token::Str("b"), Token::I32(6), - Token::StructSep, Token::Str("c"), Token::I32(7), @@ -259,15 +238,12 @@ fn test_de_named_map() { &[ Token::StructStart("DeNamedMap", 3), - Token::StructSep, Token::Str("a"), Token::I32(5), - Token::StructSep, Token::Str("b"), Token::I32(6), - Token::StructSep, Token::Str("c"), Token::I32(7), @@ -302,19 +278,10 @@ fn test_ser_enum_seq() { ), &[ Token::EnumSeqStart("SerEnum", "Seq", 4), - - Token::EnumSeqSep, Token::I8(1), - - Token::EnumSeqSep, Token::I32(2), - - Token::EnumSeqSep, Token::I32(3), - - Token::EnumSeqSep, Token::I32(4), - Token::EnumSeqEnd, ], ); @@ -337,19 +304,15 @@ fn test_ser_enum_map() { &[ Token::EnumMapStart("SerEnum", "Map", 4), - Token::EnumMapSep, Token::Str("a"), Token::I8(1), - Token::EnumMapSep, Token::Str("b"), Token::I32(2), - Token::EnumMapSep, Token::Str("c"), Token::I32(3), - Token::EnumMapSep, Token::Str("d"), Token::I32(4), @@ -384,19 +347,10 @@ fn test_de_enum_seq() { ), &[ Token::EnumSeqStart("DeEnum", "Seq", 4), - - Token::EnumSeqSep, Token::I8(1), - - Token::EnumSeqSep, Token::I32(2), - - Token::EnumSeqSep, Token::I32(3), - - Token::EnumSeqSep, Token::I32(4), - Token::EnumSeqEnd, ], ); @@ -419,19 +373,15 @@ fn test_de_enum_map() { &[ Token::EnumMapStart("DeEnum", "Map", 4), - Token::EnumMapSep, Token::Str("a"), Token::I8(1), - Token::EnumMapSep, Token::Str("b"), Token::I32(2), - Token::EnumMapSep, Token::Str("c"), Token::I32(3), - Token::EnumMapSep, Token::Str("d"), Token::I32(4), @@ -465,7 +415,6 @@ fn test_lifetimes() { &[ Token::EnumMapStart("Lifetimes", "LifetimeMap", 1), - Token::EnumMapSep, Token::Str("a"), Token::I32(5), @@ -478,7 +427,6 @@ fn test_lifetimes() { &[ Token::EnumMapStart("Lifetimes", "NoLifetimeMap", 1), - Token::EnumMapSep, Token::Str("a"), Token::I32(5), @@ -494,7 +442,6 @@ fn test_generic_struct() { &[ Token::StructStart("GenericStruct", 1), - Token::StructSep, Token::Str("x"), Token::U32(5), @@ -520,13 +467,8 @@ fn test_generic_tuple_struct() { &GenericTupleStruct(5u32, 6u32), &[ Token::TupleStructStart("GenericTupleStruct", 2), - - Token::TupleStructSep, Token::U32(5), - - Token::TupleStructSep, Token::U32(6), - Token::TupleStructEnd, ] ); @@ -559,13 +501,8 @@ fn test_generic_enum_seq() { &GenericEnum::Seq::(5, 6), &[ Token::EnumSeqStart("GenericEnum", "Seq", 2), - - Token::EnumSeqSep, Token::U32(5), - - Token::EnumSeqSep, Token::U32(6), - Token::EnumSeqEnd, ] ); @@ -578,11 +515,9 @@ fn test_generic_enum_map() { &[ Token::EnumMapStart("GenericEnum", "Map", 2), - Token::EnumMapSep, Token::Str("x"), Token::U32(5), - Token::EnumMapSep, Token::Str("y"), Token::U32(6), @@ -598,7 +533,6 @@ fn test_default_ty_param() { &[ Token::StructStart("DefaultTyParam", 1), - Token::StructSep, Token::Str("phantom"), Token::UnitStruct("PhantomData"), @@ -619,11 +553,9 @@ fn test_enum_state_field() { &[ Token::EnumMapStart("SomeEnum", "Key", 2), - Token::EnumMapSep, Token::Str("key"), Token::Char('a'), - Token::EnumMapSep, Token::Str("state"), Token::Bool(true), @@ -654,7 +586,6 @@ fn test_untagged_enum() { &[ Token::StructStart("Untagged", 1), - Token::StructSep, Token::Str("a"), Token::U8(1), @@ -667,7 +598,6 @@ fn test_untagged_enum() { &[ Token::StructStart("Untagged", 1), - Token::StructSep, Token::Str("b"), Token::U8(2), @@ -699,13 +629,8 @@ fn test_untagged_enum() { &Untagged::F(1, 2), &[ Token::TupleStart(2), - - Token::TupleSep, Token::U8(1), - - Token::TupleSep, Token::U8(2), - Token::TupleEnd, ] ); @@ -720,10 +645,7 @@ fn test_untagged_enum() { assert_de_tokens_error::( &[ Token::TupleStart(1), - - Token::TupleSep, Token::U8(1), - Token::TupleEnd, ], Error::Message("data did not match any variant of untagged enum Untagged".to_owned()), @@ -732,16 +654,9 @@ fn test_untagged_enum() { assert_de_tokens_error::( &[ Token::TupleStart(3), - - Token::TupleSep, Token::U8(1), - - Token::TupleSep, Token::U8(2), - - Token::TupleSep, Token::U8(3), - Token::TupleEnd, ], Error::Message("data did not match any variant of untagged enum Untagged".to_owned()), @@ -778,11 +693,9 @@ fn test_internally_tagged_enum() { &[ Token::StructStart("InternallyTagged", 2), - Token::StructSep, Token::Str("type"), Token::Str("A"), - Token::StructSep, Token::Str("a"), Token::U8(1), @@ -795,11 +708,9 @@ fn test_internally_tagged_enum() { &[ Token::StructStart("InternallyTagged", 2), - Token::StructSep, Token::Str("type"), Token::Str("B"), - Token::StructSep, Token::Str("b"), Token::U8(2), @@ -812,7 +723,6 @@ fn test_internally_tagged_enum() { &[ Token::StructStart("InternallyTagged", 1), - Token::StructSep, Token::Str("type"), Token::Str("C"), @@ -825,7 +735,6 @@ fn test_internally_tagged_enum() { &[ Token::MapStart(Some(1)), - Token::MapSep, Token::Str("type"), Token::Str("D"), @@ -838,7 +747,6 @@ fn test_internally_tagged_enum() { &[ Token::MapStart(Some(1)), - Token::MapSep, Token::Str("type"), Token::Str("E"), @@ -851,11 +759,9 @@ fn test_internally_tagged_enum() { &[ Token::StructStart("Struct", 2), - Token::StructSep, Token::Str("type"), Token::Str("F"), - Token::StructSep, Token::Str("f"), Token::U8(6), @@ -875,7 +781,6 @@ fn test_internally_tagged_enum() { &[ Token::MapStart(Some(1)), - Token::MapSep, Token::Str("type"), Token::Str("Z"), @@ -902,7 +807,6 @@ fn test_adjacently_tagged_enum() { &[ Token::StructStart("AdjacentlyTagged", 1), - Token::StructSep, Token::Str("t"), Token::Str("Unit"), @@ -916,11 +820,9 @@ fn test_adjacently_tagged_enum() { &[ Token::StructStart("AdjacentlyTagged", 1), - Token::StructSep, Token::Str("t"), Token::Str("Unit"), - Token::StructSep, Token::Str("c"), Token::Unit, @@ -934,11 +836,9 @@ fn test_adjacently_tagged_enum() { &[ Token::StructStart("AdjacentlyTagged", 1), - Token::StructSep, Token::Str("c"), Token::Unit, - Token::StructSep, Token::Str("t"), Token::Str("Unit"), @@ -952,11 +852,9 @@ fn test_adjacently_tagged_enum() { &[ Token::StructStart("AdjacentlyTagged", 2), - Token::StructSep, Token::Str("t"), Token::Str("Newtype"), - Token::StructSep, Token::Str("c"), Token::U8(1), @@ -970,11 +868,9 @@ fn test_adjacently_tagged_enum() { &[ Token::StructStart("AdjacentlyTagged", 2), - Token::StructSep, Token::Str("c"), Token::U8(1), - Token::StructSep, Token::Str("t"), Token::Str("Newtype"), @@ -988,16 +884,12 @@ fn test_adjacently_tagged_enum() { &[ Token::StructStart("AdjacentlyTagged", 2), - Token::StructSep, Token::Str("t"), Token::Str("Tuple"), - Token::StructSep, Token::Str("c"), Token::TupleStart(2), - Token::TupleSep, Token::U8(1), - Token::TupleSep, Token::U8(1), Token::TupleEnd, @@ -1011,16 +903,12 @@ fn test_adjacently_tagged_enum() { &[ Token::StructStart("AdjacentlyTagged", 2), - Token::StructSep, Token::Str("c"), Token::TupleStart(2), - Token::TupleSep, Token::U8(1), - Token::TupleSep, Token::U8(1), Token::TupleEnd, - Token::StructSep, Token::Str("t"), Token::Str("Tuple"), @@ -1034,14 +922,11 @@ fn test_adjacently_tagged_enum() { &[ Token::StructStart("AdjacentlyTagged", 2), - Token::StructSep, Token::Str("t"), Token::Str("Struct"), - Token::StructSep, Token::Str("c"), Token::StructStart("Struct", 1), - Token::StructSep, Token::Str("f"), Token::U8(1), Token::StructEnd, @@ -1056,15 +941,12 @@ fn test_adjacently_tagged_enum() { &[ Token::StructStart("AdjacentlyTagged", 2), - Token::StructSep, Token::Str("c"), Token::StructStart("Struct", 1), - Token::StructSep, Token::Str("f"), Token::U8(1), Token::StructEnd, - Token::StructSep, Token::Str("t"), Token::Str("Struct"), @@ -1094,11 +976,9 @@ fn test_enum_in_internally_tagged_enum() { &[ Token::MapStart(Some(2)), - Token::MapSep, Token::Str("type"), Token::Str("Inner"), - Token::MapSep, Token::Str("Unit"), Token::Unit, @@ -1111,11 +991,9 @@ fn test_enum_in_internally_tagged_enum() { &[ Token::MapStart(Some(2)), - Token::MapSep, Token::Str("type"), Token::Str("Inner"), - Token::MapSep, Token::Str("Newtype"), Token::U8(1), @@ -1128,16 +1006,12 @@ fn test_enum_in_internally_tagged_enum() { &[ Token::MapStart(Some(2)), - Token::MapSep, Token::Str("type"), Token::Str("Inner"), - Token::MapSep, Token::Str("Tuple"), Token::TupleStructStart("Tuple", 2), - Token::TupleStructSep, Token::U8(1), - Token::TupleStructSep, Token::U8(1), Token::TupleStructEnd, @@ -1150,14 +1024,11 @@ fn test_enum_in_internally_tagged_enum() { &[ Token::MapStart(Some(2)), - Token::MapSep, Token::Str("type"), Token::Str("Inner"), - Token::MapSep, Token::Str("Struct"), Token::StructStart("Struct", 1), - Token::StructSep, Token::Str("f"), Token::U8(1), Token::StructEnd, @@ -1202,12 +1073,8 @@ fn test_enum_in_untagged_enum() { &Outer::Inner(Inner::Tuple(1, 1)), &[ Token::EnumSeqStart("Inner", "Tuple", 2), - - Token::EnumSeqSep, Token::U8(1), - Token::EnumSeqSep, Token::U8(1), - Token::EnumSeqEnd, ] ); @@ -1217,7 +1084,6 @@ fn test_enum_in_untagged_enum() { &[ Token::EnumMapStart("Inner", "Struct", 1), - Token::EnumMapSep, Token::Str("f"), Token::U8(1), @@ -1259,10 +1125,8 @@ fn test_rename_all() { &E::Serialize { serialize: true, serialize_seq: true }, &[ Token::EnumMapStart("E", "serialize", 2), - Token::EnumMapSep, Token::Str("serialize"), Token::Bool(true), - Token::EnumMapSep, Token::Str("serializeSeq"), Token::Bool(true), Token::EnumMapEnd, @@ -1273,10 +1137,8 @@ fn test_rename_all() { &E::SerializeSeq { serialize: true, serialize_seq: true }, &[ Token::EnumMapStart("E", "serialize_seq", 2), - Token::EnumMapSep, Token::Str("serialize"), Token::Bool(true), - Token::EnumMapSep, Token::Str("serialize-seq"), Token::Bool(true), Token::EnumMapEnd, @@ -1287,10 +1149,8 @@ fn test_rename_all() { &E::SerializeMap { serialize: true, serialize_seq: true }, &[ Token::EnumMapStart("E", "serialize_map", 2), - Token::EnumMapSep, Token::Str("SERIALIZE"), Token::Bool(true), - Token::EnumMapSep, Token::Str("SERIALIZE_SEQ"), Token::Bool(true), Token::EnumMapEnd, @@ -1301,10 +1161,8 @@ fn test_rename_all() { &S { serialize: true, serialize_seq: true }, &[ Token::StructStart("S", 2), - Token::StructSep, Token::Str("Serialize"), Token::Bool(true), - Token::StructSep, Token::Str("SerializeSeq"), Token::Bool(true), Token::StructEnd, diff --git a/test_suite/tests/test_ser.rs b/test_suite/tests/test_ser.rs index 7613cb8a..89df7851 100644 --- a/test_suite/tests/test_ser.rs +++ b/test_suite/tests/test_ser.rs @@ -125,13 +125,8 @@ declare_tests! { ], &[1, 2, 3][..] => &[ Token::SeqStart(Some(3)), - Token::SeqSep, Token::I32(1), - - Token::SeqSep, Token::I32(2), - - Token::SeqSep, Token::I32(3), Token::SeqEnd, ], @@ -143,13 +138,8 @@ declare_tests! { ], [1, 2, 3] => &[ Token::SeqArrayStart(3), - Token::SeqSep, Token::I32(1), - - Token::SeqSep, Token::I32(2), - - Token::SeqSep, Token::I32(3), Token::SeqEnd, ], @@ -161,22 +151,15 @@ declare_tests! { ], vec![vec![], vec![1], vec![2, 3]] => &[ Token::SeqStart(Some(3)), - Token::SeqSep, Token::SeqStart(Some(0)), Token::SeqEnd, - Token::SeqSep, Token::SeqStart(Some(1)), - Token::SeqSep, Token::I32(1), Token::SeqEnd, - Token::SeqSep, Token::SeqStart(Some(2)), - Token::SeqSep, Token::I32(2), - - Token::SeqSep, Token::I32(3), Token::SeqEnd, Token::SeqEnd, @@ -189,13 +172,11 @@ declare_tests! { ], hashset![1] => &[ Token::SeqStart(Some(1)), - Token::SeqSep, Token::I32(1), Token::SeqEnd, ], hashset![FnvHasher @ 1] => &[ Token::SeqStart(Some(1)), - Token::SeqSep, Token::I32(1), Token::SeqEnd, ], @@ -203,19 +184,13 @@ declare_tests! { test_tuple { (1,) => &[ Token::TupleStart(1), - Token::TupleSep, Token::I32(1), Token::TupleEnd, ], (1, 2, 3) => &[ Token::TupleStart(3), - Token::TupleSep, Token::I32(1), - - Token::TupleSep, Token::I32(2), - - Token::TupleSep, Token::I32(3), Token::TupleEnd, ], @@ -223,37 +198,30 @@ declare_tests! { test_btreemap { btreemap![1 => 2] => &[ Token::MapStart(Some(1)), - Token::MapSep, Token::I32(1), Token::I32(2), Token::MapEnd, ], btreemap![1 => 2, 3 => 4] => &[ Token::MapStart(Some(2)), - Token::MapSep, Token::I32(1), Token::I32(2), - Token::MapSep, Token::I32(3), Token::I32(4), Token::MapEnd, ], btreemap![1 => btreemap![], 2 => btreemap![3 => 4, 5 => 6]] => &[ Token::MapStart(Some(2)), - Token::MapSep, Token::I32(1), Token::MapStart(Some(0)), Token::MapEnd, - Token::MapSep, Token::I32(2), Token::MapStart(Some(2)), - Token::MapSep, Token::I32(3), Token::I32(4), - Token::MapSep, Token::I32(5), Token::I32(6), Token::MapEnd, @@ -267,14 +235,12 @@ declare_tests! { ], hashmap![1 => 2] => &[ Token::MapStart(Some(1)), - Token::MapSep, Token::I32(1), Token::I32(2), Token::MapEnd, ], hashmap![FnvHasher @ 1 => 2] => &[ Token::MapStart(Some(1)), - Token::MapSep, Token::I32(1), Token::I32(2), Token::MapEnd, @@ -286,13 +252,8 @@ declare_tests! { test_tuple_struct { TupleStruct(1, 2, 3) => &[ Token::TupleStructStart("TupleStruct", 3), - Token::TupleStructSep, Token::I32(1), - - Token::TupleStructSep, Token::I32(2), - - Token::TupleStructSep, Token::I32(3), Token::TupleStructEnd, ], @@ -300,15 +261,12 @@ declare_tests! { test_struct { Struct { a: 1, b: 2, c: 3 } => &[ Token::StructStart("Struct", 3), - Token::StructSep, Token::Str("a"), Token::I32(1), - Token::StructSep, Token::Str("b"), Token::I32(2), - Token::StructSep, Token::Str("c"), Token::I32(3), Token::StructEnd, @@ -319,20 +277,15 @@ declare_tests! { Enum::One(42) => &[Token::EnumNewType("Enum", "One"), Token::I32(42)], Enum::Seq(1, 2) => &[ Token::EnumSeqStart("Enum", "Seq", 2), - Token::EnumSeqSep, Token::I32(1), - - Token::EnumSeqSep, Token::I32(2), Token::EnumSeqEnd, ], Enum::Map { a: 1, b: 2 } => &[ Token::EnumMapStart("Enum", "Map", 2), - Token::EnumMapSep, Token::Str("a"), Token::I32(1), - Token::EnumMapSep, Token::Str("b"), Token::I32(2), Token::EnumMapEnd, @@ -344,11 +297,8 @@ declare_tests! { test_boxed_slice { Box::new([0, 1, 2]) => &[ Token::SeqArrayStart(3), - Token::SeqSep, Token::I32(0), - Token::SeqSep, Token::I32(1), - Token::SeqSep, Token::I32(2), Token::SeqEnd, ], @@ -356,11 +306,9 @@ declare_tests! { test_duration { Duration::new(1, 2) => &[ Token::StructStart("Duration", 2), - Token::StructSep, Token::Str("secs"), Token::U64(1), - Token::StructSep, Token::Str("nanos"), Token::U32(2), Token::StructEnd, @@ -369,11 +317,9 @@ declare_tests! { test_range { 1u32..2u32 => &[ Token::StructStart("Range", 2), - Token::StructSep, Token::Str("start"), Token::U32(1), - Token::StructSep, Token::Str("end"), Token::U32(2), Token::StructEnd, From f03e8e6056fd35758cde9113e248587baf83dfaa Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 09:48:23 -0700 Subject: [PATCH 023/177] Exhaustive match in serde_test deserializer --- serde_test/src/de.rs | 80 ++++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index 2811241e..8bfb8f70 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -84,51 +84,52 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { fn deserialize(self, visitor: V) -> Result where V: Visitor<'de> { - match self.next_token() { - Some(Token::Bool(v)) => visitor.visit_bool(v), - Some(Token::I8(v)) => visitor.visit_i8(v), - Some(Token::I16(v)) => visitor.visit_i16(v), - Some(Token::I32(v)) => visitor.visit_i32(v), - Some(Token::I64(v)) => visitor.visit_i64(v), - Some(Token::U8(v)) => visitor.visit_u8(v), - Some(Token::U16(v)) => visitor.visit_u16(v), - Some(Token::U32(v)) => visitor.visit_u32(v), - Some(Token::U64(v)) => visitor.visit_u64(v), - Some(Token::F32(v)) => visitor.visit_f32(v), - Some(Token::F64(v)) => visitor.visit_f64(v), - Some(Token::Char(v)) => visitor.visit_char(v), - Some(Token::Str(v)) => visitor.visit_str(v), - Some(Token::BorrowedStr(v)) => visitor.visit_borrowed_str(v), - Some(Token::String(v)) => visitor.visit_string(v.to_owned()), - Some(Token::Bytes(v)) => visitor.visit_bytes(v), - Some(Token::BorrowedBytes(v)) => visitor.visit_borrowed_bytes(v), - Some(Token::ByteBuf(v)) => visitor.visit_byte_buf(v.to_vec()), - Some(Token::Option(false)) => visitor.visit_none(), - Some(Token::Option(true)) => visitor.visit_some(self), - Some(Token::Unit) => visitor.visit_unit(), - Some(Token::UnitStruct(_name)) => visitor.visit_unit(), - Some(Token::StructNewType(_name)) => visitor.visit_newtype_struct(self), - Some(Token::SeqStart(len)) => { + let token = self.next_token().ok_or(Error::EndOfTokens)?; + match token { + Token::Bool(v) => visitor.visit_bool(v), + Token::I8(v) => visitor.visit_i8(v), + Token::I16(v) => visitor.visit_i16(v), + Token::I32(v) => visitor.visit_i32(v), + Token::I64(v) => visitor.visit_i64(v), + Token::U8(v) => visitor.visit_u8(v), + Token::U16(v) => visitor.visit_u16(v), + Token::U32(v) => visitor.visit_u32(v), + Token::U64(v) => visitor.visit_u64(v), + Token::F32(v) => visitor.visit_f32(v), + Token::F64(v) => visitor.visit_f64(v), + Token::Char(v) => visitor.visit_char(v), + Token::Str(v) => visitor.visit_str(v), + Token::BorrowedStr(v) => visitor.visit_borrowed_str(v), + Token::String(v) => visitor.visit_string(v.to_owned()), + Token::Bytes(v) => visitor.visit_bytes(v), + Token::BorrowedBytes(v) => visitor.visit_borrowed_bytes(v), + Token::ByteBuf(v) => visitor.visit_byte_buf(v.to_vec()), + Token::Option(false) => visitor.visit_none(), + Token::Option(true) => visitor.visit_some(self), + Token::Unit => visitor.visit_unit(), + Token::UnitStruct(_name) => visitor.visit_unit(), + Token::StructNewType(_name) => visitor.visit_newtype_struct(self), + Token::SeqStart(len) => { self.visit_seq(len, Token::SeqEnd, visitor) } - Some(Token::SeqArrayStart(len)) => { + Token::SeqArrayStart(len) => { self.visit_seq(Some(len), Token::SeqEnd, visitor) } - Some(Token::TupleStart(len)) => { + Token::TupleStart(len) => { self.visit_seq(Some(len), Token::TupleEnd, visitor) } - Some(Token::TupleStructStart(_, len)) => { + Token::TupleStructStart(_, len) => { self.visit_seq(Some(len), Token::TupleStructEnd, visitor) } - Some(Token::MapStart(len)) => { + Token::MapStart(len) => { self.visit_map(len, Token::MapEnd, visitor) } - Some(Token::StructStart(_, len)) => { + Token::StructStart(_, len) => { self.visit_map(Some(len), Token::StructEnd, visitor) } - Some(Token::EnumStart(_)) => { + Token::EnumStart(_) => { let variant = self.next_token().ok_or(Error::EndOfTokens)?; let next = *self.tokens.first().ok_or(Error::EndOfTokens)?; match (variant, next) { @@ -152,18 +153,23 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } } } - Some(Token::EnumUnit(_, variant)) => visitor.visit_str(variant), - Some(Token::EnumNewType(_, variant)) => { + Token::EnumUnit(_, variant) => visitor.visit_str(variant), + Token::EnumNewType(_, variant) => { visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Any)) } - Some(Token::EnumSeqStart(_, variant, _)) => { + Token::EnumSeqStart(_, variant, _) => { visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Seq)) } - Some(Token::EnumMapStart(_, variant, _)) => { + Token::EnumMapStart(_, variant, _) => { visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Map)) } - Some(token) => Err(Error::UnexpectedToken(token)), - None => Err(Error::EndOfTokens), + Token::SeqEnd | + Token::TupleEnd | + Token::TupleStructEnd | + Token::MapEnd | + Token::StructEnd | + Token::EnumSeqEnd | + Token::EnumMapEnd => Err(Error::UnexpectedToken(token)), } } From b6605b57e04b28f0a1cdbcbd65f21a9e7f6550f1 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 10:26:34 -0700 Subject: [PATCH 024/177] Modernize serde_test Token names --- serde_test/src/token.rs | 50 +++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/serde_test/src/token.rs b/serde_test/src/token.rs index 5e9cead0..a9d01a33 100644 --- a/serde_test/src/token.rs +++ b/serde_test/src/token.rs @@ -54,11 +54,13 @@ pub enum Token { /// A serialized `ByteBuf` ByteBuf(&'static [u8]), - /// The header to a serialized `Option`. + /// The header to a serialized `Option` containing some value. /// - /// `None` is serialized as `Option(false)`, while `Some` is serialized as `Option(true)`, then - /// the value contained in the option. - Option(bool), + /// The tokens of the value follow after this header. + Some, + + /// A serialized `Option` containing none. + None, /// A serialized `()`. Unit, @@ -70,52 +72,46 @@ pub enum Token { /// /// Newtype structs are serialized with this header, followed by the value contained in the /// newtype struct. - StructNewType(&'static str), + NewtypeStruct(&'static str), /// The header to an enum of the given name. - /// - /// This token is only used for deserializers, and ensures that the following tokens are read as - /// an enum. Because this is never emitted by serializers, calling `assert_ser_tokens` or - /// `assert_tokens` will fail if this token is used. - /// - /// TODO: Trash this. - EnumStart(&'static str), + Enum(&'static str), /// A unit variant of an enum of the given name, of the given name. /// /// The first string represents the name of the enum, and the second represents the name of the /// variant. - EnumUnit(&'static str, &'static str), + UnitVariant(&'static str, &'static str), /// The header to a newtype variant of an enum of the given name, of the given name. /// /// The first string represents the name of the enum, and the second represents the name of the /// variant. The value contained within this enum works the same as `StructNewType`. - EnumNewType(&'static str, &'static str), + NewtypeVariant(&'static str, &'static str), /// The header to a sequence of the given length. /// /// These are serialized via `serialize_seq`, which takes an optional length. After this /// header is a list of elements, followed by `SeqEnd`. - SeqStart(Option), + Seq(Option), /// The header to an array of the given length. /// /// These are serialized via `serialize_seq_fized_size`, which requires a length. After this /// header is a list of elements, followed by `SeqEnd`. - SeqArrayStart(usize), + SeqFixedSize(usize), /// An indicator of the end of a sequence. SeqEnd, - /// The header to a tuple of the given length, similar to `SeqArrayStart`. - TupleStart(usize), + /// The header to a tuple of the given length, similar to `SeqFixedSize`. + Tuple(usize), /// An indicator of the end of a tuple, similar to `SeqEnd`. TupleEnd, /// The header to a tuple struct of the given name and length. - TupleStructStart(&'static str, usize), + TupleStruct(&'static str, usize), /// An indicator of the end of a tuple struct, similar to `TupleEnd`. TupleStructEnd, @@ -124,27 +120,27 @@ pub enum Token { /// /// These are serialized via `serialize_map`, which takes an optional length. After this header /// is a list of key-value pairs, followed by `MapEnd`. - MapStart(Option), + Map(Option), /// An indicator of the end of a map. MapEnd, - /// The header of a struct of the given name and length, similar to `MapStart`. - StructStart(&'static str, usize), + /// The header of a struct of the given name and length, similar to `Map`. + Struct(&'static str, usize), /// An indicator of the end of a struct, similar to `MapEnd`. StructEnd, /// The header to a tuple variant of an enum of the given name, of the given name and length. - EnumSeqStart(&'static str, &'static str, usize), + TupleVariant(&'static str, &'static str, usize), /// An indicator of the end of a tuple variant, similar to `TupleEnd`. - EnumSeqEnd, + TupleVariantEnd, /// The header of a struct variant of an enum of the given name, of the given name and length, - /// similar to `StructStart`. - EnumMapStart(&'static str, &'static str, usize), + /// similar to `Struct`. + StructVariant(&'static str, &'static str, usize), /// An indicator of the end of a struct, similar to `StructEnd`. - EnumMapEnd, + StructVariantEnd, } From 826b53f691eb523436d1e4f0b28c5bc0aec52ecd Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 10:30:46 -0700 Subject: [PATCH 025/177] Update token names in serde_test --- serde_test/src/de.rs | 102 +++++++++++++++++++++--------------------- serde_test/src/ser.rs | 34 +++++++------- 2 files changed, 68 insertions(+), 68 deletions(-) diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index 8bfb8f70..fcbb762b 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -104,32 +104,32 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { Token::Bytes(v) => visitor.visit_bytes(v), Token::BorrowedBytes(v) => visitor.visit_borrowed_bytes(v), Token::ByteBuf(v) => visitor.visit_byte_buf(v.to_vec()), - Token::Option(false) => visitor.visit_none(), - Token::Option(true) => visitor.visit_some(self), + Token::None => visitor.visit_none(), + Token::Some => visitor.visit_some(self), Token::Unit => visitor.visit_unit(), Token::UnitStruct(_name) => visitor.visit_unit(), - Token::StructNewType(_name) => visitor.visit_newtype_struct(self), - Token::SeqStart(len) => { + Token::NewtypeStruct(_name) => visitor.visit_newtype_struct(self), + Token::Seq(len) => { self.visit_seq(len, Token::SeqEnd, visitor) } - Token::SeqArrayStart(len) => { + Token::SeqFixedSize(len) => { self.visit_seq(Some(len), Token::SeqEnd, visitor) } - Token::TupleStart(len) => { + Token::Tuple(len) => { self.visit_seq(Some(len), Token::TupleEnd, visitor) } - Token::TupleStructStart(_, len) => { + Token::TupleStruct(_, len) => { self.visit_seq(Some(len), Token::TupleStructEnd, visitor) } - Token::MapStart(len) => { + Token::Map(len) => { self.visit_map(len, Token::MapEnd, visitor) } - Token::StructStart(_, len) => { + Token::Struct(_, len) => { self.visit_map(Some(len), Token::StructEnd, visitor) } - Token::EnumStart(_) => { + Token::Enum(_) => { let variant = self.next_token().ok_or(Error::EndOfTokens)?; let next = *self.tokens.first().ok_or(Error::EndOfTokens)?; match (variant, next) { @@ -153,14 +153,14 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } } } - Token::EnumUnit(_, variant) => visitor.visit_str(variant), - Token::EnumNewType(_, variant) => { + Token::UnitVariant(_, variant) => visitor.visit_str(variant), + Token::NewtypeVariant(_, variant) => { visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Any)) } - Token::EnumSeqStart(_, variant, _) => { + Token::TupleVariant(_, variant, _) => { visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Seq)) } - Token::EnumMapStart(_, variant, _) => { + Token::StructVariant(_, variant, _) => { visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Map)) } Token::SeqEnd | @@ -168,8 +168,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { Token::TupleStructEnd | Token::MapEnd | Token::StructEnd | - Token::EnumSeqEnd | - Token::EnumMapEnd => Err(Error::UnexpectedToken(token)), + Token::TupleVariantEnd | + Token::StructVariantEnd => Err(Error::UnexpectedToken(token)), } } @@ -180,11 +180,11 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { { match self.tokens.first() { Some(&Token::Unit) | - Some(&Token::Option(false)) => { + Some(&Token::None) => { self.next_token(); visitor.visit_none() } - Some(&Token::Option(true)) => { + Some(&Token::Some) => { self.next_token(); visitor.visit_some(self) } @@ -201,15 +201,15 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de> { match self.tokens.first() { - Some(&Token::EnumStart(n)) if name == n => { + Some(&Token::Enum(n)) if name == n => { self.next_token(); visitor.visit_enum(DeserializerEnumVisitor { de: self }) } - Some(&Token::EnumUnit(n, _)) | - Some(&Token::EnumNewType(n, _)) | - Some(&Token::EnumSeqStart(n, _, _)) | - Some(&Token::EnumMapStart(n, _, _)) if name == n => { + Some(&Token::UnitVariant(n, _)) | + Some(&Token::NewtypeVariant(n, _)) | + Some(&Token::TupleVariant(n, _, _)) | + Some(&Token::StructVariant(n, _, _)) if name == n => { visitor.visit_enum(DeserializerEnumVisitor { de: self }) } Some(_) => { @@ -241,7 +241,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de> { match self.tokens.first() { - Some(&Token::StructNewType(n)) => { + Some(&Token::NewtypeStruct(n)) => { self.next_token(); if name == n { visitor.visit_newtype_struct(self) @@ -258,7 +258,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de> { match self.tokens.first() { - Some(&Token::SeqArrayStart(_)) => { + Some(&Token::SeqFixedSize(_)) => { self.next_token(); self.visit_seq(Some(len), Token::SeqEnd, visitor) } @@ -276,19 +276,19 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { self.next_token(); visitor.visit_unit() } - Some(&Token::SeqStart(_)) => { + Some(&Token::Seq(_)) => { self.next_token(); self.visit_seq(Some(len), Token::SeqEnd, visitor) } - Some(&Token::SeqArrayStart(_)) => { + Some(&Token::SeqFixedSize(_)) => { self.next_token(); self.visit_seq(Some(len), Token::SeqEnd, visitor) } - Some(&Token::TupleStart(_)) => { + Some(&Token::Tuple(_)) => { self.next_token(); self.visit_seq(Some(len), Token::TupleEnd, visitor) } - Some(&Token::TupleStructStart(_, _)) => { + Some(&Token::TupleStruct(_, _)) => { self.next_token(); self.visit_seq(Some(len), Token::TupleStructEnd, @@ -319,19 +319,19 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { Err(Error::InvalidName(n)) } } - Some(&Token::SeqStart(_)) => { + Some(&Token::Seq(_)) => { self.next_token(); self.visit_seq(Some(len), Token::SeqEnd, visitor) } - Some(&Token::SeqArrayStart(_)) => { + Some(&Token::SeqFixedSize(_)) => { self.next_token(); self.visit_seq(Some(len), Token::SeqEnd, visitor) } - Some(&Token::TupleStart(_)) => { + Some(&Token::Tuple(_)) => { self.next_token(); self.visit_seq(Some(len), Token::TupleEnd, visitor) } - Some(&Token::TupleStructStart(n, _)) => { + Some(&Token::TupleStruct(n, _)) => { self.next_token(); if name == n { self.visit_seq(Some(len), @@ -354,7 +354,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de> { match self.tokens.first() { - Some(&Token::StructStart(n, _)) => { + Some(&Token::Struct(n, _)) => { self.next_token(); if name == n { self.visit_map(Some(fields.len()), @@ -364,7 +364,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { Err(Error::InvalidName(n)) } } - Some(&Token::MapStart(_)) => { + Some(&Token::Map(_)) => { self.next_token(); self.visit_map(Some(fields.len()), Token::MapEnd, visitor) } @@ -448,10 +448,10 @@ impl<'de, 'a> EnumVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { where V: DeserializeSeed<'de> { match self.de.tokens.first() { - Some(&Token::EnumUnit(_, v)) | - Some(&Token::EnumNewType(_, v)) | - Some(&Token::EnumSeqStart(_, v, _)) | - Some(&Token::EnumMapStart(_, v, _)) => { + Some(&Token::UnitVariant(_, v)) | + Some(&Token::NewtypeVariant(_, v)) | + Some(&Token::TupleVariant(_, v, _)) | + Some(&Token::StructVariant(_, v, _)) => { let de = v.into_deserializer(); let value = try!(seed.deserialize(de)); Ok((value, self)) @@ -470,7 +470,7 @@ impl<'de, 'a> VariantVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { fn visit_unit(self) -> Result<(), Error> { match self.de.tokens.first() { - Some(&Token::EnumUnit(_, _)) => { + Some(&Token::UnitVariant(_, _)) => { self.de.next_token(); Ok(()) } @@ -483,7 +483,7 @@ impl<'de, 'a> VariantVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { where T: DeserializeSeed<'de> { match self.de.tokens.first() { - Some(&Token::EnumNewType(_, _)) => { + Some(&Token::NewtypeVariant(_, _)) => { self.de.next_token(); seed.deserialize(self.de) } @@ -496,16 +496,16 @@ impl<'de, 'a> VariantVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { where V: Visitor<'de> { match self.de.tokens.first() { - Some(&Token::EnumSeqStart(_, _, enum_len)) => { + Some(&Token::TupleVariant(_, _, enum_len)) => { let token = self.de.next_token().unwrap(); if len == enum_len { - self.de.visit_seq(Some(len), Token::EnumSeqEnd, visitor) + self.de.visit_seq(Some(len), Token::TupleVariantEnd, visitor) } else { Err(Error::UnexpectedToken(token)) } } - Some(&Token::SeqStart(Some(enum_len))) => { + Some(&Token::Seq(Some(enum_len))) => { let token = self.de.next_token().unwrap(); if len == enum_len { @@ -523,18 +523,18 @@ impl<'de, 'a> VariantVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { where V: Visitor<'de> { match self.de.tokens.first() { - Some(&Token::EnumMapStart(_, _, enum_len)) => { + Some(&Token::StructVariant(_, _, enum_len)) => { let token = self.de.next_token().unwrap(); if fields.len() == enum_len { self.de.visit_map(Some(fields.len()), - Token::EnumMapEnd, + Token::StructVariantEnd, visitor) } else { Err(Error::UnexpectedToken(token)) } } - Some(&Token::MapStart(Some(enum_len))) => { + Some(&Token::Map(Some(enum_len))) => { let token = self.de.next_token().unwrap(); if fields.len() == enum_len { @@ -605,11 +605,11 @@ impl<'de, 'a> MapVisitor<'de> for EnumMapVisitor<'a, 'de> { let visitor = DeserializerSeqVisitor { de: self.de, len: None, - end: Token::EnumSeqEnd, + end: Token::TupleVariantEnd, }; try!(seed.deserialize(SeqVisitorDeserializer::new(visitor))) }; - try!(self.de.expect_token(Token::EnumSeqEnd)); + try!(self.de.expect_token(Token::TupleVariantEnd)); Ok(value) } EnumFormat::Map => { @@ -617,11 +617,11 @@ impl<'de, 'a> MapVisitor<'de> for EnumMapVisitor<'a, 'de> { let visitor = DeserializerMapVisitor { de: self.de, len: None, - end: Token::EnumMapEnd, + end: Token::StructVariantEnd, }; try!(seed.deserialize(MapVisitorDeserializer::new(visitor))) }; - try!(self.de.expect_token(Token::EnumMapEnd)); + try!(self.de.expect_token(Token::StructVariantEnd)); Ok(value) } EnumFormat::Any => seed.deserialize(&mut *self.de), diff --git a/serde_test/src/ser.rs b/serde_test/src/ser.rs index 919565b1..2a82970f 100644 --- a/serde_test/src/ser.rs +++ b/serde_test/src/ser.rs @@ -149,12 +149,12 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { _variant_index: usize, variant: &'static str) -> Result<(), Error> { - if self.tokens.first() == Some(&Token::EnumStart(name)) { + if self.tokens.first() == Some(&Token::Enum(name)) { self.next_token(); assert_next_token!(self, Str(variant)); assert_next_token!(self, Unit); } else { - assert_next_token!(self, EnumUnit(name, variant)); + assert_next_token!(self, UnitVariant(name, variant)); } Ok(()) } @@ -162,7 +162,7 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { fn serialize_newtype_struct(self, name: &'static str, value: &T) -> Result<(), Error> where T: Serialize { - assert_next_token!(self, StructNewType(name)); + assert_next_token!(self, NewtypeStruct(name)); value.serialize(self) } @@ -174,44 +174,44 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { -> Result<(), Error> where T: Serialize { - if self.tokens.first() == Some(&Token::EnumStart(name)) { + if self.tokens.first() == Some(&Token::Enum(name)) { self.next_token(); assert_next_token!(self, Str(variant)); } else { - assert_next_token!(self, EnumNewType(name, variant)); + assert_next_token!(self, NewtypeVariant(name, variant)); } value.serialize(self) } fn serialize_none(self) -> Result<(), Error> { - assert_next_token!(self, Option(false)); + assert_next_token!(self, None); Ok(()) } fn serialize_some(self, value: &T) -> Result<(), Error> where T: Serialize { - assert_next_token!(self, Option(true)); + assert_next_token!(self, Some); value.serialize(self) } fn serialize_seq(self, len: Option) -> Result { - assert_next_token!(self, SeqStart(len)); + assert_next_token!(self, Seq(len)); Ok(self) } fn serialize_seq_fixed_size(self, len: usize) -> Result { - assert_next_token!(self, SeqArrayStart(len)); + assert_next_token!(self, SeqFixedSize(len)); Ok(self) } fn serialize_tuple(self, len: usize) -> Result { - assert_next_token!(self, TupleStart(len)); + assert_next_token!(self, Tuple(len)); Ok(self) } fn serialize_tuple_struct(self, name: &'static str, len: usize) -> Result { - assert_next_token!(self, TupleStructStart(name, len)); + assert_next_token!(self, TupleStruct(name, len)); Ok(self) } @@ -221,17 +221,17 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { variant: &'static str, len: usize) -> Result { - assert_next_token!(self, EnumSeqStart(name, variant, len)); + assert_next_token!(self, TupleVariant(name, variant, len)); Ok(self) } fn serialize_map(self, len: Option) -> Result { - assert_next_token!(self, MapStart(len)); + assert_next_token!(self, Map(len)); Ok(self) } fn serialize_struct(self, name: &'static str, len: usize) -> Result { - assert_next_token!(self, StructStart(name, len)); + assert_next_token!(self, Struct(name, len)); Ok(self) } @@ -241,7 +241,7 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { variant: &'static str, len: usize) -> Result { - assert_next_token!(self, EnumMapStart(name, variant, len)); + assert_next_token!(self, StructVariant(name, variant, len)); Ok(self) } } @@ -305,7 +305,7 @@ impl<'s, 'a> ser::SerializeTupleVariant for &'s mut Serializer<'a> { } fn end(self) -> Result<(), Error> { - assert_next_token!(self, EnumSeqEnd); + assert_next_token!(self, TupleVariantEnd); Ok(()) } } @@ -367,7 +367,7 @@ impl<'s, 'a> ser::SerializeStructVariant for &'s mut Serializer<'a> { } fn end(self) -> Result<(), Self::Error> { - assert_next_token!(self, EnumMapEnd); + assert_next_token!(self, StructVariantEnd); Ok(()) } } From 51d3fb1ebc89727bb4a722452ed976e8b8439323 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 10:40:14 -0700 Subject: [PATCH 026/177] Update token names in test suite --- test_suite/tests/test_annotations.rs | 124 ++++++++--------- test_suite/tests/test_borrow.rs | 6 +- test_suite/tests/test_bytes.rs | 8 +- test_suite/tests/test_de.rs | 200 +++++++++++++-------------- test_suite/tests/test_macros.rs | 158 ++++++++++----------- test_suite/tests/test_ser.rs | 74 +++++----- 6 files changed, 285 insertions(+), 285 deletions(-) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index 1eef647c..490fb724 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -85,7 +85,7 @@ fn test_default_struct() { assert_de_tokens( &DefaultStruct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 }, &[ - Token::StructStart("DefaultStruct", 3), + Token::Struct("DefaultStruct", 3), Token::Str("a1"), Token::I32(1), @@ -109,7 +109,7 @@ fn test_default_struct() { assert_de_tokens( &DefaultStruct { a1: 1, a2: 0, a3: 123, a4: 0, a5: 123 }, &[ - Token::StructStart("DefaultStruct", 1), + Token::Struct("DefaultStruct", 1), Token::Str("a1"), Token::I32(1), @@ -142,7 +142,7 @@ fn test_default_enum() { assert_de_tokens( &DefaultEnum::Struct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 }, &[ - Token::EnumMapStart("DefaultEnum", "Struct", 3), + Token::StructVariant("DefaultEnum", "Struct", 3), Token::Str("a1"), Token::I32(1), @@ -159,19 +159,19 @@ fn test_default_enum() { Token::Str("a5"), Token::I32(5), - Token::EnumMapEnd, + Token::StructVariantEnd, ] ); assert_de_tokens( &DefaultEnum::Struct { a1: 1, a2: 0, a3: 123, a4: 0, a5: 123 }, &[ - Token::EnumMapStart("DefaultEnum", "Struct", 3), + Token::StructVariant("DefaultEnum", "Struct", 3), Token::Str("a1"), Token::I32(1), - Token::EnumMapEnd, + Token::StructVariantEnd, ] ); } @@ -199,7 +199,7 @@ fn test_no_std_default() { assert_de_tokens( &ContainsNoStdDefault { a: NoStdDefault(123) }, &[ - Token::StructStart("ContainsNoStdDefault", 1), + Token::Struct("ContainsNoStdDefault", 1), Token::StructEnd, ] ); @@ -207,10 +207,10 @@ fn test_no_std_default() { assert_de_tokens( &ContainsNoStdDefault { a: NoStdDefault(8) }, &[ - Token::StructStart("ContainsNoStdDefault", 1), + Token::Struct("ContainsNoStdDefault", 1), Token::Str("a"), - Token::StructNewType("NoStdDefault"), + Token::NewtypeStruct("NoStdDefault"), Token::I8(8), Token::StructEnd, @@ -271,7 +271,7 @@ fn test_elt_not_deserialize() { e: NotDeserializeEnum::Trouble, }, &[ - Token::StructStart("ContainsNotDeserialize", 3), + Token::Struct("ContainsNotDeserialize", 3), Token::StructEnd, ] ); @@ -289,7 +289,7 @@ fn test_ignore_unknown() { assert_de_tokens( &DefaultStruct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 }, &[ - Token::StructStart("DefaultStruct", 5), + Token::Struct("DefaultStruct", 5), Token::Str("whoops1"), Token::I32(2), @@ -298,7 +298,7 @@ fn test_ignore_unknown() { Token::I32(1), Token::Str("whoops2"), - Token::SeqStart(Some(1)), + Token::Seq(Some(1)), Token::I32(2), Token::SeqEnd, @@ -317,7 +317,7 @@ fn test_ignore_unknown() { assert_de_tokens_error::( &[ - Token::StructStart("DenyUnknown", 2), + Token::Struct("DenyUnknown", 2), Token::Str("a1"), Token::I32(1), @@ -349,7 +349,7 @@ fn test_rename_struct() { assert_tokens( &RenameStruct { a1: 1, a2: 2 }, &[ - Token::StructStart("Superhero", 2), + Token::Struct("Superhero", 2), Token::Str("a1"), Token::I32(1), @@ -364,7 +364,7 @@ fn test_rename_struct() { assert_ser_tokens( &RenameStructSerializeDeserialize { a1: 1, a2: 2 }, &[ - Token::StructStart("SuperheroSer", 2), + Token::Struct("SuperheroSer", 2), Token::Str("a1"), Token::I32(1), @@ -379,7 +379,7 @@ fn test_rename_struct() { assert_de_tokens( &RenameStructSerializeDeserialize { a1: 1, a2: 2 }, &[ - Token::StructStart("SuperheroDe", 2), + Token::Struct("SuperheroDe", 2), Token::Str("a1"), Token::I32(1), @@ -425,14 +425,14 @@ fn test_rename_enum() { assert_tokens( &RenameEnum::Batman, &[ - Token::EnumUnit("Superhero", "bruce_wayne"), + Token::UnitVariant("Superhero", "bruce_wayne"), ] ); assert_tokens( &RenameEnum::Superman(0), &[ - Token::EnumNewType("Superhero", "clark_kent"), + Token::NewtypeVariant("Superhero", "clark_kent"), Token::I8(0), ] ); @@ -440,22 +440,22 @@ fn test_rename_enum() { assert_tokens( &RenameEnum::WonderWoman(0, 1), &[ - Token::EnumSeqStart("Superhero", "diana_prince", 2), + Token::TupleVariant("Superhero", "diana_prince", 2), Token::I8(0), Token::I8(1), - Token::EnumSeqEnd, + Token::TupleVariantEnd, ] ); assert_tokens( &RenameEnum::Flash { a: 1 }, &[ - Token::EnumMapStart("Superhero", "barry_allan", 1), + Token::StructVariant("Superhero", "barry_allan", 1), Token::Str("b"), Token::I32(1), - Token::EnumMapEnd, + Token::StructVariantEnd, ] ); @@ -465,7 +465,7 @@ fn test_rename_enum() { b: String::new(), }, &[ - Token::EnumMapStart("SuperheroSer", "dick_grayson", 2), + Token::StructVariant("SuperheroSer", "dick_grayson", 2), Token::Str("a"), Token::I8(0), @@ -473,7 +473,7 @@ fn test_rename_enum() { Token::Str("c"), Token::Str(""), - Token::EnumMapEnd, + Token::StructVariantEnd, ] ); @@ -483,7 +483,7 @@ fn test_rename_enum() { b: String::new(), }, &[ - Token::EnumMapStart("SuperheroDe", "jason_todd", 2), + Token::StructVariant("SuperheroDe", "jason_todd", 2), Token::Str("a"), Token::I8(0), @@ -491,7 +491,7 @@ fn test_rename_enum() { Token::Str("d"), Token::Str(""), - Token::EnumMapEnd, + Token::StructVariantEnd, ] ); } @@ -515,7 +515,7 @@ fn test_skip_serializing_struct() { c: 3, }, &[ - Token::StructStart("SkipSerializingStruct", 2), + Token::Struct("SkipSerializingStruct", 2), Token::Str("a"), Token::I8(1), @@ -534,7 +534,7 @@ fn test_skip_serializing_struct() { c: 123, }, &[ - Token::StructStart("SkipSerializingStruct", 1), + Token::Struct("SkipSerializingStruct", 1), Token::Str("a"), Token::I8(1), @@ -565,7 +565,7 @@ fn test_skip_serializing_enum() { c: 3, }, &[ - Token::EnumMapStart("SkipSerializingEnum", "Struct", 2), + Token::StructVariant("SkipSerializingEnum", "Struct", 2), Token::Str("a"), Token::I8(1), @@ -573,7 +573,7 @@ fn test_skip_serializing_enum() { Token::Str("c"), Token::I32(3), - Token::EnumMapEnd, + Token::StructVariantEnd, ] ); @@ -584,12 +584,12 @@ fn test_skip_serializing_enum() { c: 123, }, &[ - Token::EnumMapStart("SkipSerializingEnum", "Struct", 1), + Token::StructVariant("SkipSerializingEnum", "Struct", 1), Token::Str("a"), Token::I8(1), - Token::EnumMapEnd, + Token::StructVariantEnd, ] ); } @@ -630,10 +630,10 @@ fn test_elt_not_serialize() { d: NotSerializeEnum::Trouble, }, &[ - Token::StructStart("ContainsNotSerialize", 2), + Token::Struct("ContainsNotSerialize", 2), Token::Str("a"), - Token::Option(true), + Token::Some, Token::I8(1), Token::Str("d"), @@ -660,7 +660,7 @@ fn test_serialize_with_struct() { b: 2, }, &[ - Token::StructStart("SerializeWithStruct", 2), + Token::Struct("SerializeWithStruct", 2), Token::Str("a"), Token::I8(1), @@ -678,7 +678,7 @@ fn test_serialize_with_struct() { b: 123, }, &[ - Token::StructStart("SerializeWithStruct", 2), + Token::Struct("SerializeWithStruct", 2), Token::Str("a"), Token::I8(1), @@ -709,7 +709,7 @@ fn test_serialize_with_enum() { b: 2, }, &[ - Token::EnumMapStart("SerializeWithEnum", "Struct", 2), + Token::StructVariant("SerializeWithEnum", "Struct", 2), Token::Str("a"), Token::I8(1), @@ -717,7 +717,7 @@ fn test_serialize_with_enum() { Token::Str("b"), Token::Bool(false), - Token::EnumMapEnd, + Token::StructVariantEnd, ] ); @@ -727,7 +727,7 @@ fn test_serialize_with_enum() { b: 123, }, &[ - Token::EnumMapStart("SerializeWithEnum", "Struct", 2), + Token::StructVariant("SerializeWithEnum", "Struct", 2), Token::Str("a"), Token::I8(1), @@ -735,7 +735,7 @@ fn test_serialize_with_enum() { Token::Str("b"), Token::Bool(true), - Token::EnumMapEnd, + Token::StructVariantEnd, ] ); } @@ -755,7 +755,7 @@ fn test_deserialize_with_struct() { b: 2, }, &[ - Token::StructStart("DeserializeWithStruct", 2), + Token::Struct("DeserializeWithStruct", 2), Token::Str("a"), Token::I8(1), @@ -773,7 +773,7 @@ fn test_deserialize_with_struct() { b: 123, }, &[ - Token::StructStart("DeserializeWithStruct", 2), + Token::Struct("DeserializeWithStruct", 2), Token::Str("a"), Token::I8(1), @@ -803,7 +803,7 @@ fn test_deserialize_with_enum() { b: 2, }, &[ - Token::EnumMapStart("DeserializeWithEnum", "Struct", 2), + Token::StructVariant("DeserializeWithEnum", "Struct", 2), Token::Str("a"), Token::I8(1), @@ -811,7 +811,7 @@ fn test_deserialize_with_enum() { Token::Str("b"), Token::Bool(false), - Token::EnumMapEnd, + Token::StructVariantEnd, ] ); @@ -821,7 +821,7 @@ fn test_deserialize_with_enum() { b: 123, }, &[ - Token::EnumMapStart("DeserializeWithEnum", "Struct", 2), + Token::StructVariant("DeserializeWithEnum", "Struct", 2), Token::Str("a"), Token::I8(1), @@ -829,7 +829,7 @@ fn test_deserialize_with_enum() { Token::Str("b"), Token::Bool(true), - Token::EnumMapEnd, + Token::StructVariantEnd, ] ); } @@ -838,7 +838,7 @@ fn test_deserialize_with_enum() { fn test_missing_renamed_field_struct() { assert_de_tokens_error::( &[ - Token::StructStart("Superhero", 2), + Token::Struct("Superhero", 2), Token::Str("a1"), Token::I32(1), @@ -850,7 +850,7 @@ fn test_missing_renamed_field_struct() { assert_de_tokens_error::( &[ - Token::StructStart("SuperheroDe", 2), + Token::Struct("SuperheroDe", 2), Token::Str("a1"), Token::I32(1), @@ -865,21 +865,21 @@ fn test_missing_renamed_field_struct() { fn test_missing_renamed_field_enum() { assert_de_tokens_error::( &[ - Token::EnumMapStart("Superhero", "barry_allan", 1), + Token::StructVariant("Superhero", "barry_allan", 1), - Token::EnumMapEnd, + Token::StructVariantEnd, ], Error::Message("missing field `b`".to_owned()), ); assert_de_tokens_error::>( &[ - Token::EnumMapStart("SuperheroDe", "jason_todd", 2), + Token::StructVariant("SuperheroDe", "jason_todd", 2), Token::Str("a"), Token::I8(0), - Token::EnumMapEnd, + Token::StructVariantEnd, ], Error::Message("missing field `d`".to_owned()), ); @@ -895,17 +895,17 @@ enum InvalidLengthEnum { fn test_invalid_length_enum() { assert_de_tokens_error::( &[ - Token::EnumSeqStart("InvalidLengthEnum", "A", 3), + Token::TupleVariant("InvalidLengthEnum", "A", 3), Token::I32(1), - Token::EnumSeqEnd, + Token::TupleVariantEnd, ], Error::Message("invalid length 1, expected tuple of 3 elements".to_owned()), ); assert_de_tokens_error::( &[ - Token::EnumSeqStart("InvalidLengthEnum", "B", 3), + Token::TupleVariant("InvalidLengthEnum", "B", 3), Token::I32(1), - Token::EnumSeqEnd, + Token::TupleVariantEnd, ], Error::Message("invalid length 1, expected tuple of 2 elements".to_owned()), ); @@ -966,26 +966,26 @@ impl From> for EnumToU32 { #[test] fn test_from_into_traits() { assert_ser_tokens::(&EnumToU32::One, - &[Token::Option(true), + &[Token::Some, Token::U32(1) ] ); assert_ser_tokens::(&EnumToU32::Nothing, - &[Token::Option(false)] + &[Token::None] ); assert_de_tokens::(&EnumToU32::Two, - &[Token::Option(true), + &[Token::Some, Token::U32(2) ] ); assert_ser_tokens::(&StructFromEnum(Some(5)), - &[Token::Option(false)] + &[Token::None] ); assert_ser_tokens::(&StructFromEnum(None), - &[Token::Option(false)] + &[Token::None] ); assert_de_tokens::(&StructFromEnum(Some(2)), - &[Token::Option(true), + &[Token::Some, Token::U32(2) ] ); diff --git a/test_suite/tests/test_borrow.rs b/test_suite/tests/test_borrow.rs index c12bcdcd..b440a380 100644 --- a/test_suite/tests/test_borrow.rs +++ b/test_suite/tests/test_borrow.rs @@ -89,7 +89,7 @@ fn test_tuple() { assert_de_tokens( &("str", &b"bytes"[..]), &[ - Token::TupleStart(2), + Token::Tuple(2), Token::BorrowedStr("str"), Token::BorrowedBytes(b"bytes"), Token::TupleEnd, @@ -108,7 +108,7 @@ fn test_struct() { assert_de_tokens( &Borrowing { bs: "str", bb: b"bytes" }, &[ - Token::StructStart("Borrowing", 2), + Token::Struct("Borrowing", 2), Token::BorrowedStr("bs"), Token::BorrowedStr("str"), @@ -132,7 +132,7 @@ fn test_cow() { } let tokens = &[ - Token::StructStart("Cows", 2), + Token::Struct("Cows", 2), Token::Str("copied"), Token::BorrowedStr("copied"), diff --git a/test_suite/tests/test_bytes.rs b/test_suite/tests/test_bytes.rs index 3cc941d3..4da64e1c 100644 --- a/test_suite/tests/test_bytes.rs +++ b/test_suite/tests/test_bytes.rs @@ -22,11 +22,11 @@ fn test_byte_buf() { assert_de_tokens(&empty, &[Token::Str("")]); assert_de_tokens(&empty, &[Token::String("")]); assert_de_tokens(&empty, &[ - Token::SeqStart(None), + Token::Seq(None), Token::SeqEnd, ]); assert_de_tokens(&empty, &[ - Token::SeqStart(Some(0)), + Token::Seq(Some(0)), Token::SeqEnd, ]); @@ -36,14 +36,14 @@ fn test_byte_buf() { assert_de_tokens(&buf, &[Token::Str("ABC")]); assert_de_tokens(&buf, &[Token::String("ABC")]); assert_de_tokens(&buf, &[ - Token::SeqStart(None), + Token::Seq(None), Token::U8(65), Token::U8(66), Token::U8(67), Token::SeqEnd, ]); assert_de_tokens(&buf, &[ - Token::SeqStart(Some(3)), + Token::Seq(Some(3)), Token::U8(65), Token::U8(66), Token::U8(67), diff --git a/test_suite/tests/test_de.rs b/test_suite/tests/test_de.rs index 5fe900e1..eb8a9705 100644 --- a/test_suite/tests/test_de.rs +++ b/test_suite/tests/test_de.rs @@ -151,7 +151,7 @@ fn assert_de_tokens_ignore(ignorable_tokens: &[Token]) { // Embed the tokens to be ignored in the normal token // stream for an IgnoreBase type let concated_tokens : Vec = vec![ - Token::MapStart(Some(2)), + Token::Map(Some(2)), Token::Str("a"), Token::I32(1), @@ -218,20 +218,20 @@ declare_tests! { } test_option { None:: => &[Token::Unit], - None:: => &[Token::Option(false)], + None:: => &[Token::None], Some(1) => &[ - Token::Option(true), + Token::Some, Token::I32(1), ], } test_result { Ok::(0) => &[ - Token::EnumStart("Result"), + Token::Enum("Result"), Token::Str("Ok"), Token::I32(0), ], Err::(1) => &[ - Token::EnumStart("Result"), + Token::Enum("Result"), Token::Str("Err"), Token::I32(1), ], @@ -245,44 +245,44 @@ declare_tests! { Token::UnitStruct("UnitStruct"), ], UnitStruct => &[ - Token::SeqStart(Some(0)), + Token::Seq(Some(0)), Token::SeqEnd, ], UnitStruct => &[ - Token::SeqStart(None), + Token::Seq(None), Token::SeqEnd, ], } test_newtype_struct { NewtypeStruct(1) => &[ - Token::StructNewType("NewtypeStruct"), + Token::NewtypeStruct("NewtypeStruct"), Token::I32(1), ], } test_tuple_struct { TupleStruct(1, 2, 3) => &[ - Token::SeqStart(Some(3)), + Token::Seq(Some(3)), Token::I32(1), Token::I32(2), Token::I32(3), Token::SeqEnd, ], TupleStruct(1, 2, 3) => &[ - Token::SeqStart(None), + Token::Seq(None), Token::I32(1), Token::I32(2), Token::I32(3), Token::SeqEnd, ], TupleStruct(1, 2, 3) => &[ - Token::TupleStructStart("TupleStruct", 3), + Token::TupleStruct("TupleStruct", 3), Token::I32(1), Token::I32(2), Token::I32(3), Token::TupleStructEnd, ], TupleStruct(1, 2, 3) => &[ - Token::TupleStructStart("TupleStruct", 3), + Token::TupleStruct("TupleStruct", 3), Token::I32(1), Token::I32(2), Token::I32(3), @@ -291,47 +291,47 @@ declare_tests! { } test_btreeset { BTreeSet::::new() => &[ - Token::SeqStart(Some(0)), + Token::Seq(Some(0)), Token::SeqEnd, ], btreeset![btreeset![], btreeset![1], btreeset![2, 3]] => &[ - Token::SeqStart(Some(3)), - Token::SeqStart(Some(0)), + Token::Seq(Some(3)), + Token::Seq(Some(0)), Token::SeqEnd, - Token::SeqStart(Some(1)), + Token::Seq(Some(1)), Token::I32(1), Token::SeqEnd, - Token::SeqStart(Some(2)), + Token::Seq(Some(2)), Token::I32(2), Token::I32(3), Token::SeqEnd, Token::SeqEnd, ], BTreeSet::::new() => &[ - Token::TupleStructStart("Anything", 0), + Token::TupleStruct("Anything", 0), Token::TupleStructEnd, ], } test_hashset { HashSet::::new() => &[ - Token::SeqStart(Some(0)), + Token::Seq(Some(0)), Token::SeqEnd, ], hashset![1, 2, 3] => &[ - Token::SeqStart(Some(3)), + Token::Seq(Some(3)), Token::I32(1), Token::I32(2), Token::I32(3), Token::SeqEnd, ], HashSet::::new() => &[ - Token::TupleStructStart("Anything", 0), + Token::TupleStruct("Anything", 0), Token::TupleStructEnd, ], hashset![FnvHasher @ 1, 2, 3] => &[ - Token::SeqStart(Some(3)), + Token::Seq(Some(3)), Token::I32(1), Token::I32(2), Token::I32(3), @@ -340,93 +340,93 @@ declare_tests! { } test_vec { Vec::::new() => &[ - Token::SeqStart(Some(0)), + Token::Seq(Some(0)), Token::SeqEnd, ], vec![vec![], vec![1], vec![2, 3]] => &[ - Token::SeqStart(Some(3)), - Token::SeqStart(Some(0)), + Token::Seq(Some(3)), + Token::Seq(Some(0)), Token::SeqEnd, - Token::SeqStart(Some(1)), + Token::Seq(Some(1)), Token::I32(1), Token::SeqEnd, - Token::SeqStart(Some(2)), + Token::Seq(Some(2)), Token::I32(2), Token::I32(3), Token::SeqEnd, Token::SeqEnd, ], Vec::::new() => &[ - Token::TupleStructStart("Anything", 0), + Token::TupleStruct("Anything", 0), Token::TupleStructEnd, ], } test_array { [0; 0] => &[ - Token::SeqStart(Some(0)), + Token::Seq(Some(0)), Token::SeqEnd, ], [0; 0] => &[ - Token::SeqArrayStart(0), + Token::SeqFixedSize(0), Token::SeqEnd, ], ([0; 0], [1], [2, 3]) => &[ - Token::SeqStart(Some(3)), - Token::SeqStart(Some(0)), + Token::Seq(Some(3)), + Token::Seq(Some(0)), Token::SeqEnd, - Token::SeqStart(Some(1)), + Token::Seq(Some(1)), Token::I32(1), Token::SeqEnd, - Token::SeqStart(Some(2)), + Token::Seq(Some(2)), Token::I32(2), Token::I32(3), Token::SeqEnd, Token::SeqEnd, ], ([0; 0], [1], [2, 3]) => &[ - Token::SeqArrayStart(3), - Token::SeqArrayStart(0), + Token::SeqFixedSize(3), + Token::SeqFixedSize(0), Token::SeqEnd, - Token::SeqArrayStart(1), + Token::SeqFixedSize(1), Token::I32(1), Token::SeqEnd, - Token::SeqArrayStart(2), + Token::SeqFixedSize(2), Token::I32(2), Token::I32(3), Token::SeqEnd, Token::SeqEnd, ], [0; 0] => &[ - Token::TupleStructStart("Anything", 0), + Token::TupleStruct("Anything", 0), Token::TupleStructEnd, ], } test_tuple { (1,) => &[ - Token::SeqStart(Some(1)), + Token::Seq(Some(1)), Token::I32(1), Token::SeqEnd, ], (1, 2, 3) => &[ - Token::SeqStart(Some(3)), + Token::Seq(Some(3)), Token::I32(1), Token::I32(2), Token::I32(3), Token::SeqEnd, ], (1,) => &[ - Token::TupleStart(1), + Token::Tuple(1), Token::I32(1), Token::TupleEnd, ], (1, 2, 3) => &[ - Token::TupleStart(3), + Token::Tuple(3), Token::I32(1), Token::I32(2), Token::I32(3), @@ -435,17 +435,17 @@ declare_tests! { } test_btreemap { BTreeMap::::new() => &[ - Token::MapStart(Some(0)), + Token::Map(Some(0)), Token::MapEnd, ], btreemap![1 => 2] => &[ - Token::MapStart(Some(1)), + Token::Map(Some(1)), Token::I32(1), Token::I32(2), Token::MapEnd, ], btreemap![1 => 2, 3 => 4] => &[ - Token::MapStart(Some(2)), + Token::Map(Some(2)), Token::I32(1), Token::I32(2), @@ -454,13 +454,13 @@ declare_tests! { Token::MapEnd, ], btreemap![1 => btreemap![], 2 => btreemap![3 => 4, 5 => 6]] => &[ - Token::MapStart(Some(2)), + Token::Map(Some(2)), Token::I32(1), - Token::MapStart(Some(0)), + Token::Map(Some(0)), Token::MapEnd, Token::I32(2), - Token::MapStart(Some(2)), + Token::Map(Some(2)), Token::I32(3), Token::I32(4), @@ -470,23 +470,23 @@ declare_tests! { Token::MapEnd, ], BTreeMap::::new() => &[ - Token::StructStart("Anything", 0), + Token::Struct("Anything", 0), Token::StructEnd, ], } test_hashmap { HashMap::::new() => &[ - Token::MapStart(Some(0)), + Token::Map(Some(0)), Token::MapEnd, ], hashmap![1 => 2] => &[ - Token::MapStart(Some(1)), + Token::Map(Some(1)), Token::I32(1), Token::I32(2), Token::MapEnd, ], hashmap![1 => 2, 3 => 4] => &[ - Token::MapStart(Some(2)), + Token::Map(Some(2)), Token::I32(1), Token::I32(2), @@ -495,13 +495,13 @@ declare_tests! { Token::MapEnd, ], hashmap![1 => hashmap![], 2 => hashmap![3 => 4, 5 => 6]] => &[ - Token::MapStart(Some(2)), + Token::Map(Some(2)), Token::I32(1), - Token::MapStart(Some(0)), + Token::Map(Some(0)), Token::MapEnd, Token::I32(2), - Token::MapStart(Some(2)), + Token::Map(Some(2)), Token::I32(3), Token::I32(4), @@ -511,11 +511,11 @@ declare_tests! { Token::MapEnd, ], HashMap::::new() => &[ - Token::StructStart("Anything", 0), + Token::Struct("Anything", 0), Token::StructEnd, ], hashmap![FnvHasher @ 1 => 2, 3 => 4] => &[ - Token::MapStart(Some(2)), + Token::Map(Some(2)), Token::I32(1), Token::I32(2), @@ -526,7 +526,7 @@ declare_tests! { } test_struct { Struct { a: 1, b: 2, c: 0 } => &[ - Token::MapStart(Some(3)), + Token::Map(Some(3)), Token::Str("a"), Token::I32(1), @@ -535,7 +535,7 @@ declare_tests! { Token::MapEnd, ], Struct { a: 1, b: 2, c: 0 } => &[ - Token::StructStart("Struct", 3), + Token::Struct("Struct", 3), Token::Str("a"), Token::I32(1), @@ -544,7 +544,7 @@ declare_tests! { Token::StructEnd, ], Struct { a: 1, b: 2, c: 0 } => &[ - Token::SeqStart(Some(3)), + Token::Seq(Some(3)), Token::I32(1), Token::I32(2), Token::SeqEnd, @@ -552,7 +552,7 @@ declare_tests! { } test_struct_with_skip { Struct { a: 1, b: 2, c: 0 } => &[ - Token::MapStart(Some(3)), + Token::Map(Some(3)), Token::Str("a"), Token::I32(1), @@ -567,7 +567,7 @@ declare_tests! { Token::MapEnd, ], Struct { a: 1, b: 2, c: 0 } => &[ - Token::StructStart("Struct", 3), + Token::Struct("Struct", 3), Token::Str("a"), Token::I32(1), @@ -584,11 +584,11 @@ declare_tests! { } test_struct_skip_all { StructSkipAll { a: 0 } => &[ - Token::StructStart("StructSkipAll", 0), + Token::Struct("StructSkipAll", 0), Token::StructEnd, ], StructSkipAll { a: 0 } => &[ - Token::StructStart("StructSkipAll", 1), + Token::Struct("StructSkipAll", 1), Token::Str("a"), Token::I32(1), @@ -599,13 +599,13 @@ declare_tests! { } test_struct_skip_all_deny_unknown { StructSkipAllDenyUnknown { a: 0 } => &[ - Token::StructStart("StructSkipAllDenyUnknown", 0), + Token::Struct("StructSkipAllDenyUnknown", 0), Token::StructEnd, ], } test_struct_default { StructDefault { a: 50, b: "overwritten".to_string() } => &[ - Token::StructStart("StructDefault", 1), + Token::Struct("StructDefault", 1), Token::Str("a"), Token::I32(50), @@ -614,33 +614,33 @@ declare_tests! { Token::StructEnd, ], StructDefault { a: 100, b: "default".to_string() } => &[ - Token::StructStart("StructDefault", 0), + Token::Struct("StructDefault", 0), Token::StructEnd, ], } test_enum_unit { Enum::Unit => &[ - Token::EnumUnit("Enum", "Unit"), + Token::UnitVariant("Enum", "Unit"), ], } test_enum_simple { Enum::Simple(1) => &[ - Token::EnumNewType("Enum", "Simple"), + Token::NewtypeVariant("Enum", "Simple"), Token::I32(1), ], } test_enum_seq { Enum::Seq(1, 2, 3) => &[ - Token::EnumSeqStart("Enum", "Seq", 3), + Token::TupleVariant("Enum", "Seq", 3), Token::I32(1), Token::I32(2), Token::I32(3), - Token::EnumSeqEnd, + Token::TupleVariantEnd, ], } test_enum_map { Enum::Map { a: 1, b: 2, c: 3 } => &[ - Token::EnumMapStart("Enum", "Map", 3), + Token::StructVariant("Enum", "Map", 3), Token::Str("a"), Token::I32(1), @@ -649,19 +649,19 @@ declare_tests! { Token::Str("c"), Token::I32(3), - Token::EnumMapEnd, + Token::StructVariantEnd, ], } test_enum_unit_usize { Enum::Unit => &[ - Token::EnumStart("Enum"), + Token::Enum("Enum"), Token::U32(0), Token::Unit, ], } test_enum_unit_bytes { Enum::Unit => &[ - Token::EnumStart("Enum"), + Token::Enum("Enum"), Token::Bytes(b"Unit"), Token::Unit, ], @@ -671,7 +671,7 @@ declare_tests! { } test_boxed_slice { Box::new([0, 1, 2]) => &[ - Token::SeqStart(Some(3)), + Token::Seq(Some(3)), Token::I32(0), Token::I32(1), Token::I32(2), @@ -680,7 +680,7 @@ declare_tests! { } test_duration { Duration::new(1, 2) => &[ - Token::StructStart("Duration", 2), + Token::Struct("Duration", 2), Token::Str("secs"), Token::U64(1), @@ -689,7 +689,7 @@ declare_tests! { Token::StructEnd, ], Duration::new(1, 2) => &[ - Token::SeqStart(Some(2)), + Token::Seq(Some(2)), Token::I64(1), Token::I64(2), Token::SeqEnd, @@ -697,7 +697,7 @@ declare_tests! { } test_range { 1u32..2u32 => &[ - Token::StructStart("Range", 2), + Token::Struct("Range", 2), Token::Str("start"), Token::U32(1), @@ -706,7 +706,7 @@ declare_tests! { Token::StructEnd, ], 1u32..2u32 => &[ - Token::SeqStart(Some(2)), + Token::Seq(Some(2)), Token::U64(1), Token::U64(2), Token::SeqEnd, @@ -742,9 +742,9 @@ fn test_osstring() { let value = OsString::from_vec(vec![1, 2, 3]); let tokens = [ - Token::EnumStart("OsString"), + Token::Enum("OsString"), Token::Str("Unix"), - Token::SeqStart(Some(2)), + Token::Seq(Some(2)), Token::U8(1), Token::U8(2), Token::U8(3), @@ -762,9 +762,9 @@ fn test_osstring() { let value = OsString::from_wide(&[1, 2, 3]); let tokens = [ - Token::EnumStart("OsString"), + Token::Enum("OsString"), Token::Str("Windows"), - Token::SeqStart(Some(2)), + Token::Seq(Some(2)), Token::U16(1), Token::U16(2), Token::U16(3), @@ -816,7 +816,7 @@ fn test_cstr_internal_null_end() { declare_error_tests! { test_unknown_field { &[ - Token::StructStart("StructDenyUnknown", 2), + Token::Struct("StructDenyUnknown", 2), Token::Str("a"), Token::I32(0), @@ -826,39 +826,39 @@ declare_error_tests! { } test_skipped_field_is_unknown { &[ - Token::StructStart("StructDenyUnknown", 2), + Token::Struct("StructDenyUnknown", 2), Token::Str("b"), ], Error::Message("unknown field `b`, expected `a`".to_owned()), } test_skip_all_deny_unknown { &[ - Token::StructStart("StructSkipAllDenyUnknown", 1), + Token::Struct("StructSkipAllDenyUnknown", 1), Token::Str("a"), ], Error::Message("unknown field `a`, there are no fields".to_owned()), } test_unknown_variant { &[ - Token::EnumUnit("Enum", "Foo"), + Token::UnitVariant("Enum", "Foo"), ], Error::Message("unknown variant `Foo`, expected one of `Unit`, `Simple`, `Seq`, `Map`".to_owned()), } test_enum_skipped_variant { &[ - Token::EnumUnit("Enum", "Skipped"), + Token::UnitVariant("Enum", "Skipped"), ], Error::Message("unknown variant `Skipped`, expected one of `Unit`, `Simple`, `Seq`, `Map`".to_owned()), } test_enum_skip_all { &[ - Token::EnumUnit("EnumSkipAll", "Skipped"), + Token::UnitVariant("EnumSkipAll", "Skipped"), ], Error::Message("unknown variant `Skipped`, there are no variants".to_owned()), } test_struct_seq_too_long { &[ - Token::SeqStart(Some(4)), + Token::Seq(Some(4)), Token::I32(1), Token::I32(2), Token::I32(3), @@ -867,7 +867,7 @@ declare_error_tests! { } test_duplicate_field_struct { &[ - Token::MapStart(Some(3)), + Token::Map(Some(3)), Token::Str("a"), Token::I32(1), @@ -877,7 +877,7 @@ declare_error_tests! { } test_duplicate_field_enum { &[ - Token::EnumMapStart("Enum", "Map", 3), + Token::StructVariant("Enum", "Map", 3), Token::Str("a"), Token::I32(1), @@ -887,7 +887,7 @@ declare_error_tests! { } test_enum_out_of_range { &[ - Token::EnumStart("Enum"), + Token::Enum("Enum"), Token::U32(4), Token::Unit, ], @@ -895,7 +895,7 @@ declare_error_tests! { } test_short_tuple<(u8, u8, u8)> { &[ - Token::TupleStart(1), + Token::Tuple(1), Token::U8(1), Token::TupleEnd, ], @@ -903,7 +903,7 @@ declare_error_tests! { } test_short_array<[u8; 3]> { &[ - Token::SeqStart(Some(1)), + Token::Seq(Some(1)), Token::U8(1), Token::SeqEnd, ], @@ -923,21 +923,21 @@ declare_error_tests! { } test_unit_from_empty_seq<()> { &[ - Token::SeqStart(Some(0)), + Token::Seq(Some(0)), Token::SeqEnd, ], Error::Message("invalid type: sequence, expected unit".into()), } test_unit_from_empty_seq_without_len<()> { &[ - Token::SeqStart(None), + Token::Seq(None), Token::SeqEnd, ], Error::Message("invalid type: sequence, expected unit".into()), } test_unit_from_tuple_struct<()> { &[ - Token::TupleStructStart("Anything", 0), + Token::TupleStruct("Anything", 0), Token::TupleStructEnd, ], Error::Message("invalid type: sequence, expected unit".into()), diff --git a/test_suite/tests/test_macros.rs b/test_suite/tests/test_macros.rs index f739e860..344b5832 100644 --- a/test_suite/tests/test_macros.rs +++ b/test_suite/tests/test_macros.rs @@ -164,7 +164,7 @@ fn test_ser_named_tuple() { assert_ser_tokens( &SerNamedTuple(&a, &mut b, c), &[ - Token::TupleStructStart("SerNamedTuple", 3), + Token::TupleStruct("SerNamedTuple", 3), Token::I32(5), Token::I32(6), Token::I32(7), @@ -178,7 +178,7 @@ fn test_de_named_tuple() { assert_de_tokens( &DeNamedTuple(5, 6, 7), &[ - Token::SeqStart(Some(3)), + Token::Seq(Some(3)), Token::I32(5), Token::I32(6), Token::I32(7), @@ -189,7 +189,7 @@ fn test_de_named_tuple() { assert_de_tokens( &DeNamedTuple(5, 6, 7), &[ - Token::TupleStructStart("DeNamedTuple", 3), + Token::TupleStruct("DeNamedTuple", 3), Token::I32(5), Token::I32(6), Token::I32(7), @@ -211,7 +211,7 @@ fn test_ser_named_map() { c: c, }, &[ - Token::StructStart("SerNamedMap", 3), + Token::Struct("SerNamedMap", 3), Token::Str("a"), Token::I32(5), @@ -236,7 +236,7 @@ fn test_de_named_map() { c: 7, }, &[ - Token::StructStart("DeNamedMap", 3), + Token::Struct("DeNamedMap", 3), Token::Str("a"), Token::I32(5), @@ -257,7 +257,7 @@ fn test_ser_enum_unit() { assert_ser_tokens( &SerEnum::Unit::, &[ - Token::EnumUnit("SerEnum", "Unit"), + Token::UnitVariant("SerEnum", "Unit"), ] ); } @@ -277,12 +277,12 @@ fn test_ser_enum_seq() { &mut d, ), &[ - Token::EnumSeqStart("SerEnum", "Seq", 4), + Token::TupleVariant("SerEnum", "Seq", 4), Token::I8(1), Token::I32(2), Token::I32(3), Token::I32(4), - Token::EnumSeqEnd, + Token::TupleVariantEnd, ], ); } @@ -302,7 +302,7 @@ fn test_ser_enum_map() { d: &mut d, }, &[ - Token::EnumMapStart("SerEnum", "Map", 4), + Token::StructVariant("SerEnum", "Map", 4), Token::Str("a"), Token::I8(1), @@ -316,7 +316,7 @@ fn test_ser_enum_map() { Token::Str("d"), Token::I32(4), - Token::EnumMapEnd, + Token::StructVariantEnd, ], ); } @@ -326,7 +326,7 @@ fn test_de_enum_unit() { assert_tokens( &DeEnum::Unit::, &[ - Token::EnumUnit("DeEnum", "Unit"), + Token::UnitVariant("DeEnum", "Unit"), ], ); } @@ -346,12 +346,12 @@ fn test_de_enum_seq() { d, ), &[ - Token::EnumSeqStart("DeEnum", "Seq", 4), + Token::TupleVariant("DeEnum", "Seq", 4), Token::I8(1), Token::I32(2), Token::I32(3), Token::I32(4), - Token::EnumSeqEnd, + Token::TupleVariantEnd, ], ); } @@ -371,7 +371,7 @@ fn test_de_enum_map() { d: d, }, &[ - Token::EnumMapStart("DeEnum", "Map", 4), + Token::StructVariant("DeEnum", "Map", 4), Token::Str("a"), Token::I8(1), @@ -385,7 +385,7 @@ fn test_de_enum_map() { Token::Str("d"), Token::I32(4), - Token::EnumMapEnd, + Token::StructVariantEnd, ], ); } @@ -397,7 +397,7 @@ fn test_lifetimes() { assert_ser_tokens( &Lifetimes::LifetimeSeq(&value), &[ - Token::EnumNewType("Lifetimes", "LifetimeSeq"), + Token::NewtypeVariant("Lifetimes", "LifetimeSeq"), Token::I32(5), ] ); @@ -405,7 +405,7 @@ fn test_lifetimes() { assert_ser_tokens( &Lifetimes::NoLifetimeSeq(5), &[ - Token::EnumNewType("Lifetimes", "NoLifetimeSeq"), + Token::NewtypeVariant("Lifetimes", "NoLifetimeSeq"), Token::I32(5), ] ); @@ -413,24 +413,24 @@ fn test_lifetimes() { assert_ser_tokens( &Lifetimes::LifetimeMap { a: &value }, &[ - Token::EnumMapStart("Lifetimes", "LifetimeMap", 1), + Token::StructVariant("Lifetimes", "LifetimeMap", 1), Token::Str("a"), Token::I32(5), - Token::EnumMapEnd, + Token::StructVariantEnd, ] ); assert_ser_tokens( &Lifetimes::NoLifetimeMap { a: 5 }, &[ - Token::EnumMapStart("Lifetimes", "NoLifetimeMap", 1), + Token::StructVariant("Lifetimes", "NoLifetimeMap", 1), Token::Str("a"), Token::I32(5), - Token::EnumMapEnd, + Token::StructVariantEnd, ] ); } @@ -440,7 +440,7 @@ fn test_generic_struct() { assert_tokens( &GenericStruct { x: 5u32 }, &[ - Token::StructStart("GenericStruct", 1), + Token::Struct("GenericStruct", 1), Token::Str("x"), Token::U32(5), @@ -455,7 +455,7 @@ fn test_generic_newtype_struct() { assert_tokens( &GenericNewTypeStruct(5u32), &[ - Token::StructNewType("GenericNewTypeStruct"), + Token::NewtypeStruct("GenericNewTypeStruct"), Token::U32(5), ] ); @@ -466,7 +466,7 @@ fn test_generic_tuple_struct() { assert_tokens( &GenericTupleStruct(5u32, 6u32), &[ - Token::TupleStructStart("GenericTupleStruct", 2), + Token::TupleStruct("GenericTupleStruct", 2), Token::U32(5), Token::U32(6), Token::TupleStructEnd, @@ -479,7 +479,7 @@ fn test_generic_enum_unit() { assert_tokens( &GenericEnum::Unit::, &[ - Token::EnumUnit("GenericEnum", "Unit"), + Token::UnitVariant("GenericEnum", "Unit"), ] ); } @@ -489,7 +489,7 @@ fn test_generic_enum_newtype() { assert_tokens( &GenericEnum::NewType::(5), &[ - Token::EnumNewType("GenericEnum", "NewType"), + Token::NewtypeVariant("GenericEnum", "NewType"), Token::U32(5), ] ); @@ -500,10 +500,10 @@ fn test_generic_enum_seq() { assert_tokens( &GenericEnum::Seq::(5, 6), &[ - Token::EnumSeqStart("GenericEnum", "Seq", 2), + Token::TupleVariant("GenericEnum", "Seq", 2), Token::U32(5), Token::U32(6), - Token::EnumSeqEnd, + Token::TupleVariantEnd, ] ); } @@ -513,7 +513,7 @@ fn test_generic_enum_map() { assert_tokens( &GenericEnum::Map:: { x: 5, y: 6 }, &[ - Token::EnumMapStart("GenericEnum", "Map", 2), + Token::StructVariant("GenericEnum", "Map", 2), Token::Str("x"), Token::U32(5), @@ -521,7 +521,7 @@ fn test_generic_enum_map() { Token::Str("y"), Token::U32(6), - Token::EnumMapEnd, + Token::StructVariantEnd, ] ); } @@ -531,7 +531,7 @@ fn test_default_ty_param() { assert_tokens( &DefaultTyParam:: { phantom: PhantomData }, &[ - Token::StructStart("DefaultTyParam", 1), + Token::Struct("DefaultTyParam", 1), Token::Str("phantom"), Token::UnitStruct("PhantomData"), @@ -551,7 +551,7 @@ fn test_enum_state_field() { assert_tokens( &SomeEnum::Key { key: 'a', state: true }, &[ - Token::EnumMapStart("SomeEnum", "Key", 2), + Token::StructVariant("SomeEnum", "Key", 2), Token::Str("key"), Token::Char('a'), @@ -559,7 +559,7 @@ fn test_enum_state_field() { Token::Str("state"), Token::Bool(true), - Token::EnumMapEnd, + Token::StructVariantEnd, ] ); } @@ -584,7 +584,7 @@ fn test_untagged_enum() { assert_tokens( &Untagged::A { a: 1 }, &[ - Token::StructStart("Untagged", 1), + Token::Struct("Untagged", 1), Token::Str("a"), Token::U8(1), @@ -596,7 +596,7 @@ fn test_untagged_enum() { assert_tokens( &Untagged::B { b: 2 }, &[ - Token::StructStart("Untagged", 1), + Token::Struct("Untagged", 1), Token::Str("b"), Token::U8(2), @@ -628,7 +628,7 @@ fn test_untagged_enum() { assert_tokens( &Untagged::F(1, 2), &[ - Token::TupleStart(2), + Token::Tuple(2), Token::U8(1), Token::U8(2), Token::TupleEnd, @@ -637,14 +637,14 @@ fn test_untagged_enum() { assert_de_tokens_error::( &[ - Token::Option(false), + Token::None, ], Error::Message("data did not match any variant of untagged enum Untagged".to_owned()), ); assert_de_tokens_error::( &[ - Token::TupleStart(1), + Token::Tuple(1), Token::U8(1), Token::TupleEnd, ], @@ -653,7 +653,7 @@ fn test_untagged_enum() { assert_de_tokens_error::( &[ - Token::TupleStart(3), + Token::Tuple(3), Token::U8(1), Token::U8(2), Token::U8(3), @@ -691,7 +691,7 @@ fn test_internally_tagged_enum() { assert_tokens( &InternallyTagged::A { a: 1 }, &[ - Token::StructStart("InternallyTagged", 2), + Token::Struct("InternallyTagged", 2), Token::Str("type"), Token::Str("A"), @@ -706,7 +706,7 @@ fn test_internally_tagged_enum() { assert_tokens( &InternallyTagged::B { b: 2 }, &[ - Token::StructStart("InternallyTagged", 2), + Token::Struct("InternallyTagged", 2), Token::Str("type"), Token::Str("B"), @@ -721,7 +721,7 @@ fn test_internally_tagged_enum() { assert_tokens( &InternallyTagged::C, &[ - Token::StructStart("InternallyTagged", 1), + Token::Struct("InternallyTagged", 1), Token::Str("type"), Token::Str("C"), @@ -733,7 +733,7 @@ fn test_internally_tagged_enum() { assert_tokens( &InternallyTagged::D(BTreeMap::new()), &[ - Token::MapStart(Some(1)), + Token::Map(Some(1)), Token::Str("type"), Token::Str("D"), @@ -745,7 +745,7 @@ fn test_internally_tagged_enum() { assert_tokens( &InternallyTagged::E(Newtype(BTreeMap::new())), &[ - Token::MapStart(Some(1)), + Token::Map(Some(1)), Token::Str("type"), Token::Str("E"), @@ -757,7 +757,7 @@ fn test_internally_tagged_enum() { assert_tokens( &InternallyTagged::F(Struct { f: 6 }), &[ - Token::StructStart("Struct", 2), + Token::Struct("Struct", 2), Token::Str("type"), Token::Str("F"), @@ -771,7 +771,7 @@ fn test_internally_tagged_enum() { assert_de_tokens_error::( &[ - Token::MapStart(Some(0)), + Token::Map(Some(0)), Token::MapEnd, ], Error::Message("missing field `type`".to_owned()), @@ -779,7 +779,7 @@ fn test_internally_tagged_enum() { assert_de_tokens_error::( &[ - Token::MapStart(Some(1)), + Token::Map(Some(1)), Token::Str("type"), Token::Str("Z"), @@ -805,7 +805,7 @@ fn test_adjacently_tagged_enum() { assert_tokens( &AdjacentlyTagged::Unit::, &[ - Token::StructStart("AdjacentlyTagged", 1), + Token::Struct("AdjacentlyTagged", 1), Token::Str("t"), Token::Str("Unit"), @@ -818,7 +818,7 @@ fn test_adjacently_tagged_enum() { assert_de_tokens( &AdjacentlyTagged::Unit::, &[ - Token::StructStart("AdjacentlyTagged", 1), + Token::Struct("AdjacentlyTagged", 1), Token::Str("t"), Token::Str("Unit"), @@ -834,7 +834,7 @@ fn test_adjacently_tagged_enum() { assert_de_tokens( &AdjacentlyTagged::Unit::, &[ - Token::StructStart("AdjacentlyTagged", 1), + Token::Struct("AdjacentlyTagged", 1), Token::Str("c"), Token::Unit, @@ -850,7 +850,7 @@ fn test_adjacently_tagged_enum() { assert_tokens( &AdjacentlyTagged::Newtype::(1), &[ - Token::StructStart("AdjacentlyTagged", 2), + Token::Struct("AdjacentlyTagged", 2), Token::Str("t"), Token::Str("Newtype"), @@ -866,7 +866,7 @@ fn test_adjacently_tagged_enum() { assert_de_tokens( &AdjacentlyTagged::Newtype::(1), &[ - Token::StructStart("AdjacentlyTagged", 2), + Token::Struct("AdjacentlyTagged", 2), Token::Str("c"), Token::U8(1), @@ -882,13 +882,13 @@ fn test_adjacently_tagged_enum() { assert_tokens( &AdjacentlyTagged::Tuple::(1, 1), &[ - Token::StructStart("AdjacentlyTagged", 2), + Token::Struct("AdjacentlyTagged", 2), Token::Str("t"), Token::Str("Tuple"), Token::Str("c"), - Token::TupleStart(2), + Token::Tuple(2), Token::U8(1), Token::U8(1), Token::TupleEnd, @@ -901,10 +901,10 @@ fn test_adjacently_tagged_enum() { assert_de_tokens( &AdjacentlyTagged::Tuple::(1, 1), &[ - Token::StructStart("AdjacentlyTagged", 2), + Token::Struct("AdjacentlyTagged", 2), Token::Str("c"), - Token::TupleStart(2), + Token::Tuple(2), Token::U8(1), Token::U8(1), Token::TupleEnd, @@ -920,13 +920,13 @@ fn test_adjacently_tagged_enum() { assert_tokens( &AdjacentlyTagged::Struct:: { f: 1 }, &[ - Token::StructStart("AdjacentlyTagged", 2), + Token::Struct("AdjacentlyTagged", 2), Token::Str("t"), Token::Str("Struct"), Token::Str("c"), - Token::StructStart("Struct", 1), + Token::Struct("Struct", 1), Token::Str("f"), Token::U8(1), Token::StructEnd, @@ -939,10 +939,10 @@ fn test_adjacently_tagged_enum() { assert_de_tokens( &AdjacentlyTagged::Struct:: { f: 1 }, &[ - Token::StructStart("AdjacentlyTagged", 2), + Token::Struct("AdjacentlyTagged", 2), Token::Str("c"), - Token::StructStart("Struct", 1), + Token::Struct("Struct", 1), Token::Str("f"), Token::U8(1), Token::StructEnd, @@ -974,7 +974,7 @@ fn test_enum_in_internally_tagged_enum() { assert_tokens( &Outer::Inner(Inner::Unit), &[ - Token::MapStart(Some(2)), + Token::Map(Some(2)), Token::Str("type"), Token::Str("Inner"), @@ -989,7 +989,7 @@ fn test_enum_in_internally_tagged_enum() { assert_tokens( &Outer::Inner(Inner::Newtype(1)), &[ - Token::MapStart(Some(2)), + Token::Map(Some(2)), Token::Str("type"), Token::Str("Inner"), @@ -1004,13 +1004,13 @@ fn test_enum_in_internally_tagged_enum() { assert_tokens( &Outer::Inner(Inner::Tuple(1, 1)), &[ - Token::MapStart(Some(2)), + Token::Map(Some(2)), Token::Str("type"), Token::Str("Inner"), Token::Str("Tuple"), - Token::TupleStructStart("Tuple", 2), + Token::TupleStruct("Tuple", 2), Token::U8(1), Token::U8(1), Token::TupleStructEnd, @@ -1022,13 +1022,13 @@ fn test_enum_in_internally_tagged_enum() { assert_tokens( &Outer::Inner(Inner::Struct { f: 1 }), &[ - Token::MapStart(Some(2)), + Token::Map(Some(2)), Token::Str("type"), Token::Str("Inner"), Token::Str("Struct"), - Token::StructStart("Struct", 1), + Token::Struct("Struct", 1), Token::Str("f"), Token::U8(1), Token::StructEnd, @@ -1057,14 +1057,14 @@ fn test_enum_in_untagged_enum() { assert_tokens( &Outer::Inner(Inner::Unit), &[ - Token::EnumUnit("Inner", "Unit"), + Token::UnitVariant("Inner", "Unit"), ] ); assert_tokens( &Outer::Inner(Inner::Newtype(1)), &[ - Token::EnumNewType("Inner", "Newtype"), + Token::NewtypeVariant("Inner", "Newtype"), Token::U8(1), ] ); @@ -1072,22 +1072,22 @@ fn test_enum_in_untagged_enum() { assert_tokens( &Outer::Inner(Inner::Tuple(1, 1)), &[ - Token::EnumSeqStart("Inner", "Tuple", 2), + Token::TupleVariant("Inner", "Tuple", 2), Token::U8(1), Token::U8(1), - Token::EnumSeqEnd, + Token::TupleVariantEnd, ] ); assert_tokens( &Outer::Inner(Inner::Struct { f: 1 }), &[ - Token::EnumMapStart("Inner", "Struct", 1), + Token::StructVariant("Inner", "Struct", 1), Token::Str("f"), Token::U8(1), - Token::EnumMapEnd, + Token::StructVariantEnd, ] ); } @@ -1124,43 +1124,43 @@ fn test_rename_all() { assert_tokens( &E::Serialize { serialize: true, serialize_seq: true }, &[ - Token::EnumMapStart("E", "serialize", 2), + Token::StructVariant("E", "serialize", 2), Token::Str("serialize"), Token::Bool(true), Token::Str("serializeSeq"), Token::Bool(true), - Token::EnumMapEnd, + Token::StructVariantEnd, ] ); assert_tokens( &E::SerializeSeq { serialize: true, serialize_seq: true }, &[ - Token::EnumMapStart("E", "serialize_seq", 2), + Token::StructVariant("E", "serialize_seq", 2), Token::Str("serialize"), Token::Bool(true), Token::Str("serialize-seq"), Token::Bool(true), - Token::EnumMapEnd, + Token::StructVariantEnd, ] ); assert_tokens( &E::SerializeMap { serialize: true, serialize_seq: true }, &[ - Token::EnumMapStart("E", "serialize_map", 2), + Token::StructVariant("E", "serialize_map", 2), Token::Str("SERIALIZE"), Token::Bool(true), Token::Str("SERIALIZE_SEQ"), Token::Bool(true), - Token::EnumMapEnd, + Token::StructVariantEnd, ] ); assert_tokens( &S { serialize: true, serialize_seq: true }, &[ - Token::StructStart("S", 2), + Token::Struct("S", 2), Token::Str("Serialize"), Token::Bool(true), Token::Str("SerializeSeq"), diff --git a/test_suite/tests/test_ser.rs b/test_suite/tests/test_ser.rs index 89df7851..3c5b4385 100644 --- a/test_suite/tests/test_ser.rs +++ b/test_suite/tests/test_ser.rs @@ -102,29 +102,29 @@ declare_tests! { "abc".to_owned() => &[Token::Str("abc")], } test_option { - None:: => &[Token::Option(false)], + None:: => &[Token::None], Some(1) => &[ - Token::Option(true), + Token::Some, Token::I32(1), ], } test_result { Ok::(0) => &[ - Token::EnumNewType("Result", "Ok"), + Token::NewtypeVariant("Result", "Ok"), Token::I32(0), ], Err::(1) => &[ - Token::EnumNewType("Result", "Err"), + Token::NewtypeVariant("Result", "Err"), Token::I32(1), ], } test_slice { &[0][..0] => &[ - Token::SeqStart(Some(0)), + Token::Seq(Some(0)), Token::SeqEnd, ], &[1, 2, 3][..] => &[ - Token::SeqStart(Some(3)), + Token::Seq(Some(3)), Token::I32(1), Token::I32(2), Token::I32(3), @@ -133,11 +133,11 @@ declare_tests! { } test_array { [0; 0] => &[ - Token::SeqArrayStart(0), + Token::SeqFixedSize(0), Token::SeqEnd, ], [1, 2, 3] => &[ - Token::SeqArrayStart(3), + Token::SeqFixedSize(3), Token::I32(1), Token::I32(2), Token::I32(3), @@ -146,19 +146,19 @@ declare_tests! { } test_vec { Vec::::new() => &[ - Token::SeqStart(Some(0)), + Token::Seq(Some(0)), Token::SeqEnd, ], vec![vec![], vec![1], vec![2, 3]] => &[ - Token::SeqStart(Some(3)), - Token::SeqStart(Some(0)), + Token::Seq(Some(3)), + Token::Seq(Some(0)), Token::SeqEnd, - Token::SeqStart(Some(1)), + Token::Seq(Some(1)), Token::I32(1), Token::SeqEnd, - Token::SeqStart(Some(2)), + Token::Seq(Some(2)), Token::I32(2), Token::I32(3), Token::SeqEnd, @@ -167,28 +167,28 @@ declare_tests! { } test_hashset { HashSet::::new() => &[ - Token::SeqStart(Some(0)), + Token::Seq(Some(0)), Token::SeqEnd, ], hashset![1] => &[ - Token::SeqStart(Some(1)), + Token::Seq(Some(1)), Token::I32(1), Token::SeqEnd, ], hashset![FnvHasher @ 1] => &[ - Token::SeqStart(Some(1)), + Token::Seq(Some(1)), Token::I32(1), Token::SeqEnd, ], } test_tuple { (1,) => &[ - Token::TupleStart(1), + Token::Tuple(1), Token::I32(1), Token::TupleEnd, ], (1, 2, 3) => &[ - Token::TupleStart(3), + Token::Tuple(3), Token::I32(1), Token::I32(2), Token::I32(3), @@ -197,13 +197,13 @@ declare_tests! { } test_btreemap { btreemap![1 => 2] => &[ - Token::MapStart(Some(1)), + Token::Map(Some(1)), Token::I32(1), Token::I32(2), Token::MapEnd, ], btreemap![1 => 2, 3 => 4] => &[ - Token::MapStart(Some(2)), + Token::Map(Some(2)), Token::I32(1), Token::I32(2), @@ -212,13 +212,13 @@ declare_tests! { Token::MapEnd, ], btreemap![1 => btreemap![], 2 => btreemap![3 => 4, 5 => 6]] => &[ - Token::MapStart(Some(2)), + Token::Map(Some(2)), Token::I32(1), - Token::MapStart(Some(0)), + Token::Map(Some(0)), Token::MapEnd, Token::I32(2), - Token::MapStart(Some(2)), + Token::Map(Some(2)), Token::I32(3), Token::I32(4), @@ -230,17 +230,17 @@ declare_tests! { } test_hashmap { HashMap::::new() => &[ - Token::MapStart(Some(0)), + Token::Map(Some(0)), Token::MapEnd, ], hashmap![1 => 2] => &[ - Token::MapStart(Some(1)), + Token::Map(Some(1)), Token::I32(1), Token::I32(2), Token::MapEnd, ], hashmap![FnvHasher @ 1 => 2] => &[ - Token::MapStart(Some(1)), + Token::Map(Some(1)), Token::I32(1), Token::I32(2), Token::MapEnd, @@ -251,7 +251,7 @@ declare_tests! { } test_tuple_struct { TupleStruct(1, 2, 3) => &[ - Token::TupleStructStart("TupleStruct", 3), + Token::TupleStruct("TupleStruct", 3), Token::I32(1), Token::I32(2), Token::I32(3), @@ -260,7 +260,7 @@ declare_tests! { } test_struct { Struct { a: 1, b: 2, c: 3 } => &[ - Token::StructStart("Struct", 3), + Token::Struct("Struct", 3), Token::Str("a"), Token::I32(1), @@ -273,22 +273,22 @@ declare_tests! { ], } test_enum { - Enum::Unit => &[Token::EnumUnit("Enum", "Unit")], - Enum::One(42) => &[Token::EnumNewType("Enum", "One"), Token::I32(42)], + Enum::Unit => &[Token::UnitVariant("Enum", "Unit")], + Enum::One(42) => &[Token::NewtypeVariant("Enum", "One"), Token::I32(42)], Enum::Seq(1, 2) => &[ - Token::EnumSeqStart("Enum", "Seq", 2), + Token::TupleVariant("Enum", "Seq", 2), Token::I32(1), Token::I32(2), - Token::EnumSeqEnd, + Token::TupleVariantEnd, ], Enum::Map { a: 1, b: 2 } => &[ - Token::EnumMapStart("Enum", "Map", 2), + Token::StructVariant("Enum", "Map", 2), Token::Str("a"), Token::I32(1), Token::Str("b"), Token::I32(2), - Token::EnumMapEnd, + Token::StructVariantEnd, ], } test_box { @@ -296,7 +296,7 @@ declare_tests! { } test_boxed_slice { Box::new([0, 1, 2]) => &[ - Token::SeqArrayStart(3), + Token::SeqFixedSize(3), Token::I32(0), Token::I32(1), Token::I32(2), @@ -305,7 +305,7 @@ declare_tests! { } test_duration { Duration::new(1, 2) => &[ - Token::StructStart("Duration", 2), + Token::Struct("Duration", 2), Token::Str("secs"), Token::U64(1), @@ -316,7 +316,7 @@ declare_tests! { } test_range { 1u32..2u32 => &[ - Token::StructStart("Range", 2), + Token::Struct("Range", 2), Token::Str("start"), Token::U32(1), From e66033e53ef829a0ca4d5f94ef8aae6125582456 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 11:22:47 -0700 Subject: [PATCH 027/177] Remove implicit conversion from float to integer --- serde/src/de/impls.rs | 56 +++++++++++++++++++++---------------- test_suite/tests/test_de.rs | 8 ++++-- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index d30392f6..9fb37e64 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -130,7 +130,7 @@ macro_rules! impl_deserialize_num_method { } macro_rules! impl_deserialize_num { - ($ty:ident, $method:ident) => { + ($ty:ident, $method:ident, $($visit:ident),*) => { impl<'de> Deserialize<'de> for $ty { #[inline] fn deserialize(deserializer: D) -> Result<$ty, D::Error> @@ -145,36 +145,44 @@ macro_rules! impl_deserialize_num { formatter.write_str(stringify!($ty)) } - impl_deserialize_num_method!($ty, i8, visit_i8, from_i8, Signed, i64); - impl_deserialize_num_method!($ty, i16, visit_i16, from_i16, Signed, i64); - impl_deserialize_num_method!($ty, i32, visit_i32, from_i32, Signed, i64); - impl_deserialize_num_method!($ty, i64, visit_i64, from_i64, Signed, i64); - impl_deserialize_num_method!($ty, u8, visit_u8, from_u8, Unsigned, u64); - impl_deserialize_num_method!($ty, u16, visit_u16, from_u16, Unsigned, u64); - impl_deserialize_num_method!($ty, u32, visit_u32, from_u32, Unsigned, u64); - impl_deserialize_num_method!($ty, u64, visit_u64, from_u64, Unsigned, u64); - impl_deserialize_num_method!($ty, f32, visit_f32, from_f32, Float, f64); - impl_deserialize_num_method!($ty, f64, visit_f64, from_f64, Float, f64); + $( + impl_deserialize_num!($visit $ty); + )* } deserializer.$method(PrimitiveVisitor) } } - } + }; + (integer $ty:ident) => { + impl_deserialize_num_method!($ty, i8, visit_i8, from_i8, Signed, i64); + impl_deserialize_num_method!($ty, i16, visit_i16, from_i16, Signed, i64); + impl_deserialize_num_method!($ty, i32, visit_i32, from_i32, Signed, i64); + impl_deserialize_num_method!($ty, i64, visit_i64, from_i64, Signed, i64); + impl_deserialize_num_method!($ty, u8, visit_u8, from_u8, Unsigned, u64); + impl_deserialize_num_method!($ty, u16, visit_u16, from_u16, Unsigned, u64); + impl_deserialize_num_method!($ty, u32, visit_u32, from_u32, Unsigned, u64); + impl_deserialize_num_method!($ty, u64, visit_u64, from_u64, Unsigned, u64); + }; + (float $ty:ident) => { + impl_deserialize_num_method!($ty, f32, visit_f32, from_f32, Float, f64); + impl_deserialize_num_method!($ty, f64, visit_f64, from_f64, Float, f64); + }; } -impl_deserialize_num!(isize, deserialize_i64); -impl_deserialize_num!(i8, deserialize_i8); -impl_deserialize_num!(i16, deserialize_i16); -impl_deserialize_num!(i32, deserialize_i32); -impl_deserialize_num!(i64, deserialize_i64); -impl_deserialize_num!(usize, deserialize_u64); -impl_deserialize_num!(u8, deserialize_u8); -impl_deserialize_num!(u16, deserialize_u16); -impl_deserialize_num!(u32, deserialize_u32); -impl_deserialize_num!(u64, deserialize_u64); -impl_deserialize_num!(f32, deserialize_f32); -impl_deserialize_num!(f64, deserialize_f64); +impl_deserialize_num!(isize, deserialize_i64, integer); +impl_deserialize_num!(i8, deserialize_i8, integer); +impl_deserialize_num!(i16, deserialize_i16, integer); +impl_deserialize_num!(i32, deserialize_i32, integer); +impl_deserialize_num!(i64, deserialize_i64, integer); +impl_deserialize_num!(usize, deserialize_u64, integer); +impl_deserialize_num!(u8, deserialize_u8, integer); +impl_deserialize_num!(u16, deserialize_u16, integer); +impl_deserialize_num!(u32, deserialize_u32, integer); +impl_deserialize_num!(u64, deserialize_u64, integer); + +impl_deserialize_num!(f32, deserialize_f32, integer, float); +impl_deserialize_num!(f64, deserialize_f64, integer, float); /////////////////////////////////////////////////////////////////////////////// diff --git a/test_suite/tests/test_de.rs b/test_suite/tests/test_de.rs index eb8a9705..bff0b48b 100644 --- a/test_suite/tests/test_de.rs +++ b/test_suite/tests/test_de.rs @@ -187,8 +187,6 @@ declare_tests! { 0isize => &[Token::U16(0)], 0isize => &[Token::U32(0)], 0isize => &[Token::U64(0)], - 0isize => &[Token::F32(0.)], - 0isize => &[Token::F64(0.)], } test_ints { 0i8 => &[Token::I8(0)], @@ -1032,4 +1030,10 @@ declare_error_tests! { ], Error::Message("invalid type: string \"1\", expected isize".into()), } + test_integer_from_float { + &[ + Token::F32(0.0), + ], + Error::Message("invalid type: floating point `0`, expected isize".into()), + } } From 07ac9eb53808898d6b44f0e8ac4ab8ad54b0bd95 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 12:11:47 -0700 Subject: [PATCH 028/177] Remove unused number conversion logic --- serde/src/de/from_primitive.rs | 168 ++++----------------------------- serde/src/de/impls.rs | 39 +++++--- 2 files changed, 45 insertions(+), 162 deletions(-) diff --git a/serde/src/de/from_primitive.rs b/serde/src/de/from_primitive.rs index 14e51860..75f56b47 100644 --- a/serde/src/de/from_primitive.rs +++ b/serde/src/de/from_primitive.rs @@ -57,71 +57,40 @@ bounded_impl!(f64, f64::MIN, f64::MAX); /// A generic trait for converting a value to a number. pub trait ToPrimitive { /// Converts the value of `self` to an `isize`. - #[inline] - fn to_isize(&self) -> Option { - self.to_i64().and_then(|x| x.to_isize()) - } + fn to_isize(&self) -> Option; /// Converts the value of `self` to an `i8`. - #[inline] - fn to_i8(&self) -> Option { - self.to_i64().and_then(|x| x.to_i8()) - } + fn to_i8(&self) -> Option; /// Converts the value of `self` to an `i16`. - #[inline] - fn to_i16(&self) -> Option { - self.to_i64().and_then(|x| x.to_i16()) - } + fn to_i16(&self) -> Option; /// Converts the value of `self` to an `i32`. - #[inline] - fn to_i32(&self) -> Option { - self.to_i64().and_then(|x| x.to_i32()) - } + fn to_i32(&self) -> Option; /// Converts the value of `self` to an `i64`. fn to_i64(&self) -> Option; /// Converts the value of `self` to a `usize`. - #[inline] - fn to_usize(&self) -> Option { - self.to_u64().and_then(|x| x.to_usize()) - } + fn to_usize(&self) -> Option; /// Converts the value of `self` to an `u8`. - #[inline] - fn to_u8(&self) -> Option { - self.to_u64().and_then(|x| x.to_u8()) - } + fn to_u8(&self) -> Option; /// Converts the value of `self` to an `u16`. - #[inline] - fn to_u16(&self) -> Option { - self.to_u64().and_then(|x| x.to_u16()) - } + fn to_u16(&self) -> Option; /// Converts the value of `self` to an `u32`. - #[inline] - fn to_u32(&self) -> Option { - self.to_u64().and_then(|x| x.to_u32()) - } + fn to_u32(&self) -> Option; /// Converts the value of `self` to an `u64`. - #[inline] fn to_u64(&self) -> Option; /// Converts the value of `self` to an `f32`. - #[inline] - fn to_f32(&self) -> Option { - self.to_f64().and_then(|x| x.to_f32()) - } + fn to_f32(&self) -> Option; /// Converts the value of `self` to an `f64`. - #[inline] - fn to_f64(&self) -> Option { - self.to_i64().and_then(|x| x.to_f64()) - } + fn to_f64(&self) -> Option; } macro_rules! impl_to_primitive_int_to_int { @@ -268,129 +237,32 @@ impl_to_primitive_uint! { u16 } impl_to_primitive_uint! { u32 } impl_to_primitive_uint! { u64 } -macro_rules! impl_to_primitive_float_to_float { - ($SrcT:ident, $DstT:ident, $slf:expr) => ( - if size_of::<$SrcT>() <= size_of::<$DstT>() { - Some($slf as $DstT) - } else { - let n = $slf as f64; - let max_value: $SrcT = ::core::$SrcT::MAX; - if -max_value as f64 <= n && n <= max_value as f64 { - Some($slf as $DstT) - } else { - None - } - } - ) -} - -macro_rules! impl_to_primitive_float { - ($T:ident) => ( - impl ToPrimitive for $T { - #[inline] - fn to_isize(&self) -> Option { Some(*self as isize) } - #[inline] - fn to_i8(&self) -> Option { Some(*self as i8) } - #[inline] - fn to_i16(&self) -> Option { Some(*self as i16) } - #[inline] - fn to_i32(&self) -> Option { Some(*self as i32) } - #[inline] - fn to_i64(&self) -> Option { Some(*self as i64) } - - #[inline] - fn to_usize(&self) -> Option { Some(*self as usize) } - #[inline] - fn to_u8(&self) -> Option { Some(*self as u8) } - #[inline] - fn to_u16(&self) -> Option { Some(*self as u16) } - #[inline] - fn to_u32(&self) -> Option { Some(*self as u32) } - #[inline] - fn to_u64(&self) -> Option { Some(*self as u64) } - - #[inline] - fn to_f32(&self) -> Option { impl_to_primitive_float_to_float!($T, f32, *self) } - #[inline] - fn to_f64(&self) -> Option { impl_to_primitive_float_to_float!($T, f64, *self) } - } - ) -} - -impl_to_primitive_float! { f32 } -impl_to_primitive_float! { f64 } - pub trait FromPrimitive: Sized { - #[inline] - fn from_isize(n: isize) -> Option { - FromPrimitive::from_i64(n as i64) - } - - #[inline] - fn from_i8(n: i8) -> Option { - FromPrimitive::from_i64(n as i64) - } - - #[inline] - fn from_i16(n: i16) -> Option { - FromPrimitive::from_i64(n as i64) - } - - #[inline] - fn from_i32(n: i32) -> Option { - FromPrimitive::from_i64(n as i64) - } - + fn from_isize(n: isize) -> Option; + fn from_i8(n: i8) -> Option; + fn from_i16(n: i16) -> Option; + fn from_i32(n: i32) -> Option; fn from_i64(n: i64) -> Option; - - #[inline] - fn from_usize(n: usize) -> Option { - FromPrimitive::from_u64(n as u64) - } - - #[inline] - fn from_u8(n: u8) -> Option { - FromPrimitive::from_u64(n as u64) - } - - #[inline] - fn from_u16(n: u16) -> Option { - FromPrimitive::from_u64(n as u64) - } - - #[inline] - fn from_u32(n: u32) -> Option { - FromPrimitive::from_u64(n as u64) - } - + fn from_usize(n: usize) -> Option; + fn from_u8(n: u8) -> Option; + fn from_u16(n: u16) -> Option; + fn from_u32(n: u32) -> Option; fn from_u64(n: u64) -> Option; - - #[inline] - fn from_f32(n: f32) -> Option { - FromPrimitive::from_f64(n as f64) - } - - #[inline] - fn from_f64(n: f64) -> Option { - FromPrimitive::from_i64(n as i64) - } } macro_rules! impl_from_primitive { ($T:ty, $to_ty:ident) => ( impl FromPrimitive for $T { + #[inline] fn from_isize(n: isize) -> Option<$T> { n.$to_ty() } #[inline] fn from_i8(n: i8) -> Option<$T> { n.$to_ty() } #[inline] fn from_i16(n: i16) -> Option<$T> { n.$to_ty() } #[inline] fn from_i32(n: i32) -> Option<$T> { n.$to_ty() } #[inline] fn from_i64(n: i64) -> Option<$T> { n.$to_ty() } - + #[inline] fn from_usize(n: usize) -> Option<$T> { n.$to_ty() } #[inline] fn from_u8(n: u8) -> Option<$T> { n.$to_ty() } #[inline] fn from_u16(n: u16) -> Option<$T> { n.$to_ty() } #[inline] fn from_u32(n: u32) -> Option<$T> { n.$to_ty() } #[inline] fn from_u64(n: u64) -> Option<$T> { n.$to_ty() } - - #[inline] fn from_f32(n: f32) -> Option<$T> { n.$to_ty() } - #[inline] fn from_f64(n: f64) -> Option<$T> { n.$to_ty() } } ) } diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 9fb37e64..9f666729 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -115,11 +115,11 @@ impl<'de> Deserialize<'de> for bool { /////////////////////////////////////////////////////////////////////////////// -macro_rules! impl_deserialize_num_method { - ($ty:ident, $src_ty:ident, $method:ident, $from_method:ident, $group:ident, $group_ty:ident) => { +macro_rules! visit_integer_method { + ($src_ty:ident, $method:ident, $from_method:ident, $group:ident, $group_ty:ident) => { #[inline] - fn $method(self, v: $src_ty) -> Result<$ty, E> - where E: Error, + fn $method(self, v: $src_ty) -> Result + where E: Error { match FromPrimitive::$from_method(v) { Some(v) => Ok(v), @@ -129,6 +129,17 @@ macro_rules! impl_deserialize_num_method { } } +macro_rules! visit_float_method { + ($src_ty:ident, $method:ident) => { + #[inline] + fn $method(self, v: $src_ty) -> Result + where E: Error + { + Ok(v as Self::Value) + } + } +} + macro_rules! impl_deserialize_num { ($ty:ident, $method:ident, $($visit:ident),*) => { impl<'de> Deserialize<'de> for $ty { @@ -155,18 +166,18 @@ macro_rules! impl_deserialize_num { } }; (integer $ty:ident) => { - impl_deserialize_num_method!($ty, i8, visit_i8, from_i8, Signed, i64); - impl_deserialize_num_method!($ty, i16, visit_i16, from_i16, Signed, i64); - impl_deserialize_num_method!($ty, i32, visit_i32, from_i32, Signed, i64); - impl_deserialize_num_method!($ty, i64, visit_i64, from_i64, Signed, i64); - impl_deserialize_num_method!($ty, u8, visit_u8, from_u8, Unsigned, u64); - impl_deserialize_num_method!($ty, u16, visit_u16, from_u16, Unsigned, u64); - impl_deserialize_num_method!($ty, u32, visit_u32, from_u32, Unsigned, u64); - impl_deserialize_num_method!($ty, u64, visit_u64, from_u64, Unsigned, u64); + visit_integer_method!(i8, visit_i8, from_i8, Signed, i64); + visit_integer_method!(i16, visit_i16, from_i16, Signed, i64); + visit_integer_method!(i32, visit_i32, from_i32, Signed, i64); + visit_integer_method!(i64, visit_i64, from_i64, Signed, i64); + visit_integer_method!(u8, visit_u8, from_u8, Unsigned, u64); + visit_integer_method!(u16, visit_u16, from_u16, Unsigned, u64); + visit_integer_method!(u32, visit_u32, from_u32, Unsigned, u64); + visit_integer_method!(u64, visit_u64, from_u64, Unsigned, u64); }; (float $ty:ident) => { - impl_deserialize_num_method!($ty, f32, visit_f32, from_f32, Float, f64); - impl_deserialize_num_method!($ty, f64, visit_f64, from_f64, Float, f64); + visit_float_method!(f32, visit_f32); + visit_float_method!(f64, visit_f64); }; } From 1a63cbccb21a59e5f18624d30ab613b2421ee780 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 12:29:05 -0700 Subject: [PATCH 029/177] Remove unused ToPrimitive trait --- serde/src/de/from_primitive.rs | 212 ++++++++++----------------------- 1 file changed, 62 insertions(+), 150 deletions(-) diff --git a/serde/src/de/from_primitive.rs b/serde/src/de/from_primitive.rs index 75f56b47..d881cd78 100644 --- a/serde/src/de/from_primitive.rs +++ b/serde/src/de/from_primitive.rs @@ -51,49 +51,7 @@ bounded_impl!(i16, i16::MIN, i16::MAX); bounded_impl!(i32, i32::MIN, i32::MAX); bounded_impl!(i64, i64::MIN, i64::MAX); -bounded_impl!(f32, f32::MIN, f32::MAX); -bounded_impl!(f64, f64::MIN, f64::MAX); - -/// A generic trait for converting a value to a number. -pub trait ToPrimitive { - /// Converts the value of `self` to an `isize`. - fn to_isize(&self) -> Option; - - /// Converts the value of `self` to an `i8`. - fn to_i8(&self) -> Option; - - /// Converts the value of `self` to an `i16`. - fn to_i16(&self) -> Option; - - /// Converts the value of `self` to an `i32`. - fn to_i32(&self) -> Option; - - /// Converts the value of `self` to an `i64`. - fn to_i64(&self) -> Option; - - /// Converts the value of `self` to a `usize`. - fn to_usize(&self) -> Option; - - /// Converts the value of `self` to an `u8`. - fn to_u8(&self) -> Option; - - /// Converts the value of `self` to an `u16`. - fn to_u16(&self) -> Option; - - /// Converts the value of `self` to an `u32`. - fn to_u32(&self) -> Option; - - /// Converts the value of `self` to an `u64`. - fn to_u64(&self) -> Option; - - /// Converts the value of `self` to an `f32`. - fn to_f32(&self) -> Option; - - /// Converts the value of `self` to an `f64`. - fn to_f64(&self) -> Option; -} - -macro_rules! impl_to_primitive_int_to_int { +macro_rules! int_to_int { ($SrcT:ty, $DstT:ty, $slf:expr) => ( { if size_of::<$SrcT>() <= size_of::<$DstT>() { @@ -112,7 +70,7 @@ macro_rules! impl_to_primitive_int_to_int { ) } -macro_rules! impl_to_primitive_int_to_uint { +macro_rules! int_to_uint { ($SrcT:ty, $DstT:ty, $slf:expr) => ( { let zero: $SrcT = 0; @@ -126,46 +84,7 @@ macro_rules! impl_to_primitive_int_to_uint { ) } -macro_rules! impl_to_primitive_int { - ($T:ty) => ( - impl ToPrimitive for $T { - #[inline] - fn to_isize(&self) -> Option { impl_to_primitive_int_to_int!($T, isize, *self) } - #[inline] - fn to_i8(&self) -> Option { impl_to_primitive_int_to_int!($T, i8, *self) } - #[inline] - fn to_i16(&self) -> Option { impl_to_primitive_int_to_int!($T, i16, *self) } - #[inline] - fn to_i32(&self) -> Option { impl_to_primitive_int_to_int!($T, i32, *self) } - #[inline] - fn to_i64(&self) -> Option { impl_to_primitive_int_to_int!($T, i64, *self) } - - #[inline] - fn to_usize(&self) -> Option { impl_to_primitive_int_to_uint!($T, usize, *self) } - #[inline] - fn to_u8(&self) -> Option { impl_to_primitive_int_to_uint!($T, u8, *self) } - #[inline] - fn to_u16(&self) -> Option { impl_to_primitive_int_to_uint!($T, u16, *self) } - #[inline] - fn to_u32(&self) -> Option { impl_to_primitive_int_to_uint!($T, u32, *self) } - #[inline] - fn to_u64(&self) -> Option { impl_to_primitive_int_to_uint!($T, u64, *self) } - - #[inline] - fn to_f32(&self) -> Option { Some(*self as f32) } - #[inline] - fn to_f64(&self) -> Option { Some(*self as f64) } - } - ) -} - -impl_to_primitive_int! { isize } -impl_to_primitive_int! { i8 } -impl_to_primitive_int! { i16 } -impl_to_primitive_int! { i32 } -impl_to_primitive_int! { i64 } - -macro_rules! impl_to_primitive_uint_to_int { +macro_rules! uint_to_int { ($DstT:ty, $slf:expr) => ( { let max_value: $DstT = Bounded::max_value(); @@ -178,7 +97,7 @@ macro_rules! impl_to_primitive_uint_to_int { ) } -macro_rules! impl_to_primitive_uint_to_uint { +macro_rules! uint_to_uint { ($SrcT:ty, $DstT:ty, $slf:expr) => ( { if size_of::<$SrcT>() <= size_of::<$DstT>() { @@ -196,47 +115,6 @@ macro_rules! impl_to_primitive_uint_to_uint { ) } -macro_rules! impl_to_primitive_uint { - ($T:ty) => ( - impl ToPrimitive for $T { - #[inline] - fn to_isize(&self) -> Option { impl_to_primitive_uint_to_int!(isize, *self) } - #[inline] - fn to_i8(&self) -> Option { impl_to_primitive_uint_to_int!(i8, *self) } - #[inline] - fn to_i16(&self) -> Option { impl_to_primitive_uint_to_int!(i16, *self) } - #[inline] - fn to_i32(&self) -> Option { impl_to_primitive_uint_to_int!(i32, *self) } - #[inline] - fn to_i64(&self) -> Option { impl_to_primitive_uint_to_int!(i64, *self) } - - #[inline] - fn to_usize(&self) -> Option { - impl_to_primitive_uint_to_uint!($T, usize, *self) - } - #[inline] - fn to_u8(&self) -> Option { impl_to_primitive_uint_to_uint!($T, u8, *self) } - #[inline] - fn to_u16(&self) -> Option { impl_to_primitive_uint_to_uint!($T, u16, *self) } - #[inline] - fn to_u32(&self) -> Option { impl_to_primitive_uint_to_uint!($T, u32, *self) } - #[inline] - fn to_u64(&self) -> Option { impl_to_primitive_uint_to_uint!($T, u64, *self) } - - #[inline] - fn to_f32(&self) -> Option { Some(*self as f32) } - #[inline] - fn to_f64(&self) -> Option { Some(*self as f64) } - } - ) -} - -impl_to_primitive_uint! { usize } -impl_to_primitive_uint! { u8 } -impl_to_primitive_uint! { u16 } -impl_to_primitive_uint! { u32 } -impl_to_primitive_uint! { u64 } - pub trait FromPrimitive: Sized { fn from_isize(n: isize) -> Option; fn from_i8(n: i8) -> Option; @@ -250,32 +128,66 @@ pub trait FromPrimitive: Sized { fn from_u64(n: u64) -> Option; } -macro_rules! impl_from_primitive { - ($T:ty, $to_ty:ident) => ( +macro_rules! impl_from_primitive_for_int { + ($T:ty) => ( impl FromPrimitive for $T { - #[inline] fn from_isize(n: isize) -> Option<$T> { n.$to_ty() } - #[inline] fn from_i8(n: i8) -> Option<$T> { n.$to_ty() } - #[inline] fn from_i16(n: i16) -> Option<$T> { n.$to_ty() } - #[inline] fn from_i32(n: i32) -> Option<$T> { n.$to_ty() } - #[inline] fn from_i64(n: i64) -> Option<$T> { n.$to_ty() } - #[inline] fn from_usize(n: usize) -> Option<$T> { n.$to_ty() } - #[inline] fn from_u8(n: u8) -> Option<$T> { n.$to_ty() } - #[inline] fn from_u16(n: u16) -> Option<$T> { n.$to_ty() } - #[inline] fn from_u32(n: u32) -> Option<$T> { n.$to_ty() } - #[inline] fn from_u64(n: u64) -> Option<$T> { n.$to_ty() } + #[inline] fn from_isize(n: isize) -> Option { int_to_int!(isize, $T, n) } + #[inline] fn from_i8(n: i8) -> Option { int_to_int!(i8, $T, n) } + #[inline] fn from_i16(n: i16) -> Option { int_to_int!(i16, $T, n) } + #[inline] fn from_i32(n: i32) -> Option { int_to_int!(i32, $T, n) } + #[inline] fn from_i64(n: i64) -> Option { int_to_int!(i64, $T, n) } + #[inline] fn from_usize(n: usize) -> Option { uint_to_int!($T, n) } + #[inline] fn from_u8(n: u8) -> Option { uint_to_int!($T, n) } + #[inline] fn from_u16(n: u16) -> Option { uint_to_int!($T, n) } + #[inline] fn from_u32(n: u32) -> Option { uint_to_int!($T, n) } + #[inline] fn from_u64(n: u64) -> Option { uint_to_int!($T, n) } } ) } -impl_from_primitive! { isize, to_isize } -impl_from_primitive! { i8, to_i8 } -impl_from_primitive! { i16, to_i16 } -impl_from_primitive! { i32, to_i32 } -impl_from_primitive! { i64, to_i64 } -impl_from_primitive! { usize, to_usize } -impl_from_primitive! { u8, to_u8 } -impl_from_primitive! { u16, to_u16 } -impl_from_primitive! { u32, to_u32 } -impl_from_primitive! { u64, to_u64 } -impl_from_primitive! { f32, to_f32 } -impl_from_primitive! { f64, to_f64 } +macro_rules! impl_from_primitive_for_uint { + ($T:ty) => ( + impl FromPrimitive for $T { + #[inline] fn from_isize(n: isize) -> Option { int_to_uint!(isize, $T, n) } + #[inline] fn from_i8(n: i8) -> Option { int_to_uint!(i8, $T, n) } + #[inline] fn from_i16(n: i16) -> Option { int_to_uint!(i16, $T, n) } + #[inline] fn from_i32(n: i32) -> Option { int_to_uint!(i32, $T, n) } + #[inline] fn from_i64(n: i64) -> Option { int_to_uint!(i64, $T, n) } + #[inline] fn from_usize(n: usize) -> Option { uint_to_uint!(usize, $T, n) } + #[inline] fn from_u8(n: u8) -> Option { uint_to_uint!(u8, $T, n) } + #[inline] fn from_u16(n: u16) -> Option { uint_to_uint!(u16, $T, n) } + #[inline] fn from_u32(n: u32) -> Option { uint_to_uint!(u32, $T, n) } + #[inline] fn from_u64(n: u64) -> Option { uint_to_uint!(u64, $T, n) } + } + ) +} + +macro_rules! impl_from_primitive_for_float { + ($T:ty) => ( + impl FromPrimitive for $T { + #[inline] fn from_isize(n: isize) -> Option { Some(n as Self) } + #[inline] fn from_i8(n: i8) -> Option { Some(n as Self) } + #[inline] fn from_i16(n: i16) -> Option { Some(n as Self) } + #[inline] fn from_i32(n: i32) -> Option { Some(n as Self) } + #[inline] fn from_i64(n: i64) -> Option { Some(n as Self) } + #[inline] fn from_usize(n: usize) -> Option { Some(n as Self) } + #[inline] fn from_u8(n: u8) -> Option { Some(n as Self) } + #[inline] fn from_u16(n: u16) -> Option { Some(n as Self) } + #[inline] fn from_u32(n: u32) -> Option { Some(n as Self) } + #[inline] fn from_u64(n: u64) -> Option { Some(n as Self) } + } + ) +} + +impl_from_primitive_for_int!(isize); +impl_from_primitive_for_int!(i8); +impl_from_primitive_for_int!(i16); +impl_from_primitive_for_int!(i32); +impl_from_primitive_for_int!(i64); +impl_from_primitive_for_uint!(usize); +impl_from_primitive_for_uint!(u8); +impl_from_primitive_for_uint!(u16); +impl_from_primitive_for_uint!(u32); +impl_from_primitive_for_uint!(u64); +impl_from_primitive_for_float!(f32); +impl_from_primitive_for_float!(f64); From 145733ce7752fdfe86723513e77315bfcf522e21 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 12:36:51 -0700 Subject: [PATCH 030/177] Remove redundant Bounded trait --- serde/src/de/from_primitive.rs | 46 +++------------------------------- 1 file changed, 4 insertions(+), 42 deletions(-) diff --git a/serde/src/de/from_primitive.rs b/serde/src/de/from_primitive.rs index d881cd78..92b166d9 100644 --- a/serde/src/de/from_primitive.rs +++ b/serde/src/de/from_primitive.rs @@ -18,39 +18,6 @@ use core::{isize, i8, i16, i32, i64}; use core::{f32, f64}; use core::mem::size_of; -/// Numbers which have upper and lower bounds -pub trait Bounded { - // FIXME (#5527): These should be associated constants - /// returns the smallest finite number this type can represent - fn min_value() -> Self; - /// returns the largest finite number this type can represent - fn max_value() -> Self; -} - -macro_rules! bounded_impl { - ($t:ty, $min:expr, $max:expr) => { - impl Bounded for $t { - #[inline] - fn min_value() -> $t { $min } - - #[inline] - fn max_value() -> $t { $max } - } - } -} - -bounded_impl!(usize, usize::MIN, usize::MAX); -bounded_impl!(u8, u8::MIN, u8::MAX); -bounded_impl!(u16, u16::MIN, u16::MAX); -bounded_impl!(u32, u32::MIN, u32::MAX); -bounded_impl!(u64, u64::MIN, u64::MAX); - -bounded_impl!(isize, isize::MIN, isize::MAX); -bounded_impl!(i8, i8::MIN, i8::MAX); -bounded_impl!(i16, i16::MIN, i16::MAX); -bounded_impl!(i32, i32::MIN, i32::MAX); -bounded_impl!(i64, i64::MIN, i64::MAX); - macro_rules! int_to_int { ($SrcT:ty, $DstT:ty, $slf:expr) => ( { @@ -58,9 +25,7 @@ macro_rules! int_to_int { Some($slf as $DstT) } else { let n = $slf as i64; - let min_value: $DstT = Bounded::min_value(); - let max_value: $DstT = Bounded::max_value(); - if min_value as i64 <= n && n <= max_value as i64 { + if <$DstT>::min_value() as i64 <= n && n <= <$DstT>::max_value() as i64 { Some($slf as $DstT) } else { None @@ -74,8 +39,7 @@ macro_rules! int_to_uint { ($SrcT:ty, $DstT:ty, $slf:expr) => ( { let zero: $SrcT = 0; - let max_value: $DstT = Bounded::max_value(); - if zero <= $slf && $slf as u64 <= max_value as u64 { + if zero <= $slf && $slf as u64 <= <$DstT>::max_value() as u64 { Some($slf as $DstT) } else { None @@ -87,8 +51,7 @@ macro_rules! int_to_uint { macro_rules! uint_to_int { ($DstT:ty, $slf:expr) => ( { - let max_value: $DstT = Bounded::max_value(); - if $slf as u64 <= max_value as u64 { + if $slf as u64 <= <$DstT>::max_value() as u64 { Some($slf as $DstT) } else { None @@ -104,8 +67,7 @@ macro_rules! uint_to_uint { Some($slf as $DstT) } else { let zero: $SrcT = 0; - let max_value: $DstT = Bounded::max_value(); - if zero <= $slf && $slf as u64 <= max_value as u64 { + if zero <= $slf && $slf as u64 <= <$DstT>::max_value() as u64 { Some($slf as $DstT) } else { None From e7d3d515dfddeff18ca6fa5eea692d8813115677 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 13:06:05 -0700 Subject: [PATCH 031/177] Simplify integer conversion logic --- serde/src/de/from_primitive.rs | 119 ++++++++++++--------------------- 1 file changed, 42 insertions(+), 77 deletions(-) diff --git a/serde/src/de/from_primitive.rs b/serde/src/de/from_primitive.rs index 92b166d9..88f53e17 100644 --- a/serde/src/de/from_primitive.rs +++ b/serde/src/de/from_primitive.rs @@ -8,71 +8,36 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Extracted from https://github.com/rust-num/num. - -// Rust 1.5 is unhappy that this private module is undocumented. -#![allow(missing_docs)] - use core::{usize, u8, u16, u32, u64}; use core::{isize, i8, i16, i32, i64}; use core::{f32, f64}; -use core::mem::size_of; macro_rules! int_to_int { - ($SrcT:ty, $DstT:ty, $slf:expr) => ( - { - if size_of::<$SrcT>() <= size_of::<$DstT>() { - Some($slf as $DstT) - } else { - let n = $slf as i64; - if <$DstT>::min_value() as i64 <= n && n <= <$DstT>::max_value() as i64 { - Some($slf as $DstT) - } else { - None - } - } + ($dst:ident, $n:ident) => ( + if $dst::MIN as i64 <= $n as i64 && $n as i64 <= $dst::MAX as i64 { + Some($n as $dst) + } else { + None } ) } macro_rules! int_to_uint { - ($SrcT:ty, $DstT:ty, $slf:expr) => ( - { - let zero: $SrcT = 0; - if zero <= $slf && $slf as u64 <= <$DstT>::max_value() as u64 { - Some($slf as $DstT) - } else { - None - } + ($dst:ident, $n:ident) => ( + if 0 <= $n && $n as u64 <= $dst::MAX as u64 { + Some($n as $dst) + } else { + None } ) } -macro_rules! uint_to_int { - ($DstT:ty, $slf:expr) => ( - { - if $slf as u64 <= <$DstT>::max_value() as u64 { - Some($slf as $DstT) - } else { - None - } - } - ) -} - -macro_rules! uint_to_uint { - ($SrcT:ty, $DstT:ty, $slf:expr) => ( - { - if size_of::<$SrcT>() <= size_of::<$DstT>() { - Some($slf as $DstT) - } else { - let zero: $SrcT = 0; - if zero <= $slf && $slf as u64 <= <$DstT>::max_value() as u64 { - Some($slf as $DstT) - } else { - None - } - } +macro_rules! uint_to { + ($dst:ident, $n:ident) => ( + if $n as u64 <= $dst::MAX as u64 { + Some($n as $dst) + } else { + None } ) } @@ -91,42 +56,42 @@ pub trait FromPrimitive: Sized { } macro_rules! impl_from_primitive_for_int { - ($T:ty) => ( - impl FromPrimitive for $T { - #[inline] fn from_isize(n: isize) -> Option { int_to_int!(isize, $T, n) } - #[inline] fn from_i8(n: i8) -> Option { int_to_int!(i8, $T, n) } - #[inline] fn from_i16(n: i16) -> Option { int_to_int!(i16, $T, n) } - #[inline] fn from_i32(n: i32) -> Option { int_to_int!(i32, $T, n) } - #[inline] fn from_i64(n: i64) -> Option { int_to_int!(i64, $T, n) } - #[inline] fn from_usize(n: usize) -> Option { uint_to_int!($T, n) } - #[inline] fn from_u8(n: u8) -> Option { uint_to_int!($T, n) } - #[inline] fn from_u16(n: u16) -> Option { uint_to_int!($T, n) } - #[inline] fn from_u32(n: u32) -> Option { uint_to_int!($T, n) } - #[inline] fn from_u64(n: u64) -> Option { uint_to_int!($T, n) } + ($t:ident) => ( + impl FromPrimitive for $t { + #[inline] fn from_isize(n: isize) -> Option { int_to_int!($t, n) } + #[inline] fn from_i8(n: i8) -> Option { int_to_int!($t, n) } + #[inline] fn from_i16(n: i16) -> Option { int_to_int!($t, n) } + #[inline] fn from_i32(n: i32) -> Option { int_to_int!($t, n) } + #[inline] fn from_i64(n: i64) -> Option { int_to_int!($t, n) } + #[inline] fn from_usize(n: usize) -> Option { uint_to!($t, n) } + #[inline] fn from_u8(n: u8) -> Option { uint_to!($t, n) } + #[inline] fn from_u16(n: u16) -> Option { uint_to!($t, n) } + #[inline] fn from_u32(n: u32) -> Option { uint_to!($t, n) } + #[inline] fn from_u64(n: u64) -> Option { uint_to!($t, n) } } ) } macro_rules! impl_from_primitive_for_uint { - ($T:ty) => ( - impl FromPrimitive for $T { - #[inline] fn from_isize(n: isize) -> Option { int_to_uint!(isize, $T, n) } - #[inline] fn from_i8(n: i8) -> Option { int_to_uint!(i8, $T, n) } - #[inline] fn from_i16(n: i16) -> Option { int_to_uint!(i16, $T, n) } - #[inline] fn from_i32(n: i32) -> Option { int_to_uint!(i32, $T, n) } - #[inline] fn from_i64(n: i64) -> Option { int_to_uint!(i64, $T, n) } - #[inline] fn from_usize(n: usize) -> Option { uint_to_uint!(usize, $T, n) } - #[inline] fn from_u8(n: u8) -> Option { uint_to_uint!(u8, $T, n) } - #[inline] fn from_u16(n: u16) -> Option { uint_to_uint!(u16, $T, n) } - #[inline] fn from_u32(n: u32) -> Option { uint_to_uint!(u32, $T, n) } - #[inline] fn from_u64(n: u64) -> Option { uint_to_uint!(u64, $T, n) } + ($t:ident) => ( + impl FromPrimitive for $t { + #[inline] fn from_isize(n: isize) -> Option { int_to_uint!($t, n) } + #[inline] fn from_i8(n: i8) -> Option { int_to_uint!($t, n) } + #[inline] fn from_i16(n: i16) -> Option { int_to_uint!($t, n) } + #[inline] fn from_i32(n: i32) -> Option { int_to_uint!($t, n) } + #[inline] fn from_i64(n: i64) -> Option { int_to_uint!($t, n) } + #[inline] fn from_usize(n: usize) -> Option { uint_to!($t, n) } + #[inline] fn from_u8(n: u8) -> Option { uint_to!($t, n) } + #[inline] fn from_u16(n: u16) -> Option { uint_to!($t, n) } + #[inline] fn from_u32(n: u32) -> Option { uint_to!($t, n) } + #[inline] fn from_u64(n: u64) -> Option { uint_to!($t, n) } } ) } macro_rules! impl_from_primitive_for_float { - ($T:ty) => ( - impl FromPrimitive for $T { + ($t:ident) => ( + impl FromPrimitive for $t { #[inline] fn from_isize(n: isize) -> Option { Some(n as Self) } #[inline] fn from_i8(n: i8) -> Option { Some(n as Self) } #[inline] fn from_i16(n: i16) -> Option { Some(n as Self) } From 8fd41d3b287e41af10e91614e7b197695ac7a187 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 15:11:47 -0700 Subject: [PATCH 032/177] Disable publishing --- serde/Cargo.toml | 1 + serde_derive/Cargo.toml | 1 + serde_test/Cargo.toml | 1 + 3 files changed, 3 insertions(+) diff --git a/serde/Cargo.toml b/serde/Cargo.toml index 86fbe3c3..277c6798 100644 --- a/serde/Cargo.toml +++ b/serde/Cargo.toml @@ -11,6 +11,7 @@ keywords = ["serde", "serialization", "no_std"] categories = ["encoding"] readme = "../README.md" include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +publish = false # this branch contains breaking changes [badges] travis-ci = { repository = "serde-rs/serde" } diff --git a/serde_derive/Cargo.toml b/serde_derive/Cargo.toml index 6a49f513..23b0a134 100644 --- a/serde_derive/Cargo.toml +++ b/serde_derive/Cargo.toml @@ -10,6 +10,7 @@ documentation = "https://serde.rs/codegen.html" keywords = ["serde", "serialization", "no_std"] readme = "../README.md" include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +publish = false # this branch contains breaking changes [features] unstable = [] diff --git a/serde_test/Cargo.toml b/serde_test/Cargo.toml index 63c442f5..8907f973 100644 --- a/serde_test/Cargo.toml +++ b/serde_test/Cargo.toml @@ -10,6 +10,7 @@ documentation = "https://docs.serde.rs/serde_test/" keywords = ["serde", "serialization"] readme = "../README.md" include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +publish = false # this branch contains breaking changes [dependencies] serde = { version = "0.9", path = "../serde" } From ebe214e8ac127e7e7c2f7cbbf1cfaa7cb848772f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 15:19:29 -0700 Subject: [PATCH 033/177] Remove CString dependency on ByteBuf --- serde/src/de/impls.rs | 67 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 9f666729..5d5e8e8e 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -58,9 +58,6 @@ use de::{Deserialize, Deserializer, EnumVisitor, Error, MapVisitor, SeqVisitor, VariantVisitor, Visitor}; use de::from_primitive::FromPrimitive; -#[cfg(feature = "std")] -use bytes::ByteBuf; - /////////////////////////////////////////////////////////////////////////////// struct UnitVisitor; @@ -354,13 +351,52 @@ impl<'de: 'a, 'a> Deserialize<'de> for &'a [u8] { /////////////////////////////////////////////////////////////////////////////// -#[cfg(all(feature = "std", feature="unstable"))] -impl<'de> Deserialize<'de> for Box { - fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> +#[cfg(feature = "std")] +struct CStringVisitor; + +#[cfg(feature = "std")] +impl<'de> Visitor<'de> for CStringVisitor { + type Value = CString; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("byte array") + } + + fn visit_seq(self, mut visitor: V) -> Result + where V: SeqVisitor<'de> { - let s = try!(CString::deserialize(deserializer)); - Ok(s.into_boxed_c_str()) + let len = cmp::min(visitor.size_hint().0, 4096); + let mut values = Vec::with_capacity(len); + + while let Some(value) = try!(visitor.visit()) { + values.push(value); + } + + CString::new(values).map_err(Error::custom) + } + + fn visit_bytes(self, v: &[u8]) -> Result + where E: Error + { + CString::new(v).map_err(Error::custom) + } + + fn visit_byte_buf(self, v: Vec) -> Result + where E: Error + { + CString::new(v).map_err(Error::custom) + } + + fn visit_str(self, v: &str) -> Result + where E: Error + { + CString::new(v).map_err(Error::custom) + } + + fn visit_string(self, v: String) -> Result + where E: Error + { + CString::new(v).map_err(Error::custom) } } @@ -369,8 +405,17 @@ impl<'de> Deserialize<'de> for CString { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { - let bytes = try!(ByteBuf::deserialize(deserializer)); - CString::new(bytes).map_err(Error::custom) + deserializer.deserialize_byte_buf(CStringVisitor) + } +} + +#[cfg(all(feature = "std", feature="unstable"))] +impl<'de> Deserialize<'de> for Box { + fn deserialize(deserializer: D) -> Result + where D: Deserializer<'de> + { + let s = try!(CString::deserialize(deserializer)); + Ok(s.into_boxed_c_str()) } } From aa30ef827c8ab032c25ebed8d796d9201a90dd5b Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 15:20:14 -0700 Subject: [PATCH 034/177] Move Bytes and ByteBuf to their own crate Moved to https://github.com/serde-rs/bytes. --- serde/src/bytes.rs | 315 --------------------------------- serde/src/de/value.rs | 82 --------- serde/src/lib.rs | 1 - test_suite/tests/test_bytes.rs | 52 ------ 4 files changed, 450 deletions(-) delete mode 100644 serde/src/bytes.rs delete mode 100644 test_suite/tests/test_bytes.rs diff --git a/serde/src/bytes.rs b/serde/src/bytes.rs deleted file mode 100644 index b6b6d02a..00000000 --- a/serde/src/bytes.rs +++ /dev/null @@ -1,315 +0,0 @@ -//! Wrapper types to enable optimized handling of `&[u8]` and `Vec`. -//! -//! Without specialization, Rust forces us to treat `&[u8]` just like any other -//! slice and `Vec` just like any other vector. In reality this particular -//! slice and vector can often be serialized and deserialized in a more -//! efficient, compact representation in many formats. -//! -//! When working with such a format, you can opt into specialized handling of -//! `&[u8]` by wrapping it in `bytes::Bytes` and `Vec` by wrapping it in -//! `bytes::ByteBuf`. -//! -//! Rust support for specialization is being tracked in -//! [rust-lang/rust#31844][specialization]. Once it lands in the stable compiler -//! we will be deprecating these wrapper types in favor of optimizing `&[u8]` -//! and `Vec` out of the box. -//! -//! [specialization]: https://github.com/rust-lang/rust/issues/31844 - -use core::{ops, fmt, char, iter, slice}; -use core::fmt::Write; - -use ser; - -#[cfg(any(feature = "std", feature = "collections"))] -pub use self::bytebuf::ByteBuf; - -#[cfg(any(feature = "std", feature = "collections"))] -#[doc(hidden)] // does anybody need this? -pub use self::bytebuf::ByteBufVisitor; - -#[cfg(feature = "collections")] -use collections::Vec; - -/////////////////////////////////////////////////////////////////////////////// - -/// Wraps a `&[u8]` in order to serialize in an efficient way. Does not support -/// deserialization. -/// -/// ```rust -/// # #[macro_use] extern crate serde_derive; -/// # extern crate serde; -/// # use std::net::IpAddr; -/// # -/// use serde::bytes::Bytes; -/// -/// # #[allow(dead_code)] -/// #[derive(Serialize)] -/// struct Packet<'a> { -/// destination: IpAddr, -/// payload: Bytes<'a>, -/// } -/// # -/// # fn main() {} -/// ``` -#[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)] -pub struct Bytes<'a> { - bytes: &'a [u8], -} - -impl<'a> Bytes<'a> { - /// Wrap an existing `&[u8]`. - pub fn new(bytes: &'a [u8]) -> Self { - Bytes { bytes: bytes } - } -} - -impl<'a> fmt::Debug for Bytes<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(f.write_str("b\"")); - for c in escape_bytestring(self.bytes) { - try!(f.write_char(c)); - } - f.write_char('"') - } -} - -impl<'a> From<&'a [u8]> for Bytes<'a> { - fn from(bytes: &'a [u8]) -> Self { - Bytes::new(bytes) - } -} - -#[cfg(any(feature = "std", feature = "collections"))] -impl<'a> From<&'a Vec> for Bytes<'a> { - fn from(bytes: &'a Vec) -> Self { - Bytes::new(bytes) - } -} - -impl<'a> Into<&'a [u8]> for Bytes<'a> { - fn into(self) -> &'a [u8] { - self.bytes - } -} - -impl<'a> ops::Deref for Bytes<'a> { - type Target = [u8]; - - fn deref(&self) -> &[u8] { - self.bytes - } -} - -impl<'a> ser::Serialize for Bytes<'a> { - #[inline] - fn serialize(&self, serializer: S) -> Result - where S: ser::Serializer - { - serializer.serialize_bytes(self.bytes) - } -} - -/////////////////////////////////////////////////////////////////////////////// - -#[cfg(any(feature = "std", feature = "collections"))] -mod bytebuf { - use core::cmp; - use core::ops; - use core::fmt; - use core::fmt::Write; - - use ser; - use de; - - #[cfg(feature = "collections")] - use collections::{String, Vec}; - - /// Wraps a `Vec` in order to serialize and deserialize in an efficient - /// way. - /// - /// ```rust - /// # #[macro_use] extern crate serde_derive; - /// # extern crate serde; - /// # use std::net::IpAddr; - /// # - /// use serde::bytes::ByteBuf; - /// - /// # #[allow(dead_code)] - /// #[derive(Serialize, Deserialize)] - /// struct Packet { - /// destination: IpAddr, - /// payload: ByteBuf, - /// } - /// # - /// # fn main() {} - /// ``` - #[derive(Clone, Default, Eq, Hash, PartialEq, PartialOrd, Ord)] - pub struct ByteBuf { - bytes: Vec, - } - - impl ByteBuf { - /// Construct a new, empty `ByteBuf`. - pub fn new() -> Self { - ByteBuf::from(Vec::new()) - } - - /// Construct a new, empty `ByteBuf` with the specified capacity. - pub fn with_capacity(cap: usize) -> Self { - ByteBuf::from(Vec::with_capacity(cap)) - } - - /// Wrap existing bytes in a `ByteBuf`. - pub fn from>>(bytes: T) -> Self { - ByteBuf { bytes: bytes.into() } - } - } - - impl fmt::Debug for ByteBuf { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(f.write_str("b\"")); - for c in super::escape_bytestring(self.bytes.as_ref()) { - try!(f.write_char(c)); - } - f.write_char('"') - } - } - - impl Into> for ByteBuf { - fn into(self) -> Vec { - self.bytes - } - } - - impl From> for ByteBuf { - fn from(bytes: Vec) -> Self { - ByteBuf::from(bytes) - } - } - - impl AsRef> for ByteBuf { - fn as_ref(&self) -> &Vec { - &self.bytes - } - } - - impl AsRef<[u8]> for ByteBuf { - fn as_ref(&self) -> &[u8] { - &self.bytes - } - } - - impl AsMut> for ByteBuf { - fn as_mut(&mut self) -> &mut Vec { - &mut self.bytes - } - } - - impl AsMut<[u8]> for ByteBuf { - fn as_mut(&mut self) -> &mut [u8] { - &mut self.bytes - } - } - - impl ops::Deref for ByteBuf { - type Target = [u8]; - - fn deref(&self) -> &[u8] { - &self.bytes[..] - } - } - - impl ops::DerefMut for ByteBuf { - fn deref_mut(&mut self) -> &mut [u8] { - &mut self.bytes[..] - } - } - - impl ser::Serialize for ByteBuf { - fn serialize(&self, serializer: S) -> Result - where S: ser::Serializer - { - serializer.serialize_bytes(self) - } - } - - /// This type implements the `serde::de::Visitor` trait for a `ByteBuf`. - pub struct ByteBufVisitor; - - impl<'de> de::Visitor<'de> for ByteBufVisitor { - type Value = ByteBuf; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("byte array") - } - - #[inline] - fn visit_unit(self) -> Result - where E: de::Error - { - Ok(ByteBuf::new()) - } - - #[inline] - fn visit_seq(self, mut visitor: V) -> Result - where V: de::SeqVisitor<'de> - { - let len = cmp::min(visitor.size_hint().0, 4096); - let mut values = Vec::with_capacity(len); - - while let Some(value) = try!(visitor.visit()) { - values.push(value); - } - - Ok(ByteBuf::from(values)) - } - - #[inline] - fn visit_bytes(self, v: &[u8]) -> Result - where E: de::Error - { - Ok(ByteBuf::from(v)) - } - - #[inline] - fn visit_byte_buf(self, v: Vec) -> Result - where E: de::Error - { - Ok(ByteBuf::from(v)) - } - - fn visit_str(self, v: &str) -> Result - where E: de::Error - { - Ok(ByteBuf::from(v)) - } - - fn visit_string(self, v: String) -> Result - where E: de::Error - { - Ok(ByteBuf::from(v)) - } - } - - impl<'de> de::Deserialize<'de> for ByteBuf { - #[inline] - fn deserialize(deserializer: D) -> Result - where D: de::Deserializer<'de> - { - deserializer.deserialize_byte_buf(ByteBufVisitor) - } - } -} - -/////////////////////////////////////////////////////////////////////////////// - -#[inline] -fn escape_bytestring<'a> - (bytes: &'a [u8]) - -> iter::FlatMap, char::EscapeDefault, fn(&u8) -> char::EscapeDefault> { - fn f(b: &u8) -> char::EscapeDefault { - char::from_u32(*b as u32).unwrap().escape_default() - } - bytes.iter().flat_map(f as fn(&u8) -> char::EscapeDefault) -} diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 13aaaba7..f4d1eba0 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -29,7 +29,6 @@ use core::iter::{self, Iterator}; use core::marker::PhantomData; use de::{self, Expected, SeqVisitor}; -use bytes; /////////////////////////////////////////////////////////////////////////////// @@ -959,87 +958,6 @@ impl<'de, V_> de::Deserializer<'de> for MapVisitorDeserializer /////////////////////////////////////////////////////////////////////////////// -impl<'de, 'a, E> ValueDeserializer<'de, E> for bytes::Bytes<'a> - where E: de::Error -{ - type Deserializer = BytesDeserializer<'a, E>; - - fn into_deserializer(self) -> BytesDeserializer<'a, E> { - BytesDeserializer { - value: self.into(), - marker: PhantomData, - } - } -} - -/// A helper deserializer that deserializes a `&[u8]`. -pub struct BytesDeserializer<'a, E> { - value: &'a [u8], - marker: PhantomData, -} - -impl<'de, 'a, E> de::Deserializer<'de> for BytesDeserializer<'a, E> - where E: de::Error -{ - type Error = E; - - fn deserialize(self, visitor: V) -> Result - where V: de::Visitor<'de> - { - visitor.visit_bytes(self.value) - } - - forward_to_deserialize! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct - struct struct_field tuple enum ignored_any byte_buf - } -} - -/////////////////////////////////////////////////////////////////////////////// - -#[cfg(any(feature = "std", feature = "collections"))] -impl<'de, E> ValueDeserializer<'de, E> for bytes::ByteBuf - where E: de::Error -{ - type Deserializer = ByteBufDeserializer; - - fn into_deserializer(self) -> Self::Deserializer { - ByteBufDeserializer { - value: self.into(), - marker: PhantomData, - } - } -} - -/// A helper deserializer that deserializes a `Vec`. -#[cfg(any(feature = "std", feature = "collections"))] -pub struct ByteBufDeserializer { - value: Vec, - marker: PhantomData, -} - -#[cfg(any(feature = "std", feature = "collections"))] -impl<'de, E> de::Deserializer<'de> for ByteBufDeserializer - where E: de::Error -{ - type Error = E; - - fn deserialize(self, visitor: V) -> Result - where V: de::Visitor<'de> - { - visitor.visit_byte_buf(self.value) - } - - forward_to_deserialize! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct - struct struct_field tuple enum ignored_any byte_buf - } -} - -/////////////////////////////////////////////////////////////////////////////// - mod private { use de::{self, Unexpected}; use core::marker::PhantomData; diff --git a/serde/src/lib.rs b/serde/src/lib.rs index cfd2f7d0..eb7aa326 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -93,7 +93,6 @@ pub use de::{Deserialize, Deserializer}; #[macro_use] mod macros; -pub mod bytes; pub mod de; #[cfg(feature = "std")] #[doc(hidden)] diff --git a/test_suite/tests/test_bytes.rs b/test_suite/tests/test_bytes.rs deleted file mode 100644 index 4da64e1c..00000000 --- a/test_suite/tests/test_bytes.rs +++ /dev/null @@ -1,52 +0,0 @@ -extern crate serde; -use serde::bytes::{ByteBuf, Bytes}; - -extern crate serde_test; -use serde_test::{assert_tokens, assert_ser_tokens, assert_de_tokens, Token}; - -#[test] -fn test_bytes() { - let empty = Bytes::new(&[]); - assert_ser_tokens(&empty, &[Token::Bytes(b"")]); - - let buf = vec![65, 66, 67]; - let bytes = Bytes::new(&buf); - assert_ser_tokens(&bytes, &[Token::Bytes(b"ABC")]); -} - -#[test] -fn test_byte_buf() { - let empty = ByteBuf::new(); - assert_tokens(&empty, &[Token::Bytes(b"")]); - assert_de_tokens(&empty, &[Token::ByteBuf(b"")]); - assert_de_tokens(&empty, &[Token::Str("")]); - assert_de_tokens(&empty, &[Token::String("")]); - assert_de_tokens(&empty, &[ - Token::Seq(None), - Token::SeqEnd, - ]); - assert_de_tokens(&empty, &[ - Token::Seq(Some(0)), - Token::SeqEnd, - ]); - - let buf = ByteBuf::from(vec![65, 66, 67]); - assert_tokens(&buf, &[Token::Bytes(b"ABC")]); - assert_de_tokens(&buf, &[Token::ByteBuf(b"ABC")]); - assert_de_tokens(&buf, &[Token::Str("ABC")]); - assert_de_tokens(&buf, &[Token::String("ABC")]); - assert_de_tokens(&buf, &[ - Token::Seq(None), - Token::U8(65), - Token::U8(66), - Token::U8(67), - Token::SeqEnd, - ]); - assert_de_tokens(&buf, &[ - Token::Seq(Some(3)), - Token::U8(65), - Token::U8(66), - Token::U8(67), - Token::SeqEnd, - ]); -} From 3cc14c2a6dfea730cc0d7e6eb9d6b9fa1607ca78 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 16:12:41 -0700 Subject: [PATCH 035/177] Remove serde::error::Error --- serde/src/de/mod.rs | 246 ++++++++++++++++++++++-------------------- serde/src/de/value.rs | 9 +- serde/src/error.rs | 17 --- serde/src/lib.rs | 2 - serde/src/ser/mod.rs | 68 +++++++----- 5 files changed, 167 insertions(+), 175 deletions(-) delete mode 100644 serde/src/error.rs diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index c9b427f2..a918ea97 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -96,8 +96,6 @@ #[cfg(feature = "std")] use std::error; -#[cfg(not(feature = "std"))] -use error; #[cfg(all(not(feature = "std"), feature = "collections"))] use collections::{String, Vec}; @@ -123,131 +121,141 @@ pub use self::ignored_any::IgnoredAny; /////////////////////////////////////////////////////////////////////////////// -/// The `Error` trait allows `Deserialize` implementations to create descriptive -/// error messages belonging to the `Deserializer` against which they are -/// currently running. -/// -/// Every `Deserializer` declares an `Error` type that encompasses both -/// general-purpose deserialization errors as well as errors specific to the -/// particular deserialization format. For example the `Error` type of -/// `serde_json` can represent errors like an invalid JSON escape sequence or an -/// unterminated string literal, in addition to the error cases that are part of -/// this trait. -/// -/// Most deserializers should only need to provide the `Error::custom` method -/// and inherit the default behavior for the other methods. -pub trait Error: Sized + error::Error { - /// Raised when there is general error when deserializing a type. - /// - /// The message should not be capitalized and should not end with a period. - /// - /// ```rust - /// # use serde::de::{Deserialize, Deserializer, Error}; - /// # use std::str::FromStr; - /// # #[allow(dead_code)] - /// # struct IpAddr; - /// # impl FromStr for IpAddr { - /// # type Err = String; - /// # fn from_str(_: &str) -> Result { unimplemented!() } - /// # } - /// impl<'de> Deserialize<'de> for IpAddr { - /// fn deserialize(deserializer: D) -> Result - /// where D: Deserializer<'de> - /// { - /// let s = try!(String::deserialize(deserializer)); - /// s.parse().map_err(Error::custom) - /// } - /// } - /// ``` - fn custom(msg: T) -> Self; +macro_rules! declare_error_trait { + (Error: Sized $(+ $supertrait:path)*) => { + /// The `Error` trait allows `Deserialize` implementations to create descriptive + /// error messages belonging to the `Deserializer` against which they are + /// currently running. + /// + /// Every `Deserializer` declares an `Error` type that encompasses both + /// general-purpose deserialization errors as well as errors specific to the + /// particular deserialization format. For example the `Error` type of + /// `serde_json` can represent errors like an invalid JSON escape sequence or an + /// unterminated string literal, in addition to the error cases that are part of + /// this trait. + /// + /// Most deserializers should only need to provide the `Error::custom` method + /// and inherit the default behavior for the other methods. + pub trait Error: Sized $(+ $supertrait)* { + /// Raised when there is general error when deserializing a type. + /// + /// The message should not be capitalized and should not end with a period. + /// + /// ```rust + /// # use serde::de::{Deserialize, Deserializer, Error}; + /// # use std::str::FromStr; + /// # #[allow(dead_code)] + /// # struct IpAddr; + /// # impl FromStr for IpAddr { + /// # type Err = String; + /// # fn from_str(_: &str) -> Result { unimplemented!() } + /// # } + /// impl<'de> Deserialize<'de> for IpAddr { + /// fn deserialize(deserializer: D) -> Result + /// where D: Deserializer<'de> + /// { + /// let s = try!(String::deserialize(deserializer)); + /// s.parse().map_err(Error::custom) + /// } + /// } + /// ``` + fn custom(msg: T) -> Self; - /// Raised when a `Deserialize` receives a type different from what it was - /// expecting. - /// - /// The `unexp` argument provides information about what type was received. - /// This is the type that was present in the input file or other source data - /// of the Deserializer. - /// - /// The `exp` argument provides information about what type was being - /// expected. This is the type that is written in the program. - /// - /// For example if we try to deserialize a String out of a JSON file - /// containing an integer, the unexpected type is the integer and the - /// expected type is the string. - fn invalid_type(unexp: Unexpected, exp: &Expected) -> Self { - Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp)) - } + /// Raised when a `Deserialize` receives a type different from what it was + /// expecting. + /// + /// The `unexp` argument provides information about what type was received. + /// This is the type that was present in the input file or other source data + /// of the Deserializer. + /// + /// The `exp` argument provides information about what type was being + /// expected. This is the type that is written in the program. + /// + /// For example if we try to deserialize a String out of a JSON file + /// containing an integer, the unexpected type is the integer and the + /// expected type is the string. + fn invalid_type(unexp: Unexpected, exp: &Expected) -> Self { + Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp)) + } - /// Raised when a `Deserialize` receives a value of the right type but that - /// is wrong for some other reason. - /// - /// The `unexp` argument provides information about what value was received. - /// This is the value that was present in the input file or other source - /// data of the Deserializer. - /// - /// The `exp` argument provides information about what value was being - /// expected. This is the type that is written in the program. - /// - /// For example if we try to deserialize a String out of some binary data - /// that is not valid UTF-8, the unexpected value is the bytes and the - /// expected value is a string. - fn invalid_value(unexp: Unexpected, exp: &Expected) -> Self { - Error::custom(format_args!("invalid value: {}, expected {}", unexp, exp)) - } + /// Raised when a `Deserialize` receives a value of the right type but that + /// is wrong for some other reason. + /// + /// The `unexp` argument provides information about what value was received. + /// This is the value that was present in the input file or other source + /// data of the Deserializer. + /// + /// The `exp` argument provides information about what value was being + /// expected. This is the type that is written in the program. + /// + /// For example if we try to deserialize a String out of some binary data + /// that is not valid UTF-8, the unexpected value is the bytes and the + /// expected value is a string. + fn invalid_value(unexp: Unexpected, exp: &Expected) -> Self { + Error::custom(format_args!("invalid value: {}, expected {}", unexp, exp)) + } - /// Raised when deserializing a sequence or map and the input data contains - /// too many or too few elements. - /// - /// The `len` argument is the number of elements encountered. The sequence - /// or map may have expected more arguments or fewer arguments. - /// - /// The `exp` argument provides information about what data was being - /// expected. For example `exp` might say that a tuple of size 6 was - /// expected. - fn invalid_length(len: usize, exp: &Expected) -> Self { - Error::custom(format_args!("invalid length {}, expected {}", len, exp)) - } + /// Raised when deserializing a sequence or map and the input data contains + /// too many or too few elements. + /// + /// The `len` argument is the number of elements encountered. The sequence + /// or map may have expected more arguments or fewer arguments. + /// + /// The `exp` argument provides information about what data was being + /// expected. For example `exp` might say that a tuple of size 6 was + /// expected. + fn invalid_length(len: usize, exp: &Expected) -> Self { + Error::custom(format_args!("invalid length {}, expected {}", len, exp)) + } - /// Raised when a `Deserialize` enum type received a variant with an - /// unrecognized name. - fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self { - if expected.is_empty() { - Error::custom(format_args!("unknown variant `{}`, there are no variants", - variant)) - } else { - Error::custom(format_args!("unknown variant `{}`, expected {}", - variant, - OneOf { names: expected })) + /// Raised when a `Deserialize` enum type received a variant with an + /// unrecognized name. + fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self { + if expected.is_empty() { + Error::custom(format_args!("unknown variant `{}`, there are no variants", + variant)) + } else { + Error::custom(format_args!("unknown variant `{}`, expected {}", + variant, + OneOf { names: expected })) + } + } + + /// Raised when a `Deserialize` struct type received a field with an + /// unrecognized name. + fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self { + if expected.is_empty() { + Error::custom(format_args!("unknown field `{}`, there are no fields", + field)) + } else { + Error::custom(format_args!("unknown field `{}`, expected {}", + field, + OneOf { names: expected })) + } + } + + /// Raised when a `Deserialize` struct type expected to receive a required + /// field with a particular name but that field was not present in the + /// input. + fn missing_field(field: &'static str) -> Self { + Error::custom(format_args!("missing field `{}`", field)) + } + + /// Raised when a `Deserialize` struct type received more than one of the + /// same field. + fn duplicate_field(field: &'static str) -> Self { + Error::custom(format_args!("duplicate field `{}`", field)) + } } } - - /// Raised when a `Deserialize` struct type received a field with an - /// unrecognized name. - fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self { - if expected.is_empty() { - Error::custom(format_args!("unknown field `{}`, there are no fields", - field)) - } else { - Error::custom(format_args!("unknown field `{}`, expected {}", - field, - OneOf { names: expected })) - } - } - - /// Raised when a `Deserialize` struct type expected to receive a required - /// field with a particular name but that field was not present in the - /// input. - fn missing_field(field: &'static str) -> Self { - Error::custom(format_args!("missing field `{}`", field)) - } - - /// Raised when a `Deserialize` struct type received more than one of the - /// same field. - fn duplicate_field(field: &'static str) -> Self { - Error::custom(format_args!("duplicate field `{}`", field)) - } } +#[cfg(feature = "std")] +declare_error_trait!(Error: Sized + error::Error); + +#[cfg(not(feature = "std"))] +declare_error_trait!(Error: Sized); + /// `Unexpected` represents an unexpected invocation of any one of the `Visitor` /// trait methods. /// diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index f4d1eba0..3b157b0c 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -21,8 +21,6 @@ use collections::string::ToString; use core::hash::Hash; #[cfg(feature = "std")] use std::error; -#[cfg(not(feature = "std"))] -use error; use core::fmt::{self, Display}; use core::iter::{self, Iterator}; @@ -67,16 +65,11 @@ impl Display for Error { } } +#[cfg(feature = "std")] impl error::Error for Error { - #[cfg(any(feature = "std", feature = "collections"))] fn description(&self) -> &str { &self.err } - - #[cfg(not(any(feature = "std", feature = "collections")))] - fn description(&self) -> &str { - "Serde deserialization error" - } } /////////////////////////////////////////////////////////////////////////////// diff --git a/serde/src/error.rs b/serde/src/error.rs deleted file mode 100644 index fe91c28f..00000000 --- a/serde/src/error.rs +++ /dev/null @@ -1,17 +0,0 @@ -//! A stand-in for `std::error` -use core::fmt::{Debug, Display}; - -/// A stand-in for `std::error::Error`, which requires no allocation. -pub trait Error: Debug + Display { - /// A short description of the error. - /// - /// The description should not contain newlines or sentence-ending - /// punctuation, to facilitate embedding in larger user-facing - /// strings. - fn description(&self) -> &str; - - /// The lower-level cause of this error, if any. - fn cause(&self) -> Option<&Error> { - None - } -} diff --git a/serde/src/lib.rs b/serde/src/lib.rs index eb7aa326..3fe7ec57 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -98,8 +98,6 @@ pub mod de; #[doc(hidden)] pub mod iter; pub mod ser; -#[cfg_attr(feature = "std", doc(hidden))] -pub mod error; mod utils; // Generated code uses these to support no_std. Not public API. diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index fb9ef2dd..475d6836 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -94,8 +94,6 @@ #[cfg(feature = "std")] use std::error; -#[cfg(not(feature = "std"))] -use error; #[cfg(all(feature = "collections", not(feature = "std")))] use collections::string::String; @@ -117,35 +115,47 @@ pub use self::impossible::Impossible; /////////////////////////////////////////////////////////////////////////////// -/// Trait used by `Serialize` implementations to generically construct errors -/// belonging to the `Serializer` against which they are currently running. -pub trait Error: Sized + error::Error { - /// Raised when a `Serialize` implementation encounters a general error - /// while serializing a type. - /// - /// The message should not be capitalized and should not end with a period. - /// - /// For example, a filesystem `Path` may refuse to serialize itself if it - /// contains invalid UTF-8 data. - /// - /// ```rust - /// # use serde::ser::{Serialize, Serializer, Error}; - /// # struct Path; - /// # impl Path { fn to_str(&self) -> Option<&str> { unimplemented!() } } - /// impl Serialize for Path { - /// fn serialize(&self, serializer: S) -> Result - /// where S: Serializer - /// { - /// match self.to_str() { - /// Some(s) => s.serialize(serializer), - /// None => Err(Error::custom("path contains invalid UTF-8 characters")), - /// } - /// } - /// } - /// ``` - fn custom(msg: T) -> Self; +macro_rules! declare_error_trait { + (Error: Sized $(+ $supertrait:path)*) => { + /// Trait used by `Serialize` implementations to generically construct + /// errors belonging to the `Serializer` against which they are + /// currently running. + pub trait Error: Sized $(+ $supertrait)* { + /// Raised when a `Serialize` implementation encounters a general + /// error while serializing a type. + /// + /// The message should not be capitalized and should not end with a + /// period. + /// + /// For example, a filesystem `Path` may refuse to serialize itself + /// if it contains invalid UTF-8 data. + /// + /// ```rust + /// # use serde::ser::{Serialize, Serializer, Error}; + /// # struct Path; + /// # impl Path { fn to_str(&self) -> Option<&str> { unimplemented!() } } + /// impl Serialize for Path { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// match self.to_str() { + /// Some(s) => s.serialize(serializer), + /// None => Err(Error::custom("path contains invalid UTF-8 characters")), + /// } + /// } + /// } + /// ``` + fn custom(msg: T) -> Self; + } + } } +#[cfg(feature = "std")] +declare_error_trait!(Error: Sized + error::Error); + +#[cfg(not(feature = "std"))] +declare_error_trait!(Error: Sized); + /////////////////////////////////////////////////////////////////////////////// /// A **data structure** that can be serialized into any data format supported From 5f49eb8b24cd3c079db335fb104cc4bd0c639a51 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 16:18:11 -0700 Subject: [PATCH 036/177] Remove unused import of MapVisitor --- serde/src/de/impls.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 5d5e8e8e..21f557f9 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -54,8 +54,10 @@ use core::nonzero::{NonZero, Zeroable}; #[allow(deprecated)] // required for impl Deserialize for NonZero use core::num::Zero; -use de::{Deserialize, Deserializer, EnumVisitor, Error, MapVisitor, SeqVisitor, Unexpected, +use de::{Deserialize, Deserializer, EnumVisitor, Error, SeqVisitor, Unexpected, VariantVisitor, Visitor}; +#[cfg(any(feature = "std", feature = "collections"))] +use de::MapVisitor; use de::from_primitive::FromPrimitive; /////////////////////////////////////////////////////////////////////////////// From 11c89695a146c68b5c0c291085cc02cf29feb464 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 16:22:47 -0700 Subject: [PATCH 037/177] Rust 1.13.0 macro parsing workaround --- serde/src/de/mod.rs | 4 ++-- serde/src/ser/mod.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index a918ea97..37d7719e 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -122,7 +122,7 @@ pub use self::ignored_any::IgnoredAny; /////////////////////////////////////////////////////////////////////////////// macro_rules! declare_error_trait { - (Error: Sized $(+ $supertrait:path)*) => { + (Error: Sized $(+ $($supertrait:ident)::*)*) => { /// The `Error` trait allows `Deserialize` implementations to create descriptive /// error messages belonging to the `Deserializer` against which they are /// currently running. @@ -136,7 +136,7 @@ macro_rules! declare_error_trait { /// /// Most deserializers should only need to provide the `Error::custom` method /// and inherit the default behavior for the other methods. - pub trait Error: Sized $(+ $supertrait)* { + pub trait Error: Sized $(+ $($supertrait)::*)* { /// Raised when there is general error when deserializing a type. /// /// The message should not be capitalized and should not end with a period. diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 475d6836..63065e09 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -116,11 +116,11 @@ pub use self::impossible::Impossible; /////////////////////////////////////////////////////////////////////////////// macro_rules! declare_error_trait { - (Error: Sized $(+ $supertrait:path)*) => { + (Error: Sized $(+ $($supertrait:ident)::*)*) => { /// Trait used by `Serialize` implementations to generically construct /// errors belonging to the `Serializer` against which they are /// currently running. - pub trait Error: Sized $(+ $supertrait)* { + pub trait Error: Sized $(+ $($supertrait)::*)* { /// Raised when a `Serialize` implementation encounters a general /// error while serializing a type. /// From e2a1f08e433fdc4fec14d64696625b134f7fd113 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 16:26:58 -0700 Subject: [PATCH 038/177] Remove unused import of std::ops --- serde/src/lib.rs | 2 +- serde/src/ser/impls.rs | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/serde/src/lib.rs b/serde/src/lib.rs index eb7aa326..2d7a4ff3 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -65,7 +65,7 @@ #![cfg_attr(feature = "alloc", feature(alloc))] #![cfg_attr(feature = "collections", feature(collections))] #![cfg_attr(feature = "cargo-clippy", allow(linkedlist, type_complexity, doc_markdown))] -#![deny(missing_docs)] +#![deny(missing_docs, unused_imports)] #[cfg(feature = "collections")] extern crate collections; diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 4f817760..a9bfaf09 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -14,11 +14,7 @@ use collections::borrow::ToOwned; #[cfg(feature = "std")] use core::hash::{Hash, BuildHasher}; #[cfg(feature = "std")] -use std::net; -#[cfg(any(feature = "std", feature = "unstable"))] -use core::ops; -#[cfg(feature = "std")] -use std::path; +use std::{net, ops, path}; #[cfg(feature = "std")] use std::ffi::{CString, CStr, OsString, OsStr}; #[cfg(feature = "std")] From 1e32329e61716c137482fb30ab2968f283538baf Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 16:30:46 -0700 Subject: [PATCH 039/177] Fix unused feature gate warning --- serde/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/serde/src/lib.rs b/serde/src/lib.rs index 2d7a4ff3..12632795 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -61,7 +61,8 @@ #![doc(html_root_url="https://docs.serde.rs")] #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(feature = "unstable", feature(nonzero, specialization, zero_one, into_boxed_c_str))] +#![cfg_attr(feature = "unstable", feature(nonzero, specialization, zero_one))] +#![cfg_attr(all(feature = "std", feature = "unstable"), feature(into_boxed_c_str))] #![cfg_attr(feature = "alloc", feature(alloc))] #![cfg_attr(feature = "collections", feature(collections))] #![cfg_attr(feature = "cargo-clippy", allow(linkedlist, type_complexity, doc_markdown))] From 6388019ad4840a1b5c515ffc353e6a4f2df3adc3 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 17:34:13 -0700 Subject: [PATCH 040/177] Relax impls for [T; 0] --- serde/src/de/impls.rs | 9 +++------ serde/src/ser/impls.rs | 11 ++++++++++- test_suite/tests/test_gen.rs | 5 +++++ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 21f557f9..eefe3215 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -625,9 +625,7 @@ impl ArrayVisitor { } } -impl<'de, T> Visitor<'de> for ArrayVisitor<[T; 0]> - where T: Deserialize<'de> -{ +impl<'de, T> Visitor<'de> for ArrayVisitor<[T; 0]> { type Value = [T; 0]; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -642,9 +640,8 @@ impl<'de, T> Visitor<'de> for ArrayVisitor<[T; 0]> } } -impl<'de, T> Deserialize<'de> for [T; 0] - where T: Deserialize<'de> -{ +// Does not require T: Deserialize<'de>. +impl<'de, T> Deserialize<'de> for [T; 0] { fn deserialize(deserializer: D) -> Result<[T; 0], D::Error> where D: Deserializer<'de> { diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index a9bfaf09..6cfa32a9 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -143,6 +143,16 @@ impl Serialize for PhantomData { /////////////////////////////////////////////////////////////////////////////// +// Does not require T: Serialize. +impl Serialize for [T; 0] { + #[inline] + fn serialize(&self, serializer: S) -> Result + where S: Serializer + { + try!(serializer.serialize_seq_fixed_size(0)).end() + } +} + macro_rules! array_impls { ($len:expr) => { impl Serialize for [T; $len] where T: Serialize { @@ -160,7 +170,6 @@ macro_rules! array_impls { } } -array_impls!(0); array_impls!(1); array_impls!(2); array_impls!(3); diff --git a/test_suite/tests/test_gen.rs b/test_suite/tests/test_gen.rs index 68e63505..c1e68a92 100644 --- a/test_suite/tests/test_gen.rs +++ b/test_suite/tests/test_gen.rs @@ -295,6 +295,11 @@ fn test_gen() { #[derive(Serialize, Deserialize)] #[serde(deny_unknown_fields)] struct UnitDenyUnknown; + + #[derive(Serialize, Deserialize)] + struct EmptyArray { + empty: [X; 0], + } } ////////////////////////////////////////////////////////////////////////// From dd62801b22e77f14bf3fa1702226f954c9a6cc80 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 6 Apr 2017 14:22:03 -0700 Subject: [PATCH 041/177] Use spaces around =-sign like Rust does --- serde/src/de/impls.rs | 4 +-- serde/src/lib.rs | 2 +- serde_codegen_internals/src/attr.rs | 38 ++++++++++++++--------------- serde_derive/src/de.rs | 4 +-- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index eefe3215..59793812 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -25,7 +25,7 @@ use std::path; use core::str; #[cfg(feature = "std")] use std::ffi::{CString, OsString}; -#[cfg(all(feature = "std", feature="unstable"))] +#[cfg(all(feature = "std", feature = "unstable"))] use std::ffi::CStr; #[cfg(feature = "std")] @@ -411,7 +411,7 @@ impl<'de> Deserialize<'de> for CString { } } -#[cfg(all(feature = "std", feature="unstable"))] +#[cfg(all(feature = "std", feature = "unstable"))] impl<'de> Deserialize<'de> for Box { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> diff --git a/serde/src/lib.rs b/serde/src/lib.rs index e2ed19ea..349e3b6a 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -59,7 +59,7 @@ //! Redis when using [redis-rs](https://crates.io/crates/redis). //! *(deserialization only)* -#![doc(html_root_url="https://docs.serde.rs")] +#![doc(html_root_url = "https://docs.serde.rs")] #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(feature = "unstable", feature(nonzero, specialization, zero_one))] #![cfg_attr(all(feature = "std", feature = "unstable"), feature(into_boxed_c_str))] diff --git a/serde_codegen_internals/src/attr.rs b/serde_codegen_internals/src/attr.rs index 13b429b9..270a4823 100644 --- a/serde_codegen_internals/src/attr.rs +++ b/serde_codegen_internals/src/attr.rs @@ -155,7 +155,7 @@ impl Item { for meta_items in item.attrs.iter().filter_map(get_serde_meta_items) { for meta_item in meta_items { match meta_item { - // Parse `#[serde(rename="foo")]` + // Parse `#[serde(rename = "foo")]` MetaItem(NameValue(ref name, ref lit)) if name == "rename" => { if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) { ser_name.set(s.clone()); @@ -163,7 +163,7 @@ impl Item { } } - // Parse `#[serde(rename(serialize="foo", deserialize="bar"))]` + // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]` MetaItem(List(ref name, ref meta_items)) if name == "rename" => { if let Ok((ser, de)) = get_renames(cx, meta_items) { ser_name.set_opt(ser); @@ -171,7 +171,7 @@ impl Item { } } - // Parse `#[serde(rename_all="foo")]` + // Parse `#[serde(rename_all = "foo")]` MetaItem(NameValue(ref name, ref lit)) if name == "rename_all" => { if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) { match RenameRule::from_str(&s) { @@ -203,7 +203,7 @@ impl Item { } } - // Parse `#[serde(default="...")]` + // Parse `#[serde(default = "...")]` MetaItem(NameValue(ref name, ref lit)) if name == "default" => { if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) { match item.body { @@ -218,7 +218,7 @@ impl Item { } } - // Parse `#[serde(bound="D: Serialize")]` + // Parse `#[serde(bound = "D: Serialize")]` MetaItem(NameValue(ref name, ref lit)) if name == "bound" => { if let Ok(where_predicates) = parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit) { @@ -227,7 +227,7 @@ impl Item { } } - // Parse `#[serde(bound(serialize="D: Serialize", deserialize="D: Deserialize"))]` + // Parse `#[serde(bound(serialize = "D: Serialize", deserialize = "D: Deserialize"))]` MetaItem(List(ref name, ref meta_items)) if name == "bound" => { if let Ok((ser, de)) = get_where_predicates(cx, meta_items) { ser_bound.set_opt(ser); @@ -423,7 +423,7 @@ impl Variant { for meta_items in variant.attrs.iter().filter_map(get_serde_meta_items) { for meta_item in meta_items { match meta_item { - // Parse `#[serde(rename="foo")]` + // Parse `#[serde(rename = "foo")]` MetaItem(NameValue(ref name, ref lit)) if name == "rename" => { if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) { ser_name.set(s.clone()); @@ -431,7 +431,7 @@ impl Variant { } } - // Parse `#[serde(rename(serialize="foo", deserialize="bar"))]` + // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]` MetaItem(List(ref name, ref meta_items)) if name == "rename" => { if let Ok((ser, de)) = get_renames(cx, meta_items) { ser_name.set_opt(ser); @@ -439,7 +439,7 @@ impl Variant { } } - // Parse `#[serde(rename_all="foo")]` + // Parse `#[serde(rename_all = "foo")]` MetaItem(NameValue(ref name, ref lit)) if name == "rename_all" => { if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) { match RenameRule::from_str(&s) { @@ -567,7 +567,7 @@ impl Field { for meta_items in field.attrs.iter().filter_map(get_serde_meta_items) { for meta_item in meta_items { match meta_item { - // Parse `#[serde(rename="foo")]` + // Parse `#[serde(rename = "foo")]` MetaItem(NameValue(ref name, ref lit)) if name == "rename" => { if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) { ser_name.set(s.clone()); @@ -575,7 +575,7 @@ impl Field { } } - // Parse `#[serde(rename(serialize="foo", deserialize="bar"))]` + // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]` MetaItem(List(ref name, ref meta_items)) if name == "rename" => { if let Ok((ser, de)) = get_renames(cx, meta_items) { ser_name.set_opt(ser); @@ -588,7 +588,7 @@ impl Field { default.set(Default::Default); } - // Parse `#[serde(default="...")]` + // Parse `#[serde(default = "...")]` MetaItem(NameValue(ref name, ref lit)) if name == "default" => { if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) { default.set(Default::Path(path)); @@ -605,28 +605,28 @@ impl Field { skip_deserializing.set_true(); } - // Parse `#[serde(skip_serializing_if="...")]` + // Parse `#[serde(skip_serializing_if = "...")]` MetaItem(NameValue(ref name, ref lit)) if name == "skip_serializing_if" => { if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) { skip_serializing_if.set(path); } } - // Parse `#[serde(serialize_with="...")]` + // Parse `#[serde(serialize_with = "...")]` MetaItem(NameValue(ref name, ref lit)) if name == "serialize_with" => { if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) { serialize_with.set(path); } } - // Parse `#[serde(deserialize_with="...")]` + // Parse `#[serde(deserialize_with = "...")]` MetaItem(NameValue(ref name, ref lit)) if name == "deserialize_with" => { if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) { deserialize_with.set(path); } } - // Parse `#[serde(with="...")]` + // Parse `#[serde(with = "...")]` MetaItem(NameValue(ref name, ref lit)) if name == "with" => { if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) { let mut ser_path = path.clone(); @@ -638,7 +638,7 @@ impl Field { } } - // Parse `#[serde(bound="D: Serialize")]` + // Parse `#[serde(bound = "D: Serialize")]` MetaItem(NameValue(ref name, ref lit)) if name == "bound" => { if let Ok(where_predicates) = parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit) { @@ -647,7 +647,7 @@ impl Field { } } - // Parse `#[serde(bound(serialize="D: Serialize", deserialize="D: Deserialize"))]` + // Parse `#[serde(bound(serialize = "D: Serialize", deserialize = "D: Deserialize"))]` MetaItem(List(ref name, ref meta_items)) if name == "bound" => { if let Ok((ser, de)) = get_where_predicates(cx, meta_items) { ser_bound.set_opt(ser); @@ -688,7 +688,7 @@ impl Field { } // Is skip_deserializing, initialize the field to Default::default() - // unless a different default is specified by `#[serde(default="...")]` + // unless a different default is specified by `#[serde(default = "...")]` if skip_deserializing.0.value.is_some() { default.set_if_none(Default::Default); } diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 84be769b..441d7dc5 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -1371,8 +1371,8 @@ fn field_i(i: usize) -> Ident { Ident::new(format!("__field{}", i)) } -/// This function wraps the expression in `#[serde(deserialize_with="...")]` in -/// a trait to prevent it from accessing the internal `Deserialize` state. +/// This function wraps the expression in `#[serde(deserialize_with = "...")]` +/// in a trait to prevent it from accessing the internal `Deserialize` state. fn wrap_deserialize_with(ident: &syn::Ident, params: &Parameters, field_ty: &syn::Ty, From 33760e122c032060b71232ad08dd4bfefffef3be Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 6 Apr 2017 14:27:18 -0700 Subject: [PATCH 042/177] Remove LineColIterator This belongs in a helper crate. --- serde/src/iter.rs | 73 ----------------------------------------------- serde/src/lib.rs | 3 -- 2 files changed, 76 deletions(-) delete mode 100644 serde/src/iter.rs diff --git a/serde/src/iter.rs b/serde/src/iter.rs deleted file mode 100644 index 784fe9bc..00000000 --- a/serde/src/iter.rs +++ /dev/null @@ -1,73 +0,0 @@ -//! Module that contains helper iterators. - -use std::io; -use std::iter::Peekable; - -/// Iterator over a byte stream that tracks the current position's line and column. -pub struct LineColIterator>> { - iter: Iter, - line: usize, - col: usize, -} - -impl>> LineColIterator { - /// Construct a new `LineColIterator`. - pub fn new(iter: Iter) -> LineColIterator { - LineColIterator { - iter: iter, - line: 1, - col: 0, - } - } - - /// Report the current line inside the iterator. - pub fn line(&self) -> usize { - self.line - } - - /// Report the current column inside the iterator. - pub fn col(&self) -> usize { - self.col - } - - /// Gets a reference to the underlying iterator. - pub fn get_ref(&self) -> &Iter { - &self.iter - } - - /// Gets a mutable reference to the underlying iterator. - pub fn get_mut(&mut self) -> &mut Iter { - &mut self.iter - } - - /// Unwraps this `LineColIterator`, returning the underlying iterator. - pub fn into_inner(self) -> Iter { - self.iter - } -} - -impl>> LineColIterator> { - /// peeks at the next value - pub fn peek(&mut self) -> Option<&io::Result> { - self.iter.peek() - } -} - -impl>> Iterator for LineColIterator { - type Item = io::Result; - fn next(&mut self) -> Option> { - match self.iter.next() { - None => None, - Some(Ok(b'\n')) => { - self.line += 1; - self.col = 0; - Some(Ok(b'\n')) - } - Some(Ok(c)) => { - self.col += 1; - Some(Ok(c)) - } - Some(Err(e)) => Some(Err(e)), - } - } -} diff --git a/serde/src/lib.rs b/serde/src/lib.rs index 349e3b6a..10cb570f 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -95,9 +95,6 @@ pub use de::{Deserialize, Deserializer}; mod macros; pub mod de; -#[cfg(feature = "std")] -#[doc(hidden)] -pub mod iter; pub mod ser; mod utils; From 7ef80a845db362c932fec5cdbabebee04909ac4b Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 6 Apr 2017 16:11:30 -0700 Subject: [PATCH 043/177] Unignore DeserializeOwned example --- serde/src/de/mod.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 37d7719e..b5b74f69 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -481,13 +481,18 @@ pub trait Deserialize<'de>: Sized { /// from the input string, but a `from_reader` function may only deserialize /// owned data. /// -/// ```rust,ignore -/// pub fn from_str<'a, T>(s: &'a str) -> Result +/// ```rust +/// # use serde::de::{Deserialize, DeserializeOwned}; +/// # use std::io::{Read, Result}; +/// # +/// # trait Ignore { +/// fn from_str<'a, T>(s: &'a str) -> Result /// where T: Deserialize<'a>; /// -/// pub fn from_reader(rdr: R) -> Result +/// fn from_reader(rdr: R) -> Result /// where R: Read, /// T: DeserializeOwned; +/// # } /// ``` pub trait DeserializeOwned: for<'de> Deserialize<'de> {} impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} From 9d73271db2e6f5d4ea2dfa93234e13f72b033c79 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 6 Apr 2017 16:19:47 -0700 Subject: [PATCH 044/177] Unignore VariantVisitor::visit_unit example --- serde/src/de/mod.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index b5b74f69..22f3e89f 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -1476,12 +1476,32 @@ pub trait VariantVisitor<'de>: Sized { /// If the data contains a different type of variant, the following /// `invalid_type` error should be constructed: /// - /// ```rust,ignore + /// ```rust + /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantVisitor, Unexpected}; + /// # + /// # struct X; + /// # + /// # impl<'de> VariantVisitor<'de> for X { + /// # type Error = value::Error; + /// # /// fn visit_unit(self) -> Result<(), Self::Error> { /// // What the data actually contained; suppose it is a tuple variant. /// let unexp = Unexpected::TupleVariant; /// Err(de::Error::invalid_type(unexp, &"unit variant")) /// } + /// # + /// # fn visit_newtype_seed(self, _: T) -> Result + /// # where T: DeserializeSeed<'de> + /// # { unimplemented!() } + /// # + /// # fn visit_tuple(self, _: usize, _: V) -> Result + /// # where V: Visitor<'de> + /// # { unimplemented!() } + /// # + /// # fn visit_struct(self, _: &[&str], _: V) -> Result + /// # where V: Visitor<'de> + /// # { unimplemented!() } + /// # } /// ``` fn visit_unit(self) -> Result<(), Self::Error>; From 2b449683f36dc2de9c018af166fa8855b85621d7 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 6 Apr 2017 16:21:27 -0700 Subject: [PATCH 045/177] Unignore VariantVisitor::visit_newtype_seed example --- serde/src/de/mod.rs | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 22f3e89f..23255160 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -1513,14 +1513,34 @@ pub trait VariantVisitor<'de>: Sized { /// If the data contains a different type of variant, the following /// `invalid_type` error should be constructed: /// - /// ```rust,ignore + /// ```rust + /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantVisitor, Unexpected}; + /// # + /// # struct X; + /// # + /// # impl<'de> VariantVisitor<'de> for X { + /// # type Error = value::Error; + /// # + /// # fn visit_unit(self) -> Result<(), Self::Error> { + /// # unimplemented!() + /// # } + /// # /// fn visit_newtype_seed(self, _seed: T) -> Result - /// where T: de::DeserializeSeed + /// where T: DeserializeSeed<'de> /// { /// // What the data actually contained; suppose it is a unit variant. /// let unexp = Unexpected::UnitVariant; /// Err(de::Error::invalid_type(unexp, &"newtype variant")) /// } + /// # + /// # fn visit_tuple(self, _: usize, _: V) -> Result + /// # where V: Visitor<'de> + /// # { unimplemented!() } + /// # + /// # fn visit_struct(self, _: &[&str], _: V) -> Result + /// # where V: Visitor<'de> + /// # { unimplemented!() } + /// # } /// ``` fn visit_newtype_seed(self, seed: T) -> Result where T: DeserializeSeed<'de>; From d2d489287306719d00f0189863a94834aac5c6cf Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 6 Apr 2017 16:26:51 -0700 Subject: [PATCH 046/177] Unignore VariantVisitor::visit_tuple example --- serde/src/de/mod.rs | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 23255160..d83a5cd9 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -1564,16 +1564,36 @@ pub trait VariantVisitor<'de>: Sized { /// If the data contains a different type of variant, the following /// `invalid_type` error should be constructed: /// - /// ```rust,ignore + /// ```rust + /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantVisitor, Unexpected}; + /// # + /// # struct X; + /// # + /// # impl<'de> VariantVisitor<'de> for X { + /// # type Error = value::Error; + /// # + /// # fn visit_unit(self) -> Result<(), Self::Error> { + /// # unimplemented!() + /// # } + /// # + /// # fn visit_newtype_seed(self, _: T) -> Result + /// # where T: DeserializeSeed<'de> + /// # { unimplemented!() } + /// # /// fn visit_tuple(self, /// _len: usize, /// _visitor: V) -> Result - /// where V: Visitor + /// where V: Visitor<'de> /// { /// // What the data actually contained; suppose it is a unit variant. /// let unexp = Unexpected::UnitVariant; - /// Err(Error::invalid_type(unexp, &"tuple variant")) + /// Err(de::Error::invalid_type(unexp, &"tuple variant")) /// } + /// # + /// # fn visit_struct(self, _: &[&str], _: V) -> Result + /// # where V: Visitor<'de> + /// # { unimplemented!() } + /// # } /// ``` fn visit_tuple(self, len: usize, visitor: V) -> Result where V: Visitor<'de>; From f12a951f2237a635c7a13bbb6cd964d51f236286 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 6 Apr 2017 16:28:24 -0700 Subject: [PATCH 047/177] Unignore VariantVisitor::visit_struct example --- serde/src/de/mod.rs | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index d83a5cd9..d8b860b2 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -1605,16 +1605,36 @@ pub trait VariantVisitor<'de>: Sized { /// If the data contains a different type of variant, the following /// `invalid_type` error should be constructed: /// - /// ```rust,ignore + /// ```rust + /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantVisitor, Unexpected}; + /// # + /// # struct X; + /// # + /// # impl<'de> VariantVisitor<'de> for X { + /// # type Error = value::Error; + /// # + /// # fn visit_unit(self) -> Result<(), Self::Error> { + /// # unimplemented!() + /// # } + /// # + /// # fn visit_newtype_seed(self, _: T) -> Result + /// # where T: DeserializeSeed<'de> + /// # { unimplemented!() } + /// # + /// # fn visit_tuple(self, _: usize, _: V) -> Result + /// # where V: Visitor<'de> + /// # { unimplemented!() } + /// # /// fn visit_struct(self, /// _fields: &'static [&'static str], /// _visitor: V) -> Result - /// where V: Visitor + /// where V: Visitor<'de> /// { /// // What the data actually contained; suppose it is a unit variant. /// let unexp = Unexpected::UnitVariant; - /// Err(Error::invalid_type(unexp, &"struct variant")) + /// Err(de::Error::invalid_type(unexp, &"struct variant")) /// } + /// # } /// ``` fn visit_struct(self, fields: &'static [&'static str], From 21c211934939a3537940e283d01240b2ef4894a3 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 6 Apr 2017 17:09:01 -0700 Subject: [PATCH 048/177] Unignore the Impossible example --- serde/src/macros.rs | 120 ++++++++++++++++++++++++++++++++++++ serde/src/ser/impossible.rs | 21 ++++++- serde/src/ser/private.rs | 53 +++++++++------- 3 files changed, 172 insertions(+), 22 deletions(-) diff --git a/serde/src/macros.rs b/serde/src/macros.rs index 7505846c..9f958f08 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -209,3 +209,123 @@ macro_rules! serialize_display_bounded_length { } } } + +#[doc(hidden)] +#[macro_export] +macro_rules! __serialize_unimplemented_method { + ($func:ident $(<$t:ident>)* ($($arg:ty),*) -> $ret:ident) => { + fn $func $(<$t: ?Sized + $crate::Serialize>)* (self $(, _: $arg)*) -> $crate::export::Result { + unimplemented!() + } + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __serialize_unimplemented_helper { + (bool) => { + __serialize_unimplemented_method!(serialize_bool(bool) -> Ok); + }; + (i8) => { + __serialize_unimplemented_method!(serialize_i8(i8) -> Ok); + }; + (i16) => { + __serialize_unimplemented_method!(serialize_i16(i16) -> Ok); + }; + (i32) => { + __serialize_unimplemented_method!(serialize_i32(i32) -> Ok); + }; + (i64) => { + __serialize_unimplemented_method!(serialize_i64(i64) -> Ok); + }; + (u8) => { + __serialize_unimplemented_method!(serialize_u8(u8) -> Ok); + }; + (u16) => { + __serialize_unimplemented_method!(serialize_u16(u16) -> Ok); + }; + (u32) => { + __serialize_unimplemented_method!(serialize_u32(u32) -> Ok); + }; + (u64) => { + __serialize_unimplemented_method!(serialize_u64(u64) -> Ok); + }; + (f32) => { + __serialize_unimplemented_method!(serialize_f32(f32) -> Ok); + }; + (f64) => { + __serialize_unimplemented_method!(serialize_f64(f64) -> Ok); + }; + (char) => { + __serialize_unimplemented_method!(serialize_char(char) -> Ok); + }; + (str) => { + __serialize_unimplemented_method!(serialize_str(&str) -> Ok); + }; + (bytes) => { + __serialize_unimplemented_method!(serialize_bytes(&[u8]) -> Ok); + }; + (none) => { + __serialize_unimplemented_method!(serialize_none() -> Ok); + }; + (some) => { + __serialize_unimplemented_method!(serialize_some(&T) -> Ok); + }; + (unit) => { + __serialize_unimplemented_method!(serialize_unit() -> Ok); + }; + (unit_struct) => { + __serialize_unimplemented_method!(serialize_unit_struct(&str) -> Ok); + }; + (unit_variant) => { + __serialize_unimplemented_method!(serialize_unit_variant(&str, usize, &str) -> Ok); + }; + (newtype_struct) => { + __serialize_unimplemented_method!(serialize_newtype_struct(&str, &T) -> Ok); + }; + (newtype_variant) => { + __serialize_unimplemented_method!(serialize_newtype_variant(&str, usize, &str, &T) -> Ok); + }; + (seq) => { + type SerializeSeq = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_seq(Option) -> SerializeSeq); + }; + (seq_fixed_size) => { + __serialize_unimplemented_method!(serialize_seq_fixed_size(usize) -> SerializeSeq); + }; + (tuple) => { + type SerializeTuple = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_tuple(usize) -> SerializeTuple); + }; + (tuple_struct) => { + type SerializeTupleStruct = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_tuple_struct(&str, usize) -> SerializeTupleStruct); + }; + (tuple_variant) => { + type SerializeTupleVariant = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_tuple_variant(&str, usize, &str, usize) -> SerializeTupleVariant); + }; + (map) => { + type SerializeMap = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_map(Option) -> SerializeMap); + }; + (struct) => { + type SerializeStruct = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_struct(&str, usize) -> SerializeStruct); + }; + (struct_variant) => { + type SerializeStructVariant = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_struct_variant(&str, usize, &str, usize) -> SerializeStructVariant); + }; +} + +/// Used only by Serde doc tests. Not public API. +#[doc(hidden)] +#[macro_export] +macro_rules! __serialize_unimplemented { + ($($func:ident)*) => { + $( + __serialize_unimplemented_helper!($func); + )* + }; +} diff --git a/serde/src/ser/impossible.rs b/serde/src/ser/impossible.rs index 6b8e7c28..e4aedba7 100644 --- a/serde/src/ser/impossible.rs +++ b/serde/src/ser/impossible.rs @@ -13,7 +13,15 @@ use ser::{self, Serialize, SerializeSeq, SerializeTuple, SerializeTupleStruct, /// `SerializeTuple`, `SerializeTupleStruct`, `SerializeTupleVariant`, /// `SerializeMap`, `SerializeStruct`, and `SerializeStructVariant`. /// -/// ```rust,ignore +/// ```rust +/// # #[macro_use] +/// # extern crate serde; +/// # +/// # use serde::ser::{Serializer, Impossible}; +/// # use serde::ser::private::Error; +/// # +/// # struct MySerializer; +/// # /// impl Serializer for MySerializer { /// type Ok = (); /// type Error = Error; @@ -27,11 +35,22 @@ use ser::{self, Serialize, SerializeSeq, SerializeTuple, SerializeTupleStruct, /// -> Result { /// // Given Impossible cannot be instantiated, the only /// // thing we can do here is to return an error. +/// # macro_rules! ellipses { () => { /// Err(...) +/// # } } +/// # unimplemented!() /// } /// /// /* other Serializer methods */ +/// # __serialize_unimplemented! { +/// # bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str bytes none some +/// # unit unit_struct unit_variant newtype_struct newtype_variant +/// # seq_fixed_size tuple tuple_struct tuple_variant map struct +/// # struct_variant +/// # } /// } +/// # +/// # fn main() {} /// ``` pub struct Impossible { void: Void, diff --git a/serde/src/ser/private.rs b/serde/src/ser/private.rs index 6e30cb72..5d1f723f 100644 --- a/serde/src/ser/private.rs +++ b/serde/src/ser/private.rs @@ -5,6 +5,9 @@ use ser::{self, Serialize, Serializer, SerializeMap, SerializeStruct, Impossible #[cfg(any(feature = "std", feature = "collections"))] use ser::content::{SerializeTupleVariantAsMapValue, SerializeStructVariantAsMapValue}; +#[cfg(feature = "std")] +use std::error; + /// Not public API. pub fn serialize_tagged_newtype(serializer: S, type_ident: &'static str, @@ -71,31 +74,15 @@ impl Display for Unsupported { } } -struct Error { - type_ident: &'static str, - variant_ident: &'static str, - ty: Unsupported, -} - -impl Display for Error { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!(formatter, - "cannot serialize tagged newtype variant {}::{} containing {}", - self.type_ident, - self.variant_ident, - self.ty) - } -} - impl TaggedSerializer where S: Serializer { fn bad_type(self, what: Unsupported) -> S::Error { - ser::Error::custom(Error { - type_ident: self.type_ident, - variant_ident: self.variant_ident, - ty: what, - }) + ser::Error::custom(format_args!( + "cannot serialize tagged newtype variant {}::{} containing {}", + self.type_ident, + self.variant_ident, + what)) } } @@ -320,3 +307,27 @@ impl Serializer for TaggedSerializer Err(self.bad_type(Unsupported::String)) } } + +/// Used only by Serde doc tests. Not public API. +#[doc(hidden)] +#[derive(Debug)] +pub struct Error; + +impl ser::Error for Error { + fn custom(_: T) -> Self { + unimplemented!() + } +} + +#[cfg(feature = "std")] +impl error::Error for Error { + fn description(&self) -> &str { + unimplemented!() + } +} + +impl Display for Error { + fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { + unimplemented!() + } +} From a581c0d147ae5f4169f951465e645ba66b6e8a4d Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 09:00:00 -0700 Subject: [PATCH 049/177] Keep Debug and Display as supertraits even in no_std --- serde/src/de/mod.rs | 8 +++++--- serde/src/ser/mod.rs | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index d8b860b2..eac50313 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -101,6 +101,8 @@ use std::error; use collections::{String, Vec}; use core::fmt::{self, Display}; +#[cfg(not(feature = "std"))] +use core::fmt::Debug; use core::marker::PhantomData; /////////////////////////////////////////////////////////////////////////////// @@ -122,7 +124,7 @@ pub use self::ignored_any::IgnoredAny; /////////////////////////////////////////////////////////////////////////////// macro_rules! declare_error_trait { - (Error: Sized $(+ $($supertrait:ident)::*)*) => { + (Error: Sized $(+ $($supertrait:ident)::+)*) => { /// The `Error` trait allows `Deserialize` implementations to create descriptive /// error messages belonging to the `Deserializer` against which they are /// currently running. @@ -136,7 +138,7 @@ macro_rules! declare_error_trait { /// /// Most deserializers should only need to provide the `Error::custom` method /// and inherit the default behavior for the other methods. - pub trait Error: Sized $(+ $($supertrait)::*)* { + pub trait Error: Sized $(+ $($supertrait)::+)* { /// Raised when there is general error when deserializing a type. /// /// The message should not be capitalized and should not end with a period. @@ -254,7 +256,7 @@ macro_rules! declare_error_trait { declare_error_trait!(Error: Sized + error::Error); #[cfg(not(feature = "std"))] -declare_error_trait!(Error: Sized); +declare_error_trait!(Error: Sized + Debug + Display); /// `Unexpected` represents an unexpected invocation of any one of the `Visitor` /// trait methods. diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 63065e09..5c4f81a9 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -97,6 +97,8 @@ use std::error; #[cfg(all(feature = "collections", not(feature = "std")))] use collections::string::String; +#[cfg(not(feature = "std"))] +use core::fmt::Debug; use core::fmt::Display; #[cfg(any(feature = "std", feature = "collections"))] use core::fmt::Write; @@ -116,11 +118,11 @@ pub use self::impossible::Impossible; /////////////////////////////////////////////////////////////////////////////// macro_rules! declare_error_trait { - (Error: Sized $(+ $($supertrait:ident)::*)*) => { + (Error: Sized $(+ $($supertrait:ident)::+)*) => { /// Trait used by `Serialize` implementations to generically construct /// errors belonging to the `Serializer` against which they are /// currently running. - pub trait Error: Sized $(+ $($supertrait)::*)* { + pub trait Error: Sized $(+ $($supertrait)::+)* { /// Raised when a `Serialize` implementation encounters a general /// error while serializing a type. /// @@ -154,7 +156,7 @@ macro_rules! declare_error_trait { declare_error_trait!(Error: Sized + error::Error); #[cfg(not(feature = "std"))] -declare_error_trait!(Error: Sized); +declare_error_trait!(Error: Sized + Debug + Display); /////////////////////////////////////////////////////////////////////////////// From e57ce37ac1312be8ba09d6dcd1d30b84e925e085 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 09:07:08 -0700 Subject: [PATCH 050/177] Unignore Serializer::serialize_bytes example --- serde/src/ser/mod.rs | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 5c4f81a9..eeac1761 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -374,12 +374,36 @@ pub trait Serializer: Sized { /// `serialize_seq`. If forwarded, the implementation looks usually just /// like this: /// - /// ```rust,ignore - /// let mut seq = self.serialize_seq(Some(value.len()))?; - /// for b in value { - /// seq.serialize_element(b)?; + /// ```rust + /// # #[macro_use] + /// # extern crate serde; + /// # + /// # use serde::ser::{Serializer, SerializeSeq}; + /// # use serde::ser::private::Error; + /// # + /// # struct MySerializer; + /// # + /// # impl Serializer for MySerializer { + /// # type Ok = (); + /// # type Error = Error; + /// # + /// fn serialize_bytes(self, value: &[u8]) -> Result { + /// let mut seq = self.serialize_seq(Some(value.len()))?; + /// for b in value { + /// seq.serialize_element(b)?; + /// } + /// seq.end() /// } - /// seq.end() + /// # + /// # __serialize_unimplemented! { + /// # bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str none some + /// # unit unit_struct unit_variant newtype_struct newtype_variant + /// # seq seq_fixed_size tuple tuple_struct tuple_variant map struct + /// # struct_variant + /// # } + /// # } + /// # + /// # fn main() {} /// ``` fn serialize_bytes(self, value: &[u8]) -> Result; From 995f2b3f76d2b27a2dee30c87a7193063b41187f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 09:21:30 -0700 Subject: [PATCH 051/177] Ignore clippy false positive --- test_suite/tests/test_gen.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test_suite/tests/test_gen.rs b/test_suite/tests/test_gen.rs index c1e68a92..10b952e4 100644 --- a/test_suite/tests/test_gen.rs +++ b/test_suite/tests/test_gen.rs @@ -4,6 +4,10 @@ #![cfg_attr(feature = "unstable", feature(non_ascii_idents))] +// Clippy false positive +// https://github.com/Manishearth/rust-clippy/issues/292 +#![cfg_attr(feature = "cargo-clippy", allow(needless_lifetimes))] + #[macro_use] extern crate serde_derive; From 467b5fc59532e210b4a4603cefec92bc19ff9595 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 09:28:33 -0700 Subject: [PATCH 052/177] Macro to ignore tokens in doc test --- serde/src/macros.rs | 7 +++++++ serde/src/ser/impossible.rs | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/serde/src/macros.rs b/serde/src/macros.rs index 9f958f08..dcd2433e 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -329,3 +329,10 @@ macro_rules! __serialize_unimplemented { )* }; } + +/// Used only by Serde doc tests. Not public API. +#[doc(hidden)] +#[macro_export] +macro_rules! __serde_ignore_tokens { + ($($tt:tt)+) => {} +} diff --git a/serde/src/ser/impossible.rs b/serde/src/ser/impossible.rs index e4aedba7..82755d72 100644 --- a/serde/src/ser/impossible.rs +++ b/serde/src/ser/impossible.rs @@ -35,9 +35,9 @@ use ser::{self, Serialize, SerializeSeq, SerializeTuple, SerializeTupleStruct, /// -> Result { /// // Given Impossible cannot be instantiated, the only /// // thing we can do here is to return an error. -/// # macro_rules! ellipses { () => { +/// # __serde_ignore_tokens! { /// Err(...) -/// # } } +/// # } /// # unimplemented!() /// } /// From 726eea9a97ba1cf6b77fdc8f535240ff27d7d665 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 09:46:45 -0700 Subject: [PATCH 053/177] Separate out the private functionality This makes it easier when clicking through [src] links from rustdoc, not having to sift through public and internal code combined together. --- serde/src/de/content.rs | 1340 ----------------------- serde/src/de/mod.rs | 6 - serde/src/de/private.rs | 176 ---- serde/src/lib.rs | 6 +- serde/src/macros.rs | 159 --- serde/src/private/de.rs | 1520 +++++++++++++++++++++++++++ serde/src/private/macros.rs | 126 +++ serde/src/private/mod.rs | 4 + serde/src/private/ser.rs | 944 +++++++++++++++++ serde/src/ser/content.rs | 607 ----------- serde/src/ser/impls.rs | 31 + serde/src/ser/impossible.rs | 2 +- serde/src/ser/mod.rs | 8 +- serde/src/ser/private.rs | 333 ------ serde_codegen_internals/src/attr.rs | 4 +- serde_derive/src/de.rs | 36 +- serde_derive/src/ser.rs | 2 +- 17 files changed, 2653 insertions(+), 2651 deletions(-) delete mode 100644 serde/src/de/content.rs delete mode 100644 serde/src/de/private.rs create mode 100644 serde/src/private/de.rs create mode 100644 serde/src/private/macros.rs create mode 100644 serde/src/private/mod.rs create mode 100644 serde/src/private/ser.rs delete mode 100644 serde/src/ser/content.rs delete mode 100644 serde/src/ser/private.rs diff --git a/serde/src/de/content.rs b/serde/src/de/content.rs deleted file mode 100644 index 62f71d10..00000000 --- a/serde/src/de/content.rs +++ /dev/null @@ -1,1340 +0,0 @@ -// This module is doc(hidden) and nothing here should be used outside of -// generated code. -// -// We will iterate on the implementation for a few releases and only have to -// worry about backward compatibility for the `untagged` and `tag` attributes -// rather than for this entire mechanism. -// -// This issue is tracking making some of this stuff public: -// https://github.com/serde-rs/serde/issues/741 - -#![doc(hidden)] - -use core::cmp; -use core::fmt; -use core::marker::PhantomData; - -#[cfg(all(not(feature = "std"), feature = "collections"))] -use collections::{String, Vec}; - -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::boxed::Box; - -use de::{self, Deserialize, DeserializeSeed, Deserializer, Visitor, SeqVisitor, MapVisitor, - EnumVisitor, Unexpected}; - -/// Used from generated code to buffer the contents of the Deserializer when -/// deserializing untagged enums and internally tagged enums. -/// -/// Not public API. Use serde-value instead. -#[derive(Debug)] -pub enum Content { - Bool(bool), - - U8(u8), - U16(u16), - U32(u32), - U64(u64), - - I8(i8), - I16(i16), - I32(i32), - I64(i64), - - F32(f32), - F64(f64), - - Char(char), - String(String), - Bytes(Vec), - - None, - Some(Box), - - Unit, - Newtype(Box), - Seq(Vec), - Map(Vec<(Content, Content)>), -} - -impl Content { - 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::Bytes(ref 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, - } - } -} - -impl<'de> Deserialize<'de> for Content { - fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> - { - // Untagged and internally tagged enums are only supported in - // self-describing formats. - deserializer.deserialize(ContentVisitor) - } -} - -struct ContentVisitor; - -impl<'de> Visitor<'de> for ContentVisitor { - type Value = Content; - - fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.write_str("any value") - } - - fn visit_bool(self, value: bool) -> Result - where F: de::Error - { - Ok(Content::Bool(value)) - } - - fn visit_i8(self, value: i8) -> Result - where F: de::Error - { - Ok(Content::I8(value)) - } - - fn visit_i16(self, value: i16) -> Result - where F: de::Error - { - Ok(Content::I16(value)) - } - - fn visit_i32(self, value: i32) -> Result - where F: de::Error - { - Ok(Content::I32(value)) - } - - fn visit_i64(self, value: i64) -> Result - where F: de::Error - { - Ok(Content::I64(value)) - } - - fn visit_u8(self, value: u8) -> Result - where F: de::Error - { - Ok(Content::U8(value)) - } - - fn visit_u16(self, value: u16) -> Result - where F: de::Error - { - Ok(Content::U16(value)) - } - - fn visit_u32(self, value: u32) -> Result - where F: de::Error - { - Ok(Content::U32(value)) - } - - fn visit_u64(self, value: u64) -> Result - where F: de::Error - { - Ok(Content::U64(value)) - } - - fn visit_f32(self, value: f32) -> Result - where F: de::Error - { - Ok(Content::F32(value)) - } - - fn visit_f64(self, value: f64) -> Result - where F: de::Error - { - Ok(Content::F64(value)) - } - - fn visit_char(self, value: char) -> Result - where F: de::Error - { - Ok(Content::Char(value)) - } - - fn visit_str(self, value: &str) -> Result - where F: de::Error - { - Ok(Content::String(value.into())) - } - - fn visit_string(self, value: String) -> Result - where F: de::Error - { - Ok(Content::String(value)) - } - - fn visit_bytes(self, value: &[u8]) -> Result - where F: de::Error - { - Ok(Content::Bytes(value.into())) - } - - fn visit_byte_buf(self, value: Vec) -> Result - where F: de::Error - { - Ok(Content::Bytes(value)) - } - - fn visit_unit(self) -> Result - where F: de::Error - { - Ok(Content::Unit) - } - - fn visit_none(self) -> Result - where F: de::Error - { - Ok(Content::None) - } - - fn visit_some(self, deserializer: D) -> Result - where D: Deserializer<'de> - { - Deserialize::deserialize(deserializer).map(|v| Content::Some(Box::new(v))) - } - - fn visit_newtype_struct(self, deserializer: D) -> Result - where D: Deserializer<'de> - { - Deserialize::deserialize(deserializer).map(|v| Content::Newtype(Box::new(v))) - } - - fn visit_seq(self, mut visitor: V) -> Result - where V: SeqVisitor<'de> - { - let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); - while let Some(e) = try!(visitor.visit()) { - vec.push(e); - } - Ok(Content::Seq(vec)) - } - - fn visit_map(self, mut visitor: V) -> Result - where V: MapVisitor<'de> - { - let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); - while let Some(kv) = try!(visitor.visit()) { - vec.push(kv); - } - Ok(Content::Map(vec)) - } - - fn visit_enum(self, _visitor: V) -> Result - where V: EnumVisitor<'de> - { - Err(de::Error::custom("untagged and internally tagged enums do not support enum input")) - } -} - -/// This is the type of the map keys in an internally tagged enum. -/// -/// Not public API. -pub enum TagOrContent { - Tag, - Content(Content), -} - -struct TagOrContentVisitor { - name: &'static str, -} - -impl TagOrContentVisitor { - fn new(name: &'static str) -> Self { - TagOrContentVisitor { name: name } - } -} - -impl<'de> DeserializeSeed<'de> for TagOrContentVisitor { - type Value = TagOrContent; - - fn deserialize(self, deserializer: D) -> Result - where D: Deserializer<'de> - { - // Internally tagged enums are only supported in self-describing - // formats. - deserializer.deserialize(self) - } -} - -impl<'de> Visitor<'de> for TagOrContentVisitor { - type Value = TagOrContent; - - fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "a type tag `{}` or any other value", self.name) - } - - fn visit_bool(self, value: bool) -> Result - where F: de::Error - { - ContentVisitor.visit_bool(value).map(TagOrContent::Content) - } - - fn visit_i8(self, value: i8) -> Result - where F: de::Error - { - ContentVisitor.visit_i8(value).map(TagOrContent::Content) - } - - fn visit_i16(self, value: i16) -> Result - where F: de::Error - { - ContentVisitor.visit_i16(value).map(TagOrContent::Content) - } - - fn visit_i32(self, value: i32) -> Result - where F: de::Error - { - ContentVisitor.visit_i32(value).map(TagOrContent::Content) - } - - fn visit_i64(self, value: i64) -> Result - where F: de::Error - { - ContentVisitor.visit_i64(value).map(TagOrContent::Content) - } - - fn visit_u8(self, value: u8) -> Result - where F: de::Error - { - ContentVisitor.visit_u8(value).map(TagOrContent::Content) - } - - fn visit_u16(self, value: u16) -> Result - where F: de::Error - { - ContentVisitor.visit_u16(value).map(TagOrContent::Content) - } - - fn visit_u32(self, value: u32) -> Result - where F: de::Error - { - ContentVisitor.visit_u32(value).map(TagOrContent::Content) - } - - fn visit_u64(self, value: u64) -> Result - where F: de::Error - { - ContentVisitor.visit_u64(value).map(TagOrContent::Content) - } - - fn visit_f32(self, value: f32) -> Result - where F: de::Error - { - ContentVisitor.visit_f32(value).map(TagOrContent::Content) - } - - fn visit_f64(self, value: f64) -> Result - where F: de::Error - { - ContentVisitor.visit_f64(value).map(TagOrContent::Content) - } - - fn visit_char(self, value: char) -> Result - where F: de::Error - { - ContentVisitor.visit_char(value).map(TagOrContent::Content) - } - - fn visit_str(self, value: &str) -> Result - where F: de::Error - { - if value == self.name { - Ok(TagOrContent::Tag) - } else { - ContentVisitor.visit_str(value).map(TagOrContent::Content) - } - } - - fn visit_string(self, value: String) -> Result - where F: de::Error - { - if value == self.name { - Ok(TagOrContent::Tag) - } else { - ContentVisitor.visit_string(value).map(TagOrContent::Content) - } - } - - fn visit_bytes(self, value: &[u8]) -> Result - where F: de::Error - { - if value == self.name.as_bytes() { - Ok(TagOrContent::Tag) - } else { - ContentVisitor.visit_bytes(value).map(TagOrContent::Content) - } - } - - fn visit_byte_buf(self, value: Vec) -> Result - where F: de::Error - { - if value == self.name.as_bytes() { - Ok(TagOrContent::Tag) - } else { - ContentVisitor.visit_byte_buf(value).map(TagOrContent::Content) - } - } - - fn visit_unit(self) -> Result - where F: de::Error - { - ContentVisitor.visit_unit().map(TagOrContent::Content) - } - - fn visit_none(self) -> Result - where F: de::Error - { - ContentVisitor.visit_none().map(TagOrContent::Content) - } - - fn visit_some(self, deserializer: D) -> Result - where D: Deserializer<'de> - { - ContentVisitor.visit_some(deserializer).map(TagOrContent::Content) - } - - fn visit_newtype_struct(self, deserializer: D) -> Result - where D: Deserializer<'de> - { - ContentVisitor.visit_newtype_struct(deserializer).map(TagOrContent::Content) - } - - fn visit_seq(self, visitor: V) -> Result - where V: SeqVisitor<'de> - { - ContentVisitor.visit_seq(visitor).map(TagOrContent::Content) - } - - fn visit_map(self, visitor: V) -> Result - where V: MapVisitor<'de> - { - ContentVisitor.visit_map(visitor).map(TagOrContent::Content) - } - - fn visit_enum(self, visitor: V) -> Result - where V: EnumVisitor<'de> - { - ContentVisitor.visit_enum(visitor).map(TagOrContent::Content) - } -} - -/// Used by generated code to deserialize an internally tagged enum. -/// -/// Not public API. -pub struct TaggedContent { - pub tag: T, - pub content: Content, -} - -/// Not public API. -pub struct TaggedContentVisitor { - tag_name: &'static str, - tag: PhantomData, -} - -impl TaggedContentVisitor { - /// Visitor for the content of an internally tagged enum with the given tag - /// name. - pub fn new(name: &'static str) -> Self { - TaggedContentVisitor { - tag_name: name, - tag: PhantomData, - } - } -} - -impl<'de, T> DeserializeSeed<'de> for TaggedContentVisitor - where T: Deserialize<'de> -{ - type Value = TaggedContent; - - fn deserialize(self, deserializer: D) -> Result - where D: Deserializer<'de> - { - // Internally tagged enums are only supported in self-describing - // formats. - deserializer.deserialize(self) - } -} - -impl<'de, T> Visitor<'de> for TaggedContentVisitor - where T: Deserialize<'de> -{ - type Value = TaggedContent; - - fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.write_str("any value") - } - - fn visit_map(self, mut visitor: V) -> Result - where V: MapVisitor<'de> - { - let mut tag = None; - let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); - while let Some(k) = try!(visitor.visit_key_seed(TagOrContentVisitor::new(self.tag_name))) { - match k { - TagOrContent::Tag => { - if tag.is_some() { - return Err(de::Error::duplicate_field(self.tag_name)); - } - tag = Some(try!(visitor.visit_value())); - } - TagOrContent::Content(k) => { - let v = try!(visitor.visit_value()); - vec.push((k, v)); - } - } - } - match tag { - None => Err(de::Error::missing_field(self.tag_name)), - Some(tag) => { - Ok(TaggedContent { - tag: tag, - content: Content::Map(vec), - }) - } - } - } -} - -/// Used by generated code to deserialize an adjacently tagged enum. -/// -/// Not public API. -pub enum TagOrContentField { - Tag, - Content, -} - -/// Not public API. -pub struct TagOrContentFieldVisitor { - pub tag: &'static str, - pub content: &'static str, -} - -impl<'de> DeserializeSeed<'de> for TagOrContentFieldVisitor { - type Value = TagOrContentField; - - fn deserialize(self, deserializer: D) -> Result - where D: Deserializer<'de> - { - deserializer.deserialize_str(self) - } -} - -impl<'de> Visitor<'de> for TagOrContentFieldVisitor { - type Value = TagOrContentField; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!(formatter, "{:?} or {:?}", self.tag, self.content) - } - - fn visit_str(self, field: &str) -> Result - where E: de::Error - { - if field == self.tag { - Ok(TagOrContentField::Tag) - } else if field == self.content { - Ok(TagOrContentField::Content) - } else { - Err(de::Error::invalid_value(Unexpected::Str(field), &self)) - } - } -} - -/// Not public API -pub struct ContentDeserializer { - content: Content, - err: PhantomData, -} - -/// Used when deserializing an internally tagged enum because the content will -/// be used exactly once. -impl<'de, E> Deserializer<'de> for ContentDeserializer - where E: de::Error -{ - type Error = E; - - fn deserialize(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::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) => { - let seq = v.into_iter().map(ContentDeserializer::new); - let mut seq_visitor = de::value::SeqDeserializer::new(seq); - let value = try!(visitor.visit_seq(&mut seq_visitor)); - try!(seq_visitor.end()); - Ok(value) - } - Content::Map(v) => { - let map = v.into_iter().map(|(k, v)| { - (ContentDeserializer::new(k), - ContentDeserializer::new(v)) - }); - let mut map_visitor = de::value::MapDeserializer::new(map); - let value = try!(visitor.visit_map(&mut map_visitor)); - try!(map_visitor.end()); - Ok(value) - } - Content::Bytes(v) => visitor.visit_byte_buf(v), - } - } - - fn deserialize_option(self, visitor: V) -> Result - 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(), - _ => visitor.visit_some(self), - } - } - - fn deserialize_newtype_struct(self, _name: &str, visitor: V) -> Result - where V: Visitor<'de> - { - visitor.visit_newtype_struct(self) - } - - fn deserialize_enum(self, - _name: &str, - _variants: &'static [&'static str], - visitor: V) - -> Result - where V: Visitor<'de> - { - let (variant, value) = match self.content { - Content::Map(value) => { - let mut iter = value.into_iter(); - let (variant, value) = match iter.next() { - Some(v) => v, - None => { - return Err(de::Error::invalid_value(de::Unexpected::Map, - &"map with a single key")); - } - }; - // enums are encoded in json as maps with a single key:value pair - if iter.next().is_some() { - return Err(de::Error::invalid_value(de::Unexpected::Map, - &"map with a single key")); - } - (variant, Some(value)) - } - Content::String(variant) => (Content::String(variant), None), - other => { - return Err(de::Error::invalid_type(other.unexpected(), &"string or map")); - } - }; - - visitor.visit_enum(EnumDeserializer { - variant: variant, - value: value, - err: PhantomData, - }) - } - - forward_to_deserialize! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq - seq_fixed_size bytes byte_buf map unit_struct tuple_struct struct - struct_field tuple ignored_any - } -} - -impl ContentDeserializer { - /// private API, don't use - pub fn new(content: Content) -> Self { - ContentDeserializer { - content: content, - err: PhantomData, - } - } -} - -struct EnumDeserializer - where E: de::Error -{ - variant: Content, - value: Option, - err: PhantomData, -} - -impl<'de, E> de::EnumVisitor<'de> for EnumDeserializer - where E: de::Error -{ - type Error = E; - type Variant = VariantDeserializer; - - fn visit_variant_seed(self, - seed: V) - -> Result<(V::Value, VariantDeserializer), Self::Error> - where V: de::DeserializeSeed<'de> - { - let visitor = VariantDeserializer { - value: self.value, - err: PhantomData, - }; - seed.deserialize(ContentDeserializer::new(self.variant)).map(|v| (v, visitor)) - } -} - -struct VariantDeserializer - where E: de::Error -{ - value: Option, - err: PhantomData, -} - -impl<'de, E> de::VariantVisitor<'de> for VariantDeserializer - where E: de::Error -{ - type Error = E; - - fn visit_unit(self) -> Result<(), E> { - match self.value { - Some(value) => de::Deserialize::deserialize(ContentDeserializer::new(value)), - None => Ok(()), - } - } - - fn visit_newtype_seed(self, seed: T) -> Result - where T: de::DeserializeSeed<'de> - { - match self.value { - Some(value) => seed.deserialize(ContentDeserializer::new(value)), - None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"newtype variant")), - } - } - - fn visit_tuple(self, _len: usize, visitor: V) -> Result - where V: de::Visitor<'de> - { - match self.value { - Some(Content::Seq(v)) => { - de::Deserializer::deserialize(SeqDeserializer::new(v), visitor) - } - Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"tuple variant")), - None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"tuple variant")), - } - } - - fn visit_struct(self, - _fields: &'static [&'static str], - visitor: V) - -> Result - where V: de::Visitor<'de> - { - match self.value { - Some(Content::Map(v)) => { - de::Deserializer::deserialize(MapDeserializer::new(v), visitor) - } - Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant")), - _ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant")), - } - } -} - -struct SeqDeserializer - where E: de::Error -{ - iter: as IntoIterator>::IntoIter, - err: PhantomData, -} - -impl SeqDeserializer - where E: de::Error -{ - fn new(vec: Vec) -> Self { - SeqDeserializer { - iter: vec.into_iter(), - err: PhantomData, - } - } -} - -impl<'de, E> de::Deserializer<'de> for SeqDeserializer - where E: de::Error -{ - type Error = E; - - #[inline] - fn deserialize(mut self, visitor: V) -> Result - where V: de::Visitor<'de> - { - let len = self.iter.len(); - if len == 0 { - visitor.visit_unit() - } else { - let ret = try!(visitor.visit_seq(&mut self)); - let remaining = self.iter.len(); - if remaining == 0 { - Ok(ret) - } else { - Err(de::Error::invalid_length(len, &"fewer elements in array")) - } - } - } - - forward_to_deserialize! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct - tuple_struct struct struct_field tuple enum ignored_any - } -} - -impl<'de, E> de::SeqVisitor<'de> for SeqDeserializer - where E: de::Error -{ - type Error = E; - - fn visit_seed(&mut self, seed: T) -> Result, Self::Error> - where T: de::DeserializeSeed<'de> - { - match self.iter.next() { - Some(value) => seed.deserialize(ContentDeserializer::new(value)).map(Some), - None => Ok(None), - } - } - - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } -} - -struct MapDeserializer - where E: de::Error -{ - iter: as IntoIterator>::IntoIter, - value: Option, - err: PhantomData, -} - -impl MapDeserializer - where E: de::Error -{ - fn new(map: Vec<(Content, Content)>) -> Self { - MapDeserializer { - iter: map.into_iter(), - value: None, - err: PhantomData, - } - } -} - -impl<'de, E> de::MapVisitor<'de> for MapDeserializer - where E: de::Error -{ - type Error = E; - - fn visit_key_seed(&mut self, seed: T) -> Result, Self::Error> - where T: de::DeserializeSeed<'de> - { - match self.iter.next() { - Some((key, value)) => { - self.value = Some(value); - seed.deserialize(ContentDeserializer::new(key)).map(Some) - } - None => Ok(None), - } - } - - fn visit_value_seed(&mut self, seed: T) -> Result - where T: de::DeserializeSeed<'de> - { - match self.value.take() { - Some(value) => seed.deserialize(ContentDeserializer::new(value)), - None => Err(de::Error::custom("value is missing")), - } - } - - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } -} - -impl<'de, E> de::Deserializer<'de> for MapDeserializer - where E: de::Error -{ - type Error = E; - - #[inline] - fn deserialize(self, visitor: V) -> Result - where V: de::Visitor<'de> - { - visitor.visit_map(self) - } - - forward_to_deserialize! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct - tuple_struct struct struct_field tuple enum ignored_any - } -} - - -/// Not public API. -pub struct ContentRefDeserializer<'a, E> { - content: &'a Content, - err: PhantomData, -} - -/// Used when deserializing an untagged enum because the content may need to be -/// used more than once. -impl<'de, 'a, E> Deserializer<'de> for ContentRefDeserializer<'a, E> - where E: de::Error -{ - type Error = E; - - fn deserialize(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::Unit => visitor.visit_unit(), - Content::None => visitor.visit_none(), - Content::Some(ref v) => visitor.visit_some(ContentRefDeserializer::new(v)), - Content::Newtype(ref v) => visitor.visit_newtype_struct(ContentRefDeserializer::new(v)), - Content::Seq(ref v) => { - let seq = v.into_iter().map(ContentRefDeserializer::new); - let mut seq_visitor = de::value::SeqDeserializer::new(seq); - let value = try!(visitor.visit_seq(&mut seq_visitor)); - try!(seq_visitor.end()); - Ok(value) - } - Content::Map(ref v) => { - let map = v.into_iter().map(|&(ref k, ref v)| { - (ContentRefDeserializer::new(k), - ContentRefDeserializer::new(v)) - }); - let mut map_visitor = de::value::MapDeserializer::new(map); - let value = try!(visitor.visit_map(&mut map_visitor)); - try!(map_visitor.end()); - Ok(value) - } - Content::Bytes(ref v) => visitor.visit_bytes(v), - } - } - - fn deserialize_option(self, visitor: V) -> Result - 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(), - _ => visitor.visit_some(self), - } - } - - fn deserialize_newtype_struct(self, _name: &str, visitor: V) -> Result - where V: Visitor<'de> - { - visitor.visit_newtype_struct(self) - } - - fn deserialize_enum(self, - _name: &str, - _variants: &'static [&'static str], - visitor: V) - -> Result - where V: Visitor<'de> - { - let (variant, value) = match *self.content { - Content::Map(ref value) => { - let mut iter = value.into_iter(); - let &(ref variant, ref value) = match iter.next() { - Some(v) => v, - None => { - return Err(de::Error::invalid_value(de::Unexpected::Map, - &"map with a single key")); - } - }; - // enums are encoded in json as maps with a single key:value pair - if iter.next().is_some() { - return Err(de::Error::invalid_value(de::Unexpected::Map, - &"map with a single key")); - } - (variant, Some(value)) - } - ref s @ Content::String(_) => (s, None), - ref other => { - return Err(de::Error::invalid_type(other.unexpected(), &"string or map")); - } - }; - - visitor.visit_enum(EnumRefDeserializer { - variant: variant, - value: value, - err: PhantomData, - }) - } - - forward_to_deserialize! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq - seq_fixed_size bytes byte_buf map unit_struct tuple_struct struct - struct_field tuple ignored_any - } -} - -impl<'a, E> ContentRefDeserializer<'a, E> { - /// private API, don't use - pub fn new(content: &'a Content) -> Self { - ContentRefDeserializer { - content: content, - err: PhantomData, - } - } -} - -struct EnumRefDeserializer<'a, E> - where E: de::Error -{ - variant: &'a Content, - value: Option<&'a Content>, - err: PhantomData, -} - -impl<'de, 'a, E> de::EnumVisitor<'de> for EnumRefDeserializer<'a, E> - where E: de::Error -{ - type Error = E; - type Variant = VariantRefDeserializer<'a, Self::Error>; - - fn visit_variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> - where V: de::DeserializeSeed<'de> - { - let visitor = VariantRefDeserializer { - value: self.value, - err: PhantomData, - }; - seed.deserialize(ContentRefDeserializer::new(self.variant)).map(|v| (v, visitor)) - } -} - -struct VariantRefDeserializer<'a, E> - where E: de::Error -{ - value: Option<&'a Content>, - err: PhantomData, -} - -impl<'de, 'a, E> de::VariantVisitor<'de> for VariantRefDeserializer<'a, E> - where E: de::Error -{ - type Error = E; - - fn visit_unit(self) -> Result<(), E> { - match self.value { - Some(value) => de::Deserialize::deserialize(ContentRefDeserializer::new(value)), - None => Ok(()), - } - } - - fn visit_newtype_seed(self, seed: T) -> Result - where T: de::DeserializeSeed<'de> - { - match self.value { - Some(value) => seed.deserialize(ContentRefDeserializer::new(value)), - None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"newtype variant")), - } - } - - fn visit_tuple(self, _len: usize, visitor: V) -> Result - where V: de::Visitor<'de> - { - match self.value { - Some(&Content::Seq(ref v)) => { - de::Deserializer::deserialize(SeqRefDeserializer::new(v), visitor) - } - Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"tuple variant")), - None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"tuple variant")), - } - } - - fn visit_struct(self, - _fields: &'static [&'static str], - visitor: V) - -> Result - where V: de::Visitor<'de> - { - match self.value { - Some(&Content::Map(ref v)) => { - de::Deserializer::deserialize(MapRefDeserializer::new(v), visitor) - } - Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant")), - _ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant")), - } - } -} - -struct SeqRefDeserializer<'a, E> - where E: de::Error -{ - iter: <&'a [Content] as IntoIterator>::IntoIter, - err: PhantomData, -} - -impl<'a, E> SeqRefDeserializer<'a, E> - where E: de::Error -{ - fn new(vec: &'a [Content]) -> Self { - SeqRefDeserializer { - iter: vec.into_iter(), - err: PhantomData, - } - } -} - -impl<'de, 'a, E> de::Deserializer<'de> for SeqRefDeserializer<'a, E> - where E: de::Error -{ - type Error = E; - - #[inline] - fn deserialize(mut self, visitor: V) -> Result - where V: de::Visitor<'de> - { - let len = self.iter.len(); - if len == 0 { - visitor.visit_unit() - } else { - let ret = try!(visitor.visit_seq(&mut self)); - let remaining = self.iter.len(); - if remaining == 0 { - Ok(ret) - } else { - Err(de::Error::invalid_length(len, &"fewer elements in array")) - } - } - } - - forward_to_deserialize! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct - tuple_struct struct struct_field tuple enum ignored_any - } -} - -impl<'de, 'a, E> de::SeqVisitor<'de> for SeqRefDeserializer<'a, E> - where E: de::Error -{ - type Error = E; - - fn visit_seed(&mut self, seed: T) -> Result, Self::Error> - where T: de::DeserializeSeed<'de> - { - match self.iter.next() { - Some(value) => seed.deserialize(ContentRefDeserializer::new(value)).map(Some), - None => Ok(None), - } - } - - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } -} - -struct MapRefDeserializer<'a, E> - where E: de::Error -{ - iter: <&'a [(Content, Content)] as IntoIterator>::IntoIter, - value: Option<&'a Content>, - err: PhantomData, -} - -impl<'a, E> MapRefDeserializer<'a, E> - where E: de::Error -{ - fn new(map: &'a [(Content, Content)]) -> Self { - MapRefDeserializer { - iter: map.into_iter(), - value: None, - err: PhantomData, - } - } -} - -impl<'de, 'a, E> de::MapVisitor<'de> for MapRefDeserializer<'a, E> - where E: de::Error -{ - type Error = E; - - fn visit_key_seed(&mut self, seed: T) -> Result, Self::Error> - where T: de::DeserializeSeed<'de> - { - match self.iter.next() { - Some(&(ref key, ref value)) => { - self.value = Some(value); - seed.deserialize(ContentRefDeserializer::new(key)).map(Some) - } - None => Ok(None), - } - } - - fn visit_value_seed(&mut self, seed: T) -> Result - where T: de::DeserializeSeed<'de> - { - match self.value.take() { - Some(value) => seed.deserialize(ContentRefDeserializer::new(value)), - None => Err(de::Error::custom("value is missing")), - } - } - - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } -} - -impl<'de, 'a, E> de::Deserializer<'de> for MapRefDeserializer<'a, E> - where E: de::Error -{ - type Error = E; - - #[inline] - fn deserialize(self, visitor: V) -> Result - where V: de::Visitor<'de> - { - visitor.visit_map(self) - } - - forward_to_deserialize! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct - tuple_struct struct struct_field tuple enum ignored_any - } -} - -impl<'de, E> de::value::ValueDeserializer<'de, E> for ContentDeserializer - where E: de::Error -{ - type Deserializer = Self; - - fn into_deserializer(self) -> Self { - self - } -} - -impl<'de, 'a, E> de::value::ValueDeserializer<'de, E> for ContentRefDeserializer<'a, E> - where E: de::Error -{ - type Deserializer = Self; - - fn into_deserializer(self) -> Self { - self - } -} - -/// Visitor for deserializing an internally tagged unit variant. -/// -/// Not public API. -pub struct InternallyTaggedUnitVisitor<'a> { - type_name: &'a str, - variant_name: &'a str, -} - -impl<'a> InternallyTaggedUnitVisitor<'a> { - /// Not public API. - pub fn new(type_name: &'a str, variant_name: &'a str) -> Self { - InternallyTaggedUnitVisitor { - type_name: type_name, - variant_name: variant_name, - } - } -} - -impl<'de, 'a> Visitor<'de> for InternallyTaggedUnitVisitor<'a> { - type Value = (); - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!(formatter, "unit variant {}::{}", self.type_name, self.variant_name) - } - - fn visit_map(self, _: V) -> Result<(), V::Error> - where V: MapVisitor<'de> - { - Ok(()) - } -} - -/// Visitor for deserializing an untagged unit variant. -/// -/// Not public API. -pub struct UntaggedUnitVisitor<'a> { - type_name: &'a str, - variant_name: &'a str, -} - -impl<'a> UntaggedUnitVisitor<'a> { - /// Not public API. - pub fn new(type_name: &'a str, variant_name: &'a str) -> Self { - UntaggedUnitVisitor { - type_name: type_name, - variant_name: variant_name, - } - } -} - -impl<'de, 'a> Visitor<'de> for UntaggedUnitVisitor<'a> { - type Value = (); - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!(formatter, "unit variant {}::{}", self.type_name, self.variant_name) - } - - fn visit_unit(self) -> Result<(), E> - where E: de::Error - { - Ok(()) - } -} diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index eac50313..0def4a6c 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -113,12 +113,6 @@ mod from_primitive; mod ignored_any; mod impls; -// Helpers used by generated code. Not public API. -#[doc(hidden)] -pub mod private; -#[cfg(any(feature = "std", feature = "collections"))] -mod content; - pub use self::ignored_any::IgnoredAny; /////////////////////////////////////////////////////////////////////////////// diff --git a/serde/src/de/private.rs b/serde/src/de/private.rs deleted file mode 100644 index 8121ee15..00000000 --- a/serde/src/de/private.rs +++ /dev/null @@ -1,176 +0,0 @@ -#[cfg(any(feature = "std", feature = "collections"))] -use core::{fmt, str}; - -use core::marker::PhantomData; - -#[cfg(feature = "collections")] -use collections::borrow::ToOwned; - -#[cfg(feature = "std")] -use std::borrow::Cow; -#[cfg(all(feature = "collections", not(feature = "std")))] -use collections::borrow::Cow; - -#[cfg(all(feature = "collections", not(feature = "std")))] -use collections::{String, Vec}; - -use de::{Deserialize, Deserializer, Error, Visitor}; - -#[cfg(any(feature = "std", feature = "collections"))] -use de::Unexpected; - -#[cfg(any(feature = "std", feature = "collections"))] -pub use de::content::{Content, ContentRefDeserializer, ContentDeserializer, TaggedContentVisitor, - TagOrContentField, TagOrContentFieldVisitor, InternallyTaggedUnitVisitor, - UntaggedUnitVisitor}; - -/// If the missing field is of type `Option` then treat is as `None`, -/// otherwise it is an error. -pub fn missing_field<'de, V, E>(field: &'static str) -> Result - where V: Deserialize<'de>, - E: Error -{ - struct MissingFieldDeserializer(&'static str, PhantomData); - - impl<'de, E> Deserializer<'de> for MissingFieldDeserializer - where E: Error - { - type Error = E; - - fn deserialize(self, _visitor: V) -> Result - where V: Visitor<'de> - { - Err(Error::missing_field(self.0)) - } - - fn deserialize_option(self, visitor: V) -> Result - where V: Visitor<'de> - { - visitor.visit_none() - } - - forward_to_deserialize! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq - seq_fixed_size bytes byte_buf map unit_struct newtype_struct - tuple_struct struct struct_field tuple enum ignored_any - } - } - - let deserializer = MissingFieldDeserializer(field, PhantomData); - Deserialize::deserialize(deserializer) -} - -#[cfg(any(feature = "std", feature = "collections"))] -pub fn borrow_cow_str<'de: 'a, 'a, D>(deserializer: D) -> Result, D::Error> - where D: Deserializer<'de> -{ - struct CowStrVisitor; - - impl<'a> Visitor<'a> for CowStrVisitor { - type Value = Cow<'a, str>; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a string") - } - - fn visit_str(self, v: &str) -> Result - where E: Error - { - Ok(Cow::Owned(v.to_owned())) - } - - fn visit_borrowed_str(self, v: &'a str) -> Result - where E: Error - { - Ok(Cow::Borrowed(v)) - } - - fn visit_string(self, v: String) -> Result - where E: Error - { - Ok(Cow::Owned(v)) - } - - fn visit_bytes(self, v: &[u8]) -> Result - where E: Error - { - match str::from_utf8(v) { - Ok(s) => Ok(Cow::Owned(s.to_owned())), - Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)), - } - } - - fn visit_borrowed_bytes(self, v: &'a [u8]) -> Result - where E: Error - { - match str::from_utf8(v) { - Ok(s) => Ok(Cow::Borrowed(s)), - Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)), - } - } - - fn visit_byte_buf(self, v: Vec) -> Result - where E: Error - { - match String::from_utf8(v) { - Ok(s) => Ok(Cow::Owned(s)), - Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self)), - } - } - } - - deserializer.deserialize_str(CowStrVisitor) -} - -#[cfg(any(feature = "std", feature = "collections"))] -pub fn borrow_cow_bytes<'de: 'a, 'a, D>(deserializer: D) -> Result, D::Error> - where D: Deserializer<'de> -{ - struct CowBytesVisitor; - - impl<'a> Visitor<'a> for CowBytesVisitor { - type Value = Cow<'a, [u8]>; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a byte array") - } - - fn visit_str(self, v: &str) -> Result - where E: Error - { - Ok(Cow::Owned(v.as_bytes().to_vec())) - } - - fn visit_borrowed_str(self, v: &'a str) -> Result - where E: Error - { - Ok(Cow::Borrowed(v.as_bytes())) - } - - fn visit_string(self, v: String) -> Result - where E: Error - { - Ok(Cow::Owned(v.into_bytes())) - } - - fn visit_bytes(self, v: &[u8]) -> Result - where E: Error - { - Ok(Cow::Owned(v.to_vec())) - } - - fn visit_borrowed_bytes(self, v: &'a [u8]) -> Result - where E: Error - { - Ok(Cow::Borrowed(v)) - } - - fn visit_byte_buf(self, v: Vec) -> Result - where E: Error - { - Ok(Cow::Owned(v)) - } - } - - deserializer.deserialize_str(CowBytesVisitor) -} diff --git a/serde/src/lib.rs b/serde/src/lib.rs index 10cb570f..ada910ca 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -93,15 +93,19 @@ pub use de::{Deserialize, Deserializer}; #[macro_use] mod macros; +mod utils; pub mod de; pub mod ser; -mod utils; // Generated code uses these to support no_std. Not public API. #[doc(hidden)] pub mod export; +// Helpers used by generated code and doc tests. Not public API. +#[doc(hidden)] +pub mod private; + // Re-export #[derive(Serialize, Deserialize)]. // // This is a workaround for https://github.com/rust-lang/cargo/issues/1286. diff --git a/serde/src/macros.rs b/serde/src/macros.rs index dcd2433e..022e1214 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -177,162 +177,3 @@ macro_rules! forward_to_deserialize { $(forward_to_deserialize_helper!{$func})* }; } - -/// Seralize the `$value` that implements Display as a string, -/// when that string is statically known to never have more than -/// a constant `$MAX_LEN` bytes. -/// -/// Panics if the Display impl tries to write more than `$MAX_LEN` bytes. -#[cfg(feature = "std")] -// Not exported -macro_rules! serialize_display_bounded_length { - ($value: expr, $MAX_LEN: expr, $serializer: expr) => { - { - use std::io::Write; - let mut buffer: [u8; $MAX_LEN] = unsafe { ::std::mem::uninitialized() }; - let remaining_len; - { - let mut remaining = &mut buffer[..]; - write!(remaining, "{}", $value).unwrap(); - remaining_len = remaining.len() - } - let written_len = buffer.len() - remaining_len; - let written = &buffer[..written_len]; - - // write! only provides std::fmt::Formatter to Display implementations, - // which has methods write_str and write_char but no method to write arbitrary bytes. - // Therefore, `written` is well-formed in UTF-8. - let written_str = unsafe { - ::std::str::from_utf8_unchecked(written) - }; - $serializer.serialize_str(written_str) - } - } -} - -#[doc(hidden)] -#[macro_export] -macro_rules! __serialize_unimplemented_method { - ($func:ident $(<$t:ident>)* ($($arg:ty),*) -> $ret:ident) => { - fn $func $(<$t: ?Sized + $crate::Serialize>)* (self $(, _: $arg)*) -> $crate::export::Result { - unimplemented!() - } - }; -} - -#[doc(hidden)] -#[macro_export] -macro_rules! __serialize_unimplemented_helper { - (bool) => { - __serialize_unimplemented_method!(serialize_bool(bool) -> Ok); - }; - (i8) => { - __serialize_unimplemented_method!(serialize_i8(i8) -> Ok); - }; - (i16) => { - __serialize_unimplemented_method!(serialize_i16(i16) -> Ok); - }; - (i32) => { - __serialize_unimplemented_method!(serialize_i32(i32) -> Ok); - }; - (i64) => { - __serialize_unimplemented_method!(serialize_i64(i64) -> Ok); - }; - (u8) => { - __serialize_unimplemented_method!(serialize_u8(u8) -> Ok); - }; - (u16) => { - __serialize_unimplemented_method!(serialize_u16(u16) -> Ok); - }; - (u32) => { - __serialize_unimplemented_method!(serialize_u32(u32) -> Ok); - }; - (u64) => { - __serialize_unimplemented_method!(serialize_u64(u64) -> Ok); - }; - (f32) => { - __serialize_unimplemented_method!(serialize_f32(f32) -> Ok); - }; - (f64) => { - __serialize_unimplemented_method!(serialize_f64(f64) -> Ok); - }; - (char) => { - __serialize_unimplemented_method!(serialize_char(char) -> Ok); - }; - (str) => { - __serialize_unimplemented_method!(serialize_str(&str) -> Ok); - }; - (bytes) => { - __serialize_unimplemented_method!(serialize_bytes(&[u8]) -> Ok); - }; - (none) => { - __serialize_unimplemented_method!(serialize_none() -> Ok); - }; - (some) => { - __serialize_unimplemented_method!(serialize_some(&T) -> Ok); - }; - (unit) => { - __serialize_unimplemented_method!(serialize_unit() -> Ok); - }; - (unit_struct) => { - __serialize_unimplemented_method!(serialize_unit_struct(&str) -> Ok); - }; - (unit_variant) => { - __serialize_unimplemented_method!(serialize_unit_variant(&str, usize, &str) -> Ok); - }; - (newtype_struct) => { - __serialize_unimplemented_method!(serialize_newtype_struct(&str, &T) -> Ok); - }; - (newtype_variant) => { - __serialize_unimplemented_method!(serialize_newtype_variant(&str, usize, &str, &T) -> Ok); - }; - (seq) => { - type SerializeSeq = $crate::ser::Impossible; - __serialize_unimplemented_method!(serialize_seq(Option) -> SerializeSeq); - }; - (seq_fixed_size) => { - __serialize_unimplemented_method!(serialize_seq_fixed_size(usize) -> SerializeSeq); - }; - (tuple) => { - type SerializeTuple = $crate::ser::Impossible; - __serialize_unimplemented_method!(serialize_tuple(usize) -> SerializeTuple); - }; - (tuple_struct) => { - type SerializeTupleStruct = $crate::ser::Impossible; - __serialize_unimplemented_method!(serialize_tuple_struct(&str, usize) -> SerializeTupleStruct); - }; - (tuple_variant) => { - type SerializeTupleVariant = $crate::ser::Impossible; - __serialize_unimplemented_method!(serialize_tuple_variant(&str, usize, &str, usize) -> SerializeTupleVariant); - }; - (map) => { - type SerializeMap = $crate::ser::Impossible; - __serialize_unimplemented_method!(serialize_map(Option) -> SerializeMap); - }; - (struct) => { - type SerializeStruct = $crate::ser::Impossible; - __serialize_unimplemented_method!(serialize_struct(&str, usize) -> SerializeStruct); - }; - (struct_variant) => { - type SerializeStructVariant = $crate::ser::Impossible; - __serialize_unimplemented_method!(serialize_struct_variant(&str, usize, &str, usize) -> SerializeStructVariant); - }; -} - -/// Used only by Serde doc tests. Not public API. -#[doc(hidden)] -#[macro_export] -macro_rules! __serialize_unimplemented { - ($($func:ident)*) => { - $( - __serialize_unimplemented_helper!($func); - )* - }; -} - -/// Used only by Serde doc tests. Not public API. -#[doc(hidden)] -#[macro_export] -macro_rules! __serde_ignore_tokens { - ($($tt:tt)+) => {} -} diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs new file mode 100644 index 00000000..f4e95dc6 --- /dev/null +++ b/serde/src/private/de.rs @@ -0,0 +1,1520 @@ +#[cfg(any(feature = "std", feature = "collections"))] +use core::{fmt, str}; + +use core::marker::PhantomData; + +#[cfg(feature = "collections")] +use collections::borrow::ToOwned; + +#[cfg(feature = "std")] +use std::borrow::Cow; +#[cfg(all(feature = "collections", not(feature = "std")))] +use collections::borrow::Cow; + +#[cfg(all(feature = "collections", not(feature = "std")))] +use collections::{String, Vec}; + +use de::{Deserialize, Deserializer, Error, Visitor}; + +#[cfg(any(feature = "std", feature = "collections"))] +use de::Unexpected; + +#[cfg(any(feature = "std", feature = "collections"))] +pub use self::content::{Content, ContentRefDeserializer, ContentDeserializer, TaggedContentVisitor, + TagOrContentField, TagOrContentFieldVisitor, InternallyTaggedUnitVisitor, + UntaggedUnitVisitor}; + +/// If the missing field is of type `Option` then treat is as `None`, +/// otherwise it is an error. +pub fn missing_field<'de, V, E>(field: &'static str) -> Result + where V: Deserialize<'de>, + E: Error +{ + struct MissingFieldDeserializer(&'static str, PhantomData); + + impl<'de, E> Deserializer<'de> for MissingFieldDeserializer + where E: Error + { + type Error = E; + + fn deserialize(self, _visitor: V) -> Result + where V: Visitor<'de> + { + Err(Error::missing_field(self.0)) + } + + fn deserialize_option(self, visitor: V) -> Result + where V: Visitor<'de> + { + visitor.visit_none() + } + + forward_to_deserialize! { + bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq + seq_fixed_size bytes byte_buf map unit_struct newtype_struct + tuple_struct struct struct_field tuple enum ignored_any + } + } + + let deserializer = MissingFieldDeserializer(field, PhantomData); + Deserialize::deserialize(deserializer) +} + +#[cfg(any(feature = "std", feature = "collections"))] +pub fn borrow_cow_str<'de: 'a, 'a, D>(deserializer: D) -> Result, D::Error> + where D: Deserializer<'de> +{ + struct CowStrVisitor; + + impl<'a> Visitor<'a> for CowStrVisitor { + type Value = Cow<'a, str>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a string") + } + + fn visit_str(self, v: &str) -> Result + where E: Error + { + Ok(Cow::Owned(v.to_owned())) + } + + fn visit_borrowed_str(self, v: &'a str) -> Result + where E: Error + { + Ok(Cow::Borrowed(v)) + } + + fn visit_string(self, v: String) -> Result + where E: Error + { + Ok(Cow::Owned(v)) + } + + fn visit_bytes(self, v: &[u8]) -> Result + where E: Error + { + match str::from_utf8(v) { + Ok(s) => Ok(Cow::Owned(s.to_owned())), + Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)), + } + } + + fn visit_borrowed_bytes(self, v: &'a [u8]) -> Result + where E: Error + { + match str::from_utf8(v) { + Ok(s) => Ok(Cow::Borrowed(s)), + Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)), + } + } + + fn visit_byte_buf(self, v: Vec) -> Result + where E: Error + { + match String::from_utf8(v) { + Ok(s) => Ok(Cow::Owned(s)), + Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self)), + } + } + } + + deserializer.deserialize_str(CowStrVisitor) +} + +#[cfg(any(feature = "std", feature = "collections"))] +pub fn borrow_cow_bytes<'de: 'a, 'a, D>(deserializer: D) -> Result, D::Error> + where D: Deserializer<'de> +{ + struct CowBytesVisitor; + + impl<'a> Visitor<'a> for CowBytesVisitor { + type Value = Cow<'a, [u8]>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a byte array") + } + + fn visit_str(self, v: &str) -> Result + where E: Error + { + Ok(Cow::Owned(v.as_bytes().to_vec())) + } + + fn visit_borrowed_str(self, v: &'a str) -> Result + where E: Error + { + Ok(Cow::Borrowed(v.as_bytes())) + } + + fn visit_string(self, v: String) -> Result + where E: Error + { + Ok(Cow::Owned(v.into_bytes())) + } + + fn visit_bytes(self, v: &[u8]) -> Result + where E: Error + { + Ok(Cow::Owned(v.to_vec())) + } + + fn visit_borrowed_bytes(self, v: &'a [u8]) -> Result + where E: Error + { + Ok(Cow::Borrowed(v)) + } + + fn visit_byte_buf(self, v: Vec) -> Result + where E: Error + { + Ok(Cow::Owned(v)) + } + } + + deserializer.deserialize_str(CowBytesVisitor) +} + +#[cfg(any(feature = "std", feature = "collections"))] +mod content { + // This module is private and nothing here should be used outside of + // generated code. + // + // We will iterate on the implementation for a few releases and only have to + // worry about backward compatibility for the `untagged` and `tag` attributes + // rather than for this entire mechanism. + // + // This issue is tracking making some of this stuff public: + // https://github.com/serde-rs/serde/issues/741 + + #![doc(hidden)] + + use core::cmp; + use core::fmt; + use core::marker::PhantomData; + + #[cfg(all(not(feature = "std"), feature = "collections"))] + use collections::{String, Vec}; + + #[cfg(all(feature = "alloc", not(feature = "std")))] + use alloc::boxed::Box; + + use de::{self, Deserialize, DeserializeSeed, Deserializer, Visitor, SeqVisitor, MapVisitor, + EnumVisitor, Unexpected}; + + /// Used from generated code to buffer the contents of the Deserializer when + /// deserializing untagged enums and internally tagged enums. + /// + /// Not public API. Use serde-value instead. + #[derive(Debug)] + pub enum Content { + Bool(bool), + + U8(u8), + U16(u16), + U32(u32), + U64(u64), + + I8(i8), + I16(i16), + I32(i32), + I64(i64), + + F32(f32), + F64(f64), + + Char(char), + String(String), + Bytes(Vec), + + None, + Some(Box), + + Unit, + Newtype(Box), + Seq(Vec), + Map(Vec<(Content, Content)>), + } + + impl Content { + 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::Bytes(ref 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, + } + } + } + + impl<'de> Deserialize<'de> for Content { + fn deserialize(deserializer: D) -> Result + where D: Deserializer<'de> + { + // Untagged and internally tagged enums are only supported in + // self-describing formats. + deserializer.deserialize(ContentVisitor) + } + } + + struct ContentVisitor; + + impl<'de> Visitor<'de> for ContentVisitor { + type Value = Content; + + fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.write_str("any value") + } + + fn visit_bool(self, value: bool) -> Result + where F: de::Error + { + Ok(Content::Bool(value)) + } + + fn visit_i8(self, value: i8) -> Result + where F: de::Error + { + Ok(Content::I8(value)) + } + + fn visit_i16(self, value: i16) -> Result + where F: de::Error + { + Ok(Content::I16(value)) + } + + fn visit_i32(self, value: i32) -> Result + where F: de::Error + { + Ok(Content::I32(value)) + } + + fn visit_i64(self, value: i64) -> Result + where F: de::Error + { + Ok(Content::I64(value)) + } + + fn visit_u8(self, value: u8) -> Result + where F: de::Error + { + Ok(Content::U8(value)) + } + + fn visit_u16(self, value: u16) -> Result + where F: de::Error + { + Ok(Content::U16(value)) + } + + fn visit_u32(self, value: u32) -> Result + where F: de::Error + { + Ok(Content::U32(value)) + } + + fn visit_u64(self, value: u64) -> Result + where F: de::Error + { + Ok(Content::U64(value)) + } + + fn visit_f32(self, value: f32) -> Result + where F: de::Error + { + Ok(Content::F32(value)) + } + + fn visit_f64(self, value: f64) -> Result + where F: de::Error + { + Ok(Content::F64(value)) + } + + fn visit_char(self, value: char) -> Result + where F: de::Error + { + Ok(Content::Char(value)) + } + + fn visit_str(self, value: &str) -> Result + where F: de::Error + { + Ok(Content::String(value.into())) + } + + fn visit_string(self, value: String) -> Result + where F: de::Error + { + Ok(Content::String(value)) + } + + fn visit_bytes(self, value: &[u8]) -> Result + where F: de::Error + { + Ok(Content::Bytes(value.into())) + } + + fn visit_byte_buf(self, value: Vec) -> Result + where F: de::Error + { + Ok(Content::Bytes(value)) + } + + fn visit_unit(self) -> Result + where F: de::Error + { + Ok(Content::Unit) + } + + fn visit_none(self) -> Result + where F: de::Error + { + Ok(Content::None) + } + + fn visit_some(self, deserializer: D) -> Result + where D: Deserializer<'de> + { + Deserialize::deserialize(deserializer).map(|v| Content::Some(Box::new(v))) + } + + fn visit_newtype_struct(self, deserializer: D) -> Result + where D: Deserializer<'de> + { + Deserialize::deserialize(deserializer).map(|v| Content::Newtype(Box::new(v))) + } + + fn visit_seq(self, mut visitor: V) -> Result + where V: SeqVisitor<'de> + { + let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); + while let Some(e) = try!(visitor.visit()) { + vec.push(e); + } + Ok(Content::Seq(vec)) + } + + fn visit_map(self, mut visitor: V) -> Result + where V: MapVisitor<'de> + { + let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); + while let Some(kv) = try!(visitor.visit()) { + vec.push(kv); + } + Ok(Content::Map(vec)) + } + + fn visit_enum(self, _visitor: V) -> Result + where V: EnumVisitor<'de> + { + Err(de::Error::custom("untagged and internally tagged enums do not support enum input")) + } + } + + /// This is the type of the map keys in an internally tagged enum. + /// + /// Not public API. + pub enum TagOrContent { + Tag, + Content(Content), + } + + struct TagOrContentVisitor { + name: &'static str, + } + + impl TagOrContentVisitor { + fn new(name: &'static str) -> Self { + TagOrContentVisitor { name: name } + } + } + + impl<'de> DeserializeSeed<'de> for TagOrContentVisitor { + type Value = TagOrContent; + + fn deserialize(self, deserializer: D) -> Result + where D: Deserializer<'de> + { + // Internally tagged enums are only supported in self-describing + // formats. + deserializer.deserialize(self) + } + } + + impl<'de> Visitor<'de> for TagOrContentVisitor { + type Value = TagOrContent; + + fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "a type tag `{}` or any other value", self.name) + } + + fn visit_bool(self, value: bool) -> Result + where F: de::Error + { + ContentVisitor.visit_bool(value).map(TagOrContent::Content) + } + + fn visit_i8(self, value: i8) -> Result + where F: de::Error + { + ContentVisitor.visit_i8(value).map(TagOrContent::Content) + } + + fn visit_i16(self, value: i16) -> Result + where F: de::Error + { + ContentVisitor.visit_i16(value).map(TagOrContent::Content) + } + + fn visit_i32(self, value: i32) -> Result + where F: de::Error + { + ContentVisitor.visit_i32(value).map(TagOrContent::Content) + } + + fn visit_i64(self, value: i64) -> Result + where F: de::Error + { + ContentVisitor.visit_i64(value).map(TagOrContent::Content) + } + + fn visit_u8(self, value: u8) -> Result + where F: de::Error + { + ContentVisitor.visit_u8(value).map(TagOrContent::Content) + } + + fn visit_u16(self, value: u16) -> Result + where F: de::Error + { + ContentVisitor.visit_u16(value).map(TagOrContent::Content) + } + + fn visit_u32(self, value: u32) -> Result + where F: de::Error + { + ContentVisitor.visit_u32(value).map(TagOrContent::Content) + } + + fn visit_u64(self, value: u64) -> Result + where F: de::Error + { + ContentVisitor.visit_u64(value).map(TagOrContent::Content) + } + + fn visit_f32(self, value: f32) -> Result + where F: de::Error + { + ContentVisitor.visit_f32(value).map(TagOrContent::Content) + } + + fn visit_f64(self, value: f64) -> Result + where F: de::Error + { + ContentVisitor.visit_f64(value).map(TagOrContent::Content) + } + + fn visit_char(self, value: char) -> Result + where F: de::Error + { + ContentVisitor.visit_char(value).map(TagOrContent::Content) + } + + fn visit_str(self, value: &str) -> Result + where F: de::Error + { + if value == self.name { + Ok(TagOrContent::Tag) + } else { + ContentVisitor.visit_str(value).map(TagOrContent::Content) + } + } + + fn visit_string(self, value: String) -> Result + where F: de::Error + { + if value == self.name { + Ok(TagOrContent::Tag) + } else { + ContentVisitor.visit_string(value).map(TagOrContent::Content) + } + } + + fn visit_bytes(self, value: &[u8]) -> Result + where F: de::Error + { + if value == self.name.as_bytes() { + Ok(TagOrContent::Tag) + } else { + ContentVisitor.visit_bytes(value).map(TagOrContent::Content) + } + } + + fn visit_byte_buf(self, value: Vec) -> Result + where F: de::Error + { + if value == self.name.as_bytes() { + Ok(TagOrContent::Tag) + } else { + ContentVisitor.visit_byte_buf(value).map(TagOrContent::Content) + } + } + + fn visit_unit(self) -> Result + where F: de::Error + { + ContentVisitor.visit_unit().map(TagOrContent::Content) + } + + fn visit_none(self) -> Result + where F: de::Error + { + ContentVisitor.visit_none().map(TagOrContent::Content) + } + + fn visit_some(self, deserializer: D) -> Result + where D: Deserializer<'de> + { + ContentVisitor.visit_some(deserializer).map(TagOrContent::Content) + } + + fn visit_newtype_struct(self, deserializer: D) -> Result + where D: Deserializer<'de> + { + ContentVisitor.visit_newtype_struct(deserializer).map(TagOrContent::Content) + } + + fn visit_seq(self, visitor: V) -> Result + where V: SeqVisitor<'de> + { + ContentVisitor.visit_seq(visitor).map(TagOrContent::Content) + } + + fn visit_map(self, visitor: V) -> Result + where V: MapVisitor<'de> + { + ContentVisitor.visit_map(visitor).map(TagOrContent::Content) + } + + fn visit_enum(self, visitor: V) -> Result + where V: EnumVisitor<'de> + { + ContentVisitor.visit_enum(visitor).map(TagOrContent::Content) + } + } + + /// Used by generated code to deserialize an internally tagged enum. + /// + /// Not public API. + pub struct TaggedContent { + pub tag: T, + pub content: Content, + } + + /// Not public API. + pub struct TaggedContentVisitor { + tag_name: &'static str, + tag: PhantomData, + } + + impl TaggedContentVisitor { + /// Visitor for the content of an internally tagged enum with the given tag + /// name. + pub fn new(name: &'static str) -> Self { + TaggedContentVisitor { + tag_name: name, + tag: PhantomData, + } + } + } + + impl<'de, T> DeserializeSeed<'de> for TaggedContentVisitor + where T: Deserialize<'de> + { + type Value = TaggedContent; + + fn deserialize(self, deserializer: D) -> Result + where D: Deserializer<'de> + { + // Internally tagged enums are only supported in self-describing + // formats. + deserializer.deserialize(self) + } + } + + impl<'de, T> Visitor<'de> for TaggedContentVisitor + where T: Deserialize<'de> + { + type Value = TaggedContent; + + fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.write_str("any value") + } + + fn visit_map(self, mut visitor: V) -> Result + where V: MapVisitor<'de> + { + let mut tag = None; + let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); + while let Some(k) = try!(visitor.visit_key_seed(TagOrContentVisitor::new(self.tag_name))) { + match k { + TagOrContent::Tag => { + if tag.is_some() { + return Err(de::Error::duplicate_field(self.tag_name)); + } + tag = Some(try!(visitor.visit_value())); + } + TagOrContent::Content(k) => { + let v = try!(visitor.visit_value()); + vec.push((k, v)); + } + } + } + match tag { + None => Err(de::Error::missing_field(self.tag_name)), + Some(tag) => { + Ok(TaggedContent { + tag: tag, + content: Content::Map(vec), + }) + } + } + } + } + + /// Used by generated code to deserialize an adjacently tagged enum. + /// + /// Not public API. + pub enum TagOrContentField { + Tag, + Content, + } + + /// Not public API. + pub struct TagOrContentFieldVisitor { + pub tag: &'static str, + pub content: &'static str, + } + + impl<'de> DeserializeSeed<'de> for TagOrContentFieldVisitor { + type Value = TagOrContentField; + + fn deserialize(self, deserializer: D) -> Result + where D: Deserializer<'de> + { + deserializer.deserialize_str(self) + } + } + + impl<'de> Visitor<'de> for TagOrContentFieldVisitor { + type Value = TagOrContentField; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "{:?} or {:?}", self.tag, self.content) + } + + fn visit_str(self, field: &str) -> Result + where E: de::Error + { + if field == self.tag { + Ok(TagOrContentField::Tag) + } else if field == self.content { + Ok(TagOrContentField::Content) + } else { + Err(de::Error::invalid_value(Unexpected::Str(field), &self)) + } + } + } + + /// Not public API + pub struct ContentDeserializer { + content: Content, + err: PhantomData, + } + + /// Used when deserializing an internally tagged enum because the content will + /// be used exactly once. + impl<'de, E> Deserializer<'de> for ContentDeserializer + where E: de::Error + { + type Error = E; + + fn deserialize(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::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) => { + let seq = v.into_iter().map(ContentDeserializer::new); + let mut seq_visitor = de::value::SeqDeserializer::new(seq); + let value = try!(visitor.visit_seq(&mut seq_visitor)); + try!(seq_visitor.end()); + Ok(value) + } + Content::Map(v) => { + let map = v.into_iter().map(|(k, v)| { + (ContentDeserializer::new(k), + ContentDeserializer::new(v)) + }); + let mut map_visitor = de::value::MapDeserializer::new(map); + let value = try!(visitor.visit_map(&mut map_visitor)); + try!(map_visitor.end()); + Ok(value) + } + Content::Bytes(v) => visitor.visit_byte_buf(v), + } + } + + fn deserialize_option(self, visitor: V) -> Result + 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(), + _ => visitor.visit_some(self), + } + } + + fn deserialize_newtype_struct(self, _name: &str, visitor: V) -> Result + where V: Visitor<'de> + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_enum(self, + _name: &str, + _variants: &'static [&'static str], + visitor: V) + -> Result + where V: Visitor<'de> + { + let (variant, value) = match self.content { + Content::Map(value) => { + let mut iter = value.into_iter(); + let (variant, value) = match iter.next() { + Some(v) => v, + None => { + return Err(de::Error::invalid_value(de::Unexpected::Map, + &"map with a single key")); + } + }; + // enums are encoded in json as maps with a single key:value pair + if iter.next().is_some() { + return Err(de::Error::invalid_value(de::Unexpected::Map, + &"map with a single key")); + } + (variant, Some(value)) + } + Content::String(variant) => (Content::String(variant), None), + other => { + return Err(de::Error::invalid_type(other.unexpected(), &"string or map")); + } + }; + + visitor.visit_enum(EnumDeserializer { + variant: variant, + value: value, + err: PhantomData, + }) + } + + forward_to_deserialize! { + bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq + seq_fixed_size bytes byte_buf map unit_struct tuple_struct struct + struct_field tuple ignored_any + } + } + + impl ContentDeserializer { + /// private API, don't use + pub fn new(content: Content) -> Self { + ContentDeserializer { + content: content, + err: PhantomData, + } + } + } + + struct EnumDeserializer + where E: de::Error + { + variant: Content, + value: Option, + err: PhantomData, + } + + impl<'de, E> de::EnumVisitor<'de> for EnumDeserializer + where E: de::Error + { + type Error = E; + type Variant = VariantDeserializer; + + fn visit_variant_seed(self, + seed: V) + -> Result<(V::Value, VariantDeserializer), Self::Error> + where V: de::DeserializeSeed<'de> + { + let visitor = VariantDeserializer { + value: self.value, + err: PhantomData, + }; + seed.deserialize(ContentDeserializer::new(self.variant)).map(|v| (v, visitor)) + } + } + + struct VariantDeserializer + where E: de::Error + { + value: Option, + err: PhantomData, + } + + impl<'de, E> de::VariantVisitor<'de> for VariantDeserializer + where E: de::Error + { + type Error = E; + + fn visit_unit(self) -> Result<(), E> { + match self.value { + Some(value) => de::Deserialize::deserialize(ContentDeserializer::new(value)), + None => Ok(()), + } + } + + fn visit_newtype_seed(self, seed: T) -> Result + where T: de::DeserializeSeed<'de> + { + match self.value { + Some(value) => seed.deserialize(ContentDeserializer::new(value)), + None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"newtype variant")), + } + } + + fn visit_tuple(self, _len: usize, visitor: V) -> Result + where V: de::Visitor<'de> + { + match self.value { + Some(Content::Seq(v)) => { + de::Deserializer::deserialize(SeqDeserializer::new(v), visitor) + } + Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"tuple variant")), + None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"tuple variant")), + } + } + + fn visit_struct(self, + _fields: &'static [&'static str], + visitor: V) + -> Result + where V: de::Visitor<'de> + { + match self.value { + Some(Content::Map(v)) => { + de::Deserializer::deserialize(MapDeserializer::new(v), visitor) + } + Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant")), + _ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant")), + } + } + } + + struct SeqDeserializer + where E: de::Error + { + iter: as IntoIterator>::IntoIter, + err: PhantomData, + } + + impl SeqDeserializer + where E: de::Error + { + fn new(vec: Vec) -> Self { + SeqDeserializer { + iter: vec.into_iter(), + err: PhantomData, + } + } + } + + impl<'de, E> de::Deserializer<'de> for SeqDeserializer + where E: de::Error + { + type Error = E; + + #[inline] + fn deserialize(mut self, visitor: V) -> Result + where V: de::Visitor<'de> + { + let len = self.iter.len(); + if len == 0 { + visitor.visit_unit() + } else { + let ret = try!(visitor.visit_seq(&mut self)); + let remaining = self.iter.len(); + if remaining == 0 { + Ok(ret) + } else { + Err(de::Error::invalid_length(len, &"fewer elements in array")) + } + } + } + + forward_to_deserialize! { + bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option + seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct + tuple_struct struct struct_field tuple enum ignored_any + } + } + + impl<'de, E> de::SeqVisitor<'de> for SeqDeserializer + where E: de::Error + { + type Error = E; + + fn visit_seed(&mut self, seed: T) -> Result, Self::Error> + where T: de::DeserializeSeed<'de> + { + match self.iter.next() { + Some(value) => seed.deserialize(ContentDeserializer::new(value)).map(Some), + None => Ok(None), + } + } + + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } + } + + struct MapDeserializer + where E: de::Error + { + iter: as IntoIterator>::IntoIter, + value: Option, + err: PhantomData, + } + + impl MapDeserializer + where E: de::Error + { + fn new(map: Vec<(Content, Content)>) -> Self { + MapDeserializer { + iter: map.into_iter(), + value: None, + err: PhantomData, + } + } + } + + impl<'de, E> de::MapVisitor<'de> for MapDeserializer + where E: de::Error + { + type Error = E; + + fn visit_key_seed(&mut self, seed: T) -> Result, Self::Error> + where T: de::DeserializeSeed<'de> + { + match self.iter.next() { + Some((key, value)) => { + self.value = Some(value); + seed.deserialize(ContentDeserializer::new(key)).map(Some) + } + None => Ok(None), + } + } + + fn visit_value_seed(&mut self, seed: T) -> Result + where T: de::DeserializeSeed<'de> + { + match self.value.take() { + Some(value) => seed.deserialize(ContentDeserializer::new(value)), + None => Err(de::Error::custom("value is missing")), + } + } + + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } + } + + impl<'de, E> de::Deserializer<'de> for MapDeserializer + where E: de::Error + { + type Error = E; + + #[inline] + fn deserialize(self, visitor: V) -> Result + where V: de::Visitor<'de> + { + visitor.visit_map(self) + } + + forward_to_deserialize! { + bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option + seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct + tuple_struct struct struct_field tuple enum ignored_any + } + } + + + /// Not public API. + pub struct ContentRefDeserializer<'a, E> { + content: &'a Content, + err: PhantomData, + } + + /// Used when deserializing an untagged enum because the content may need to be + /// used more than once. + impl<'de, 'a, E> Deserializer<'de> for ContentRefDeserializer<'a, E> + where E: de::Error + { + type Error = E; + + fn deserialize(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::Unit => visitor.visit_unit(), + Content::None => visitor.visit_none(), + Content::Some(ref v) => visitor.visit_some(ContentRefDeserializer::new(v)), + Content::Newtype(ref v) => visitor.visit_newtype_struct(ContentRefDeserializer::new(v)), + Content::Seq(ref v) => { + let seq = v.into_iter().map(ContentRefDeserializer::new); + let mut seq_visitor = de::value::SeqDeserializer::new(seq); + let value = try!(visitor.visit_seq(&mut seq_visitor)); + try!(seq_visitor.end()); + Ok(value) + } + Content::Map(ref v) => { + let map = v.into_iter().map(|&(ref k, ref v)| { + (ContentRefDeserializer::new(k), + ContentRefDeserializer::new(v)) + }); + let mut map_visitor = de::value::MapDeserializer::new(map); + let value = try!(visitor.visit_map(&mut map_visitor)); + try!(map_visitor.end()); + Ok(value) + } + Content::Bytes(ref v) => visitor.visit_bytes(v), + } + } + + fn deserialize_option(self, visitor: V) -> Result + 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(), + _ => visitor.visit_some(self), + } + } + + fn deserialize_newtype_struct(self, _name: &str, visitor: V) -> Result + where V: Visitor<'de> + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_enum(self, + _name: &str, + _variants: &'static [&'static str], + visitor: V) + -> Result + where V: Visitor<'de> + { + let (variant, value) = match *self.content { + Content::Map(ref value) => { + let mut iter = value.into_iter(); + let &(ref variant, ref value) = match iter.next() { + Some(v) => v, + None => { + return Err(de::Error::invalid_value(de::Unexpected::Map, + &"map with a single key")); + } + }; + // enums are encoded in json as maps with a single key:value pair + if iter.next().is_some() { + return Err(de::Error::invalid_value(de::Unexpected::Map, + &"map with a single key")); + } + (variant, Some(value)) + } + ref s @ Content::String(_) => (s, None), + ref other => { + return Err(de::Error::invalid_type(other.unexpected(), &"string or map")); + } + }; + + visitor.visit_enum(EnumRefDeserializer { + variant: variant, + value: value, + err: PhantomData, + }) + } + + forward_to_deserialize! { + bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq + seq_fixed_size bytes byte_buf map unit_struct tuple_struct struct + struct_field tuple ignored_any + } + } + + impl<'a, E> ContentRefDeserializer<'a, E> { + /// private API, don't use + pub fn new(content: &'a Content) -> Self { + ContentRefDeserializer { + content: content, + err: PhantomData, + } + } + } + + struct EnumRefDeserializer<'a, E> + where E: de::Error + { + variant: &'a Content, + value: Option<&'a Content>, + err: PhantomData, + } + + impl<'de, 'a, E> de::EnumVisitor<'de> for EnumRefDeserializer<'a, E> + where E: de::Error + { + type Error = E; + type Variant = VariantRefDeserializer<'a, Self::Error>; + + fn visit_variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> + where V: de::DeserializeSeed<'de> + { + let visitor = VariantRefDeserializer { + value: self.value, + err: PhantomData, + }; + seed.deserialize(ContentRefDeserializer::new(self.variant)).map(|v| (v, visitor)) + } + } + + struct VariantRefDeserializer<'a, E> + where E: de::Error + { + value: Option<&'a Content>, + err: PhantomData, + } + + impl<'de, 'a, E> de::VariantVisitor<'de> for VariantRefDeserializer<'a, E> + where E: de::Error + { + type Error = E; + + fn visit_unit(self) -> Result<(), E> { + match self.value { + Some(value) => de::Deserialize::deserialize(ContentRefDeserializer::new(value)), + None => Ok(()), + } + } + + fn visit_newtype_seed(self, seed: T) -> Result + where T: de::DeserializeSeed<'de> + { + match self.value { + Some(value) => seed.deserialize(ContentRefDeserializer::new(value)), + None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"newtype variant")), + } + } + + fn visit_tuple(self, _len: usize, visitor: V) -> Result + where V: de::Visitor<'de> + { + match self.value { + Some(&Content::Seq(ref v)) => { + de::Deserializer::deserialize(SeqRefDeserializer::new(v), visitor) + } + Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"tuple variant")), + None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"tuple variant")), + } + } + + fn visit_struct(self, + _fields: &'static [&'static str], + visitor: V) + -> Result + where V: de::Visitor<'de> + { + match self.value { + Some(&Content::Map(ref v)) => { + de::Deserializer::deserialize(MapRefDeserializer::new(v), visitor) + } + Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant")), + _ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant")), + } + } + } + + struct SeqRefDeserializer<'a, E> + where E: de::Error + { + iter: <&'a [Content] as IntoIterator>::IntoIter, + err: PhantomData, + } + + impl<'a, E> SeqRefDeserializer<'a, E> + where E: de::Error + { + fn new(vec: &'a [Content]) -> Self { + SeqRefDeserializer { + iter: vec.into_iter(), + err: PhantomData, + } + } + } + + impl<'de, 'a, E> de::Deserializer<'de> for SeqRefDeserializer<'a, E> + where E: de::Error + { + type Error = E; + + #[inline] + fn deserialize(mut self, visitor: V) -> Result + where V: de::Visitor<'de> + { + let len = self.iter.len(); + if len == 0 { + visitor.visit_unit() + } else { + let ret = try!(visitor.visit_seq(&mut self)); + let remaining = self.iter.len(); + if remaining == 0 { + Ok(ret) + } else { + Err(de::Error::invalid_length(len, &"fewer elements in array")) + } + } + } + + forward_to_deserialize! { + bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option + seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct + tuple_struct struct struct_field tuple enum ignored_any + } + } + + impl<'de, 'a, E> de::SeqVisitor<'de> for SeqRefDeserializer<'a, E> + where E: de::Error + { + type Error = E; + + fn visit_seed(&mut self, seed: T) -> Result, Self::Error> + where T: de::DeserializeSeed<'de> + { + match self.iter.next() { + Some(value) => seed.deserialize(ContentRefDeserializer::new(value)).map(Some), + None => Ok(None), + } + } + + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } + } + + struct MapRefDeserializer<'a, E> + where E: de::Error + { + iter: <&'a [(Content, Content)] as IntoIterator>::IntoIter, + value: Option<&'a Content>, + err: PhantomData, + } + + impl<'a, E> MapRefDeserializer<'a, E> + where E: de::Error + { + fn new(map: &'a [(Content, Content)]) -> Self { + MapRefDeserializer { + iter: map.into_iter(), + value: None, + err: PhantomData, + } + } + } + + impl<'de, 'a, E> de::MapVisitor<'de> for MapRefDeserializer<'a, E> + where E: de::Error + { + type Error = E; + + fn visit_key_seed(&mut self, seed: T) -> Result, Self::Error> + where T: de::DeserializeSeed<'de> + { + match self.iter.next() { + Some(&(ref key, ref value)) => { + self.value = Some(value); + seed.deserialize(ContentRefDeserializer::new(key)).map(Some) + } + None => Ok(None), + } + } + + fn visit_value_seed(&mut self, seed: T) -> Result + where T: de::DeserializeSeed<'de> + { + match self.value.take() { + Some(value) => seed.deserialize(ContentRefDeserializer::new(value)), + None => Err(de::Error::custom("value is missing")), + } + } + + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } + } + + impl<'de, 'a, E> de::Deserializer<'de> for MapRefDeserializer<'a, E> + where E: de::Error + { + type Error = E; + + #[inline] + fn deserialize(self, visitor: V) -> Result + where V: de::Visitor<'de> + { + visitor.visit_map(self) + } + + forward_to_deserialize! { + bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option + seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct + tuple_struct struct struct_field tuple enum ignored_any + } + } + + impl<'de, E> de::value::ValueDeserializer<'de, E> for ContentDeserializer + where E: de::Error + { + type Deserializer = Self; + + fn into_deserializer(self) -> Self { + self + } + } + + impl<'de, 'a, E> de::value::ValueDeserializer<'de, E> for ContentRefDeserializer<'a, E> + where E: de::Error + { + type Deserializer = Self; + + fn into_deserializer(self) -> Self { + self + } + } + + /// Visitor for deserializing an internally tagged unit variant. + /// + /// Not public API. + pub struct InternallyTaggedUnitVisitor<'a> { + type_name: &'a str, + variant_name: &'a str, + } + + impl<'a> InternallyTaggedUnitVisitor<'a> { + /// Not public API. + pub fn new(type_name: &'a str, variant_name: &'a str) -> Self { + InternallyTaggedUnitVisitor { + type_name: type_name, + variant_name: variant_name, + } + } + } + + impl<'de, 'a> Visitor<'de> for InternallyTaggedUnitVisitor<'a> { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "unit variant {}::{}", self.type_name, self.variant_name) + } + + fn visit_map(self, _: V) -> Result<(), V::Error> + where V: MapVisitor<'de> + { + Ok(()) + } + } + + /// Visitor for deserializing an untagged unit variant. + /// + /// Not public API. + pub struct UntaggedUnitVisitor<'a> { + type_name: &'a str, + variant_name: &'a str, + } + + impl<'a> UntaggedUnitVisitor<'a> { + /// Not public API. + pub fn new(type_name: &'a str, variant_name: &'a str) -> Self { + UntaggedUnitVisitor { + type_name: type_name, + variant_name: variant_name, + } + } + } + + impl<'de, 'a> Visitor<'de> for UntaggedUnitVisitor<'a> { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "unit variant {}::{}", self.type_name, self.variant_name) + } + + fn visit_unit(self) -> Result<(), E> + where E: de::Error + { + Ok(()) + } + } +} diff --git a/serde/src/private/macros.rs b/serde/src/private/macros.rs new file mode 100644 index 00000000..f8298a29 --- /dev/null +++ b/serde/src/private/macros.rs @@ -0,0 +1,126 @@ +#[doc(hidden)] +#[macro_export] +macro_rules! __serialize_unimplemented_method { + ($func:ident $(<$t:ident>)* ($($arg:ty),*) -> $ret:ident) => { + fn $func $(<$t: ?Sized + $crate::Serialize>)* (self $(, _: $arg)*) -> $crate::export::Result { + unimplemented!() + } + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __serialize_unimplemented_helper { + (bool) => { + __serialize_unimplemented_method!(serialize_bool(bool) -> Ok); + }; + (i8) => { + __serialize_unimplemented_method!(serialize_i8(i8) -> Ok); + }; + (i16) => { + __serialize_unimplemented_method!(serialize_i16(i16) -> Ok); + }; + (i32) => { + __serialize_unimplemented_method!(serialize_i32(i32) -> Ok); + }; + (i64) => { + __serialize_unimplemented_method!(serialize_i64(i64) -> Ok); + }; + (u8) => { + __serialize_unimplemented_method!(serialize_u8(u8) -> Ok); + }; + (u16) => { + __serialize_unimplemented_method!(serialize_u16(u16) -> Ok); + }; + (u32) => { + __serialize_unimplemented_method!(serialize_u32(u32) -> Ok); + }; + (u64) => { + __serialize_unimplemented_method!(serialize_u64(u64) -> Ok); + }; + (f32) => { + __serialize_unimplemented_method!(serialize_f32(f32) -> Ok); + }; + (f64) => { + __serialize_unimplemented_method!(serialize_f64(f64) -> Ok); + }; + (char) => { + __serialize_unimplemented_method!(serialize_char(char) -> Ok); + }; + (str) => { + __serialize_unimplemented_method!(serialize_str(&str) -> Ok); + }; + (bytes) => { + __serialize_unimplemented_method!(serialize_bytes(&[u8]) -> Ok); + }; + (none) => { + __serialize_unimplemented_method!(serialize_none() -> Ok); + }; + (some) => { + __serialize_unimplemented_method!(serialize_some(&T) -> Ok); + }; + (unit) => { + __serialize_unimplemented_method!(serialize_unit() -> Ok); + }; + (unit_struct) => { + __serialize_unimplemented_method!(serialize_unit_struct(&str) -> Ok); + }; + (unit_variant) => { + __serialize_unimplemented_method!(serialize_unit_variant(&str, usize, &str) -> Ok); + }; + (newtype_struct) => { + __serialize_unimplemented_method!(serialize_newtype_struct(&str, &T) -> Ok); + }; + (newtype_variant) => { + __serialize_unimplemented_method!(serialize_newtype_variant(&str, usize, &str, &T) -> Ok); + }; + (seq) => { + type SerializeSeq = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_seq(Option) -> SerializeSeq); + }; + (seq_fixed_size) => { + __serialize_unimplemented_method!(serialize_seq_fixed_size(usize) -> SerializeSeq); + }; + (tuple) => { + type SerializeTuple = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_tuple(usize) -> SerializeTuple); + }; + (tuple_struct) => { + type SerializeTupleStruct = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_tuple_struct(&str, usize) -> SerializeTupleStruct); + }; + (tuple_variant) => { + type SerializeTupleVariant = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_tuple_variant(&str, usize, &str, usize) -> SerializeTupleVariant); + }; + (map) => { + type SerializeMap = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_map(Option) -> SerializeMap); + }; + (struct) => { + type SerializeStruct = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_struct(&str, usize) -> SerializeStruct); + }; + (struct_variant) => { + type SerializeStructVariant = $crate::ser::Impossible; + __serialize_unimplemented_method!(serialize_struct_variant(&str, usize, &str, usize) -> SerializeStructVariant); + }; +} + +/// Used only by Serde doc tests. Not public API. +#[doc(hidden)] +#[macro_export] +macro_rules! __serialize_unimplemented { + ($($func:ident)*) => { + $( + __serialize_unimplemented_helper!($func); + )* + }; +} + +/// Used only by Serde doc tests. Not public API. +#[doc(hidden)] +#[macro_export] +macro_rules! __serde_ignore_tokens { + ($($tt:tt)+) => {} +} diff --git a/serde/src/private/mod.rs b/serde/src/private/mod.rs new file mode 100644 index 00000000..0d46e9cc --- /dev/null +++ b/serde/src/private/mod.rs @@ -0,0 +1,4 @@ +pub mod ser; +pub mod de; + +mod macros; diff --git a/serde/src/private/ser.rs b/serde/src/private/ser.rs new file mode 100644 index 00000000..c8d09d0b --- /dev/null +++ b/serde/src/private/ser.rs @@ -0,0 +1,944 @@ +use core::fmt::{self, Display}; + +use ser::{self, Serialize, Serializer, SerializeMap, SerializeStruct, Impossible}; + +#[cfg(any(feature = "std", feature = "collections"))] +use self::content::{SerializeTupleVariantAsMapValue, SerializeStructVariantAsMapValue}; + +#[cfg(feature = "std")] +use std::error; + +/// Not public API. +pub fn serialize_tagged_newtype(serializer: S, + type_ident: &'static str, + variant_ident: &'static str, + tag: &'static str, + variant_name: &'static str, + value: &T) + -> Result + where S: Serializer, + T: Serialize +{ + value.serialize(TaggedSerializer { + type_ident: type_ident, + variant_ident: variant_ident, + tag: tag, + variant_name: variant_name, + delegate: serializer, + }) +} + +struct TaggedSerializer { + type_ident: &'static str, + variant_ident: &'static str, + tag: &'static str, + variant_name: &'static str, + delegate: S, +} + +enum Unsupported { + Boolean, + Integer, + Float, + Char, + String, + ByteArray, + Optional, + Unit, + UnitStruct, + Sequence, + Tuple, + TupleStruct, + #[cfg(not(any(feature = "std", feature = "collections")))] + Enum, +} + +impl Display for Unsupported { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match *self { + Unsupported::Boolean => formatter.write_str("a boolean"), + Unsupported::Integer => formatter.write_str("an integer"), + Unsupported::Float => formatter.write_str("a float"), + Unsupported::Char => formatter.write_str("a char"), + Unsupported::String => formatter.write_str("a string"), + Unsupported::ByteArray => formatter.write_str("a byte array"), + Unsupported::Optional => formatter.write_str("an optional"), + Unsupported::Unit => formatter.write_str("unit"), + Unsupported::UnitStruct => formatter.write_str("a unit struct"), + Unsupported::Sequence => formatter.write_str("a sequence"), + Unsupported::Tuple => formatter.write_str("a tuple"), + Unsupported::TupleStruct => formatter.write_str("a tuple struct"), + #[cfg(not(any(feature = "std", feature = "collections")))] + Unsupported::Enum => formatter.write_str("an enum"), + } + } +} + +impl TaggedSerializer + where S: Serializer +{ + fn bad_type(self, what: Unsupported) -> S::Error { + ser::Error::custom(format_args!( + "cannot serialize tagged newtype variant {}::{} containing {}", + self.type_ident, + self.variant_ident, + what)) + } +} + +impl Serializer for TaggedSerializer + where S: Serializer +{ + type Ok = S::Ok; + type Error = S::Error; + + type SerializeSeq = Impossible; + type SerializeTuple = Impossible; + type SerializeTupleStruct = Impossible; + type SerializeMap = S::SerializeMap; + type SerializeStruct = S::SerializeStruct; + + #[cfg(not(any(feature = "std", feature = "collections")))] + type SerializeTupleVariant = Impossible; + #[cfg(any(feature = "std", feature = "collections"))] + type SerializeTupleVariant = SerializeTupleVariantAsMapValue; + + #[cfg(not(any(feature = "std", feature = "collections")))] + type SerializeStructVariant = Impossible; + #[cfg(any(feature = "std", feature = "collections"))] + type SerializeStructVariant = SerializeStructVariantAsMapValue; + + fn serialize_bool(self, _: bool) -> Result { + Err(self.bad_type(Unsupported::Boolean)) + } + + fn serialize_i8(self, _: i8) -> Result { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_i16(self, _: i16) -> Result { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_i32(self, _: i32) -> Result { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_i64(self, _: i64) -> Result { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_u8(self, _: u8) -> Result { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_u16(self, _: u16) -> Result { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_u32(self, _: u32) -> Result { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_u64(self, _: u64) -> Result { + Err(self.bad_type(Unsupported::Integer)) + } + + fn serialize_f32(self, _: f32) -> Result { + Err(self.bad_type(Unsupported::Float)) + } + + fn serialize_f64(self, _: f64) -> Result { + Err(self.bad_type(Unsupported::Float)) + } + + fn serialize_char(self, _: char) -> Result { + Err(self.bad_type(Unsupported::Char)) + } + + fn serialize_str(self, _: &str) -> Result { + Err(self.bad_type(Unsupported::String)) + } + + fn serialize_bytes(self, _: &[u8]) -> Result { + Err(self.bad_type(Unsupported::ByteArray)) + } + + fn serialize_none(self) -> Result { + Err(self.bad_type(Unsupported::Optional)) + } + + fn serialize_some(self, _: &T) -> Result + where T: Serialize + { + Err(self.bad_type(Unsupported::Optional)) + } + + fn serialize_unit(self) -> Result { + Err(self.bad_type(Unsupported::Unit)) + } + + fn serialize_unit_struct(self, _: &'static str) -> Result { + Err(self.bad_type(Unsupported::UnitStruct)) + } + + fn serialize_unit_variant(self, + _: &'static str, + _: usize, + inner_variant: &'static str) + -> Result { + let mut map = try!(self.delegate.serialize_map(Some(2))); + try!(map.serialize_entry(self.tag, self.variant_name)); + try!(map.serialize_entry(inner_variant, &())); + map.end() + } + + fn serialize_newtype_struct(self, + _: &'static str, + value: &T) + -> Result + where T: Serialize + { + value.serialize(self) + } + + fn serialize_newtype_variant(self, + _: &'static str, + _: usize, + inner_variant: &'static str, + inner_value: &T) + -> Result + where T: Serialize + { + let mut map = try!(self.delegate.serialize_map(Some(2))); + try!(map.serialize_entry(self.tag, self.variant_name)); + try!(map.serialize_entry(inner_variant, inner_value)); + map.end() + } + + fn serialize_seq(self, _: Option) -> Result { + Err(self.bad_type(Unsupported::Sequence)) + } + + fn serialize_seq_fixed_size(self, _: usize) -> Result { + Err(self.bad_type(Unsupported::Sequence)) + } + + fn serialize_tuple(self, _: usize) -> Result { + Err(self.bad_type(Unsupported::Tuple)) + } + + fn serialize_tuple_struct(self, + _: &'static str, + _: usize) + -> Result { + Err(self.bad_type(Unsupported::TupleStruct)) + } + + #[cfg(not(any(feature = "std", feature = "collections")))] + fn serialize_tuple_variant(self, + _: &'static str, + _: usize, + _: &'static str, + _: usize) + -> Result { + // Lack of push-based serialization means we need to buffer the content + // of the tuple variant, so it requires std. + Err(self.bad_type(Unsupported::Enum)) + } + + #[cfg(any(feature = "std", feature = "collections"))] + fn serialize_tuple_variant(self, + _: &'static str, + _: usize, + inner_variant: &'static str, + len: usize) + -> Result { + let mut map = try!(self.delegate.serialize_map(Some(2))); + try!(map.serialize_entry(self.tag, self.variant_name)); + try!(map.serialize_key(inner_variant)); + Ok(SerializeTupleVariantAsMapValue::new(map, inner_variant, len)) + } + + fn serialize_map(self, len: Option) -> Result { + let mut map = try!(self.delegate.serialize_map(len.map(|len| len + 1))); + try!(map.serialize_entry(self.tag, self.variant_name)); + Ok(map) + } + + fn serialize_struct(self, + name: &'static str, + len: usize) + -> Result { + let mut state = try!(self.delegate.serialize_struct(name, len + 1)); + try!(state.serialize_field(self.tag, self.variant_name)); + Ok(state) + } + + #[cfg(not(any(feature = "std", feature = "collections")))] + fn serialize_struct_variant(self, + _: &'static str, + _: usize, + _: &'static str, + _: usize) + -> Result { + // Lack of push-based serialization means we need to buffer the content + // of the struct variant, so it requires std. + Err(self.bad_type(Unsupported::Enum)) + } + + #[cfg(any(feature = "std", feature = "collections"))] + fn serialize_struct_variant(self, + _: &'static str, + _: usize, + inner_variant: &'static str, + len: usize) + -> Result { + let mut map = try!(self.delegate.serialize_map(Some(2))); + try!(map.serialize_entry(self.tag, self.variant_name)); + try!(map.serialize_key(inner_variant)); + Ok(SerializeStructVariantAsMapValue::new(map, inner_variant, len)) + } + + #[cfg(not(any(feature = "std", feature = "collections")))] + fn collect_str(self, _: &T) -> Result + where T: Display + { + Err(self.bad_type(Unsupported::String)) + } +} + +/// Used only by Serde doc tests. Not public API. +#[doc(hidden)] +#[derive(Debug)] +pub struct Error; + +impl ser::Error for Error { + fn custom(_: T) -> Self { + unimplemented!() + } +} + +#[cfg(feature = "std")] +impl error::Error for Error { + fn description(&self) -> &str { + unimplemented!() + } +} + +impl Display for Error { + fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { + unimplemented!() + } +} + +#[cfg(any(feature = "std", feature = "collections"))] +mod content { + use core::marker::PhantomData; + + #[cfg(all(not(feature = "std"), feature = "collections"))] + use collections::{String, Vec}; + + #[cfg(all(feature = "alloc", not(feature = "std")))] + use alloc::boxed::Box; + + #[cfg(feature = "collections")] + use collections::borrow::ToOwned; + + use ser::{self, Serialize, Serializer}; + + pub struct SerializeTupleVariantAsMapValue { + map: M, + name: &'static str, + fields: Vec, + } + + impl SerializeTupleVariantAsMapValue { + pub fn new(map: M, name: &'static str, len: usize) -> Self { + SerializeTupleVariantAsMapValue { + map: map, + name: name, + fields: Vec::with_capacity(len), + } + } + } + + impl ser::SerializeTupleVariant for SerializeTupleVariantAsMapValue + where M: ser::SerializeMap + { + type Ok = M::Ok; + type Error = M::Error; + + fn serialize_field(&mut self, value: &T) -> Result<(), M::Error> { + let value = try!(value.serialize(ContentSerializer::::new())); + self.fields.push(value); + Ok(()) + } + + fn end(mut self) -> Result { + try!(self.map.serialize_value(&Content::TupleStruct(self.name, self.fields))); + self.map.end() + } + } + + pub struct SerializeStructVariantAsMapValue { + map: M, + name: &'static str, + fields: Vec<(&'static str, Content)>, + } + + impl SerializeStructVariantAsMapValue { + pub fn new(map: M, name: &'static str, len: usize) -> Self { + SerializeStructVariantAsMapValue { + map: map, + name: name, + fields: Vec::with_capacity(len), + } + } + } + + impl ser::SerializeStructVariant for SerializeStructVariantAsMapValue + where M: ser::SerializeMap + { + type Ok = M::Ok; + type Error = M::Error; + + fn serialize_field(&mut self, + key: &'static str, + value: &T) + -> Result<(), M::Error> { + let value = try!(value.serialize(ContentSerializer::::new())); + self.fields.push((key, value)); + Ok(()) + } + + fn end(mut self) -> Result { + try!(self.map.serialize_value(&Content::Struct(self.name, self.fields))); + self.map.end() + } + } + + #[derive(Debug)] + enum Content { + Bool(bool), + + U8(u8), + U16(u16), + U32(u32), + U64(u64), + + I8(i8), + I16(i16), + I32(i32), + I64(i64), + + F32(f32), + F64(f64), + + Char(char), + String(String), + Bytes(Vec), + + None, + Some(Box), + + Unit, + UnitStruct(&'static str), + UnitVariant(&'static str, usize, &'static str), + NewtypeStruct(&'static str, Box), + NewtypeVariant(&'static str, usize, &'static str, Box), + + Seq(Vec), + SeqFixedSize(Vec), + Tuple(Vec), + TupleStruct(&'static str, Vec), + TupleVariant(&'static str, usize, &'static str, Vec), + Map(Vec<(Content, Content)>), + Struct(&'static str, Vec<(&'static str, Content)>), + StructVariant(&'static str, usize, &'static str, Vec<(&'static str, Content)>), + } + + impl Serialize for Content { + fn serialize(&self, serializer: S) -> Result + where S: Serializer + { + match *self { + Content::Bool(b) => serializer.serialize_bool(b), + Content::U8(u) => serializer.serialize_u8(u), + Content::U16(u) => serializer.serialize_u16(u), + Content::U32(u) => serializer.serialize_u32(u), + Content::U64(u) => serializer.serialize_u64(u), + Content::I8(i) => serializer.serialize_i8(i), + Content::I16(i) => serializer.serialize_i16(i), + Content::I32(i) => serializer.serialize_i32(i), + Content::I64(i) => serializer.serialize_i64(i), + Content::F32(f) => serializer.serialize_f32(f), + Content::F64(f) => serializer.serialize_f64(f), + Content::Char(c) => serializer.serialize_char(c), + Content::String(ref s) => serializer.serialize_str(s), + Content::Bytes(ref b) => serializer.serialize_bytes(b), + Content::None => serializer.serialize_none(), + Content::Some(ref c) => serializer.serialize_some(&**c), + Content::Unit => serializer.serialize_unit(), + Content::UnitStruct(n) => serializer.serialize_unit_struct(n), + Content::UnitVariant(n, i, v) => serializer.serialize_unit_variant(n, i, v), + Content::NewtypeStruct(n, ref c) => serializer.serialize_newtype_struct(n, &**c), + Content::NewtypeVariant(n, i, v, ref c) => { + serializer.serialize_newtype_variant(n, i, v, &**c) + } + Content::Seq(ref elements) => elements.serialize(serializer), + Content::SeqFixedSize(ref elements) => { + use ser::SerializeSeq; + let mut seq = try!(serializer.serialize_seq_fixed_size(elements.len())); + for e in elements { + try!(seq.serialize_element(e)); + } + seq.end() + } + Content::Tuple(ref elements) => { + use ser::SerializeTuple; + let mut tuple = try!(serializer.serialize_tuple(elements.len())); + for e in elements { + try!(tuple.serialize_element(e)); + } + tuple.end() + } + Content::TupleStruct(n, ref fields) => { + use ser::SerializeTupleStruct; + let mut ts = try!(serializer.serialize_tuple_struct(n, fields.len())); + for f in fields { + try!(ts.serialize_field(f)); + } + ts.end() + } + Content::TupleVariant(n, i, v, ref fields) => { + use ser::SerializeTupleVariant; + let mut tv = try!(serializer.serialize_tuple_variant(n, i, v, fields.len())); + for f in fields { + try!(tv.serialize_field(f)); + } + tv.end() + } + Content::Map(ref entries) => { + use ser::SerializeMap; + let mut map = try!(serializer.serialize_map(Some(entries.len()))); + for &(ref k, ref v) in entries { + try!(map.serialize_entry(k, v)); + } + map.end() + } + Content::Struct(n, ref fields) => { + use ser::SerializeStruct; + let mut s = try!(serializer.serialize_struct(n, fields.len())); + for &(k, ref v) in fields { + try!(s.serialize_field(k, v)); + } + s.end() + } + Content::StructVariant(n, i, v, ref fields) => { + use ser::SerializeStructVariant; + let mut sv = try!(serializer.serialize_struct_variant(n, i, v, fields.len())); + for &(k, ref v) in fields { + try!(sv.serialize_field(k, v)); + } + sv.end() + } + } + } + } + + struct ContentSerializer { + error: PhantomData, + } + + impl ContentSerializer { + fn new() -> Self { + ContentSerializer { error: PhantomData } + } + } + + impl Serializer for ContentSerializer + where E: ser::Error + { + type Ok = Content; + type Error = E; + + type SerializeSeq = SerializeSeq; + type SerializeTuple = SerializeTuple; + type SerializeTupleStruct = SerializeTupleStruct; + type SerializeTupleVariant = SerializeTupleVariant; + type SerializeMap = SerializeMap; + type SerializeStruct = SerializeStruct; + type SerializeStructVariant = SerializeStructVariant; + + fn serialize_bool(self, v: bool) -> Result { + Ok(Content::Bool(v)) + } + + fn serialize_i8(self, v: i8) -> Result { + Ok(Content::I8(v)) + } + + fn serialize_i16(self, v: i16) -> Result { + Ok(Content::I16(v)) + } + + fn serialize_i32(self, v: i32) -> Result { + Ok(Content::I32(v)) + } + + fn serialize_i64(self, v: i64) -> Result { + Ok(Content::I64(v)) + } + + fn serialize_u8(self, v: u8) -> Result { + Ok(Content::U8(v)) + } + + fn serialize_u16(self, v: u16) -> Result { + Ok(Content::U16(v)) + } + + fn serialize_u32(self, v: u32) -> Result { + Ok(Content::U32(v)) + } + + fn serialize_u64(self, v: u64) -> Result { + Ok(Content::U64(v)) + } + + fn serialize_f32(self, v: f32) -> Result { + Ok(Content::F32(v)) + } + + fn serialize_f64(self, v: f64) -> Result { + Ok(Content::F64(v)) + } + + fn serialize_char(self, v: char) -> Result { + Ok(Content::Char(v)) + } + + fn serialize_str(self, value: &str) -> Result { + Ok(Content::String(value.to_owned())) + } + + fn serialize_bytes(self, value: &[u8]) -> Result { + Ok(Content::Bytes(value.to_owned())) + } + + fn serialize_none(self) -> Result { + Ok(Content::None) + } + + fn serialize_some(self, value: &T) -> Result { + Ok(Content::Some(Box::new(try!(value.serialize(self))))) + } + + fn serialize_unit(self) -> Result { + Ok(Content::Unit) + } + + fn serialize_unit_struct(self, name: &'static str) -> Result { + Ok(Content::UnitStruct(name)) + } + + fn serialize_unit_variant(self, + name: &'static str, + variant_index: usize, + variant: &'static str) + -> Result { + Ok(Content::UnitVariant(name, variant_index, variant)) + } + + fn serialize_newtype_struct(self, + name: &'static str, + value: &T) + -> Result { + Ok(Content::NewtypeStruct(name, Box::new(try!(value.serialize(self))))) + } + + fn serialize_newtype_variant(self, + name: &'static str, + variant_index: usize, + variant: &'static str, + value: &T) + -> Result { + Ok(Content::NewtypeVariant(name, + variant_index, + variant, + Box::new(try!(value.serialize(self))))) + } + + fn serialize_seq(self, len: Option) -> Result { + Ok(SerializeSeq { + fixed_size: false, + elements: Vec::with_capacity(len.unwrap_or(0)), + error: PhantomData, + }) + } + + fn serialize_seq_fixed_size(self, size: usize) -> Result { + Ok(SerializeSeq { + fixed_size: true, + elements: Vec::with_capacity(size), + error: PhantomData, + }) + } + + fn serialize_tuple(self, len: usize) -> Result { + Ok(SerializeTuple { + elements: Vec::with_capacity(len), + error: PhantomData, + }) + } + + fn serialize_tuple_struct(self, + name: &'static str, + len: usize) + -> Result { + Ok(SerializeTupleStruct { + name: name, + fields: Vec::with_capacity(len), + error: PhantomData, + }) + } + + fn serialize_tuple_variant(self, + name: &'static str, + variant_index: usize, + variant: &'static str, + len: usize) + -> Result { + Ok(SerializeTupleVariant { + name: name, + variant_index: variant_index, + variant: variant, + fields: Vec::with_capacity(len), + error: PhantomData, + }) + } + + fn serialize_map(self, len: Option) -> Result { + Ok(SerializeMap { + entries: Vec::with_capacity(len.unwrap_or(0)), + key: None, + error: PhantomData, + }) + } + + fn serialize_struct(self, name: &'static str, len: usize) -> Result { + Ok(SerializeStruct { + name: name, + fields: Vec::with_capacity(len), + error: PhantomData, + }) + } + + fn serialize_struct_variant(self, + name: &'static str, + variant_index: usize, + variant: &'static str, + len: usize) + -> Result { + Ok(SerializeStructVariant { + name: name, + variant_index: variant_index, + variant: variant, + fields: Vec::with_capacity(len), + error: PhantomData, + }) + } + } + + struct SerializeSeq { + fixed_size: bool, + elements: Vec, + error: PhantomData, + } + + impl ser::SerializeSeq for SerializeSeq + where E: ser::Error + { + type Ok = Content; + type Error = E; + + fn serialize_element(&mut self, value: &T) -> Result<(), E> { + let value = try!(value.serialize(ContentSerializer::::new())); + self.elements.push(value); + Ok(()) + } + + fn end(self) -> Result { + Ok(if self.fixed_size { + Content::SeqFixedSize(self.elements) + } else { + Content::Seq(self.elements) + }) + } + } + + struct SerializeTuple { + elements: Vec, + error: PhantomData, + } + + impl ser::SerializeTuple for SerializeTuple + where E: ser::Error + { + type Ok = Content; + type Error = E; + + fn serialize_element(&mut self, value: &T) -> Result<(), E> { + let value = try!(value.serialize(ContentSerializer::::new())); + self.elements.push(value); + Ok(()) + } + + fn end(self) -> Result { + Ok(Content::Tuple(self.elements)) + } + } + + struct SerializeTupleStruct { + name: &'static str, + fields: Vec, + error: PhantomData, + } + + impl ser::SerializeTupleStruct for SerializeTupleStruct + where E: ser::Error + { + type Ok = Content; + type Error = E; + + fn serialize_field(&mut self, value: &T) -> Result<(), E> { + let value = try!(value.serialize(ContentSerializer::::new())); + self.fields.push(value); + Ok(()) + } + + fn end(self) -> Result { + Ok(Content::TupleStruct(self.name, self.fields)) + } + } + + struct SerializeTupleVariant { + name: &'static str, + variant_index: usize, + variant: &'static str, + fields: Vec, + error: PhantomData, + } + + impl ser::SerializeTupleVariant for SerializeTupleVariant + where E: ser::Error + { + type Ok = Content; + type Error = E; + + fn serialize_field(&mut self, value: &T) -> Result<(), E> { + let value = try!(value.serialize(ContentSerializer::::new())); + self.fields.push(value); + Ok(()) + } + + fn end(self) -> Result { + Ok(Content::TupleVariant(self.name, self.variant_index, self.variant, self.fields)) + } + } + + struct SerializeMap { + entries: Vec<(Content, Content)>, + key: Option, + error: PhantomData, + } + + impl ser::SerializeMap for SerializeMap + where E: ser::Error + { + type Ok = Content; + type Error = E; + + fn serialize_key(&mut self, key: &T) -> Result<(), E> { + let key = try!(key.serialize(ContentSerializer::::new())); + self.key = Some(key); + Ok(()) + } + + fn serialize_value(&mut self, value: &T) -> Result<(), E> { + let key = self.key.take().expect("serialize_value called before serialize_key"); + let value = try!(value.serialize(ContentSerializer::::new())); + self.entries.push((key, value)); + Ok(()) + } + + fn end(self) -> Result { + Ok(Content::Map(self.entries)) + } + + fn serialize_entry(&mut self, + key: &K, + value: &V) + -> Result<(), E> { + let key = try!(key.serialize(ContentSerializer::::new())); + let value = try!(value.serialize(ContentSerializer::::new())); + self.entries.push((key, value)); + Ok(()) + } + } + + struct SerializeStruct { + name: &'static str, + fields: Vec<(&'static str, Content)>, + error: PhantomData, + } + + impl ser::SerializeStruct for SerializeStruct + where E: ser::Error + { + type Ok = Content; + type Error = E; + + fn serialize_field(&mut self, + key: &'static str, + value: &T) + -> Result<(), E> { + let value = try!(value.serialize(ContentSerializer::::new())); + self.fields.push((key, value)); + Ok(()) + } + + fn end(self) -> Result { + Ok(Content::Struct(self.name, self.fields)) + } + } + + struct SerializeStructVariant { + name: &'static str, + variant_index: usize, + variant: &'static str, + fields: Vec<(&'static str, Content)>, + error: PhantomData, + } + + impl ser::SerializeStructVariant for SerializeStructVariant + where E: ser::Error + { + type Ok = Content; + type Error = E; + + fn serialize_field(&mut self, + key: &'static str, + value: &T) + -> Result<(), E> { + let value = try!(value.serialize(ContentSerializer::::new())); + self.fields.push((key, value)); + Ok(()) + } + + fn end(self) -> Result { + Ok(Content::StructVariant(self.name, self.variant_index, self.variant, self.fields)) + } + } +} diff --git a/serde/src/ser/content.rs b/serde/src/ser/content.rs deleted file mode 100644 index 75482b02..00000000 --- a/serde/src/ser/content.rs +++ /dev/null @@ -1,607 +0,0 @@ -use core::marker::PhantomData; - -#[cfg(all(not(feature = "std"), feature = "collections"))] -use collections::{String, Vec}; - -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::boxed::Box; - -#[cfg(feature = "collections")] -use collections::borrow::ToOwned; - -use ser::{self, Serialize, Serializer}; - -pub struct SerializeTupleVariantAsMapValue { - map: M, - name: &'static str, - fields: Vec, -} - -impl SerializeTupleVariantAsMapValue { - pub fn new(map: M, name: &'static str, len: usize) -> Self { - SerializeTupleVariantAsMapValue { - map: map, - name: name, - fields: Vec::with_capacity(len), - } - } -} - -impl ser::SerializeTupleVariant for SerializeTupleVariantAsMapValue - where M: ser::SerializeMap -{ - type Ok = M::Ok; - type Error = M::Error; - - fn serialize_field(&mut self, value: &T) -> Result<(), M::Error> { - let value = try!(value.serialize(ContentSerializer::::new())); - self.fields.push(value); - Ok(()) - } - - fn end(mut self) -> Result { - try!(self.map.serialize_value(&Content::TupleStruct(self.name, self.fields))); - self.map.end() - } -} - -pub struct SerializeStructVariantAsMapValue { - map: M, - name: &'static str, - fields: Vec<(&'static str, Content)>, -} - -impl SerializeStructVariantAsMapValue { - pub fn new(map: M, name: &'static str, len: usize) -> Self { - SerializeStructVariantAsMapValue { - map: map, - name: name, - fields: Vec::with_capacity(len), - } - } -} - -impl ser::SerializeStructVariant for SerializeStructVariantAsMapValue - where M: ser::SerializeMap -{ - type Ok = M::Ok; - type Error = M::Error; - - fn serialize_field(&mut self, - key: &'static str, - value: &T) - -> Result<(), M::Error> { - let value = try!(value.serialize(ContentSerializer::::new())); - self.fields.push((key, value)); - Ok(()) - } - - fn end(mut self) -> Result { - try!(self.map.serialize_value(&Content::Struct(self.name, self.fields))); - self.map.end() - } -} - -#[derive(Debug)] -enum Content { - Bool(bool), - - U8(u8), - U16(u16), - U32(u32), - U64(u64), - - I8(i8), - I16(i16), - I32(i32), - I64(i64), - - F32(f32), - F64(f64), - - Char(char), - String(String), - Bytes(Vec), - - None, - Some(Box), - - Unit, - UnitStruct(&'static str), - UnitVariant(&'static str, usize, &'static str), - NewtypeStruct(&'static str, Box), - NewtypeVariant(&'static str, usize, &'static str, Box), - - Seq(Vec), - SeqFixedSize(Vec), - Tuple(Vec), - TupleStruct(&'static str, Vec), - TupleVariant(&'static str, usize, &'static str, Vec), - Map(Vec<(Content, Content)>), - Struct(&'static str, Vec<(&'static str, Content)>), - StructVariant(&'static str, usize, &'static str, Vec<(&'static str, Content)>), -} - -impl Serialize for Content { - fn serialize(&self, serializer: S) -> Result - where S: Serializer - { - match *self { - Content::Bool(b) => serializer.serialize_bool(b), - Content::U8(u) => serializer.serialize_u8(u), - Content::U16(u) => serializer.serialize_u16(u), - Content::U32(u) => serializer.serialize_u32(u), - Content::U64(u) => serializer.serialize_u64(u), - Content::I8(i) => serializer.serialize_i8(i), - Content::I16(i) => serializer.serialize_i16(i), - Content::I32(i) => serializer.serialize_i32(i), - Content::I64(i) => serializer.serialize_i64(i), - Content::F32(f) => serializer.serialize_f32(f), - Content::F64(f) => serializer.serialize_f64(f), - Content::Char(c) => serializer.serialize_char(c), - Content::String(ref s) => serializer.serialize_str(s), - Content::Bytes(ref b) => serializer.serialize_bytes(b), - Content::None => serializer.serialize_none(), - Content::Some(ref c) => serializer.serialize_some(&**c), - Content::Unit => serializer.serialize_unit(), - Content::UnitStruct(n) => serializer.serialize_unit_struct(n), - Content::UnitVariant(n, i, v) => serializer.serialize_unit_variant(n, i, v), - Content::NewtypeStruct(n, ref c) => serializer.serialize_newtype_struct(n, &**c), - Content::NewtypeVariant(n, i, v, ref c) => { - serializer.serialize_newtype_variant(n, i, v, &**c) - } - Content::Seq(ref elements) => elements.serialize(serializer), - Content::SeqFixedSize(ref elements) => { - use ser::SerializeSeq; - let mut seq = try!(serializer.serialize_seq_fixed_size(elements.len())); - for e in elements { - try!(seq.serialize_element(e)); - } - seq.end() - } - Content::Tuple(ref elements) => { - use ser::SerializeTuple; - let mut tuple = try!(serializer.serialize_tuple(elements.len())); - for e in elements { - try!(tuple.serialize_element(e)); - } - tuple.end() - } - Content::TupleStruct(n, ref fields) => { - use ser::SerializeTupleStruct; - let mut ts = try!(serializer.serialize_tuple_struct(n, fields.len())); - for f in fields { - try!(ts.serialize_field(f)); - } - ts.end() - } - Content::TupleVariant(n, i, v, ref fields) => { - use ser::SerializeTupleVariant; - let mut tv = try!(serializer.serialize_tuple_variant(n, i, v, fields.len())); - for f in fields { - try!(tv.serialize_field(f)); - } - tv.end() - } - Content::Map(ref entries) => { - use ser::SerializeMap; - let mut map = try!(serializer.serialize_map(Some(entries.len()))); - for &(ref k, ref v) in entries { - try!(map.serialize_entry(k, v)); - } - map.end() - } - Content::Struct(n, ref fields) => { - use ser::SerializeStruct; - let mut s = try!(serializer.serialize_struct(n, fields.len())); - for &(k, ref v) in fields { - try!(s.serialize_field(k, v)); - } - s.end() - } - Content::StructVariant(n, i, v, ref fields) => { - use ser::SerializeStructVariant; - let mut sv = try!(serializer.serialize_struct_variant(n, i, v, fields.len())); - for &(k, ref v) in fields { - try!(sv.serialize_field(k, v)); - } - sv.end() - } - } - } -} - -struct ContentSerializer { - error: PhantomData, -} - -impl ContentSerializer { - fn new() -> Self { - ContentSerializer { error: PhantomData } - } -} - -impl Serializer for ContentSerializer - where E: ser::Error -{ - type Ok = Content; - type Error = E; - - type SerializeSeq = SerializeSeq; - type SerializeTuple = SerializeTuple; - type SerializeTupleStruct = SerializeTupleStruct; - type SerializeTupleVariant = SerializeTupleVariant; - type SerializeMap = SerializeMap; - type SerializeStruct = SerializeStruct; - type SerializeStructVariant = SerializeStructVariant; - - fn serialize_bool(self, v: bool) -> Result { - Ok(Content::Bool(v)) - } - - fn serialize_i8(self, v: i8) -> Result { - Ok(Content::I8(v)) - } - - fn serialize_i16(self, v: i16) -> Result { - Ok(Content::I16(v)) - } - - fn serialize_i32(self, v: i32) -> Result { - Ok(Content::I32(v)) - } - - fn serialize_i64(self, v: i64) -> Result { - Ok(Content::I64(v)) - } - - fn serialize_u8(self, v: u8) -> Result { - Ok(Content::U8(v)) - } - - fn serialize_u16(self, v: u16) -> Result { - Ok(Content::U16(v)) - } - - fn serialize_u32(self, v: u32) -> Result { - Ok(Content::U32(v)) - } - - fn serialize_u64(self, v: u64) -> Result { - Ok(Content::U64(v)) - } - - fn serialize_f32(self, v: f32) -> Result { - Ok(Content::F32(v)) - } - - fn serialize_f64(self, v: f64) -> Result { - Ok(Content::F64(v)) - } - - fn serialize_char(self, v: char) -> Result { - Ok(Content::Char(v)) - } - - fn serialize_str(self, value: &str) -> Result { - Ok(Content::String(value.to_owned())) - } - - fn serialize_bytes(self, value: &[u8]) -> Result { - Ok(Content::Bytes(value.to_owned())) - } - - fn serialize_none(self) -> Result { - Ok(Content::None) - } - - fn serialize_some(self, value: &T) -> Result { - Ok(Content::Some(Box::new(try!(value.serialize(self))))) - } - - fn serialize_unit(self) -> Result { - Ok(Content::Unit) - } - - fn serialize_unit_struct(self, name: &'static str) -> Result { - Ok(Content::UnitStruct(name)) - } - - fn serialize_unit_variant(self, - name: &'static str, - variant_index: usize, - variant: &'static str) - -> Result { - Ok(Content::UnitVariant(name, variant_index, variant)) - } - - fn serialize_newtype_struct(self, - name: &'static str, - value: &T) - -> Result { - Ok(Content::NewtypeStruct(name, Box::new(try!(value.serialize(self))))) - } - - fn serialize_newtype_variant(self, - name: &'static str, - variant_index: usize, - variant: &'static str, - value: &T) - -> Result { - Ok(Content::NewtypeVariant(name, - variant_index, - variant, - Box::new(try!(value.serialize(self))))) - } - - fn serialize_seq(self, len: Option) -> Result { - Ok(SerializeSeq { - fixed_size: false, - elements: Vec::with_capacity(len.unwrap_or(0)), - error: PhantomData, - }) - } - - fn serialize_seq_fixed_size(self, size: usize) -> Result { - Ok(SerializeSeq { - fixed_size: true, - elements: Vec::with_capacity(size), - error: PhantomData, - }) - } - - fn serialize_tuple(self, len: usize) -> Result { - Ok(SerializeTuple { - elements: Vec::with_capacity(len), - error: PhantomData, - }) - } - - fn serialize_tuple_struct(self, - name: &'static str, - len: usize) - -> Result { - Ok(SerializeTupleStruct { - name: name, - fields: Vec::with_capacity(len), - error: PhantomData, - }) - } - - fn serialize_tuple_variant(self, - name: &'static str, - variant_index: usize, - variant: &'static str, - len: usize) - -> Result { - Ok(SerializeTupleVariant { - name: name, - variant_index: variant_index, - variant: variant, - fields: Vec::with_capacity(len), - error: PhantomData, - }) - } - - fn serialize_map(self, len: Option) -> Result { - Ok(SerializeMap { - entries: Vec::with_capacity(len.unwrap_or(0)), - key: None, - error: PhantomData, - }) - } - - fn serialize_struct(self, name: &'static str, len: usize) -> Result { - Ok(SerializeStruct { - name: name, - fields: Vec::with_capacity(len), - error: PhantomData, - }) - } - - fn serialize_struct_variant(self, - name: &'static str, - variant_index: usize, - variant: &'static str, - len: usize) - -> Result { - Ok(SerializeStructVariant { - name: name, - variant_index: variant_index, - variant: variant, - fields: Vec::with_capacity(len), - error: PhantomData, - }) - } -} - -struct SerializeSeq { - fixed_size: bool, - elements: Vec, - error: PhantomData, -} - -impl ser::SerializeSeq for SerializeSeq - where E: ser::Error -{ - type Ok = Content; - type Error = E; - - fn serialize_element(&mut self, value: &T) -> Result<(), E> { - let value = try!(value.serialize(ContentSerializer::::new())); - self.elements.push(value); - Ok(()) - } - - fn end(self) -> Result { - Ok(if self.fixed_size { - Content::SeqFixedSize(self.elements) - } else { - Content::Seq(self.elements) - }) - } -} - -struct SerializeTuple { - elements: Vec, - error: PhantomData, -} - -impl ser::SerializeTuple for SerializeTuple - where E: ser::Error -{ - type Ok = Content; - type Error = E; - - fn serialize_element(&mut self, value: &T) -> Result<(), E> { - let value = try!(value.serialize(ContentSerializer::::new())); - self.elements.push(value); - Ok(()) - } - - fn end(self) -> Result { - Ok(Content::Tuple(self.elements)) - } -} - -struct SerializeTupleStruct { - name: &'static str, - fields: Vec, - error: PhantomData, -} - -impl ser::SerializeTupleStruct for SerializeTupleStruct - where E: ser::Error -{ - type Ok = Content; - type Error = E; - - fn serialize_field(&mut self, value: &T) -> Result<(), E> { - let value = try!(value.serialize(ContentSerializer::::new())); - self.fields.push(value); - Ok(()) - } - - fn end(self) -> Result { - Ok(Content::TupleStruct(self.name, self.fields)) - } -} - -struct SerializeTupleVariant { - name: &'static str, - variant_index: usize, - variant: &'static str, - fields: Vec, - error: PhantomData, -} - -impl ser::SerializeTupleVariant for SerializeTupleVariant - where E: ser::Error -{ - type Ok = Content; - type Error = E; - - fn serialize_field(&mut self, value: &T) -> Result<(), E> { - let value = try!(value.serialize(ContentSerializer::::new())); - self.fields.push(value); - Ok(()) - } - - fn end(self) -> Result { - Ok(Content::TupleVariant(self.name, self.variant_index, self.variant, self.fields)) - } -} - -struct SerializeMap { - entries: Vec<(Content, Content)>, - key: Option, - error: PhantomData, -} - -impl ser::SerializeMap for SerializeMap - where E: ser::Error -{ - type Ok = Content; - type Error = E; - - fn serialize_key(&mut self, key: &T) -> Result<(), E> { - let key = try!(key.serialize(ContentSerializer::::new())); - self.key = Some(key); - Ok(()) - } - - fn serialize_value(&mut self, value: &T) -> Result<(), E> { - let key = self.key.take().expect("serialize_value called before serialize_key"); - let value = try!(value.serialize(ContentSerializer::::new())); - self.entries.push((key, value)); - Ok(()) - } - - fn end(self) -> Result { - Ok(Content::Map(self.entries)) - } - - fn serialize_entry(&mut self, - key: &K, - value: &V) - -> Result<(), E> { - let key = try!(key.serialize(ContentSerializer::::new())); - let value = try!(value.serialize(ContentSerializer::::new())); - self.entries.push((key, value)); - Ok(()) - } -} - -struct SerializeStruct { - name: &'static str, - fields: Vec<(&'static str, Content)>, - error: PhantomData, -} - -impl ser::SerializeStruct for SerializeStruct - where E: ser::Error -{ - type Ok = Content; - type Error = E; - - fn serialize_field(&mut self, - key: &'static str, - value: &T) - -> Result<(), E> { - let value = try!(value.serialize(ContentSerializer::::new())); - self.fields.push((key, value)); - Ok(()) - } - - fn end(self) -> Result { - Ok(Content::Struct(self.name, self.fields)) - } -} - -struct SerializeStructVariant { - name: &'static str, - variant_index: usize, - variant: &'static str, - fields: Vec<(&'static str, Content)>, - error: PhantomData, -} - -impl ser::SerializeStructVariant for SerializeStructVariant - where E: ser::Error -{ - type Ok = Content; - type Error = E; - - fn serialize_field(&mut self, - key: &'static str, - value: &T) - -> Result<(), E> { - let value = try!(value.serialize(ContentSerializer::::new())); - self.fields.push((key, value)); - Ok(()) - } - - fn end(self) -> Result { - Ok(Content::StructVariant(self.name, self.variant_index, self.variant, self.fields)) - } -} diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 6cfa32a9..d0a74b97 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -626,6 +626,37 @@ impl Serialize for Duration { /////////////////////////////////////////////////////////////////////////////// +/// Seralize the `$value` that implements Display as a string, +/// when that string is statically known to never have more than +/// a constant `$MAX_LEN` bytes. +/// +/// Panics if the Display impl tries to write more than `$MAX_LEN` bytes. +#[cfg(feature = "std")] +macro_rules! serialize_display_bounded_length { + ($value: expr, $MAX_LEN: expr, $serializer: expr) => { + { + use std::io::Write; + let mut buffer: [u8; $MAX_LEN] = unsafe { ::std::mem::uninitialized() }; + let remaining_len; + { + let mut remaining = &mut buffer[..]; + write!(remaining, "{}", $value).unwrap(); + remaining_len = remaining.len() + } + let written_len = buffer.len() - remaining_len; + let written = &buffer[..written_len]; + + // write! only provides std::fmt::Formatter to Display implementations, + // which has methods write_str and write_char but no method to write arbitrary bytes. + // Therefore, `written` is well-formed in UTF-8. + let written_str = unsafe { + ::std::str::from_utf8_unchecked(written) + }; + $serializer.serialize_str(written_str) + } + } +} + #[cfg(feature = "std")] impl Serialize for net::IpAddr { fn serialize(&self, serializer: S) -> Result diff --git a/serde/src/ser/impossible.rs b/serde/src/ser/impossible.rs index 82755d72..7f08a0db 100644 --- a/serde/src/ser/impossible.rs +++ b/serde/src/ser/impossible.rs @@ -18,7 +18,7 @@ use ser::{self, Serialize, SerializeSeq, SerializeTuple, SerializeTupleStruct, /// # extern crate serde; /// # /// # use serde::ser::{Serializer, Impossible}; -/// # use serde::ser::private::Error; +/// # use serde::private::ser::Error; /// # /// # struct MySerializer; /// # diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index eeac1761..831fa1c6 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -107,12 +107,6 @@ use core::iter::IntoIterator; mod impls; mod impossible; -// Helpers used by generated code. Not public API. -#[doc(hidden)] -pub mod private; -#[cfg(any(feature = "std", feature = "collections"))] -mod content; - pub use self::impossible::Impossible; /////////////////////////////////////////////////////////////////////////////// @@ -379,7 +373,7 @@ pub trait Serializer: Sized { /// # extern crate serde; /// # /// # use serde::ser::{Serializer, SerializeSeq}; - /// # use serde::ser::private::Error; + /// # use serde::private::ser::Error; /// # /// # struct MySerializer; /// # diff --git a/serde/src/ser/private.rs b/serde/src/ser/private.rs deleted file mode 100644 index 5d1f723f..00000000 --- a/serde/src/ser/private.rs +++ /dev/null @@ -1,333 +0,0 @@ -use core::fmt::{self, Display}; - -use ser::{self, Serialize, Serializer, SerializeMap, SerializeStruct, Impossible}; - -#[cfg(any(feature = "std", feature = "collections"))] -use ser::content::{SerializeTupleVariantAsMapValue, SerializeStructVariantAsMapValue}; - -#[cfg(feature = "std")] -use std::error; - -/// Not public API. -pub fn serialize_tagged_newtype(serializer: S, - type_ident: &'static str, - variant_ident: &'static str, - tag: &'static str, - variant_name: &'static str, - value: &T) - -> Result - where S: Serializer, - T: Serialize -{ - value.serialize(TaggedSerializer { - type_ident: type_ident, - variant_ident: variant_ident, - tag: tag, - variant_name: variant_name, - delegate: serializer, - }) -} - -struct TaggedSerializer { - type_ident: &'static str, - variant_ident: &'static str, - tag: &'static str, - variant_name: &'static str, - delegate: S, -} - -enum Unsupported { - Boolean, - Integer, - Float, - Char, - String, - ByteArray, - Optional, - Unit, - UnitStruct, - Sequence, - Tuple, - TupleStruct, - #[cfg(not(any(feature = "std", feature = "collections")))] - Enum, -} - -impl Display for Unsupported { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - match *self { - Unsupported::Boolean => formatter.write_str("a boolean"), - Unsupported::Integer => formatter.write_str("an integer"), - Unsupported::Float => formatter.write_str("a float"), - Unsupported::Char => formatter.write_str("a char"), - Unsupported::String => formatter.write_str("a string"), - Unsupported::ByteArray => formatter.write_str("a byte array"), - Unsupported::Optional => formatter.write_str("an optional"), - Unsupported::Unit => formatter.write_str("unit"), - Unsupported::UnitStruct => formatter.write_str("a unit struct"), - Unsupported::Sequence => formatter.write_str("a sequence"), - Unsupported::Tuple => formatter.write_str("a tuple"), - Unsupported::TupleStruct => formatter.write_str("a tuple struct"), - #[cfg(not(any(feature = "std", feature = "collections")))] - Unsupported::Enum => formatter.write_str("an enum"), - } - } -} - -impl TaggedSerializer - where S: Serializer -{ - fn bad_type(self, what: Unsupported) -> S::Error { - ser::Error::custom(format_args!( - "cannot serialize tagged newtype variant {}::{} containing {}", - self.type_ident, - self.variant_ident, - what)) - } -} - -impl Serializer for TaggedSerializer - where S: Serializer -{ - type Ok = S::Ok; - type Error = S::Error; - - type SerializeSeq = Impossible; - type SerializeTuple = Impossible; - type SerializeTupleStruct = Impossible; - type SerializeMap = S::SerializeMap; - type SerializeStruct = S::SerializeStruct; - - #[cfg(not(any(feature = "std", feature = "collections")))] - type SerializeTupleVariant = Impossible; - #[cfg(any(feature = "std", feature = "collections"))] - type SerializeTupleVariant = SerializeTupleVariantAsMapValue; - - #[cfg(not(any(feature = "std", feature = "collections")))] - type SerializeStructVariant = Impossible; - #[cfg(any(feature = "std", feature = "collections"))] - type SerializeStructVariant = SerializeStructVariantAsMapValue; - - fn serialize_bool(self, _: bool) -> Result { - Err(self.bad_type(Unsupported::Boolean)) - } - - fn serialize_i8(self, _: i8) -> Result { - Err(self.bad_type(Unsupported::Integer)) - } - - fn serialize_i16(self, _: i16) -> Result { - Err(self.bad_type(Unsupported::Integer)) - } - - fn serialize_i32(self, _: i32) -> Result { - Err(self.bad_type(Unsupported::Integer)) - } - - fn serialize_i64(self, _: i64) -> Result { - Err(self.bad_type(Unsupported::Integer)) - } - - fn serialize_u8(self, _: u8) -> Result { - Err(self.bad_type(Unsupported::Integer)) - } - - fn serialize_u16(self, _: u16) -> Result { - Err(self.bad_type(Unsupported::Integer)) - } - - fn serialize_u32(self, _: u32) -> Result { - Err(self.bad_type(Unsupported::Integer)) - } - - fn serialize_u64(self, _: u64) -> Result { - Err(self.bad_type(Unsupported::Integer)) - } - - fn serialize_f32(self, _: f32) -> Result { - Err(self.bad_type(Unsupported::Float)) - } - - fn serialize_f64(self, _: f64) -> Result { - Err(self.bad_type(Unsupported::Float)) - } - - fn serialize_char(self, _: char) -> Result { - Err(self.bad_type(Unsupported::Char)) - } - - fn serialize_str(self, _: &str) -> Result { - Err(self.bad_type(Unsupported::String)) - } - - fn serialize_bytes(self, _: &[u8]) -> Result { - Err(self.bad_type(Unsupported::ByteArray)) - } - - fn serialize_none(self) -> Result { - Err(self.bad_type(Unsupported::Optional)) - } - - fn serialize_some(self, _: &T) -> Result - where T: Serialize - { - Err(self.bad_type(Unsupported::Optional)) - } - - fn serialize_unit(self) -> Result { - Err(self.bad_type(Unsupported::Unit)) - } - - fn serialize_unit_struct(self, _: &'static str) -> Result { - Err(self.bad_type(Unsupported::UnitStruct)) - } - - fn serialize_unit_variant(self, - _: &'static str, - _: usize, - inner_variant: &'static str) - -> Result { - let mut map = try!(self.delegate.serialize_map(Some(2))); - try!(map.serialize_entry(self.tag, self.variant_name)); - try!(map.serialize_entry(inner_variant, &())); - map.end() - } - - fn serialize_newtype_struct(self, - _: &'static str, - value: &T) - -> Result - where T: Serialize - { - value.serialize(self) - } - - fn serialize_newtype_variant(self, - _: &'static str, - _: usize, - inner_variant: &'static str, - inner_value: &T) - -> Result - where T: Serialize - { - let mut map = try!(self.delegate.serialize_map(Some(2))); - try!(map.serialize_entry(self.tag, self.variant_name)); - try!(map.serialize_entry(inner_variant, inner_value)); - map.end() - } - - fn serialize_seq(self, _: Option) -> Result { - Err(self.bad_type(Unsupported::Sequence)) - } - - fn serialize_seq_fixed_size(self, _: usize) -> Result { - Err(self.bad_type(Unsupported::Sequence)) - } - - fn serialize_tuple(self, _: usize) -> Result { - Err(self.bad_type(Unsupported::Tuple)) - } - - fn serialize_tuple_struct(self, - _: &'static str, - _: usize) - -> Result { - Err(self.bad_type(Unsupported::TupleStruct)) - } - - #[cfg(not(any(feature = "std", feature = "collections")))] - fn serialize_tuple_variant(self, - _: &'static str, - _: usize, - _: &'static str, - _: usize) - -> Result { - // Lack of push-based serialization means we need to buffer the content - // of the tuple variant, so it requires std. - Err(self.bad_type(Unsupported::Enum)) - } - - #[cfg(any(feature = "std", feature = "collections"))] - fn serialize_tuple_variant(self, - _: &'static str, - _: usize, - inner_variant: &'static str, - len: usize) - -> Result { - let mut map = try!(self.delegate.serialize_map(Some(2))); - try!(map.serialize_entry(self.tag, self.variant_name)); - try!(map.serialize_key(inner_variant)); - Ok(SerializeTupleVariantAsMapValue::new(map, inner_variant, len)) - } - - fn serialize_map(self, len: Option) -> Result { - let mut map = try!(self.delegate.serialize_map(len.map(|len| len + 1))); - try!(map.serialize_entry(self.tag, self.variant_name)); - Ok(map) - } - - fn serialize_struct(self, - name: &'static str, - len: usize) - -> Result { - let mut state = try!(self.delegate.serialize_struct(name, len + 1)); - try!(state.serialize_field(self.tag, self.variant_name)); - Ok(state) - } - - #[cfg(not(any(feature = "std", feature = "collections")))] - fn serialize_struct_variant(self, - _: &'static str, - _: usize, - _: &'static str, - _: usize) - -> Result { - // Lack of push-based serialization means we need to buffer the content - // of the struct variant, so it requires std. - Err(self.bad_type(Unsupported::Enum)) - } - - #[cfg(any(feature = "std", feature = "collections"))] - fn serialize_struct_variant(self, - _: &'static str, - _: usize, - inner_variant: &'static str, - len: usize) - -> Result { - let mut map = try!(self.delegate.serialize_map(Some(2))); - try!(map.serialize_entry(self.tag, self.variant_name)); - try!(map.serialize_key(inner_variant)); - Ok(SerializeStructVariantAsMapValue::new(map, inner_variant, len)) - } - - #[cfg(not(any(feature = "std", feature = "collections")))] - fn collect_str(self, _: &T) -> Result - where T: Display - { - Err(self.bad_type(Unsupported::String)) - } -} - -/// Used only by Serde doc tests. Not public API. -#[doc(hidden)] -#[derive(Debug)] -pub struct Error; - -impl ser::Error for Error { - fn custom(_: T) -> Self { - unimplemented!() - } -} - -#[cfg(feature = "std")] -impl error::Error for Error { - fn description(&self) -> &str { - unimplemented!() - } -} - -impl Display for Error { - fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { - unimplemented!() - } -} diff --git a/serde_codegen_internals/src/attr.rs b/serde_codegen_internals/src/attr.rs index 270a4823..9e957ad9 100644 --- a/serde_codegen_internals/src/attr.rs +++ b/serde_codegen_internals/src/attr.rs @@ -705,10 +705,10 @@ impl Field { // impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, str> // impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, [u8]> if is_cow(&field.ty, "str") { - let path = syn::parse_path("_serde::de::private::borrow_cow_str").unwrap(); + let path = syn::parse_path("_serde::private::de::borrow_cow_str").unwrap(); deserialize_with.set_if_none(path); } else if is_cow(&field.ty, "[u8]") { - let path = syn::parse_path("_serde::de::private::borrow_cow_bytes").unwrap(); + let path = syn::parse_path("_serde::private::de::borrow_cow_bytes").unwrap(); deserialize_with.set_if_none(path); } } else if is_rptr(&field.ty, "str") || is_rptr(&field.ty, "[u8]") { diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 441d7dc5..5c84a649 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -622,7 +622,7 @@ fn deserialize_internally_tagged_enum(ident: &syn::Ident, params, variant, item_attrs, - quote!(_serde::de::private::ContentDeserializer::<__D::Error>::new(__tagged.content)), + quote!(_serde::private::de::ContentDeserializer::<__D::Error>::new(__tagged.content)), )); quote! { @@ -637,7 +637,7 @@ fn deserialize_internally_tagged_enum(ident: &syn::Ident, let __tagged = try!(_serde::Deserializer::deserialize( __deserializer, - _serde::de::private::TaggedContentVisitor::<__Field>::new(#tag))); + _serde::private::de::TaggedContentVisitor::<__Field>::new(#tag))); match __tagged.tag { #(#variant_arms)* @@ -693,7 +693,7 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, let type_name = item_attrs.name().deserialize_name(); let tag_or_content = quote! { - _serde::de::private::TagOrContentFieldVisitor { + _serde::private::de::TagOrContentFieldVisitor { tag: #tag, content: #content, } @@ -738,10 +738,10 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, let visit_third_key = quote! { // Visit the third key in the map, hopefully there isn't one. match try!(_serde::de::MapVisitor::visit_key_seed(&mut __visitor, #tag_or_content)) { - _serde::export::Some(_serde::de::private::TagOrContentField::Tag) => { + _serde::export::Some(_serde::private::de::TagOrContentField::Tag) => { _serde::export::Err(<__V::Error as _serde::de::Error>::duplicate_field(#tag)) } - _serde::export::Some(_serde::de::private::TagOrContentField::Content) => { + _serde::export::Some(_serde::private::de::TagOrContentField::Content) => { _serde::export::Err(<__V::Error as _serde::de::Error>::duplicate_field(#content)) } _serde::export::None => _serde::export::Ok(__ret), @@ -789,17 +789,17 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, // Visit the first key. match try!(_serde::de::MapVisitor::visit_key_seed(&mut __visitor, #tag_or_content)) { // First key is the tag. - _serde::export::Some(_serde::de::private::TagOrContentField::Tag) => { + _serde::export::Some(_serde::private::de::TagOrContentField::Tag) => { // Parse the tag. let __field = try!(_serde::de::MapVisitor::visit_value(&mut __visitor)); // Visit the second key. match try!(_serde::de::MapVisitor::visit_key_seed(&mut __visitor, #tag_or_content)) { // Second key is a duplicate of the tag. - _serde::export::Some(_serde::de::private::TagOrContentField::Tag) => { + _serde::export::Some(_serde::private::de::TagOrContentField::Tag) => { _serde::export::Err(<__V::Error as _serde::de::Error>::duplicate_field(#tag)) } // Second key is the content. - _serde::export::Some(_serde::de::private::TagOrContentField::Content) => { + _serde::export::Some(_serde::private::de::TagOrContentField::Content) => { let __ret = try!(_serde::de::MapVisitor::visit_value_seed(&mut __visitor, __Seed { field: __field, @@ -814,14 +814,14 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, } } // First key is the content. - _serde::export::Some(_serde::de::private::TagOrContentField::Content) => { + _serde::export::Some(_serde::private::de::TagOrContentField::Content) => { // Buffer up the content. - let __content = try!(_serde::de::MapVisitor::visit_value::<_serde::de::private::Content>(&mut __visitor)); + let __content = try!(_serde::de::MapVisitor::visit_value::<_serde::private::de::Content>(&mut __visitor)); // Visit the second key. match try!(_serde::de::MapVisitor::visit_key_seed(&mut __visitor, #tag_or_content)) { // Second key is the tag. - _serde::export::Some(_serde::de::private::TagOrContentField::Tag) => { - let __deserializer = _serde::de::private::ContentDeserializer::<__V::Error>::new(__content); + _serde::export::Some(_serde::private::de::TagOrContentField::Tag) => { + let __deserializer = _serde::private::de::ContentDeserializer::<__V::Error>::new(__content); // Parse the tag. let __ret = try!(match try!(_serde::de::MapVisitor::visit_value(&mut __visitor)) { // Deserialize the buffered content now that we know the variant. @@ -831,7 +831,7 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, #visit_third_key } // Second key is a duplicate of the content. - _serde::export::Some(_serde::de::private::TagOrContentField::Content) => { + _serde::export::Some(_serde::private::de::TagOrContentField::Content) => { _serde::export::Err(<__V::Error as _serde::de::Error>::duplicate_field(#content)) } // There is no second key. @@ -897,7 +897,7 @@ fn deserialize_untagged_enum(ident: &syn::Ident, params, variant, item_attrs, - quote!(_serde::de::private::ContentRefDeserializer::<__D::Error>::new(&__content)), + quote!(_serde::private::de::ContentRefDeserializer::<__D::Error>::new(&__content)), )) }); @@ -910,7 +910,7 @@ fn deserialize_untagged_enum(ident: &syn::Ident, let fallthrough_msg = format!("data did not match any variant of untagged enum {}", ident); quote_block! { - let __content = try!(<_serde::de::private::Content as _serde::Deserialize>::deserialize(__deserializer)); + let __content = try!(<_serde::private::de::Content as _serde::Deserialize>::deserialize(__deserializer)); #( if let _serde::export::Ok(__ok) = #attempts { @@ -974,7 +974,7 @@ fn deserialize_internally_tagged_variant(ident: &syn::Ident, let type_name = ident.as_ref(); let variant_name = variant.ident.as_ref(); quote_block! { - try!(_serde::Deserializer::deserialize(#deserializer, _serde::de::private::InternallyTaggedUnitVisitor::new(#type_name, #variant_name))); + try!(_serde::Deserializer::deserialize(#deserializer, _serde::private::de::InternallyTaggedUnitVisitor::new(#type_name, #variant_name))); _serde::export::Ok(#ident::#variant_ident) } } @@ -1005,7 +1005,7 @@ fn deserialize_untagged_variant(ident: &syn::Ident, _serde::export::Result::map( _serde::Deserializer::deserialize( #deserializer, - _serde::de::private::UntaggedUnitVisitor::new(#type_name, #variant_name) + _serde::private::de::UntaggedUnitVisitor::new(#type_name, #variant_name) ), |()| #ident::#variant_ident) } @@ -1428,7 +1428,7 @@ fn expr_is_missing(field: &Field, item_attrs: &attr::Item) -> Fragment { match field.attrs.deserialize_with() { None => { quote_expr! { - try!(_serde::de::private::missing_field(#name)) + try!(_serde::private::de::missing_field(#name)) } } Some(_) => { diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index a16f7567..51826928 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -379,7 +379,7 @@ fn serialize_internally_tagged_variant(ident: &syn::Ident, } quote_expr! { - _serde::ser::private::serialize_tagged_newtype( + _serde::private::ser::serialize_tagged_newtype( __serializer, #enum_ident_str, #variant_ident_str, From 2e9cc6e98a8e0c7404d800e701e56903c45d3d3c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 09:50:38 -0700 Subject: [PATCH 054/177] Move utf8 encode to where it is used --- serde/src/de/mod.rs | 3 ++- serde/src/{utils.rs => de/utf8.rs} | 10 ++++------ serde/src/lib.rs | 1 - 3 files changed, 6 insertions(+), 8 deletions(-) rename serde/src/{utils.rs => de/utf8.rs} (90%) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 0def4a6c..9a6130ab 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -112,6 +112,7 @@ pub mod value; mod from_primitive; mod ignored_any; mod impls; +mod utf8; pub use self::ignored_any::IgnoredAny; @@ -1049,7 +1050,7 @@ pub trait Visitor<'de>: Sized { fn visit_char(self, v: char) -> Result where E: Error { - self.visit_str(::utils::encode_utf8(v).as_str()) + self.visit_str(utf8::encode(v).as_str()) } /// Deserialize a `&str` into a `Value`. diff --git a/serde/src/utils.rs b/serde/src/de/utf8.rs similarity index 90% rename from serde/src/utils.rs rename to serde/src/de/utf8.rs index 4e81616a..8e02e253 100644 --- a/serde/src/utils.rs +++ b/serde/src/de/utf8.rs @@ -1,5 +1,3 @@ -//! Private utility functions - const TAG_CONT: u8 = 0b1000_0000; const TAG_TWO_B: u8 = 0b1100_0000; const TAG_THREE_B: u8 = 0b1110_0000; @@ -9,7 +7,7 @@ const MAX_TWO_B: u32 = 0x800; const MAX_THREE_B: u32 = 0x10000; #[inline] -pub fn encode_utf8(c: char) -> EncodeUtf8 { +pub fn encode(c: char) -> Encode { let code = c as u32; let mut buf = [0; 4]; let pos = if code < MAX_ONE_B { @@ -31,18 +29,18 @@ pub fn encode_utf8(c: char) -> EncodeUtf8 { buf[3] = (code & 0x3F) as u8 | TAG_CONT; 0 }; - EncodeUtf8 { + Encode { buf: buf, pos: pos, } } -pub struct EncodeUtf8 { +pub struct Encode { buf: [u8; 4], pos: usize, } -impl EncodeUtf8 { +impl Encode { // FIXME: use this from_utf8_unchecked, since we know it can never fail pub fn as_str(&self) -> &str { ::core::str::from_utf8(&self.buf[self.pos..]).unwrap() diff --git a/serde/src/lib.rs b/serde/src/lib.rs index ada910ca..fe9cfac4 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -93,7 +93,6 @@ pub use de::{Deserialize, Deserializer}; #[macro_use] mod macros; -mod utils; pub mod de; pub mod ser; From 753c711cd73799ea64893d0e23daa96ca72dabaf Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 10:01:39 -0700 Subject: [PATCH 055/177] Unignore Serializer::serialize_unit_variant example --- serde/src/ser/mod.rs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 831fa1c6..eff2ba31 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -421,12 +421,23 @@ pub trait Serializer: Sized { /// this variant within the enum, and the `variant` is the name of the /// variant. /// - /// A reasonable implementation would be to forward to `serialize_unit`. + /// ```rust + /// # use serde::{Serialize, Serializer}; + /// # + /// enum E { + /// A, + /// B, + /// } /// - /// ```rust,ignore - /// match *self { - /// E::A => serializer.serialize_unit_variant("E", 0, "A"), - /// E::B => serializer.serialize_unit_variant("E", 1, "B"), + /// impl Serialize for E { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// match *self { + /// E::A => serializer.serialize_unit_variant("E", 0, "A"), + /// E::B => serializer.serialize_unit_variant("E", 1, "B"), + /// } + /// } /// } /// ``` fn serialize_unit_variant(self, From 43d49f54be7541553ec22f4cf72c98a977a56eb8 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 10:02:11 -0700 Subject: [PATCH 056/177] Unignore Serializer::serialize_newtype_struct example --- serde/src/ser/mod.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index eff2ba31..1937d44b 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -452,8 +452,18 @@ pub trait Serializer: Sized { /// wrappers around the data they contain. A reasonable implementation would /// be to forward to `value.serialize(self)`. /// - /// ```rust,ignore - /// serializer.serialize_newtype_struct("Millimeters", &self.0) + /// ```rust + /// # use serde::{Serialize, Serializer}; + /// # + /// struct Millimeters(u8); + /// + /// impl Serialize for Millimeters { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// serializer.serialize_newtype_struct("Millimeters", &self.0) + /// } + /// } /// ``` fn serialize_newtype_struct(self, name: &'static str, From b9be543596ad89055f7c9de5a46d9d82a76c0281 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 10:04:37 -0700 Subject: [PATCH 057/177] Unignore Serializer::serialize_newtype_variant example --- serde/src/ser/mod.rs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 1937d44b..e06eaefd 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -476,9 +476,23 @@ pub trait Serializer: Sized { /// this variant within the enum, and the `variant` is the name of the /// variant. The `value` is the data contained within this newtype variant. /// - /// ```rust,ignore - /// match *self { - /// E::N(ref n) => serializer.serialize_newtype_variant("E", 0, "N", n), + /// ```rust + /// # use serde::{Serialize, Serializer}; + /// # + /// enum E { + /// M(String), + /// N(u8), + /// } + /// + /// impl Serialize for E { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// match *self { + /// E::M(ref s) => serializer.serialize_newtype_variant("E", 0, "M", s), + /// E::N(n) => serializer.serialize_newtype_variant("E", 1, "N", &n), + /// } + /// } /// } /// ``` fn serialize_newtype_variant(self, From 870305aa9317c2c802271b3f0d9add84c97153fb Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 10:11:08 -0700 Subject: [PATCH 058/177] Unignore Serializer::serialize_seq example --- serde/src/ser/mod.rs | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index e06eaefd..a06a6dce 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -510,12 +510,41 @@ pub trait Serializer: Sized { /// not be computable before the sequence is iterated. Some serializers only /// support sequences whose length is known up front. /// - /// ```rust,ignore - /// let mut seq = serializer.serialize_seq(Some(self.len()))?; - /// for element in self { - /// seq.serialize_element(element)?; + /// ```rust + /// # use std::marker::PhantomData; + /// # + /// # struct Vec(PhantomData); + /// # + /// # impl Vec { + /// # fn len(&self) -> usize { + /// # unimplemented!() + /// # } + /// # } + /// # + /// # impl<'a, T> IntoIterator for &'a Vec { + /// # type Item = &'a T; + /// # type IntoIter = Box>; + /// # fn into_iter(self) -> Self::IntoIter { + /// # unimplemented!() + /// # } + /// # } + /// # + /// # use serde::{Serialize, Serializer}; + /// # use serde::ser::SerializeSeq; + /// # + /// impl Serialize for Vec + /// where T: Serialize + /// { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// let mut seq = serializer.serialize_seq(Some(self.len()))?; + /// for element in self { + /// seq.serialize_element(element)?; + /// } + /// seq.end() + /// } /// } - /// seq.end() /// ``` fn serialize_seq(self, len: Option) -> Result; From e86e716f7a426ff740116e98322b0c7311797080 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 10:12:15 -0700 Subject: [PATCH 059/177] Show imports in Serializer examples --- serde/src/ser/mod.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index a06a6dce..217a244d 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -422,8 +422,8 @@ pub trait Serializer: Sized { /// variant. /// /// ```rust - /// # use serde::{Serialize, Serializer}; - /// # + /// use serde::{Serialize, Serializer}; + /// /// enum E { /// A, /// B, @@ -453,8 +453,8 @@ pub trait Serializer: Sized { /// be to forward to `value.serialize(self)`. /// /// ```rust - /// # use serde::{Serialize, Serializer}; - /// # + /// use serde::{Serialize, Serializer}; + /// /// struct Millimeters(u8); /// /// impl Serialize for Millimeters { @@ -477,8 +477,8 @@ pub trait Serializer: Sized { /// variant. The `value` is the data contained within this newtype variant. /// /// ```rust - /// # use serde::{Serialize, Serializer}; - /// # + /// use serde::{Serialize, Serializer}; + /// /// enum E { /// M(String), /// N(u8), @@ -529,9 +529,9 @@ pub trait Serializer: Sized { /// # } /// # } /// # - /// # use serde::{Serialize, Serializer}; - /// # use serde::ser::SerializeSeq; - /// # + /// use serde::{Serialize, Serializer}; + /// use serde::ser::SerializeSeq; + /// /// impl Serialize for Vec /// where T: Serialize /// { From d97c4f403c0fb459b7d63d0cc4305c0b37e104e4 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 10:17:40 -0700 Subject: [PATCH 060/177] Unignore Serializer::serialize_seq_fixed_size example --- serde/src/ser/mod.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 217a244d..603ebe0b 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -553,12 +553,24 @@ pub trait Serializer: Sized { /// This call must be followed by zero or more calls to `serialize_element`, /// then a call to `end`. /// - /// ```rust,ignore - /// let mut seq = serializer.serialize_seq_fixed_size(self.len())?; - /// for element in self { - /// seq.serialize_element(element)?; + /// ```rust + /// use serde::{Serialize, Serializer}; + /// use serde::ser::SerializeSeq; + /// + /// const VRAM_SIZE: usize = 386; + /// struct Vram([u16; VRAM_SIZE]); + /// + /// impl Serialize for Vram { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// let mut seq = serializer.serialize_seq_fixed_size(VRAM_SIZE)?; + /// for element in &self.0[..] { + /// seq.serialize_element(element)?; + /// } + /// seq.end() + /// } /// } - /// seq.end() /// ``` fn serialize_seq_fixed_size(self, size: usize) -> Result; From 8d130123d9ae403bf8e99e93b5b0a49164fd7160 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 10:23:52 -0700 Subject: [PATCH 061/177] Unignore Serializer::serialize_tuple example --- serde/src/ser/mod.rs | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 603ebe0b..524c7514 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -577,12 +577,33 @@ pub trait Serializer: Sized { /// Begin to serialize a tuple. This call must be followed by zero or more /// calls to `serialize_element`, then a call to `end`. /// - /// ```rust,ignore - /// let mut tup = serializer.serialize_tuple(3)?; - /// tup.serialize_element(&self.0)?; - /// tup.serialize_element(&self.1)?; - /// tup.serialize_element(&self.2)?; - /// tup.end() + /// ```rust + /// use serde::{Serialize, Serializer}; + /// use serde::ser::SerializeTuple; + /// + /// # mod fool { + /// # trait Serialize {} + /// impl Serialize for (A, B, C) + /// # {} + /// # } + /// # + /// # struct Tuple3(A, B, C); + /// # + /// # impl Serialize for Tuple3 + /// where A: Serialize, + /// B: Serialize, + /// C: Serialize + /// { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// let mut tup = serializer.serialize_tuple(3)?; + /// tup.serialize_element(&self.0)?; + /// tup.serialize_element(&self.1)?; + /// tup.serialize_element(&self.2)?; + /// tup.end() + /// } + /// } /// ``` fn serialize_tuple(self, len: usize) -> Result; From fccb3951689bc99b52f3f595413a365e2cabf417 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 10:26:00 -0700 Subject: [PATCH 062/177] Unignore Serializer::serialize_tuple_struct example --- serde/src/ser/mod.rs | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 524c7514..dbe728e1 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -614,12 +614,23 @@ pub trait Serializer: Sized { /// The `name` is the name of the tuple struct and the `len` is the number /// of data fields that will be serialized. /// - /// ```rust,ignore - /// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?; - /// ts.serialize_field(&self.0)?; - /// ts.serialize_field(&self.1)?; - /// ts.serialize_field(&self.2)?; - /// ts.end() + /// ```rust + /// use serde::{Serialize, Serializer}; + /// use serde::ser::SerializeTupleStruct; + /// + /// struct Rgb(u8, u8, u8); + /// + /// impl Serialize for Rgb { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?; + /// ts.serialize_field(&self.0)?; + /// ts.serialize_field(&self.1)?; + /// ts.serialize_field(&self.2)?; + /// ts.end() + /// } + /// } /// ``` fn serialize_tuple_struct(self, name: &'static str, From ad249c7fac7c09d5f28cfeab61365febbc117c5a Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 10:28:53 -0700 Subject: [PATCH 063/177] Unignore Serializer::serialize_tuple_variant example --- serde/src/ser/mod.rs | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index dbe728e1..89c9af40 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -645,13 +645,34 @@ pub trait Serializer: Sized { /// this variant within the enum, the `variant` is the name of the variant, /// and the `len` is the number of data fields that will be serialized. /// - /// ```rust,ignore - /// match *self { - /// E::T(ref a, ref b) => { - /// let mut tv = serializer.serialize_tuple_variant("E", 0, "T", 2)?; - /// tv.serialize_field(a)?; - /// tv.serialize_field(b)?; - /// tv.end() + /// ```rust + /// use serde::{Serialize, Serializer}; + /// use serde::ser::SerializeTupleVariant; + /// + /// enum E { + /// T(u8, u8), + /// U(String, u32, u32), + /// } + /// + /// impl Serialize for E { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// match *self { + /// E::T(ref a, ref b) => { + /// let mut tv = serializer.serialize_tuple_variant("E", 0, "T", 2)?; + /// tv.serialize_field(a)?; + /// tv.serialize_field(b)?; + /// tv.end() + /// } + /// E::U(ref a, ref b, ref c) => { + /// let mut tv = serializer.serialize_tuple_variant("E", 1, "U", 3)?; + /// tv.serialize_field(a)?; + /// tv.serialize_field(b)?; + /// tv.serialize_field(c)?; + /// tv.end() + /// } + /// } /// } /// } /// ``` From 8aa630ea48fff13c6c880c12d4b67022e476fb11 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 10:32:01 -0700 Subject: [PATCH 064/177] Unignore Serializer::serialize_map example --- serde/src/ser/mod.rs | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 89c9af40..74130bdf 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -690,12 +690,42 @@ pub trait Serializer: Sized { /// be computable before the map is iterated. Some serializers only support /// maps whose length is known up front. /// - /// ```rust,ignore - /// let mut map = serializer.serialize_map(Some(self.len()))?; - /// for (k, v) in self { - /// map.serialize_entry(k, v)?; + /// ```rust + /// # use std::marker::PhantomData; + /// # + /// # struct HashMap(PhantomData, PhantomData); + /// # + /// # impl HashMap { + /// # fn len(&self) -> usize { + /// # unimplemented!() + /// # } + /// # } + /// # + /// # impl<'a, K, V> IntoIterator for &'a HashMap { + /// # type Item = (&'a K, &'a V); + /// # type IntoIter = Box>; + /// # fn into_iter(self) -> Self::IntoIter { + /// # unimplemented!() + /// # } + /// # } + /// # + /// use serde::{Serialize, Serializer}; + /// use serde::ser::SerializeMap; + /// + /// impl Serialize for HashMap + /// where K: Serialize, + /// V: Serialize + /// { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// let mut map = serializer.serialize_map(Some(self.len()))?; + /// for (k, v) in self { + /// map.serialize_entry(k, v)?; + /// } + /// map.end() + /// } /// } - /// map.end() /// ``` fn serialize_map(self, len: Option) -> Result; From f2b230a0b8285ae2ae19a789d4b7ebfce1b1b5c0 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 10:34:03 -0700 Subject: [PATCH 065/177] Unignore Serializer::serialize_struct example --- serde/src/ser/mod.rs | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 74130bdf..8fafbbec 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -736,12 +736,27 @@ pub trait Serializer: Sized { /// The `name` is the name of the struct and the `len` is the number of /// data fields that will be serialized. /// - /// ```rust,ignore - /// let mut struc = serializer.serialize_struct("Rgb", 3)?; - /// struc.serialize_field("r", &self.r)?; - /// struc.serialize_field("g", &self.g)?; - /// struc.serialize_field("b", &self.b)?; - /// struc.end() + /// ```rust + /// use serde::{Serialize, Serializer}; + /// use serde::ser::SerializeStruct; + /// + /// struct Rgb { + /// r: u8, + /// g: u8, + /// b: u8, + /// } + /// + /// impl Serialize for Rgb { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// let mut rgb = serializer.serialize_struct("Rgb", 3)?; + /// rgb.serialize_field("r", &self.r)?; + /// rgb.serialize_field("g", &self.g)?; + /// rgb.serialize_field("b", &self.b)?; + /// rgb.end() + /// } + /// } /// ``` fn serialize_struct(self, name: &'static str, From b1cfa5aef567f8eb68cb6a1d44f38dc0514e6977 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 10:35:42 -0700 Subject: [PATCH 066/177] Unignore Serializer::serialize_struct_variant example --- serde/src/ser/mod.rs | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 8fafbbec..41052c6d 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -771,14 +771,27 @@ pub trait Serializer: Sized { /// this variant within the enum, the `variant` is the name of the variant, /// and the `len` is the number of data fields that will be serialized. /// - /// ```rust,ignore - /// match *self { - /// E::S { ref r, ref g, ref b } => { - /// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?; - /// sv.serialize_field("r", r)?; - /// sv.serialize_field("g", g)?; - /// sv.serialize_field("b", b)?; - /// sv.end() + /// ```rust + /// use serde::{Serialize, Serializer}; + /// use serde::ser::SerializeStructVariant; + /// + /// enum E { + /// S { r: u8, g: u8, b: u8 } + /// } + /// + /// impl Serialize for E { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// match *self { + /// E::S { ref r, ref g, ref b } => { + /// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?; + /// sv.serialize_field("r", r)?; + /// sv.serialize_field("g", g)?; + /// sv.serialize_field("b", b)?; + /// sv.end() + /// } + /// } /// } /// } /// ``` From 11a6e4225600aad84fbd7bbba24459318799f3e5 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 10:42:54 -0700 Subject: [PATCH 067/177] Unignore SerializeSeq example --- serde/src/ser/mod.rs | 66 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 41052c6d..32239e2f 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -900,12 +900,68 @@ pub trait Serializer: Sized { /// Returned from `Serializer::serialize_seq` and /// `Serializer::serialize_seq_fixed_size`. /// -/// ```rust,ignore -/// let mut seq = serializer.serialize_seq(Some(self.len()))?; -/// for element in self { -/// seq.serialize_element(element)?; +/// ```rust +/// # use std::marker::PhantomData; +/// # +/// # macro_rules! unimplemented_vec { +/// # ($name:ident) => { +/// # struct $name(PhantomData); +/// # +/// # impl $name { +/// # fn len(&self) -> usize { +/// # unimplemented!() +/// # } +/// # } +/// # +/// # impl<'a, T> IntoIterator for &'a $name { +/// # type Item = &'a T; +/// # type IntoIter = Box>; +/// # fn into_iter(self) -> Self::IntoIter { +/// # unimplemented!() +/// # } +/// # } +/// # } +/// # } +/// # +/// # unimplemented_vec!(Vec); +/// # unimplemented_vec!(Array); +/// # +/// use serde::{Serialize, Serializer}; +/// use serde::ser::SerializeSeq; +/// +/// impl Serialize for Vec +/// where T: Serialize +/// { +/// fn serialize(&self, serializer: S) -> Result +/// where S: Serializer +/// { +/// let mut seq = serializer.serialize_seq(Some(self.len()))?; +/// for element in self { +/// seq.serialize_element(element)?; +/// } +/// seq.end() +/// } +/// } +/// +/// # mod fool { +/// # trait Serialize {} +/// impl Serialize for [T; 16] +/// # {} +/// # } +/// # +/// # impl Serialize for Array +/// where T: Serialize +/// { +/// fn serialize(&self, serializer: S) -> Result +/// where S: Serializer +/// { +/// let mut seq = serializer.serialize_seq_fixed_size(16)?; +/// for element in self { +/// seq.serialize_element(element)?; +/// } +/// seq.end() +/// } /// } -/// seq.end() /// ``` pub trait SerializeSeq { /// Must match the `Ok` type of our `Serializer`. From 85d4dc3e2039fd7fb794974c72d55e9bc92d1991 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 10:45:13 -0700 Subject: [PATCH 068/177] Copy the Serializer examples to the helper traits --- serde/src/ser/mod.rs | 187 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 149 insertions(+), 38 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 32239e2f..12e294f5 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -979,12 +979,33 @@ pub trait SerializeSeq { /// Returned from `Serializer::serialize_tuple`. /// -/// ```rust,ignore -/// let mut tup = serializer.serialize_tuple(3)?; -/// tup.serialize_element(&self.0)?; -/// tup.serialize_element(&self.1)?; -/// tup.serialize_element(&self.2)?; -/// tup.end() +/// ```rust +/// use serde::{Serialize, Serializer}; +/// use serde::ser::SerializeTuple; +/// +/// # mod fool { +/// # trait Serialize {} +/// impl Serialize for (A, B, C) +/// # {} +/// # } +/// # +/// # struct Tuple3(A, B, C); +/// # +/// # impl Serialize for Tuple3 +/// where A: Serialize, +/// B: Serialize, +/// C: Serialize +/// { +/// fn serialize(&self, serializer: S) -> Result +/// where S: Serializer +/// { +/// let mut tup = serializer.serialize_tuple(3)?; +/// tup.serialize_element(&self.0)?; +/// tup.serialize_element(&self.1)?; +/// tup.serialize_element(&self.2)?; +/// tup.end() +/// } +/// } /// ``` pub trait SerializeTuple { /// Must match the `Ok` type of our `Serializer`. @@ -1002,12 +1023,23 @@ pub trait SerializeTuple { /// Returned from `Serializer::serialize_tuple_struct`. /// -/// ```rust,ignore -/// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?; -/// ts.serialize_field(&self.0)?; -/// ts.serialize_field(&self.1)?; -/// ts.serialize_field(&self.2)?; -/// ts.end() +/// ```rust +/// use serde::{Serialize, Serializer}; +/// use serde::ser::SerializeTupleStruct; +/// +/// struct Rgb(u8, u8, u8); +/// +/// impl Serialize for Rgb { +/// fn serialize(&self, serializer: S) -> Result +/// where S: Serializer +/// { +/// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?; +/// ts.serialize_field(&self.0)?; +/// ts.serialize_field(&self.1)?; +/// ts.serialize_field(&self.2)?; +/// ts.end() +/// } +/// } /// ``` pub trait SerializeTupleStruct { /// Must match the `Ok` type of our `Serializer`. @@ -1025,13 +1057,34 @@ pub trait SerializeTupleStruct { /// Returned from `Serializer::serialize_tuple_variant`. /// -/// ```rust,ignore -/// match *self { -/// E::T(ref a, ref b) => { -/// let mut tv = serializer.serialize_tuple_variant("E", 0, "T", 2)?; -/// tv.serialize_field(a)?; -/// tv.serialize_field(b)?; -/// tv.end() +/// ```rust +/// use serde::{Serialize, Serializer}; +/// use serde::ser::SerializeTupleVariant; +/// +/// enum E { +/// T(u8, u8), +/// U(String, u32, u32), +/// } +/// +/// impl Serialize for E { +/// fn serialize(&self, serializer: S) -> Result +/// where S: Serializer +/// { +/// match *self { +/// E::T(ref a, ref b) => { +/// let mut tv = serializer.serialize_tuple_variant("E", 0, "T", 2)?; +/// tv.serialize_field(a)?; +/// tv.serialize_field(b)?; +/// tv.end() +/// } +/// E::U(ref a, ref b, ref c) => { +/// let mut tv = serializer.serialize_tuple_variant("E", 1, "U", 3)?; +/// tv.serialize_field(a)?; +/// tv.serialize_field(b)?; +/// tv.serialize_field(c)?; +/// tv.end() +/// } +/// } /// } /// } /// ``` @@ -1051,12 +1104,42 @@ pub trait SerializeTupleVariant { /// Returned from `Serializer::serialize_map`. /// -/// ```rust,ignore -/// let mut map = serializer.serialize_map(Some(self.len()))?; -/// for (k, v) in self { -/// map.serialize_entry(k, v)?; +/// ```rust +/// # use std::marker::PhantomData; +/// # +/// # struct HashMap(PhantomData, PhantomData); +/// # +/// # impl HashMap { +/// # fn len(&self) -> usize { +/// # unimplemented!() +/// # } +/// # } +/// # +/// # impl<'a, K, V> IntoIterator for &'a HashMap { +/// # type Item = (&'a K, &'a V); +/// # type IntoIter = Box>; +/// # fn into_iter(self) -> Self::IntoIter { +/// # unimplemented!() +/// # } +/// # } +/// # +/// use serde::{Serialize, Serializer}; +/// use serde::ser::SerializeMap; +/// +/// impl Serialize for HashMap +/// where K: Serialize, +/// V: Serialize +/// { +/// fn serialize(&self, serializer: S) -> Result +/// where S: Serializer +/// { +/// let mut map = serializer.serialize_map(Some(self.len()))?; +/// for (k, v) in self { +/// map.serialize_entry(k, v)?; +/// } +/// map.end() +/// } /// } -/// map.end() /// ``` pub trait SerializeMap { /// Must match the `Ok` type of our `Serializer`. @@ -1098,12 +1181,27 @@ pub trait SerializeMap { /// Returned from `Serializer::serialize_struct`. /// -/// ```rust,ignore -/// let mut struc = serializer.serialize_struct("Rgb", 3)?; -/// struc.serialize_field("r", &self.r)?; -/// struc.serialize_field("g", &self.g)?; -/// struc.serialize_field("b", &self.b)?; -/// struc.end() +/// ```rust +/// use serde::{Serialize, Serializer}; +/// use serde::ser::SerializeStruct; +/// +/// struct Rgb { +/// r: u8, +/// g: u8, +/// b: u8, +/// } +/// +/// impl Serialize for Rgb { +/// fn serialize(&self, serializer: S) -> Result +/// where S: Serializer +/// { +/// let mut rgb = serializer.serialize_struct("Rgb", 3)?; +/// rgb.serialize_field("r", &self.r)?; +/// rgb.serialize_field("g", &self.g)?; +/// rgb.serialize_field("b", &self.b)?; +/// rgb.end() +/// } +/// } /// ``` pub trait SerializeStruct { /// Must match the `Ok` type of our `Serializer`. @@ -1124,14 +1222,27 @@ pub trait SerializeStruct { /// Returned from `Serializer::serialize_struct_variant`. /// -/// ```rust,ignore -/// match *self { -/// E::S { ref r, ref g, ref b } => { -/// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?; -/// sv.serialize_field("r", r)?; -/// sv.serialize_field("g", g)?; -/// sv.serialize_field("b", b)?; -/// sv.end() +/// ```rust +/// use serde::{Serialize, Serializer}; +/// use serde::ser::SerializeStructVariant; +/// +/// enum E { +/// S { r: u8, g: u8, b: u8 } +/// } +/// +/// impl Serialize for E { +/// fn serialize(&self, serializer: S) -> Result +/// where S: Serializer +/// { +/// match *self { +/// E::S { ref r, ref g, ref b } => { +/// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?; +/// sv.serialize_field("r", r)?; +/// sv.serialize_field("g", g)?; +/// sv.serialize_field("b", b)?; +/// sv.end() +/// } +/// } /// } /// } /// ``` From fdaa8202b945733daf0397e381367642d8437505 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 11:06:19 -0700 Subject: [PATCH 069/177] Clean up some existing examples --- serde/src/de/mod.rs | 131 ++++++++++++++++++++++++++----------------- serde/src/macros.rs | 25 +++++++-- serde/src/ser/mod.rs | 26 +++++++-- 3 files changed, 119 insertions(+), 63 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 9a6130ab..453a531b 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -139,20 +139,26 @@ macro_rules! declare_error_trait { /// The message should not be capitalized and should not end with a period. /// /// ```rust - /// # use serde::de::{Deserialize, Deserializer, Error}; /// # use std::str::FromStr; - /// # #[allow(dead_code)] + /// # /// # struct IpAddr; + /// # /// # impl FromStr for IpAddr { /// # type Err = String; - /// # fn from_str(_: &str) -> Result { unimplemented!() } + /// # + /// # fn from_str(_: &str) -> Result { + /// # unimplemented!() + /// # } /// # } + /// # + /// use serde::de::{self, Deserialize, Deserializer}; + /// /// impl<'de> Deserialize<'de> for IpAddr { /// fn deserialize(deserializer: D) -> Result /// where D: Deserializer<'de> /// { /// let s = try!(String::deserialize(deserializer)); - /// s.parse().map_err(Error::custom) + /// s.parse().map_err(de::Error::custom) /// } /// } /// ``` @@ -260,20 +266,24 @@ declare_error_trait!(Error: Sized + Debug + Display); /// `invalid_length` methods of the `Error` trait to build error messages. /// /// ```rust -/// # use serde::de::{Error, Unexpected, Visitor}; /// # use std::fmt; -/// # #[allow(dead_code)] +/// # +/// # use serde::de::{self, Unexpected, Visitor}; +/// # /// # struct Example; +/// # /// # impl<'de> Visitor<'de> for Example { -/// # type Value = (); +/// # type Value = (); +/// # +/// # fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { +/// # write!(formatter, "definitely not a boolean") +/// # } +/// # /// fn visit_bool(self, v: bool) -> Result -/// where E: Error +/// where E: de::Error /// { -/// Err(Error::invalid_type(Unexpected::Bool(v), &self)) +/// Err(de::Error::invalid_type(Unexpected::Bool(v), &self)) /// } -/// # fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { -/// # write!(formatter, "definitely not a boolean") -/// # } /// # } /// ``` #[derive(Clone, PartialEq, Debug)] @@ -380,31 +390,37 @@ impl<'a> fmt::Display for Unexpected<'a> { /// (`&self`) is an implementation of this trait. /// /// ```rust -/// # use serde::de::{Error, Unexpected, Visitor}; /// # use std::fmt; -/// # #[allow(dead_code)] +/// # +/// # use serde::de::{self, Unexpected, Visitor}; +/// # /// # struct Example; +/// # /// # impl<'de> Visitor<'de> for Example { -/// # type Value = (); +/// # type Value = (); +/// # +/// # fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { +/// # write!(formatter, "definitely not a boolean") +/// # } +/// # /// fn visit_bool(self, v: bool) -> Result -/// where E: Error +/// where E: de::Error /// { -/// Err(Error::invalid_type(Unexpected::Bool(v), &self)) +/// Err(de::Error::invalid_type(Unexpected::Bool(v), &self)) /// } -/// # fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { -/// # write!(formatter, "definitely not a boolean") -/// # } /// # } /// ``` /// /// Outside of a `Visitor`, `&"..."` can be used. /// /// ```rust -/// # use serde::de::{Error, Unexpected}; -/// # #[allow(dead_code)] -/// # fn example() -> Result<(), E> { -/// # let v = true; -/// return Err(Error::invalid_type(Unexpected::Bool(v), &"a negative integer")); +/// # use serde::de::{self, Unexpected}; +/// # +/// # fn example() -> Result<(), E> +/// # where E: de::Error +/// # { +/// # let v = true; +/// return Err(de::Error::invalid_type(Unexpected::Bool(v), &"a negative integer")); /// # } /// ``` pub trait Expected { @@ -509,11 +525,13 @@ impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} /// /// ```rust /// # use serde::Deserialize; -/// # #[allow(dead_code)] +/// # /// # enum Error {} -/// # #[allow(dead_code)] +/// # /// fn func<'de, T: Deserialize<'de>>() -> Result -/// # { unimplemented!() } +/// # { +/// # unimplemented!() +/// # } /// ``` /// /// Adjusting an API like this to support stateful deserialization is a matter @@ -521,9 +539,9 @@ impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} /// /// ```rust /// # use serde::de::DeserializeSeed; -/// # #[allow(dead_code)] +/// # /// # enum Error {} -/// # #[allow(dead_code)] +/// # /// fn func_seed<'de, T: DeserializeSeed<'de>>(seed: T) -> Result /// # { /// # let _ = seed; @@ -545,10 +563,11 @@ impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} /// trait. /// /// ```rust -/// # use serde::de::{Deserialize, DeserializeSeed, Deserializer, Visitor, SeqVisitor}; -/// # use std::fmt; -/// # use std::marker::PhantomData; -/// # +/// use std::fmt; +/// use std::marker::PhantomData; +/// +/// use serde::de::{Deserialize, DeserializeSeed, Deserializer, Visitor, SeqVisitor}; +/// /// // A DeserializeSeed implementation that uses stateful deserialization to /// // append array elements onto the end of an existing vector. The preexisting /// // state ("seed") in this case is the Vec. The `deserialize` method of @@ -576,6 +595,10 @@ impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} /// { /// type Value = (); /// +/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { +/// write!(formatter, "an array of integers") +/// } +/// /// fn visit_seq(self, mut visitor: V) -> Result<(), V::Error> /// where V: SeqVisitor<'de> /// { @@ -586,10 +609,6 @@ impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} /// } /// Ok(()) /// } -/// # -/// # fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { -/// # write!(formatter, "an array of integers") -/// # } /// } /// /// deserializer.deserialize_seq(ExtendVecVisitor(self.0)) @@ -606,6 +625,10 @@ impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} /// // contents of the inner arrays. /// type Value = Vec; /// +/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { +/// write!(formatter, "an array of arrays") +/// } +/// /// fn visit_seq(self, mut visitor: V) -> Result, V::Error> /// where V: SeqVisitor<'de> /// { @@ -620,18 +643,15 @@ impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} /// // Return the finished vec. /// Ok(vec) /// } -/// # -/// # fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { -/// # write!(formatter, "an array of arrays") -/// # } /// } /// -/// # #[allow(dead_code)] -/// # fn example<'de, D: Deserializer<'de>>(deserializer: D) -> Result<(), D::Error> { +/// # fn example<'de, D>(deserializer: D) -> Result<(), D::Error> +/// # where D: Deserializer<'de> +/// # { /// let visitor = FlattenedVecVisitor(PhantomData); /// let flattened: Vec = deserializer.deserialize_seq(visitor)?; -/// # let _ = flattened; -/// # Ok(()) } +/// # Ok(()) +/// # } /// ``` pub trait DeserializeSeed<'de>: Sized { /// The type produced by using this seed. @@ -917,11 +937,12 @@ pub trait Deserializer<'de>: Sized { /// This trait represents a visitor that walks through a deserializer. /// /// ```rust -/// # use serde::de::{Error, Unexpected, Visitor}; /// # use std::fmt; +/// # +/// # use serde::de::{self, Unexpected, Visitor}; +/// # /// /// A visitor that deserializes a long string - a string containing at least /// /// some minimum number of bytes. -/// # #[allow(dead_code)] /// struct LongString { /// min: usize, /// } @@ -934,12 +955,12 @@ pub trait Deserializer<'de>: Sized { /// } /// /// fn visit_str(self, s: &str) -> Result -/// where E: Error +/// where E: de::Error /// { /// if s.len() >= self.min { /// Ok(s.to_owned()) /// } else { -/// Err(Error::invalid_value(Unexpected::Str(s), &self)) +/// Err(de::Error::invalid_value(Unexpected::Str(s), &self)) /// } /// } /// } @@ -957,10 +978,14 @@ pub trait Visitor<'de>: Sized { /// /// ```rust /// # use std::fmt; - /// # #[allow(dead_code)] - /// # struct S { max: usize } + /// # + /// # struct S { + /// # max: usize, + /// # } + /// # /// # impl<'de> serde::de::Visitor<'de> for S { - /// # type Value = (); + /// # type Value = (); + /// # /// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { /// write!(formatter, "an integer between 0 and {}", self.max) /// } diff --git a/serde/src/macros.rs b/serde/src/macros.rs index 022e1214..5873e1a7 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -117,14 +117,21 @@ macro_rules! forward_to_deserialize_helper { /// methods. /// /// ```rust -/// # #[macro_use] extern crate serde; +/// # #[macro_use] +/// # extern crate serde; +/// # /// # use serde::de::{value, Deserializer, Visitor}; -/// # pub struct MyDeserializer; +/// # +/// # struct MyDeserializer; +/// # /// # impl<'de> Deserializer<'de> for MyDeserializer { /// # type Error = value::Error; +/// # /// # fn deserialize(self, _: V) -> Result /// # where V: Visitor<'de> -/// # { unimplemented!() } +/// # { +/// # unimplemented!() +/// # } /// # /// #[inline] /// fn deserialize_bool(self, visitor: V) -> Result @@ -132,12 +139,14 @@ macro_rules! forward_to_deserialize_helper { /// { /// self.deserialize(visitor) /// } +/// # /// # forward_to_deserialize! { /// # u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option /// # seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct /// # tuple_struct struct struct_field tuple enum ignored_any /// # } /// # } +/// # /// # fn main() {} /// ``` /// @@ -146,11 +155,16 @@ macro_rules! forward_to_deserialize_helper { /// can choose which methods to forward. /// /// ```rust -/// # #[macro_use] extern crate serde; +/// # #[macro_use] +/// # extern crate serde; +/// # /// # use serde::de::{value, Deserializer, Visitor}; -/// # pub struct MyDeserializer; +/// # +/// # struct MyDeserializer; +/// # /// impl<'de> Deserializer<'de> for MyDeserializer { /// # type Error = value::Error; +/// # /// fn deserialize(self, visitor: V) -> Result /// where V: Visitor<'de> /// { @@ -165,6 +179,7 @@ macro_rules! forward_to_deserialize_helper { /// tuple_struct struct struct_field tuple enum ignored_any /// } /// } +/// # /// # fn main() {} /// ``` /// diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 12e294f5..332bdfab 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -127,16 +127,23 @@ macro_rules! declare_error_trait { /// if it contains invalid UTF-8 data. /// /// ```rust - /// # use serde::ser::{Serialize, Serializer, Error}; /// # struct Path; - /// # impl Path { fn to_str(&self) -> Option<&str> { unimplemented!() } } + /// # + /// # impl Path { + /// # fn to_str(&self) -> Option<&str> { + /// # unimplemented!() + /// # } + /// # } + /// # + /// use serde::ser::{self, Serialize, Serializer}; + /// /// impl Serialize for Path { /// fn serialize(&self, serializer: S) -> Result /// where S: Serializer /// { /// match self.to_str() { /// Some(s) => s.serialize(serializer), - /// None => Err(Error::custom("path contains invalid UTF-8 characters")), + /// None => Err(ser::Error::custom("path contains invalid UTF-8 characters")), /// } /// } /// } @@ -524,6 +531,7 @@ pub trait Serializer: Sized { /// # impl<'a, T> IntoIterator for &'a Vec { /// # type Item = &'a T; /// # type IntoIter = Box>; + /// # /// # fn into_iter(self) -> Self::IntoIter { /// # unimplemented!() /// # } @@ -704,6 +712,7 @@ pub trait Serializer: Sized { /// # impl<'a, K, V> IntoIterator for &'a HashMap { /// # type Item = (&'a K, &'a V); /// # type IntoIter = Box>; + /// # /// # fn into_iter(self) -> Self::IntoIter { /// # unimplemented!() /// # } @@ -844,12 +853,15 @@ pub trait Serializer: Sized { /// more efficient implementation if possible. /// /// ```rust - /// # use serde::{Serialize, Serializer}; /// # struct DateTime; + /// # /// # impl DateTime { /// # fn naive_local(&self) -> () { () } /// # fn offset(&self) -> () { () } /// # } + /// # + /// use serde::{Serialize, Serializer}; + /// /// impl Serialize for DateTime { /// fn serialize(&self, serializer: S) -> Result /// where S: Serializer @@ -876,12 +888,15 @@ pub trait Serializer: Sized { /// implementation is expected to return an error. /// /// ```rust - /// # use serde::{Serialize, Serializer}; /// # struct DateTime; + /// # /// # impl DateTime { /// # fn naive_local(&self) -> () { () } /// # fn offset(&self) -> () { () } /// # } + /// # + /// use serde::{Serialize, Serializer}; + /// /// impl Serialize for DateTime { /// fn serialize(&self, serializer: S) -> Result /// where S: Serializer @@ -1118,6 +1133,7 @@ pub trait SerializeTupleVariant { /// # impl<'a, K, V> IntoIterator for &'a HashMap { /// # type Item = (&'a K, &'a V); /// # type IntoIter = Box>; +/// # /// # fn into_iter(self) -> Self::IntoIter { /// # unimplemented!() /// # } From cc933b9cdb0f787dd33a6ff01e7a65b4627e73a0 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 7 Apr 2017 17:26:03 -0700 Subject: [PATCH 070/177] Just use an existing macro --- serde/src/private/macros.rs | 7 ------- serde/src/ser/impossible.rs | 4 ++-- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/serde/src/private/macros.rs b/serde/src/private/macros.rs index f8298a29..4d40c510 100644 --- a/serde/src/private/macros.rs +++ b/serde/src/private/macros.rs @@ -117,10 +117,3 @@ macro_rules! __serialize_unimplemented { )* }; } - -/// Used only by Serde doc tests. Not public API. -#[doc(hidden)] -#[macro_export] -macro_rules! __serde_ignore_tokens { - ($($tt:tt)+) => {} -} diff --git a/serde/src/ser/impossible.rs b/serde/src/ser/impossible.rs index 7f08a0db..bc11ce66 100644 --- a/serde/src/ser/impossible.rs +++ b/serde/src/ser/impossible.rs @@ -35,9 +35,9 @@ use ser::{self, Serialize, SerializeSeq, SerializeTuple, SerializeTupleStruct, /// -> Result { /// // Given Impossible cannot be instantiated, the only /// // thing we can do here is to return an error. -/// # __serde_ignore_tokens! { +/// # stringify! { /// Err(...) -/// # } +/// # }; /// # unimplemented!() /// } /// From 74e15ea9f5ac0c9e75560a085a78001d2cf51232 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 6 Apr 2017 15:24:16 -0700 Subject: [PATCH 071/177] Configurable forward_to_deserialize --- serde/src/macros.rs | 153 ++++++++++++++++++++++++++------------------ 1 file changed, 89 insertions(+), 64 deletions(-) diff --git a/serde/src/macros.rs b/serde/src/macros.rs index 5873e1a7..b453e7c1 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -1,11 +1,14 @@ #[doc(hidden)] #[macro_export] macro_rules! forward_to_deserialize_method { - ($func:ident($($arg:ty),*)) => { + ($func:ident<$l:tt, $v:ident>($($arg:ident : $ty:ty),*)) => { #[inline] - fn $func<__V>(self, $(_: $arg,)* visitor: __V) -> $crate::export::Result<__V::Value, Self::Error> - where __V: $crate::de::Visitor<'de> + fn $func<$v>(self, $($arg: $ty,)* visitor: $v) -> $crate::export::Result<$v::Value, Self::Error> + where $v: $crate::de::Visitor<$l> { + $( + let _ = $arg; + )* self.deserialize(visitor) } }; @@ -14,92 +17,92 @@ macro_rules! forward_to_deserialize_method { #[doc(hidden)] #[macro_export] macro_rules! forward_to_deserialize_helper { - (bool) => { - forward_to_deserialize_method!{deserialize_bool()} + (bool<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_bool<$l, $v>()} }; - (u8) => { - forward_to_deserialize_method!{deserialize_u8()} + (u8<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_u8<$l, $v>()} }; - (u16) => { - forward_to_deserialize_method!{deserialize_u16()} + (u16<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_u16<$l, $v>()} }; - (u32) => { - forward_to_deserialize_method!{deserialize_u32()} + (u32<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_u32<$l, $v>()} }; - (u64) => { - forward_to_deserialize_method!{deserialize_u64()} + (u64<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_u64<$l, $v>()} }; - (i8) => { - forward_to_deserialize_method!{deserialize_i8()} + (i8<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_i8<$l, $v>()} }; - (i16) => { - forward_to_deserialize_method!{deserialize_i16()} + (i16<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_i16<$l, $v>()} }; - (i32) => { - forward_to_deserialize_method!{deserialize_i32()} + (i32<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_i32<$l, $v>()} }; - (i64) => { - forward_to_deserialize_method!{deserialize_i64()} + (i64<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_i64<$l, $v>()} }; - (f32) => { - forward_to_deserialize_method!{deserialize_f32()} + (f32<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_f32<$l, $v>()} }; - (f64) => { - forward_to_deserialize_method!{deserialize_f64()} + (f64<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_f64<$l, $v>()} }; - (char) => { - forward_to_deserialize_method!{deserialize_char()} + (char<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_char<$l, $v>()} }; - (str) => { - forward_to_deserialize_method!{deserialize_str()} + (str<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_str<$l, $v>()} }; - (string) => { - forward_to_deserialize_method!{deserialize_string()} + (string<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_string<$l, $v>()} }; - (unit) => { - forward_to_deserialize_method!{deserialize_unit()} + (unit<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_unit<$l, $v>()} }; - (option) => { - forward_to_deserialize_method!{deserialize_option()} + (option<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_option<$l, $v>()} }; - (seq) => { - forward_to_deserialize_method!{deserialize_seq()} + (seq<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_seq<$l, $v>()} }; - (seq_fixed_size) => { - forward_to_deserialize_method!{deserialize_seq_fixed_size(usize)} + (seq_fixed_size<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_seq_fixed_size<$l, $v>(len: usize)} }; - (bytes) => { - forward_to_deserialize_method!{deserialize_bytes()} + (bytes<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_bytes<$l, $v>()} }; - (byte_buf) => { - forward_to_deserialize_method!{deserialize_byte_buf()} + (byte_buf<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_byte_buf<$l, $v>()} }; - (map) => { - forward_to_deserialize_method!{deserialize_map()} + (map<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_map<$l, $v>()} }; - (unit_struct) => { - forward_to_deserialize_method!{deserialize_unit_struct(&'static str)} + (unit_struct<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_unit_struct<$l, $v>(name: &'static str)} }; - (newtype_struct) => { - forward_to_deserialize_method!{deserialize_newtype_struct(&'static str)} + (newtype_struct<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_newtype_struct<$l, $v>(name: &'static str)} }; - (tuple_struct) => { - forward_to_deserialize_method!{deserialize_tuple_struct(&'static str, usize)} + (tuple_struct<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_tuple_struct<$l, $v>(name: &'static str, len: usize)} }; - (struct) => { - forward_to_deserialize_method!{deserialize_struct(&'static str, &'static [&'static str])} + (struct<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_struct<$l, $v>(name: &'static str, fields: &'static [&'static str])} }; - (struct_field) => { - forward_to_deserialize_method!{deserialize_struct_field()} + (struct_field<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_struct_field<$l, $v>()} }; - (tuple) => { - forward_to_deserialize_method!{deserialize_tuple(usize)} + (tuple<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_tuple<$l, $v>(len: usize)} }; - (enum) => { - forward_to_deserialize_method!{deserialize_enum(&'static str, &'static [&'static str])} + (enum<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_enum<$l, $v>(name: &'static str, variants: &'static [&'static str])} }; - (ignored_any) => { - forward_to_deserialize_method!{deserialize_ignored_any()} + (ignored_any<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_ignored_any<$l, $v>()} }; } @@ -184,11 +187,33 @@ macro_rules! forward_to_deserialize_helper { /// ``` /// /// The macro assumes the convention that your `Deserializer` lifetime parameter -/// is called `'de`. It will not work if the `Deserializer` lifetime parameter -/// is called something different. +/// is called `'de` and that the `Visitor` type parameters on each method are +/// called `V`. A different type parameter and a different lifetime can be +/// specified explicitly if necessary. +/// +/// ```rust +/// # #[macro_use] extern crate serde; +/// # use serde::de::{value, Deserializer, Visitor}; +/// # pub struct MyDeserializer; +/// # impl<'q> Deserializer<'q> for MyDeserializer { +/// # type Error = value::Error; +/// # fn deserialize(self, visitor: V) -> Result +/// # where V: Visitor<'q> { unimplemented!() } +/// forward_to_deserialize! { +/// > +/// bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option +/// seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct +/// tuple_struct struct struct_field tuple enum ignored_any +/// } +/// # } +/// # fn main() {} +/// ``` #[macro_export] macro_rules! forward_to_deserialize { + (<$visitor:ident: Visitor<$lifetime:tt>> $($func:ident)*) => { + $(forward_to_deserialize_helper!{$func<$lifetime, $visitor>})* + }; ($($func:ident)*) => { - $(forward_to_deserialize_helper!{$func})* + $(forward_to_deserialize_helper!{$func<'de, V>})* }; } From 9271f7c48cf11863a24a2a45632e9a825d091e16 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 8 Apr 2017 22:46:53 -0700 Subject: [PATCH 072/177] Use a deserializer in which V would conflict --- serde/src/macros.rs | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/serde/src/macros.rs b/serde/src/macros.rs index b453e7c1..12c488a9 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -192,13 +192,24 @@ macro_rules! forward_to_deserialize_helper { /// specified explicitly if necessary. /// /// ```rust -/// # #[macro_use] extern crate serde; +/// # #[macro_use] +/// # extern crate serde; +/// # +/// # use std::marker::PhantomData; +/// # /// # use serde::de::{value, Deserializer, Visitor}; -/// # pub struct MyDeserializer; -/// # impl<'q> Deserializer<'q> for MyDeserializer { -/// # type Error = value::Error; -/// # fn deserialize(self, visitor: V) -> Result -/// # where V: Visitor<'q> { unimplemented!() } +/// # +/// # struct MyDeserializer(PhantomData); +/// # +/// # impl<'q, V> Deserializer<'q> for MyDeserializer { +/// # type Error = value::Error; +/// # +/// # fn deserialize(self, visitor: W) -> Result +/// # where W: Visitor<'q> +/// # { +/// # unimplemented!() +/// # } +/// # /// forward_to_deserialize! { /// > /// bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option @@ -206,6 +217,7 @@ macro_rules! forward_to_deserialize_helper { /// tuple_struct struct struct_field tuple enum ignored_any /// } /// # } +/// # /// # fn main() {} /// ``` #[macro_export] From a6d172111b9917a55d80b9d44666d8f9f976a1ba Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 8 Apr 2017 22:42:42 -0700 Subject: [PATCH 073/177] Derive for remote types --- serde_codegen_internals/src/ast.rs | 11 +- serde_codegen_internals/src/attr.rs | 28 +++ serde_codegen_internals/src/check.rs | 20 ++ serde_codegen_internals/src/lib.rs | 1 + serde_derive/src/de.rs | 354 +++++++++++++++++---------- serde_derive/src/ser.rs | 264 ++++++++++++-------- test_suite/tests/test_remote.rs | 184 ++++++++++++++ 7 files changed, 620 insertions(+), 242 deletions(-) create mode 100644 serde_codegen_internals/src/check.rs create mode 100644 test_suite/tests/test_remote.rs diff --git a/serde_codegen_internals/src/ast.rs b/serde_codegen_internals/src/ast.rs index 0a50691e..462d061f 100644 --- a/serde_codegen_internals/src/ast.rs +++ b/serde_codegen_internals/src/ast.rs @@ -1,5 +1,6 @@ use syn; use attr; +use check; use Ctxt; pub struct Item<'a> { @@ -62,12 +63,14 @@ impl<'a> Item<'a> { } } - Item { + let item = Item { ident: item.ident.clone(), attrs: attrs, body: body, generics: &item.generics, - } + }; + check::check(cx, &item); + item } } @@ -81,6 +84,10 @@ impl<'a> Body<'a> { Body::Struct(_, ref fields) => Box::new(fields.iter()), } } + + pub fn has_getter(&self) -> bool { + self.all_fields().any(|f| f.attrs.getter().is_some()) + } } fn enum_from_ast<'a>(cx: &Ctxt, variants: &'a [syn::Variant]) -> Vec> { diff --git a/serde_codegen_internals/src/attr.rs b/serde_codegen_internals/src/attr.rs index 9e957ad9..cb4ddd8a 100644 --- a/serde_codegen_internals/src/attr.rs +++ b/serde_codegen_internals/src/attr.rs @@ -102,6 +102,7 @@ pub struct Item { tag: EnumTag, from_type: Option, into_type: Option, + remote: Option, } /// Styles of representing an enum. @@ -151,6 +152,7 @@ impl Item { let mut content = Attr::none(cx, "content"); let mut from_type = Attr::none(cx, "from"); let mut into_type = Attr::none(cx, "into"); + let mut remote = Attr::none(cx, "remote"); for meta_items in item.attrs.iter().filter_map(get_serde_meta_items) { for meta_item in meta_items { @@ -290,6 +292,13 @@ impl Item { } } + // Parse `#[serde(remote = "...")]` + MetaItem(NameValue(ref name, ref lit)) if name == "remote" => { + if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) { + remote.set(path); + } + } + MetaItem(ref meta_item) => { cx.error(format!("unknown serde container attribute `{}`", meta_item.name())); @@ -361,6 +370,7 @@ impl Item { tag: tag, from_type: from_type.get(), into_type: into_type.get(), + remote: remote.get(), } } @@ -399,6 +409,10 @@ impl Item { pub fn into_type(&self) -> Option<&syn::Ty> { self.into_type.as_ref() } + + pub fn remote(&self) -> Option<&syn::Path> { + self.remote.as_ref() + } } /// Represents variant attribute information @@ -531,6 +545,7 @@ pub struct Field { ser_bound: Option>, de_bound: Option>, borrowed_lifetimes: BTreeSet, + getter: Option, } /// Represents the default to use for a field when deserializing. @@ -558,6 +573,7 @@ impl Field { let mut ser_bound = Attr::none(cx, "bound"); let mut de_bound = Attr::none(cx, "bound"); let mut borrowed_lifetimes = Attr::none(cx, "borrow"); + let mut getter = Attr::none(cx, "getter"); let ident = match field.ident { Some(ref ident) => ident.to_string(), @@ -676,6 +692,13 @@ impl Field { } } + // Parse `#[serde(getter = "...")]` + MetaItem(NameValue(ref name, ref lit)) if name == "getter" => { + if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) { + getter.set(path); + } + } + MetaItem(ref meta_item) => { cx.error(format!("unknown serde field attribute `{}`", meta_item.name())); } @@ -737,6 +760,7 @@ impl Field { ser_bound: ser_bound.get(), de_bound: de_bound.get(), borrowed_lifetimes: borrowed_lifetimes, + getter: getter.get(), } } @@ -788,6 +812,10 @@ impl Field { pub fn borrowed_lifetimes(&self) -> &BTreeSet { &self.borrowed_lifetimes } + + pub fn getter(&self) -> Option<&syn::Path> { + self.getter.as_ref() + } } type SerAndDe = (Option, Option); diff --git a/serde_codegen_internals/src/check.rs b/serde_codegen_internals/src/check.rs new file mode 100644 index 00000000..fd4d4e7d --- /dev/null +++ b/serde_codegen_internals/src/check.rs @@ -0,0 +1,20 @@ +use ast::{Body, Item}; +use Ctxt; + +/// Cross-cutting checks that require looking at more than a single attrs +/// object. Simpler checks should happen when parsing and building the attrs. +pub fn check(cx: &Ctxt, item: &Item) { + match item.body { + Body::Enum(_) => { + if item.body.has_getter() { + cx.error("#[serde(getter = \"...\")] is not allowed in an enum"); + } + } + Body::Struct(_, _) => { + if item.body.has_getter() && item.attrs.remote().is_none() { + cx.error("#[serde(getter = \"...\")] can only be used in structs \ + that have #[serde(remote = \"...\")]"); + } + } + } +} diff --git a/serde_codegen_internals/src/lib.rs b/serde_codegen_internals/src/lib.rs index d5baf00b..6353330b 100644 --- a/serde_codegen_internals/src/lib.rs +++ b/serde_codegen_internals/src/lib.rs @@ -9,3 +9,4 @@ mod ctxt; pub use ctxt::Ctxt; mod case; +mod check; diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 5c84a649..e1abbd16 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -14,17 +14,25 @@ pub fn expand_derive_deserialize(item: &syn::DeriveInput) -> Result(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error> + where __D: _serde::Deserializer<'de> + { + #body + } + } + } + } else { + let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(¶ms); + quote! { #[automatically_derived] impl #de_impl_generics _serde::Deserialize<'de> for #ident #ty_generics #where_clause { fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result @@ -33,13 +41,72 @@ pub fn expand_derive_deserialize(item: &syn::DeriveInput) -> Result, + + /// At least one field has a serde(getter) attribute, implying that the + /// remote type has a private field. + has_getter: bool, +} + +impl Parameters { + fn new(item: &Item) -> Self { + let local = item.ident.clone(); + let this = match item.attrs.remote() { + Some(remote) => remote.clone(), + None => item.ident.clone().into(), + }; + let generics = build_generics(item); + let borrowed = borrowed_lifetimes(item); + let has_getter = item.body.has_getter(); + + Parameters { + local: local, + this: this, + generics: generics, + borrowed: borrowed, + has_getter: has_getter, + } + } + + /// Type name to use in error messages and `&'static str` arguments to + /// various Deserializer methods. + fn type_name(&self) -> &str { + self.this.segments.last().unwrap().ident.as_ref() + } + + fn de_lifetime_def(&self) -> syn::LifetimeDef { + syn::LifetimeDef { + attrs: Vec::new(), + lifetime: syn::Lifetime::new("'de"), + bounds: self.borrowed.iter().cloned().collect(), + } + } } // All the generics in the input, plus a bound `T: Deserialize` for each generic @@ -109,14 +176,13 @@ fn deserialize_body(item: &Item, params: &Parameters) -> Fragment { } else { match item.body { Body::Enum(ref variants) => { - deserialize_item_enum(&item.ident, params, variants, &item.attrs) + deserialize_item_enum(params, variants, &item.attrs) } Body::Struct(Style::Struct, ref fields) => { if fields.iter().any(|field| field.ident.is_none()) { panic!("struct has unnamed fields"); } - deserialize_struct(&item.ident, - None, + deserialize_struct(None, params, fields, &item.attrs, @@ -127,14 +193,13 @@ fn deserialize_body(item: &Item, params: &Parameters) -> Fragment { if fields.iter().any(|field| field.ident.is_some()) { panic!("tuple struct has named fields"); } - deserialize_tuple(&item.ident, - None, + deserialize_tuple(None, params, fields, &item.attrs, None) } - Body::Struct(Style::Unit, _) => deserialize_unit_struct(&item.ident, &item.attrs), + Body::Struct(Style::Unit, _) => deserialize_unit_struct(params, &item.attrs), } } } @@ -147,33 +212,34 @@ fn deserialize_from(from_type: &syn::Ty) -> Fragment { } } -fn deserialize_unit_struct(ident: &syn::Ident, item_attrs: &attr::Item) -> Fragment { +fn deserialize_unit_struct(params: &Parameters, item_attrs: &attr::Item) -> Fragment { + let this = ¶ms.this; let type_name = item_attrs.name().deserialize_name(); - let expecting = format!("unit struct {}", ident); + let expecting = format!("unit struct {}", params.type_name()); quote_block! { struct __Visitor; impl<'de> _serde::de::Visitor<'de> for __Visitor { - type Value = #ident; + type Value = #this; fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { _serde::export::fmt::Formatter::write_str(formatter, #expecting) } #[inline] - fn visit_unit<__E>(self) -> _serde::export::Result<#ident, __E> + fn visit_unit<__E>(self) -> _serde::export::Result where __E: _serde::de::Error { - _serde::export::Ok(#ident) + _serde::export::Ok(#this) } #[inline] - fn visit_seq<__V>(self, _: __V) -> _serde::export::Result<#ident, __V::Error> + fn visit_seq<__V>(self, _: __V) -> _serde::export::Result where __V: _serde::de::SeqVisitor<'de> { - _serde::export::Ok(#ident) + _serde::export::Ok(#this) } } @@ -181,38 +247,48 @@ fn deserialize_unit_struct(ident: &syn::Ident, item_attrs: &attr::Item) -> Fragm } } -fn deserialize_tuple(ident: &syn::Ident, - variant_ident: Option<&syn::Ident>, +fn deserialize_tuple(variant_ident: Option<&syn::Ident>, params: &Parameters, fields: &[Field], item_attrs: &attr::Item, deserializer: Option) -> Fragment { + let this = ¶ms.this; let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params); + // If there are getters (implying private fields), construct the local type + // and use an `Into` conversion to get the remote type. If there are no + // getters then construct the target type directly. + let construct = if params.has_getter { + let local = ¶ms.local; + quote!(#local) + } else { + quote!(#this) + }; + let is_enum = variant_ident.is_some(); let type_path = match variant_ident { - Some(variant_ident) => quote!(#ident::#variant_ident), - None => quote!(#ident), + Some(variant_ident) => quote!(#construct::#variant_ident), + None => construct, }; let expecting = match variant_ident { - Some(variant_ident) => format!("tuple variant {}::{}", ident, variant_ident), - None => format!("tuple struct {}", ident), + Some(variant_ident) => format!("tuple variant {}::{}", params.type_name(), variant_ident), + None => format!("tuple struct {}", params.type_name()), }; let nfields = fields.len(); let visit_newtype_struct = if !is_enum && nfields == 1 { - Some(deserialize_newtype_struct(ident, &type_path, params, &fields[0])) + Some(deserialize_newtype_struct(&type_path, params, &fields[0])) } else { None }; - let visit_seq = Stmts(deserialize_seq(ident, &type_path, params, fields, false, item_attrs)); + let visit_seq = Stmts(deserialize_seq(&type_path, params, fields, false, item_attrs)); let visitor_expr = quote! { __Visitor { - marker: _serde::export::PhantomData::<#ident #ty_generics>, + marker: _serde::export::PhantomData::<#this #ty_generics>, lifetime: _serde::export::PhantomData, } }; @@ -237,12 +313,12 @@ fn deserialize_tuple(ident: &syn::Ident, quote_block! { struct __Visitor #de_impl_generics #where_clause { - marker: _serde::export::PhantomData<#ident #ty_generics>, + marker: _serde::export::PhantomData<#this #ty_generics>, lifetime: _serde::export::PhantomData<&'de ()>, } impl #de_impl_generics _serde::de::Visitor<'de> for __Visitor #de_ty_generics #where_clause { - type Value = #ident #ty_generics; + type Value = #this #ty_generics; fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { _serde::export::fmt::Formatter::write_str(formatter, #expecting) @@ -262,8 +338,7 @@ fn deserialize_tuple(ident: &syn::Ident, } } -fn deserialize_seq(ident: &syn::Ident, - type_path: &Tokens, +fn deserialize_seq(type_path: &Tokens, params: &Parameters, fields: &[Field], is_struct: bool, @@ -292,7 +367,7 @@ fn deserialize_seq(ident: &syn::Ident, } Some(path) => { let (wrapper, wrapper_ty) = wrap_deserialize_with( - ident, params, field.ty, path); + params, field.ty, path); quote!({ #wrapper _serde::export::Option::map( @@ -314,7 +389,7 @@ fn deserialize_seq(ident: &syn::Ident, } }); - let result = if is_struct { + let mut result = if is_struct { let names = fields.iter().map(|f| &f.ident); quote! { #type_path { #( #names: #vars ),* } @@ -325,14 +400,20 @@ fn deserialize_seq(ident: &syn::Ident, } }; + if params.has_getter { + let this = ¶ms.this; + result = quote! { + _serde::export::Into::<#this>::into(#result) + }; + } + quote_block! { #(#let_values)* _serde::export::Ok(#result) } } -fn deserialize_newtype_struct(ident: &syn::Ident, - type_path: &Tokens, +fn deserialize_newtype_struct(type_path: &Tokens, params: &Parameters, field: &Field) -> Tokens { @@ -345,25 +426,33 @@ fn deserialize_newtype_struct(ident: &syn::Ident, } Some(path) => { let (wrapper, wrapper_ty) = - wrap_deserialize_with(ident, params, field.ty, path); + wrap_deserialize_with(params, field.ty, path); quote!({ #wrapper try!(<#wrapper_ty as _serde::Deserialize>::deserialize(__e)).value }) } }; + + let mut result = quote!(#type_path(#value)); + if params.has_getter { + let this = ¶ms.this; + result = quote! { + _serde::export::Into::<#this>::into(#result) + }; + } + quote! { #[inline] fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result where __E: _serde::Deserializer<'de> { - _serde::export::Ok(#type_path(#value)) + _serde::export::Ok(#result) } } } -fn deserialize_struct(ident: &syn::Ident, - variant_ident: Option<&syn::Ident>, +fn deserialize_struct(variant_ident: Option<&syn::Ident>, params: &Parameters, fields: &[Field], item_attrs: &attr::Item, @@ -372,28 +461,39 @@ fn deserialize_struct(ident: &syn::Ident, let is_enum = variant_ident.is_some(); let is_untagged = deserializer.is_some(); + let this = ¶ms.this; let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params); + // If there are getters (implying private fields), construct the local type + // and use an `Into` conversion to get the remote type. If there are no + // getters then construct the target type directly. + let construct = if params.has_getter { + let local = ¶ms.local; + quote!(#local) + } else { + quote!(#this) + }; + let type_path = match variant_ident { - Some(variant_ident) => quote!(#ident::#variant_ident), - None => quote!(#ident), + Some(variant_ident) => quote!(#construct::#variant_ident), + None => construct, }; let expecting = match variant_ident { - Some(variant_ident) => format!("struct variant {}::{}", ident, variant_ident), - None => format!("struct {}", ident), + Some(variant_ident) => format!("struct variant {}::{}", params.type_name(), variant_ident), + None => format!("struct {}", params.type_name()), }; - let visit_seq = Stmts(deserialize_seq(ident, &type_path, params, fields, true, item_attrs)); + let visit_seq = Stmts(deserialize_seq(&type_path, params, fields, true, item_attrs)); let (field_visitor, fields_stmt, visit_map) = - deserialize_struct_visitor(ident, type_path, params, fields, item_attrs); + deserialize_struct_visitor(type_path, params, fields, item_attrs); let field_visitor = Stmts(field_visitor); let fields_stmt = Stmts(fields_stmt); let visit_map = Stmts(visit_map); let visitor_expr = quote! { __Visitor { - marker: _serde::export::PhantomData::<#ident #ty_generics>, + marker: _serde::export::PhantomData::<#this #ty_generics>, lifetime: _serde::export::PhantomData, } }; @@ -437,12 +537,12 @@ fn deserialize_struct(ident: &syn::Ident, #field_visitor struct __Visitor #de_impl_generics #where_clause { - marker: _serde::export::PhantomData<#ident #ty_generics>, + marker: _serde::export::PhantomData<#this #ty_generics>, lifetime: _serde::export::PhantomData<&'de ()>, } impl #de_impl_generics _serde::de::Visitor<'de> for __Visitor #de_ty_generics #where_clause { - type Value = #ident #ty_generics; + type Value = #this #ty_generics; fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { _serde::export::fmt::Formatter::write_str(formatter, #expecting) @@ -464,46 +564,43 @@ fn deserialize_struct(ident: &syn::Ident, } } -fn deserialize_item_enum(ident: &syn::Ident, - params: &Parameters, +fn deserialize_item_enum(params: &Parameters, variants: &[Variant], item_attrs: &attr::Item) -> Fragment { match *item_attrs.tag() { attr::EnumTag::External => { - deserialize_externally_tagged_enum(ident, params, variants, item_attrs) + deserialize_externally_tagged_enum(params, variants, item_attrs) } attr::EnumTag::Internal { ref tag } => { - deserialize_internally_tagged_enum(ident, - params, + deserialize_internally_tagged_enum(params, variants, item_attrs, tag) } attr::EnumTag::Adjacent { ref tag, ref content } => { - deserialize_adjacently_tagged_enum(ident, - params, + deserialize_adjacently_tagged_enum(params, variants, item_attrs, tag, content) } attr::EnumTag::None => { - deserialize_untagged_enum(ident, params, variants, item_attrs) + deserialize_untagged_enum(params, variants, item_attrs) } } } -fn deserialize_externally_tagged_enum(ident: &syn::Ident, - params: &Parameters, +fn deserialize_externally_tagged_enum(params: &Parameters, variants: &[Variant], item_attrs: &attr::Item) -> Fragment { + let this = ¶ms.this; let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params); let type_name = item_attrs.name().deserialize_name(); - let expecting = format!("enum {}", ident); + let expecting = format!("enum {}", params.type_name()); let variant_names_idents: Vec<_> = variants.iter() .enumerate() @@ -527,8 +624,7 @@ fn deserialize_externally_tagged_enum(ident: &syn::Ident, .map(|(i, variant)| { let variant_name = field_i(i); - let block = Match(deserialize_externally_tagged_variant(ident, - params, + let block = Match(deserialize_externally_tagged_variant(params, variant, item_attrs)); @@ -561,12 +657,12 @@ fn deserialize_externally_tagged_enum(ident: &syn::Ident, #variant_visitor struct __Visitor #de_impl_generics #where_clause { - marker: _serde::export::PhantomData<#ident #ty_generics>, + marker: _serde::export::PhantomData<#this #ty_generics>, lifetime: _serde::export::PhantomData<&'de ()>, } impl #de_impl_generics _serde::de::Visitor<'de> for __Visitor #de_ty_generics #where_clause { - type Value = #ident #ty_generics; + type Value = #this #ty_generics; fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { _serde::export::fmt::Formatter::write_str(formatter, #expecting) @@ -583,14 +679,13 @@ fn deserialize_externally_tagged_enum(ident: &syn::Ident, _serde::Deserializer::deserialize_enum(__deserializer, #type_name, VARIANTS, __Visitor { - marker: _serde::export::PhantomData::<#ident #ty_generics>, + marker: _serde::export::PhantomData::<#this #ty_generics>, lifetime: _serde::export::PhantomData, }) } } -fn deserialize_internally_tagged_enum(ident: &syn::Ident, - params: &Parameters, +fn deserialize_internally_tagged_enum(params: &Parameters, variants: &[Variant], item_attrs: &attr::Item, tag: &str) @@ -618,7 +713,6 @@ fn deserialize_internally_tagged_enum(ident: &syn::Ident, let variant_name = field_i(i); let block = Match(deserialize_internally_tagged_variant( - ident, params, variant, item_attrs, @@ -645,13 +739,13 @@ fn deserialize_internally_tagged_enum(ident: &syn::Ident, } } -fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, - params: &Parameters, +fn deserialize_adjacently_tagged_enum(params: &Parameters, variants: &[Variant], item_attrs: &attr::Item, tag: &str, content: &str) -> Fragment { + let this = ¶ms.this; let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params); let variant_names_idents: Vec<_> = variants.iter() @@ -676,7 +770,6 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, let variant_index = field_i(i); let block = Match(deserialize_untagged_variant( - ident, params, variant, item_attrs, @@ -689,7 +782,7 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, }) .collect(); - let expecting = format!("adjacently tagged enum {}", ident); + let expecting = format!("adjacently tagged enum {}", params.type_name()); let type_name = item_attrs.name().deserialize_name(); let tag_or_content = quote! { @@ -724,7 +817,7 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, let variant_index = field_i(i); let variant_ident = &variant.ident; quote! { - __Field::#variant_index => _serde::export::Ok(#ident::#variant_ident), + __Field::#variant_index => _serde::export::Ok(#this::#variant_ident), } }); missing_content = quote! { @@ -755,12 +848,12 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, struct __Seed #de_impl_generics #where_clause { field: __Field, - marker: _serde::export::PhantomData<#ident #ty_generics>, + marker: _serde::export::PhantomData<#this #ty_generics>, lifetime: _serde::export::PhantomData<&'de ()>, } impl #de_impl_generics _serde::de::DeserializeSeed<'de> for __Seed #de_ty_generics #where_clause { - type Value = #ident #ty_generics; + type Value = #this #ty_generics; fn deserialize<__D>(self, __deserializer: __D) -> _serde::export::Result where __D: _serde::Deserializer<'de> @@ -772,12 +865,12 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, } struct __Visitor #de_impl_generics #where_clause { - marker: _serde::export::PhantomData<#ident #ty_generics>, + marker: _serde::export::PhantomData<#this #ty_generics>, lifetime: _serde::export::PhantomData<&'de ()>, } impl #de_impl_generics _serde::de::Visitor<'de> for __Visitor #de_ty_generics #where_clause { - type Value = #ident #ty_generics; + type Value = #this #ty_generics; fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { _serde::export::fmt::Formatter::write_str(formatter, #expecting) @@ -878,14 +971,13 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident, const FIELDS: &'static [&'static str] = &[#tag, #content]; _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, __Visitor { - marker: _serde::export::PhantomData::<#ident #ty_generics>, + marker: _serde::export::PhantomData::<#this #ty_generics>, lifetime: _serde::export::PhantomData, }) } } -fn deserialize_untagged_enum(ident: &syn::Ident, - params: &Parameters, +fn deserialize_untagged_enum(params: &Parameters, variants: &[Variant], item_attrs: &attr::Item) -> Fragment { @@ -893,7 +985,6 @@ fn deserialize_untagged_enum(ident: &syn::Ident, .filter(|variant| !variant.attrs.skip_deserializing()) .map(|variant| { Expr(deserialize_untagged_variant( - ident, params, variant, item_attrs, @@ -907,7 +998,7 @@ fn deserialize_untagged_enum(ident: &syn::Ident, // largest number of fields. I'm not sure I like that. Maybe it would be // better to save all the errors and combine them into one message that // explains why none of the variants matched. - let fallthrough_msg = format!("data did not match any variant of untagged enum {}", ident); + let fallthrough_msg = format!("data did not match any variant of untagged enum {}", params.type_name()); quote_block! { let __content = try!(<_serde::private::de::Content as _serde::Deserialize>::deserialize(__deserializer)); @@ -922,8 +1013,7 @@ fn deserialize_untagged_enum(ident: &syn::Ident, } } -fn deserialize_externally_tagged_variant(ident: &syn::Ident, - params: &Parameters, +fn deserialize_externally_tagged_variant(params: &Parameters, variant: &Variant, item_attrs: &attr::Item) -> Fragment { @@ -931,28 +1021,26 @@ fn deserialize_externally_tagged_variant(ident: &syn::Ident, match variant.style { Style::Unit => { + let this = ¶ms.this; quote_block! { try!(_serde::de::VariantVisitor::visit_unit(__visitor)); - _serde::export::Ok(#ident::#variant_ident) + _serde::export::Ok(#this::#variant_ident) } } Style::Newtype => { - deserialize_externally_tagged_newtype_variant(ident, - variant_ident, + deserialize_externally_tagged_newtype_variant(variant_ident, params, &variant.fields[0]) } Style::Tuple => { - deserialize_tuple(ident, - Some(variant_ident), + deserialize_tuple(Some(variant_ident), params, &variant.fields, item_attrs, None) } Style::Struct => { - deserialize_struct(ident, - Some(variant_ident), + deserialize_struct(Some(variant_ident), params, &variant.fields, item_attrs, @@ -961,8 +1049,7 @@ fn deserialize_externally_tagged_variant(ident: &syn::Ident, } } -fn deserialize_internally_tagged_variant(ident: &syn::Ident, - params: &Parameters, +fn deserialize_internally_tagged_variant(params: &Parameters, variant: &Variant, item_attrs: &attr::Item, deserializer: Tokens) @@ -971,16 +1058,16 @@ fn deserialize_internally_tagged_variant(ident: &syn::Ident, match variant.style { Style::Unit => { - let type_name = ident.as_ref(); + let this = ¶ms.this; + let type_name = params.type_name(); let variant_name = variant.ident.as_ref(); quote_block! { try!(_serde::Deserializer::deserialize(#deserializer, _serde::private::de::InternallyTaggedUnitVisitor::new(#type_name, #variant_name))); - _serde::export::Ok(#ident::#variant_ident) + _serde::export::Ok(#this::#variant_ident) } } Style::Newtype | Style::Struct => { - deserialize_untagged_variant(ident, - params, + deserialize_untagged_variant(params, variant, item_attrs, deserializer) @@ -989,8 +1076,7 @@ fn deserialize_internally_tagged_variant(ident: &syn::Ident, } } -fn deserialize_untagged_variant(ident: &syn::Ident, - params: &Parameters, +fn deserialize_untagged_variant(params: &Parameters, variant: &Variant, item_attrs: &attr::Item, deserializer: Tokens) @@ -999,7 +1085,8 @@ fn deserialize_untagged_variant(ident: &syn::Ident, match variant.style { Style::Unit => { - let type_name = ident.as_ref(); + let this = ¶ms.this; + let type_name = params.type_name(); let variant_name = variant.ident.as_ref(); quote_expr! { _serde::export::Result::map( @@ -1007,27 +1094,24 @@ fn deserialize_untagged_variant(ident: &syn::Ident, #deserializer, _serde::private::de::UntaggedUnitVisitor::new(#type_name, #variant_name) ), - |()| #ident::#variant_ident) + |()| #this::#variant_ident) } } Style::Newtype => { - deserialize_untagged_newtype_variant(ident, - variant_ident, + deserialize_untagged_newtype_variant(variant_ident, params, &variant.fields[0], deserializer) } Style::Tuple => { - deserialize_tuple(ident, - Some(variant_ident), + deserialize_tuple(Some(variant_ident), params, &variant.fields, item_attrs, Some(deserializer)) } Style::Struct => { - deserialize_struct(ident, - Some(variant_ident), + deserialize_struct(Some(variant_ident), params, &variant.fields, item_attrs, @@ -1036,56 +1120,56 @@ fn deserialize_untagged_variant(ident: &syn::Ident, } } -fn deserialize_externally_tagged_newtype_variant(ident: &syn::Ident, - variant_ident: &syn::Ident, +fn deserialize_externally_tagged_newtype_variant(variant_ident: &syn::Ident, params: &Parameters, field: &Field) -> Fragment { + let this = ¶ms.this; match field.attrs.deserialize_with() { None => { let field_ty = &field.ty; quote_expr! { _serde::export::Result::map( _serde::de::VariantVisitor::visit_newtype::<#field_ty>(__visitor), - #ident::#variant_ident) + #this::#variant_ident) } } Some(path) => { let (wrapper, wrapper_ty) = - wrap_deserialize_with(ident, params, field.ty, path); + wrap_deserialize_with(params, field.ty, path); quote_block! { #wrapper _serde::export::Result::map( _serde::de::VariantVisitor::visit_newtype::<#wrapper_ty>(__visitor), - |__wrapper| #ident::#variant_ident(__wrapper.value)) + |__wrapper| #this::#variant_ident(__wrapper.value)) } } } } -fn deserialize_untagged_newtype_variant(ident: &syn::Ident, - variant_ident: &syn::Ident, +fn deserialize_untagged_newtype_variant(variant_ident: &syn::Ident, params: &Parameters, field: &Field, deserializer: Tokens) -> Fragment { + let this = ¶ms.this; match field.attrs.deserialize_with() { None => { let field_ty = &field.ty; quote_expr! { _serde::export::Result::map( <#field_ty as _serde::Deserialize>::deserialize(#deserializer), - #ident::#variant_ident) + #this::#variant_ident) } } Some(path) => { let (wrapper, wrapper_ty) = - wrap_deserialize_with(ident, params, field.ty, path); + wrap_deserialize_with(params, field.ty, path); quote_block! { #wrapper _serde::export::Result::map( <#wrapper_ty as _serde::Deserialize>::deserialize(#deserializer), - |__wrapper| #ident::#variant_ident(__wrapper.value)) + |__wrapper| #this::#variant_ident(__wrapper.value)) } } } @@ -1203,8 +1287,7 @@ fn deserialize_field_visitor(fields: Vec<(String, Ident)>, } } -fn deserialize_struct_visitor(ident: &syn::Ident, - struct_path: Tokens, +fn deserialize_struct_visitor(struct_path: Tokens, params: &Parameters, fields: &[Field], item_attrs: &attr::Item) @@ -1224,13 +1307,12 @@ fn deserialize_struct_visitor(ident: &syn::Ident, let field_visitor = deserialize_field_visitor(field_names_idents, item_attrs, false); - let visit_map = deserialize_map(ident, struct_path, params, fields, item_attrs); + let visit_map = deserialize_map(struct_path, params, fields, item_attrs); (field_visitor, fields_stmt, visit_map) } -fn deserialize_map(ident: &syn::Ident, - struct_path: Tokens, +fn deserialize_map(struct_path: Tokens, params: &Parameters, fields: &[Field], item_attrs: &attr::Item) @@ -1266,7 +1348,7 @@ fn deserialize_map(ident: &syn::Ident, } Some(path) => { let (wrapper, wrapper_ty) = wrap_deserialize_with( - ident, params, field.ty, path); + params, field.ty, path); quote!({ #wrapper try!(_serde::de::MapVisitor::visit_value::<#wrapper_ty>(&mut __visitor)).value @@ -1354,6 +1436,14 @@ fn deserialize_map(ident: &syn::Ident, } }; + let mut result = quote!(#struct_path { #(#result),* }); + if params.has_getter { + let this = ¶ms.this; + result = quote! { + _serde::export::Into::<#this>::into(#result) + }; + } + quote_block! { #(#let_values)* @@ -1363,7 +1453,7 @@ fn deserialize_map(ident: &syn::Ident, #(#extract_values)* - _serde::export::Ok(#struct_path { #(#result),* }) + _serde::export::Ok(#result) } } @@ -1373,17 +1463,17 @@ fn field_i(i: usize) -> Ident { /// This function wraps the expression in `#[serde(deserialize_with = "...")]` /// in a trait to prevent it from accessing the internal `Deserialize` state. -fn wrap_deserialize_with(ident: &syn::Ident, - params: &Parameters, +fn wrap_deserialize_with(params: &Parameters, field_ty: &syn::Ty, deserialize_with: &syn::Path) -> (Tokens, Tokens) { + let this = ¶ms.this; let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params); let wrapper = quote! { struct __DeserializeWith #de_impl_generics #where_clause { value: #field_ty, - phantom: _serde::export::PhantomData<#ident #ty_generics>, + phantom: _serde::export::PhantomData<#this #ty_generics>, lifetime: _serde::export::PhantomData<&'de ()>, } @@ -1444,11 +1534,7 @@ struct DeImplGenerics<'a>(&'a Parameters); impl<'a> ToTokens for DeImplGenerics<'a> { fn to_tokens(&self, tokens: &mut Tokens) { let mut generics = self.0.generics.clone(); - generics.lifetimes.insert(0, syn::LifetimeDef { - attrs: Vec::new(), - lifetime: syn::Lifetime::new("'de"), - bounds: self.0.borrowed.iter().cloned().collect(), - }); + generics.lifetimes.insert(0, self.0.de_lifetime_def()); let (impl_generics, _, _) = generics.split_for_impl(); impl_generics.to_tokens(tokens); } diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index 51826928..179c5d99 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -12,15 +12,23 @@ pub fn expand_derive_serialize(item: &syn::DeriveInput) -> Result(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error> + where __S: _serde::Serializer + { + #body + } + } + } + } else { + quote! { #[automatically_derived] impl #impl_generics _serde::Serialize for #ident #ty_generics #where_clause { fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error> @@ -29,10 +37,61 @@ pub fn expand_derive_serialize(item: &syn::DeriveInput) -> Result Self { + let self_var = if item.attrs.remote().is_some() { + Ident::new("__self") + } else { + Ident::new("self") + }; + + let this = match item.attrs.remote() { + Some(remote) => remote.clone(), + None => item.ident.clone().into(), + }; + + let generics = build_generics(item); + + Parameters { + self_var: self_var, + this: this, + generics: generics, + } + } + + /// Type name to use in error messages and `&'static str` arguments to + /// various Serializer methods. + fn type_name(&self) -> &str { + self.this.segments.last().unwrap().ident.as_ref() + } +} + // All the generics in the input, plus a bound `T: Serialize` for each generic // field type that will be serialized by us. fn build_generics(item: &Item) -> syn::Generics { @@ -60,38 +119,39 @@ fn needs_serialize_bound(attrs: &attr::Field) -> bool { !attrs.skip_serializing() && attrs.serialize_with().is_none() && attrs.ser_bound().is_none() } -fn serialize_body(item: &Item, generics: &syn::Generics) -> Fragment { +fn serialize_body(item: &Item, params: &Parameters) -> Fragment { if let Some(into_type) = item.attrs.into_type() { - serialize_into(into_type) + serialize_into(params, into_type) } else { match item.body { Body::Enum(ref variants) => { - serialize_item_enum(&item.ident, generics, variants, &item.attrs) + serialize_item_enum(params, variants, &item.attrs) } Body::Struct(Style::Struct, ref fields) => { if fields.iter().any(|field| field.ident.is_none()) { panic!("struct has unnamed fields"); } - serialize_struct(&item.ident, generics, fields, &item.attrs) + serialize_struct(params, fields, &item.attrs) } Body::Struct(Style::Tuple, ref fields) => { if fields.iter().any(|field| field.ident.is_some()) { panic!("tuple struct has named fields"); } - serialize_tuple_struct(&item.ident, generics, fields, &item.attrs) + serialize_tuple_struct(params, fields, &item.attrs) } Body::Struct(Style::Newtype, ref fields) => { - serialize_newtype_struct(&item.ident, generics, &fields[0], &item.attrs) + serialize_newtype_struct(params, &fields[0], &item.attrs) } Body::Struct(Style::Unit, _) => serialize_unit_struct(&item.attrs), } } } -fn serialize_into(into_type: &syn::Ty) -> Fragment { +fn serialize_into(params: &Parameters, into_type: &syn::Ty) -> Fragment { + let self_var = ¶ms.self_var; quote_block! { _serde::Serialize::serialize( - &>::into(_serde::export::Clone::clone(self)), + &_serde::export::Into::<#into_type>::into(_serde::export::Clone::clone(#self_var)), __serializer) } } @@ -104,16 +164,15 @@ fn serialize_unit_struct(item_attrs: &attr::Item) -> Fragment { } } -fn serialize_newtype_struct(ident: &syn::Ident, - generics: &syn::Generics, +fn serialize_newtype_struct(params: &Parameters, field: &Field, item_attrs: &attr::Item) -> Fragment { let type_name = item_attrs.name().serialize_name(); - let mut field_expr = quote!(&self.0); + let mut field_expr = get_field(params, field, 0); if let Some(path) = field.attrs.serialize_with() { - field_expr = wrap_serialize_with(ident, generics, field.ty, path, field_expr); + field_expr = wrap_serialize_with(params, field.ty, path, field_expr); } quote_expr! { @@ -121,15 +180,13 @@ fn serialize_newtype_struct(ident: &syn::Ident, } } -fn serialize_tuple_struct(ident: &syn::Ident, - generics: &syn::Generics, +fn serialize_tuple_struct(params: &Parameters, fields: &[Field], item_attrs: &attr::Item) -> Fragment { let serialize_stmts = - serialize_tuple_struct_visitor(ident, - fields, - generics, + serialize_tuple_struct_visitor(fields, + params, false, quote!(_serde::ser::SerializeTupleStruct::serialize_field)); @@ -144,15 +201,13 @@ fn serialize_tuple_struct(ident: &syn::Ident, } } -fn serialize_struct(ident: &syn::Ident, - generics: &syn::Generics, +fn serialize_struct(params: &Parameters, fields: &[Field], item_attrs: &attr::Item) -> Fragment { let serialize_fields = - serialize_struct_visitor(ident, - fields, - generics, + serialize_struct_visitor(fields, + params, false, quote!(_serde::ser::SerializeStruct::serialize_field)); @@ -165,12 +220,13 @@ fn serialize_struct(ident: &syn::Ident, let let_mut = mut_if(serialized_fields.peek().is_some()); let len = serialized_fields.map(|field| { - let ident = field.ident.clone().expect("struct has unnamed fields"); - let field_expr = quote!(&self.#ident); - match field.attrs.skip_serializing_if() { - Some(path) => quote!(if #path(#field_expr) { 0 } else { 1 }), None => quote!(1), + Some(path) => { + let ident = field.ident.clone().expect("struct has unnamed fields"); + let field_expr = get_field(params, field, ident); + quote!(if #path(#field_expr) { 0 } else { 1 }) + } } }) .fold(quote!(0), |sum, expr| quote!(#sum + #expr)); @@ -182,16 +238,16 @@ fn serialize_struct(ident: &syn::Ident, } } -fn serialize_item_enum(ident: &syn::Ident, - generics: &syn::Generics, +fn serialize_item_enum(params: &Parameters, variants: &[Variant], item_attrs: &attr::Item) -> Fragment { + let self_var = ¶ms.self_var; + let arms: Vec<_> = variants.iter() .enumerate() .map(|(variant_index, variant)| { - serialize_variant(ident, - generics, + serialize_variant(params, variant, variant_index, item_attrs) @@ -199,23 +255,23 @@ fn serialize_item_enum(ident: &syn::Ident, .collect(); quote_expr! { - match *self { + match *#self_var { #(#arms)* } } } -fn serialize_variant(ident: &syn::Ident, - generics: &syn::Generics, +fn serialize_variant(params: &Parameters, variant: &Variant, variant_index: usize, item_attrs: &attr::Item) -> Tokens { + let this = ¶ms.this; let variant_ident = variant.ident.clone(); if variant.attrs.skip_serializing() { let skipped_msg = format!("the enum variant {}::{} cannot be serialized", - ident, variant_ident); + params.type_name(), variant_ident); let skipped_err = quote! { _serde::export::Err(_serde::ser::Error::custom(#skipped_msg)) }; @@ -225,26 +281,26 @@ fn serialize_variant(ident: &syn::Ident, Style::Struct => quote!( {..} ), }; quote! { - #ident::#variant_ident #fields_pat => #skipped_err, + #this::#variant_ident #fields_pat => #skipped_err, } } else { // variant wasn't skipped let case = match variant.style { Style::Unit => { quote! { - #ident::#variant_ident + #this::#variant_ident } } Style::Newtype => { quote! { - #ident::#variant_ident(ref __field0) + #this::#variant_ident(ref __field0) } } Style::Tuple => { let field_names = (0..variant.fields.len()) .map(|i| Ident::new(format!("__field{}", i))); quote! { - #ident::#variant_ident(#(ref #field_names),*) + #this::#variant_ident(#(ref #field_names),*) } } Style::Struct => { @@ -252,35 +308,32 @@ fn serialize_variant(ident: &syn::Ident, .iter() .map(|f| f.ident.clone().expect("struct variant has unnamed fields")); quote! { - #ident::#variant_ident { #(ref #fields),* } + #this::#variant_ident { #(ref #fields),* } } } }; let body = Match(match *item_attrs.tag() { attr::EnumTag::External => { - serialize_externally_tagged_variant(ident, - generics, + serialize_externally_tagged_variant(params, variant, variant_index, item_attrs) } attr::EnumTag::Internal { ref tag } => { - serialize_internally_tagged_variant(ident, - generics, + serialize_internally_tagged_variant(params, variant, item_attrs, tag) } attr::EnumTag::Adjacent { ref tag, ref content } => { - serialize_adjacently_tagged_variant(ident, - generics, + serialize_adjacently_tagged_variant(params, variant, item_attrs, tag, content) } - attr::EnumTag::None => serialize_untagged_variant(ident, generics, variant, item_attrs), + attr::EnumTag::None => serialize_untagged_variant(params, variant, item_attrs), }); quote! { @@ -289,8 +342,7 @@ fn serialize_variant(ident: &syn::Ident, } } -fn serialize_externally_tagged_variant(ident: &syn::Ident, - generics: &syn::Generics, +fn serialize_externally_tagged_variant(params: &Parameters, variant: &Variant, variant_index: usize, item_attrs: &attr::Item) @@ -313,7 +365,7 @@ fn serialize_externally_tagged_variant(ident: &syn::Ident, let field = &variant.fields[0]; let mut field_expr = quote!(__field0); if let Some(path) = field.attrs.serialize_with() { - field_expr = wrap_serialize_with(ident, generics, field.ty, path, field_expr); + field_expr = wrap_serialize_with(params, field.ty, path, field_expr); } quote_expr! { @@ -332,8 +384,7 @@ fn serialize_externally_tagged_variant(ident: &syn::Ident, variant_index: variant_index, variant_name: variant_name, }, - ident, - generics, + params, &variant.fields) } Style::Struct => { @@ -341,16 +392,14 @@ fn serialize_externally_tagged_variant(ident: &syn::Ident, variant_index: variant_index, variant_name: variant_name, }, - ident, - generics, + params, &variant.fields, &type_name) } } } -fn serialize_internally_tagged_variant(ident: &syn::Ident, - generics: &syn::Generics, +fn serialize_internally_tagged_variant(params: &Parameters, variant: &Variant, item_attrs: &attr::Item, tag: &str) @@ -358,7 +407,7 @@ fn serialize_internally_tagged_variant(ident: &syn::Ident, let type_name = item_attrs.name().serialize_name(); let variant_name = variant.attrs.name().serialize_name(); - let enum_ident_str = ident.as_ref(); + let enum_ident_str = params.type_name(); let variant_ident_str = variant.ident.as_ref(); match variant.style { @@ -375,7 +424,7 @@ fn serialize_internally_tagged_variant(ident: &syn::Ident, let field = &variant.fields[0]; let mut field_expr = quote!(__field0); if let Some(path) = field.attrs.serialize_with() { - field_expr = wrap_serialize_with(ident, generics, field.ty, path, field_expr); + field_expr = wrap_serialize_with(params, field.ty, path, field_expr); } quote_expr! { @@ -394,8 +443,7 @@ fn serialize_internally_tagged_variant(ident: &syn::Ident, tag: tag, variant_name: variant_name, }, - ident, - generics, + params, &variant.fields, &type_name) } @@ -403,13 +451,13 @@ fn serialize_internally_tagged_variant(ident: &syn::Ident, } } -fn serialize_adjacently_tagged_variant(ident: &syn::Ident, - generics: &syn::Generics, +fn serialize_adjacently_tagged_variant(params: &Parameters, variant: &Variant, item_attrs: &attr::Item, tag: &str, content: &str) -> Fragment { + let this = ¶ms.this; let type_name = item_attrs.name().serialize_name(); let variant_name = variant.attrs.name().serialize_name(); @@ -427,7 +475,7 @@ fn serialize_adjacently_tagged_variant(ident: &syn::Ident, let field = &variant.fields[0]; let mut field_expr = quote!(__field0); if let Some(path) = field.attrs.serialize_with() { - field_expr = wrap_serialize_with(ident, generics, field.ty, path, field_expr); + field_expr = wrap_serialize_with(params, field.ty, path, field_expr); } quote_expr! { @@ -436,14 +484,12 @@ fn serialize_adjacently_tagged_variant(ident: &syn::Ident, } Style::Tuple => { serialize_tuple_variant(TupleVariant::Untagged, - ident, - generics, + params, &variant.fields) } Style::Struct => { serialize_struct_variant(StructVariant::Untagged, - ident, - generics, + params, &variant.fields, &variant_name) } @@ -466,15 +512,15 @@ fn serialize_adjacently_tagged_variant(ident: &syn::Ident, } }; - let (_, ty_generics, where_clause) = generics.split_for_impl(); + let (_, ty_generics, where_clause) = params.generics.split_for_impl(); - let wrapper_generics = bound::with_lifetime_bound(generics, "'__a"); + let wrapper_generics = bound::with_lifetime_bound(¶ms.generics, "'__a"); let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl(); quote_block! { struct __AdjacentlyTagged #wrapper_generics #where_clause { data: (#(&'__a #fields_ty,)*), - phantom: _serde::export::PhantomData<#ident #ty_generics>, + phantom: _serde::export::PhantomData<#this #ty_generics>, } impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause { @@ -493,14 +539,13 @@ fn serialize_adjacently_tagged_variant(ident: &syn::Ident, try!(_serde::ser::SerializeStruct::serialize_field( &mut __struct, #content, &__AdjacentlyTagged { data: (#(#fields_ident,)*), - phantom: _serde::export::PhantomData::<#ident #ty_generics>, + phantom: _serde::export::PhantomData::<#this #ty_generics>, })); _serde::ser::SerializeStruct::end(__struct) } } -fn serialize_untagged_variant(ident: &syn::Ident, - generics: &syn::Generics, +fn serialize_untagged_variant(params: &Parameters, variant: &Variant, item_attrs: &attr::Item) -> Fragment { @@ -514,7 +559,7 @@ fn serialize_untagged_variant(ident: &syn::Ident, let field = &variant.fields[0]; let mut field_expr = quote!(__field0); if let Some(path) = field.attrs.serialize_with() { - field_expr = wrap_serialize_with(ident, generics, field.ty, path, field_expr); + field_expr = wrap_serialize_with(params, field.ty, path, field_expr); } quote_expr! { @@ -522,13 +567,12 @@ fn serialize_untagged_variant(ident: &syn::Ident, } } Style::Tuple => { - serialize_tuple_variant(TupleVariant::Untagged, ident, generics, &variant.fields) + serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields) } Style::Struct => { let type_name = item_attrs.name().serialize_name(); serialize_struct_variant(StructVariant::Untagged, - ident, - generics, + params, &variant.fields, &type_name) } @@ -545,8 +589,7 @@ enum TupleVariant { } fn serialize_tuple_variant(context: TupleVariant, - ident: &syn::Ident, - generics: &syn::Generics, + params: &Parameters, fields: &[Field]) -> Fragment { let method = match context { @@ -557,7 +600,7 @@ fn serialize_tuple_variant(context: TupleVariant, }; let serialize_stmts = - serialize_tuple_struct_visitor(ident, fields, generics, true, method); + serialize_tuple_struct_visitor(fields, params, true, method); let len = serialize_stmts.len(); let let_mut = mut_if(len > 0); @@ -597,8 +640,7 @@ enum StructVariant<'a> { } fn serialize_struct_variant<'a>(context: StructVariant<'a>, - ident: &syn::Ident, - generics: &syn::Generics, + params: &Parameters, fields: &[Field], name: &str) -> Fragment { @@ -610,7 +652,7 @@ fn serialize_struct_variant<'a>(context: StructVariant<'a>, StructVariant::Untagged => quote!(_serde::ser::SerializeStruct::serialize_field), }; - let serialize_fields = serialize_struct_visitor(ident, fields, generics, true, method); + let serialize_fields = serialize_struct_visitor(fields, params, true, method); let mut serialized_fields = fields.iter() .filter(|&field| !field.attrs.skip_serializing()) @@ -672,9 +714,8 @@ fn serialize_struct_variant<'a>(context: StructVariant<'a>, } } -fn serialize_tuple_struct_visitor(ident: &syn::Ident, - fields: &[Field], - generics: &syn::Generics, +fn serialize_tuple_struct_visitor(fields: &[Field], + params: &Parameters, is_enum: bool, func: Tokens) -> Vec { @@ -685,8 +726,7 @@ fn serialize_tuple_struct_visitor(ident: &syn::Ident, let id = Ident::new(format!("__field{}", i)); quote!(#id) } else { - let i = Ident::new(i); - quote!(&self.#i) + get_field(params, field, i) }; let skip = field.attrs @@ -695,7 +735,7 @@ fn serialize_tuple_struct_visitor(ident: &syn::Ident, if let Some(path) = field.attrs.serialize_with() { field_expr = - wrap_serialize_with(ident, generics, field.ty, path, field_expr); + wrap_serialize_with(params, field.ty, path, field_expr); } let ser = quote! { @@ -710,9 +750,8 @@ fn serialize_tuple_struct_visitor(ident: &syn::Ident, .collect() } -fn serialize_struct_visitor(ident: &syn::Ident, - fields: &[Field], - generics: &syn::Generics, +fn serialize_struct_visitor(fields: &[Field], + params: &Parameters, is_enum: bool, func: Tokens) -> Vec { @@ -723,7 +762,7 @@ fn serialize_struct_visitor(ident: &syn::Ident, let mut field_expr = if is_enum { quote!(#field_ident) } else { - quote!(&self.#field_ident) + get_field(params, field, field_ident) }; let key_expr = field.attrs.name().serialize_name(); @@ -734,7 +773,7 @@ fn serialize_struct_visitor(ident: &syn::Ident, if let Some(path) = field.attrs.serialize_with() { field_expr = - wrap_serialize_with(ident, generics, field.ty, path, field_expr) + wrap_serialize_with(params, field.ty, path, field_expr) } let ser = quote! { @@ -749,21 +788,21 @@ fn serialize_struct_visitor(ident: &syn::Ident, .collect() } -fn wrap_serialize_with(ident: &syn::Ident, - generics: &syn::Generics, +fn wrap_serialize_with(params: &Parameters, field_ty: &syn::Ty, serialize_with: &syn::Path, value: Tokens) -> Tokens { - let (_, ty_generics, where_clause) = generics.split_for_impl(); + let this = ¶ms.this; + let (_, ty_generics, where_clause) = params.generics.split_for_impl(); - let wrapper_generics = bound::with_lifetime_bound(generics, "'__a"); + let wrapper_generics = bound::with_lifetime_bound(¶ms.generics, "'__a"); let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl(); quote!({ struct __SerializeWith #wrapper_impl_generics #where_clause { value: &'__a #field_ty, - phantom: _serde::export::PhantomData<#ident #ty_generics>, + phantom: _serde::export::PhantomData<#this #ty_generics>, } impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause { @@ -776,7 +815,7 @@ fn wrap_serialize_with(ident: &syn::Ident, &__SerializeWith { value: #value, - phantom: _serde::export::PhantomData::<#ident #ty_generics>, + phantom: _serde::export::PhantomData::<#this #ty_generics>, } }) } @@ -790,3 +829,16 @@ fn wrap_serialize_with(ident: &syn::Ident, fn mut_if(is_mut: bool) -> Option { if is_mut { Some(quote!(mut)) } else { None } } + +fn get_field(params: &Parameters, field: &Field, ident: I) -> Tokens + where I: Into +{ + let self_var = ¶ms.self_var; + match field.attrs.getter() { + None => { + let ident = ident.into(); + quote!(&#self_var.#ident) + } + Some(getter) => quote!(&#getter(#self_var)), + } +} diff --git a/test_suite/tests/test_remote.rs b/test_suite/tests/test_remote.rs new file mode 100644 index 00000000..4f21a09a --- /dev/null +++ b/test_suite/tests/test_remote.rs @@ -0,0 +1,184 @@ +#[macro_use] +extern crate serde_derive; + +extern crate serde; + +mod remote { + pub struct Unit; + + pub struct PrimitivePriv(u8); + + pub struct PrimitivePub(pub u8); + + pub struct NewtypePriv(Unit); + + pub struct NewtypePub(pub Unit); + + pub struct TuplePriv(u8, Unit); + + pub struct TuplePub(pub u8, pub Unit); + + pub struct StructPriv { + a: u8, + b: Unit, + } + + pub struct StructPub { + pub a: u8, + pub b: Unit, + } + + impl PrimitivePriv { + pub fn new(a: u8) -> Self { + PrimitivePriv(a) + } + + pub fn get(&self) -> u8 { + self.0 + } + } + + impl NewtypePriv { + pub fn new(a: Unit) -> Self { + NewtypePriv(a) + } + + pub fn get(&self) -> &Unit { + &self.0 + } + } + + impl TuplePriv { + pub fn new(a: u8, b: Unit) -> Self { + TuplePriv(a, b) + } + + pub fn first(&self) -> u8 { + self.0 + } + + pub fn second(&self) -> &Unit { + &self.1 + } + } + + impl StructPriv { + pub fn new(a: u8, b: Unit) -> Self { + StructPriv { a: a, b: b } + } + + pub fn a(&self) -> u8 { + self.a + } + + pub fn b(&self) -> &Unit { + &self.b + } + } +} + +#[derive(Serialize, Deserialize)] +struct Test { + #[serde(with = "UnitDef")] + unit: remote::Unit, + + #[serde(with = "PrimitivePrivDef")] + primitive_priv: remote::PrimitivePriv, + + #[serde(with = "PrimitivePubDef")] + primitive_pub: remote::PrimitivePub, + + #[serde(with = "NewtypePrivDef")] + newtype_priv: remote::NewtypePriv, + + #[serde(with = "NewtypePubDef")] + newtype_pub: remote::NewtypePub, + + #[serde(with = "TuplePrivDef")] + tuple_priv: remote::TuplePriv, + + #[serde(with = "TuplePubDef")] + tuple_pub: remote::TuplePub, + + #[serde(with = "StructPrivDef")] + struct_priv: remote::StructPriv, + + #[serde(with = "StructPubDef")] + struct_pub: remote::StructPub, +} + +#[derive(Serialize, Deserialize)] +#[serde(remote = "remote::Unit")] +struct UnitDef; + +#[derive(Serialize, Deserialize)] +#[serde(remote = "remote::PrimitivePriv")] +struct PrimitivePrivDef(#[serde(getter = "remote::PrimitivePriv::get")] u8); + +#[derive(Serialize, Deserialize)] +#[serde(remote = "remote::PrimitivePub")] +struct PrimitivePubDef(u8); + +#[derive(Serialize, Deserialize)] +#[serde(remote = "remote::NewtypePriv")] +struct NewtypePrivDef(#[serde(getter = "remote::NewtypePriv::get", with = "UnitDef")] remote::Unit); + +#[derive(Serialize, Deserialize)] +#[serde(remote = "remote::NewtypePub")] +struct NewtypePubDef(#[serde(with = "UnitDef")] remote::Unit); + +#[derive(Serialize, Deserialize)] +#[serde(remote = "remote::TuplePriv")] +struct TuplePrivDef( + #[serde(getter = "remote::TuplePriv::first")] u8, + #[serde(getter = "remote::TuplePriv::second", with = "UnitDef")] remote::Unit); + +#[derive(Serialize, Deserialize)] +#[serde(remote = "remote::TuplePub")] +struct TuplePubDef(u8, #[serde(with = "UnitDef")] remote::Unit); + +#[derive(Serialize, Deserialize)] +#[serde(remote = "remote::StructPriv")] +struct StructPrivDef { + #[serde(getter = "remote::StructPriv::a")] + a: u8, + + #[serde(getter = "remote::StructPriv::b")] + #[serde(with= "UnitDef")] + b: remote::Unit, +} + +#[derive(Serialize, Deserialize)] +#[serde(remote = "remote::StructPub")] +struct StructPubDef { + #[allow(dead_code)] + a: u8, + + #[allow(dead_code)] + #[serde(with= "UnitDef")] + b: remote::Unit, +} + +impl From for remote::PrimitivePriv { + fn from(def: PrimitivePrivDef) -> Self { + remote::PrimitivePriv::new(def.0) + } +} + +impl From for remote::NewtypePriv { + fn from(def: NewtypePrivDef) -> Self { + remote::NewtypePriv::new(def.0) + } +} + +impl From for remote::TuplePriv { + fn from(def: TuplePrivDef) -> Self { + remote::TuplePriv::new(def.0, def.1) + } +} + +impl From for remote::StructPriv { + fn from(def: StructPrivDef) -> Self { + remote::StructPriv::new(def.a, def.b) + } +} From 9d8987bde88b48b2f0668f80bdcdd140ddd4fd0f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 9 Apr 2017 10:59:54 -0700 Subject: [PATCH 074/177] Require getters to return the correct type --- serde/src/private/ser.rs | 6 +++++ serde_derive/src/ser.rs | 5 +++- .../tests/compile-fail/remote/wrong_getter.rs | 23 +++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 test_suite/tests/compile-fail/remote/wrong_getter.rs diff --git a/serde/src/private/ser.rs b/serde/src/private/ser.rs index c8d09d0b..333cb742 100644 --- a/serde/src/private/ser.rs +++ b/serde/src/private/ser.rs @@ -8,6 +8,12 @@ use self::content::{SerializeTupleVariantAsMapValue, SerializeStructVariantAsMap #[cfg(feature = "std")] use std::error; +/// Used to check that serde(getter) attributes return the expected type. +/// Not public API. +pub fn constrain(t: &T) -> &T { + t +} + /// Not public API. pub fn serialize_tagged_newtype(serializer: S, type_ident: &'static str, diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index 179c5d99..39c479c2 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -839,6 +839,9 @@ fn get_field(params: &Parameters, field: &Field, ident: I) -> Tokens let ident = ident.into(); quote!(&#self_var.#ident) } - Some(getter) => quote!(&#getter(#self_var)), + Some(getter) => { + let ty = field.ty; + quote!(_serde::private::ser::constrain::<#ty>(&#getter(#self_var))) + } } } diff --git a/test_suite/tests/compile-fail/remote/wrong_getter.rs b/test_suite/tests/compile-fail/remote/wrong_getter.rs new file mode 100644 index 00000000..f767263d --- /dev/null +++ b/test_suite/tests/compile-fail/remote/wrong_getter.rs @@ -0,0 +1,23 @@ +#[macro_use] +extern crate serde_derive; + +mod remote { + pub struct S { + a: u8, + } + + impl S { + pub fn get(&self) -> u16 { + self.a as u16 + } + } +} + +#[derive(Serialize)] //~ ERROR: mismatched types +#[serde(remote = "remote::S")] +struct S { + #[serde(getter = "remote::S::get")] + a: u8, //~^^^^ expected u8, found u16 +} + +fn main() {} From 5ec317a899ceed3596c7085b18238172f34126c1 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 9 Apr 2017 11:11:27 -0700 Subject: [PATCH 075/177] More compile-fail tests for remote derive --- .../tests/compile-fail/remote/bad_getter.rs | 17 +++++++++++++++++ .../tests/compile-fail/remote/bad_remote.rs | 16 ++++++++++++++++ .../tests/compile-fail/remote/enum_getter.rs | 19 +++++++++++++++++++ .../compile-fail/remote/nonremote_getter.rs | 16 ++++++++++++++++ 4 files changed, 68 insertions(+) create mode 100644 test_suite/tests/compile-fail/remote/bad_getter.rs create mode 100644 test_suite/tests/compile-fail/remote/bad_remote.rs create mode 100644 test_suite/tests/compile-fail/remote/enum_getter.rs create mode 100644 test_suite/tests/compile-fail/remote/nonremote_getter.rs diff --git a/test_suite/tests/compile-fail/remote/bad_getter.rs b/test_suite/tests/compile-fail/remote/bad_getter.rs new file mode 100644 index 00000000..3495a10b --- /dev/null +++ b/test_suite/tests/compile-fail/remote/bad_getter.rs @@ -0,0 +1,17 @@ +#[macro_use] +extern crate serde_derive; + +mod remote { + pub struct S { + a: u8, + } +} + +#[derive(Serialize)] //~ ERROR: proc-macro derive panicked +#[serde(remote = "remote::S")] +struct S { + #[serde(getter = "~~~")] //~^^^ HELP: failed to parse path: "~~~" + a: u8, +} + +fn main() {} diff --git a/test_suite/tests/compile-fail/remote/bad_remote.rs b/test_suite/tests/compile-fail/remote/bad_remote.rs new file mode 100644 index 00000000..5ef17670 --- /dev/null +++ b/test_suite/tests/compile-fail/remote/bad_remote.rs @@ -0,0 +1,16 @@ +#[macro_use] +extern crate serde_derive; + +mod remote { + pub struct S { + a: u8, + } +} + +#[derive(Serialize)] //~ ERROR: proc-macro derive panicked +#[serde(remote = "~~~")] //~^ HELP: failed to parse path: "~~~" +struct S { + a: u8, +} + +fn main() {} diff --git a/test_suite/tests/compile-fail/remote/enum_getter.rs b/test_suite/tests/compile-fail/remote/enum_getter.rs new file mode 100644 index 00000000..e012cbe1 --- /dev/null +++ b/test_suite/tests/compile-fail/remote/enum_getter.rs @@ -0,0 +1,19 @@ +#[macro_use] +extern crate serde_derive; + +mod remote { + pub enum E { + A { a: u8 } + } +} + +#[derive(Serialize)] //~ ERROR: proc-macro derive panicked +#[serde(remote = "remote::E")] +pub enum E { + A { + #[serde(getter = "get_a")] //~^^^^ HELP: #[serde(getter = "...")] is not allowed in an enum + a: u8, + } +} + +fn main() {} diff --git a/test_suite/tests/compile-fail/remote/nonremote_getter.rs b/test_suite/tests/compile-fail/remote/nonremote_getter.rs new file mode 100644 index 00000000..11271e5a --- /dev/null +++ b/test_suite/tests/compile-fail/remote/nonremote_getter.rs @@ -0,0 +1,16 @@ +#[macro_use] +extern crate serde_derive; + +#[derive(Serialize)] //~ ERROR: proc-macro derive panicked +struct S { + #[serde(getter = "S::get")] //~^^ HELP: #[serde(getter = "...")] can only be used in structs that have #[serde(remote = "...")] + a: u8, +} + +impl S { + fn get(&self) -> u8 { + self.a + } +} + +fn main() {} From 1986c1705214cb2e31ed61b78ced84b1f38955c3 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 9 Apr 2017 13:08:05 -0700 Subject: [PATCH 076/177] Remove conversion from empty seq to unit struct --- serde_derive/src/de.rs | 7 ------- test_suite/tests/test_de.rs | 15 +++++++-------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 5c84a649..4c4ffe14 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -168,13 +168,6 @@ fn deserialize_unit_struct(ident: &syn::Ident, item_attrs: &attr::Item) -> Fragm { _serde::export::Ok(#ident) } - - #[inline] - fn visit_seq<__V>(self, _: __V) -> _serde::export::Result<#ident, __V::Error> - where __V: _serde::de::SeqVisitor<'de> - { - _serde::export::Ok(#ident) - } } _serde::Deserializer::deserialize_unit_struct(__deserializer, #type_name, __Visitor) diff --git a/test_suite/tests/test_de.rs b/test_suite/tests/test_de.rs index bff0b48b..43fa0bf3 100644 --- a/test_suite/tests/test_de.rs +++ b/test_suite/tests/test_de.rs @@ -242,14 +242,6 @@ declare_tests! { UnitStruct => &[ Token::UnitStruct("UnitStruct"), ], - UnitStruct => &[ - Token::Seq(Some(0)), - Token::SeqEnd, - ], - UnitStruct => &[ - Token::Seq(None), - Token::SeqEnd, - ], } test_newtype_struct { NewtypeStruct(1) => &[ @@ -1036,4 +1028,11 @@ declare_error_tests! { ], Error::Message("invalid type: floating point `0`, expected isize".into()), } + test_unit_struct_from_seq { + &[ + Token::Seq(Some(0)), + Token::SeqEnd, + ], + Error::Message("invalid type: sequence, expected unit struct UnitStruct".into()), + } } From a38b24136b44618af5e2fff77d822c6d0ad25efc Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 9 Apr 2017 13:35:20 -0700 Subject: [PATCH 077/177] Rename deserialize_struct_field to deserialize_identifier Because it applies to both struct fields and discriminants of an enum. --- serde/src/de/impls.rs | 4 ++-- serde/src/de/mod.rs | 4 ++-- serde/src/de/value.rs | 22 +++++++++++----------- serde/src/macros.rs | 8 ++++---- serde/src/private/de.rs | 14 +++++++------- serde_derive/src/de.rs | 2 +- serde_test/src/de.rs | 4 ++-- 7 files changed, 29 insertions(+), 29 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 59793812..ffe3291c 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -1232,7 +1232,7 @@ impl<'de> Deserialize<'de> for Duration { } } - deserializer.deserialize_struct_field(FieldVisitor) + deserializer.deserialize_identifier(FieldVisitor) } } @@ -1358,7 +1358,7 @@ impl<'de, Idx: Deserialize<'de>> Deserialize<'de> for std::ops::Range { } } - deserializer.deserialize_struct_field(FieldVisitor) + deserializer.deserialize_identifier(FieldVisitor) } } diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 453a531b..754fa12e 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -911,8 +911,8 @@ pub trait Deserializer<'de>: Sized { where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting the name of a struct - /// field. - fn deserialize_struct_field(self, visitor: V) -> Result + /// field or the discriminant of an enum variant. + fn deserialize_identifier(self, visitor: V) -> Result where V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting an enum value with a diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 3b157b0c..1323450d 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -108,7 +108,7 @@ impl<'de, E> de::Deserializer<'de> for UnitDeserializer forward_to_deserialize! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct struct - struct_field tuple enum ignored_any byte_buf + identifier tuple enum ignored_any byte_buf } fn deserialize(self, visitor: V) -> Result @@ -155,7 +155,7 @@ macro_rules! primitive_deserializer { forward_to_deserialize! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct - tuple_struct struct struct_field tuple enum ignored_any byte_buf + tuple_struct struct identifier tuple enum ignored_any byte_buf } fn deserialize(self, visitor: V) -> Result @@ -208,7 +208,7 @@ impl<'de, E> de::Deserializer<'de> for U32Deserializer forward_to_deserialize! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct - struct struct_field tuple ignored_any byte_buf + struct identifier tuple ignored_any byte_buf } fn deserialize(self, visitor: V) -> Result @@ -286,7 +286,7 @@ impl<'de, 'a, E> de::Deserializer<'de> for StrDeserializer<'a, E> forward_to_deserialize! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct - struct struct_field tuple ignored_any byte_buf + struct identifier tuple ignored_any byte_buf } } @@ -351,7 +351,7 @@ impl<'de, E> de::Deserializer<'de> for StringDeserializer forward_to_deserialize! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct - struct struct_field tuple ignored_any byte_buf + struct identifier tuple ignored_any byte_buf } } @@ -420,7 +420,7 @@ impl<'de, 'a, E> de::Deserializer<'de> for CowStrDeserializer<'a, E> forward_to_deserialize! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct - struct struct_field tuple ignored_any byte_buf + struct identifier tuple ignored_any byte_buf } } @@ -495,7 +495,7 @@ impl<'de, I, T, E> de::Deserializer<'de> for SeqDeserializer forward_to_deserialize! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct - struct struct_field tuple enum ignored_any byte_buf + struct identifier tuple enum ignored_any byte_buf } } @@ -603,7 +603,7 @@ impl<'de, V_> de::Deserializer<'de> for SeqVisitorDeserializer forward_to_deserialize! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct - struct struct_field tuple enum ignored_any byte_buf + struct identifier tuple enum ignored_any byte_buf } } @@ -707,7 +707,7 @@ impl<'de, I, E> de::Deserializer<'de> for MapDeserializer<'de, I, E> forward_to_deserialize! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - bytes map unit_struct newtype_struct tuple_struct struct struct_field + bytes map unit_struct newtype_struct tuple_struct struct identifier tuple enum ignored_any byte_buf } } @@ -804,7 +804,7 @@ impl<'de, A, B, E> de::Deserializer<'de> for PairDeserializer forward_to_deserialize! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - bytes map unit_struct newtype_struct tuple_struct struct struct_field + bytes map unit_struct newtype_struct tuple_struct struct identifier tuple enum ignored_any byte_buf } @@ -945,7 +945,7 @@ impl<'de, V_> de::Deserializer<'de> for MapVisitorDeserializer forward_to_deserialize! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct - struct struct_field tuple enum ignored_any byte_buf + struct identifier tuple enum ignored_any byte_buf } } diff --git a/serde/src/macros.rs b/serde/src/macros.rs index 5873e1a7..80ababfa 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -89,8 +89,8 @@ macro_rules! forward_to_deserialize_helper { (struct) => { forward_to_deserialize_method!{deserialize_struct(&'static str, &'static [&'static str])} }; - (struct_field) => { - forward_to_deserialize_method!{deserialize_struct_field()} + (identifier) => { + forward_to_deserialize_method!{deserialize_identifier()} }; (tuple) => { forward_to_deserialize_method!{deserialize_tuple(usize)} @@ -143,7 +143,7 @@ macro_rules! forward_to_deserialize_helper { /// # forward_to_deserialize! { /// # u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option /// # seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct -/// # tuple_struct struct struct_field tuple enum ignored_any +/// # tuple_struct struct identifier tuple enum ignored_any /// # } /// # } /// # @@ -176,7 +176,7 @@ macro_rules! forward_to_deserialize_helper { /// forward_to_deserialize! { /// bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option /// seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct -/// tuple_struct struct struct_field tuple enum ignored_any +/// tuple_struct struct identifier tuple enum ignored_any /// } /// } /// # diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index f4e95dc6..2d019b42 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -52,7 +52,7 @@ pub fn missing_field<'de, V, E>(field: &'static str) -> Result forward_to_deserialize! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct - tuple_struct struct struct_field tuple enum ignored_any + tuple_struct struct identifier tuple enum ignored_any } } @@ -855,7 +855,7 @@ mod content { forward_to_deserialize! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq seq_fixed_size bytes byte_buf map unit_struct tuple_struct struct - struct_field tuple ignored_any + identifier tuple ignored_any } } @@ -996,7 +996,7 @@ mod content { forward_to_deserialize! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct - tuple_struct struct struct_field tuple enum ignored_any + tuple_struct struct identifier tuple enum ignored_any } } @@ -1085,7 +1085,7 @@ mod content { forward_to_deserialize! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct - tuple_struct struct struct_field tuple enum ignored_any + tuple_struct struct identifier tuple enum ignored_any } } @@ -1202,7 +1202,7 @@ mod content { forward_to_deserialize! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq seq_fixed_size bytes byte_buf map unit_struct tuple_struct struct - struct_field tuple ignored_any + identifier tuple ignored_any } } @@ -1341,7 +1341,7 @@ mod content { forward_to_deserialize! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct - tuple_struct struct struct_field tuple enum ignored_any + tuple_struct struct identifier tuple enum ignored_any } } @@ -1430,7 +1430,7 @@ mod content { forward_to_deserialize! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct - tuple_struct struct struct_field tuple enum ignored_any + tuple_struct struct identifier tuple enum ignored_any } } diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 4c4ffe14..2335cce1 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -1190,7 +1190,7 @@ fn deserialize_field_visitor(fields: Vec<(String, Ident)>, } } - _serde::Deserializer::deserialize_struct_field(__deserializer, __FieldVisitor) + _serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor) } } } diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index fcbb762b..243c8eb6 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -78,7 +78,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { forward_to_deserialize! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit - seq bytes byte_buf map struct_field ignored_any + seq bytes byte_buf map identifier ignored_any } fn deserialize(self, visitor: V) -> Result @@ -645,6 +645,6 @@ impl<'de> de::Deserializer<'de> for BytesDeserializer { forward_to_deserialize! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct - struct struct_field tuple enum ignored_any byte_buf + struct identifier tuple enum ignored_any byte_buf } } From 52e93150e6b26b0fba0b27f3e175e9470ab0e4df Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 9 Apr 2017 13:50:38 -0700 Subject: [PATCH 078/177] Standardize on u32 as the type of a variant index --- serde/src/private/macros.rs | 8 ++++---- serde/src/private/ser.rs | 32 ++++++++++++++++---------------- serde/src/ser/mod.rs | 8 ++++---- serde_derive/src/ser.rs | 16 +++++++++++----- serde_test/src/ser.rs | 8 ++++---- 5 files changed, 39 insertions(+), 33 deletions(-) diff --git a/serde/src/private/macros.rs b/serde/src/private/macros.rs index 4d40c510..f0e0703a 100644 --- a/serde/src/private/macros.rs +++ b/serde/src/private/macros.rs @@ -66,13 +66,13 @@ macro_rules! __serialize_unimplemented_helper { __serialize_unimplemented_method!(serialize_unit_struct(&str) -> Ok); }; (unit_variant) => { - __serialize_unimplemented_method!(serialize_unit_variant(&str, usize, &str) -> Ok); + __serialize_unimplemented_method!(serialize_unit_variant(&str, u32, &str) -> Ok); }; (newtype_struct) => { __serialize_unimplemented_method!(serialize_newtype_struct(&str, &T) -> Ok); }; (newtype_variant) => { - __serialize_unimplemented_method!(serialize_newtype_variant(&str, usize, &str, &T) -> Ok); + __serialize_unimplemented_method!(serialize_newtype_variant(&str, u32, &str, &T) -> Ok); }; (seq) => { type SerializeSeq = $crate::ser::Impossible; @@ -91,7 +91,7 @@ macro_rules! __serialize_unimplemented_helper { }; (tuple_variant) => { type SerializeTupleVariant = $crate::ser::Impossible; - __serialize_unimplemented_method!(serialize_tuple_variant(&str, usize, &str, usize) -> SerializeTupleVariant); + __serialize_unimplemented_method!(serialize_tuple_variant(&str, u32, &str, usize) -> SerializeTupleVariant); }; (map) => { type SerializeMap = $crate::ser::Impossible; @@ -103,7 +103,7 @@ macro_rules! __serialize_unimplemented_helper { }; (struct_variant) => { type SerializeStructVariant = $crate::ser::Impossible; - __serialize_unimplemented_method!(serialize_struct_variant(&str, usize, &str, usize) -> SerializeStructVariant); + __serialize_unimplemented_method!(serialize_struct_variant(&str, u32, &str, usize) -> SerializeStructVariant); }; } diff --git a/serde/src/private/ser.rs b/serde/src/private/ser.rs index c8d09d0b..157d7656 100644 --- a/serde/src/private/ser.rs +++ b/serde/src/private/ser.rs @@ -184,7 +184,7 @@ impl Serializer for TaggedSerializer fn serialize_unit_variant(self, _: &'static str, - _: usize, + _: u32, inner_variant: &'static str) -> Result { let mut map = try!(self.delegate.serialize_map(Some(2))); @@ -204,7 +204,7 @@ impl Serializer for TaggedSerializer fn serialize_newtype_variant(self, _: &'static str, - _: usize, + _: u32, inner_variant: &'static str, inner_value: &T) -> Result @@ -238,7 +238,7 @@ impl Serializer for TaggedSerializer #[cfg(not(any(feature = "std", feature = "collections")))] fn serialize_tuple_variant(self, _: &'static str, - _: usize, + _: u32, _: &'static str, _: usize) -> Result { @@ -250,7 +250,7 @@ impl Serializer for TaggedSerializer #[cfg(any(feature = "std", feature = "collections"))] fn serialize_tuple_variant(self, _: &'static str, - _: usize, + _: u32, inner_variant: &'static str, len: usize) -> Result { @@ -278,7 +278,7 @@ impl Serializer for TaggedSerializer #[cfg(not(any(feature = "std", feature = "collections")))] fn serialize_struct_variant(self, _: &'static str, - _: usize, + _: u32, _: &'static str, _: usize) -> Result { @@ -290,7 +290,7 @@ impl Serializer for TaggedSerializer #[cfg(any(feature = "std", feature = "collections"))] fn serialize_struct_variant(self, _: &'static str, - _: usize, + _: u32, inner_variant: &'static str, len: usize) -> Result { @@ -444,18 +444,18 @@ mod content { Unit, UnitStruct(&'static str), - UnitVariant(&'static str, usize, &'static str), + UnitVariant(&'static str, u32, &'static str), NewtypeStruct(&'static str, Box), - NewtypeVariant(&'static str, usize, &'static str, Box), + NewtypeVariant(&'static str, u32, &'static str, Box), Seq(Vec), SeqFixedSize(Vec), Tuple(Vec), TupleStruct(&'static str, Vec), - TupleVariant(&'static str, usize, &'static str, Vec), + TupleVariant(&'static str, u32, &'static str, Vec), Map(Vec<(Content, Content)>), Struct(&'static str, Vec<(&'static str, Content)>), - StructVariant(&'static str, usize, &'static str, Vec<(&'static str, Content)>), + StructVariant(&'static str, u32, &'static str, Vec<(&'static str, Content)>), } impl Serialize for Content { @@ -645,7 +645,7 @@ mod content { fn serialize_unit_variant(self, name: &'static str, - variant_index: usize, + variant_index: u32, variant: &'static str) -> Result { Ok(Content::UnitVariant(name, variant_index, variant)) @@ -660,7 +660,7 @@ mod content { fn serialize_newtype_variant(self, name: &'static str, - variant_index: usize, + variant_index: u32, variant: &'static str, value: &T) -> Result { @@ -706,7 +706,7 @@ mod content { fn serialize_tuple_variant(self, name: &'static str, - variant_index: usize, + variant_index: u32, variant: &'static str, len: usize) -> Result { @@ -737,7 +737,7 @@ mod content { fn serialize_struct_variant(self, name: &'static str, - variant_index: usize, + variant_index: u32, variant: &'static str, len: usize) -> Result { @@ -825,7 +825,7 @@ mod content { struct SerializeTupleVariant { name: &'static str, - variant_index: usize, + variant_index: u32, variant: &'static str, fields: Vec, error: PhantomData, @@ -916,7 +916,7 @@ mod content { struct SerializeStructVariant { name: &'static str, - variant_index: usize, + variant_index: u32, variant: &'static str, fields: Vec<(&'static str, Content)>, error: PhantomData, diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 332bdfab..1a20646a 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -449,7 +449,7 @@ pub trait Serializer: Sized { /// ``` fn serialize_unit_variant(self, name: &'static str, - variant_index: usize, + variant_index: u32, variant: &'static str) -> Result; @@ -504,7 +504,7 @@ pub trait Serializer: Sized { /// ``` fn serialize_newtype_variant(self, name: &'static str, - variant_index: usize, + variant_index: u32, variant: &'static str, value: &T) -> Result; @@ -686,7 +686,7 @@ pub trait Serializer: Sized { /// ``` fn serialize_tuple_variant(self, name: &'static str, - variant_index: usize, + variant_index: u32, variant: &'static str, len: usize) -> Result; @@ -806,7 +806,7 @@ pub trait Serializer: Sized { /// ``` fn serialize_struct_variant(self, name: &'static str, - variant_index: usize, + variant_index: u32, variant: &'static str, len: usize) -> Result; diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index 51826928..d7d05dc4 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -6,6 +6,8 @@ use fragment::{Fragment, Stmts, Match}; use internals::ast::{Body, Field, Item, Style, Variant}; use internals::{self, attr}; +use std::u32; + pub fn expand_derive_serialize(item: &syn::DeriveInput) -> Result { let ctxt = internals::Ctxt::new(); let item = Item::from_ast(&ctxt, item); @@ -149,6 +151,8 @@ fn serialize_struct(ident: &syn::Ident, fields: &[Field], item_attrs: &attr::Item) -> Fragment { + assert!(fields.len() as u64 <= u32::MAX as u64); + let serialize_fields = serialize_struct_visitor(ident, fields, @@ -187,13 +191,15 @@ fn serialize_item_enum(ident: &syn::Ident, variants: &[Variant], item_attrs: &attr::Item) -> Fragment { + assert!(variants.len() as u64 <= u32::MAX as u64); + let arms: Vec<_> = variants.iter() .enumerate() .map(|(variant_index, variant)| { serialize_variant(ident, generics, variant, - variant_index, + variant_index as u32, item_attrs) }) .collect(); @@ -208,7 +214,7 @@ fn serialize_item_enum(ident: &syn::Ident, fn serialize_variant(ident: &syn::Ident, generics: &syn::Generics, variant: &Variant, - variant_index: usize, + variant_index: u32, item_attrs: &attr::Item) -> Tokens { let variant_ident = variant.ident.clone(); @@ -292,7 +298,7 @@ fn serialize_variant(ident: &syn::Ident, fn serialize_externally_tagged_variant(ident: &syn::Ident, generics: &syn::Generics, variant: &Variant, - variant_index: usize, + variant_index: u32, item_attrs: &attr::Item) -> Fragment { let type_name = item_attrs.name().serialize_name(); @@ -538,7 +544,7 @@ fn serialize_untagged_variant(ident: &syn::Ident, enum TupleVariant { ExternallyTagged { type_name: String, - variant_index: usize, + variant_index: u32, variant_name: String, }, Untagged, @@ -589,7 +595,7 @@ fn serialize_tuple_variant(context: TupleVariant, enum StructVariant<'a> { ExternallyTagged { - variant_index: usize, + variant_index: u32, variant_name: String, }, InternallyTagged { tag: &'a str, variant_name: String }, diff --git a/serde_test/src/ser.rs b/serde_test/src/ser.rs index 2a82970f..f6c401ee 100644 --- a/serde_test/src/ser.rs +++ b/serde_test/src/ser.rs @@ -146,7 +146,7 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { fn serialize_unit_variant(self, name: &'static str, - _variant_index: usize, + _variant_index: u32, variant: &'static str) -> Result<(), Error> { if self.tokens.first() == Some(&Token::Enum(name)) { @@ -168,7 +168,7 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { fn serialize_newtype_variant(self, name: &'static str, - _variant_index: usize, + _variant_index: u32, variant: &'static str, value: &T) -> Result<(), Error> @@ -217,7 +217,7 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { fn serialize_tuple_variant(self, name: &'static str, - _variant_index: usize, + _variant_index: u32, variant: &'static str, len: usize) -> Result { @@ -237,7 +237,7 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { fn serialize_struct_variant(self, name: &'static str, - _variant_index: usize, + _variant_index: u32, variant: &'static str, len: usize) -> Result { From e133b8b708c9dc3f340c79dee64e408a08deb360 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 9 Apr 2017 14:11:27 -0700 Subject: [PATCH 079/177] Fix unused import on windows --- test_suite/tests/test_ser.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test_suite/tests/test_ser.rs b/test_suite/tests/test_ser.rs index 3c5b4385..a01af687 100644 --- a/test_suite/tests/test_ser.rs +++ b/test_suite/tests/test_ser.rs @@ -4,10 +4,12 @@ extern crate serde_derive; use std::collections::{BTreeMap, HashMap, HashSet}; use std::net; use std::path::{Path, PathBuf}; -use std::str; use std::time::Duration; use std::ffi::CString; +#[cfg(unix)] +use std::str; + extern crate serde; extern crate serde_test; From 2deacf8eaad547c0aa415b0a07998fddaf0cb702 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 10 Apr 2017 12:12:00 -0700 Subject: [PATCH 080/177] Detect incorrect remote type without getter --- serde_derive/src/ser.rs | 21 +++++++++++++++---- .../tests/compile-fail/remote/wrong_ser.rs | 16 ++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 test_suite/tests/compile-fail/remote/wrong_ser.rs diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index 39c479c2..7b893e44 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -61,11 +61,15 @@ struct Parameters { /// Generics including any explicit and inferred bounds for the impl. generics: syn::Generics, + + /// Type has a `serde(remote = "...")` attribute. + is_remote: bool, } impl Parameters { fn new(item: &Item) -> Self { - let self_var = if item.attrs.remote().is_some() { + let is_remote = item.attrs.remote().is_some(); + let self_var = if is_remote { Ident::new("__self") } else { Ident::new("self") @@ -82,6 +86,7 @@ impl Parameters { self_var: self_var, this: this, generics: generics, + is_remote: is_remote, } } @@ -834,14 +839,22 @@ fn get_field(params: &Parameters, field: &Field, ident: I) -> Tokens where I: Into { let self_var = ¶ms.self_var; - match field.attrs.getter() { - None => { + match (params.is_remote, field.attrs.getter()) { + (false, None) => { let ident = ident.into(); quote!(&#self_var.#ident) } - Some(getter) => { + (true, None) => { + let ty = field.ty; + let ident = ident.into(); + quote!(_serde::private::ser::constrain::<#ty>(&#self_var.#ident)) + } + (true, Some(getter)) => { let ty = field.ty; quote!(_serde::private::ser::constrain::<#ty>(&#getter(#self_var))) } + (false, Some(_)) => { + unreachable!("getter is only allowed for remote impls"); + } } } diff --git a/test_suite/tests/compile-fail/remote/wrong_ser.rs b/test_suite/tests/compile-fail/remote/wrong_ser.rs new file mode 100644 index 00000000..bd4ca1a2 --- /dev/null +++ b/test_suite/tests/compile-fail/remote/wrong_ser.rs @@ -0,0 +1,16 @@ +#[macro_use] +extern crate serde_derive; + +mod remote { + pub struct S { + pub a: u16, + } +} + +#[derive(Serialize)] //~ ERROR: mismatched types +#[serde(remote = "remote::S")] +struct S { + a: u8, //~^^^ expected u8, found u16 +} + +fn main() {} From ad5bf04c4e983f7663ae58e3728e93610b3ce3f3 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 10 Apr 2017 12:15:40 -0700 Subject: [PATCH 081/177] Test for incorrect remote type deserializing --- test_suite/tests/compile-fail/remote/wrong_de.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 test_suite/tests/compile-fail/remote/wrong_de.rs diff --git a/test_suite/tests/compile-fail/remote/wrong_de.rs b/test_suite/tests/compile-fail/remote/wrong_de.rs new file mode 100644 index 00000000..58a05e19 --- /dev/null +++ b/test_suite/tests/compile-fail/remote/wrong_de.rs @@ -0,0 +1,12 @@ +#[macro_use] +extern crate serde_derive; + +mod remote { + pub struct S(pub u16); +} + +#[derive(Deserialize)] //~ ERROR: mismatched types +#[serde(remote = "remote::S")] +struct S(u8); //~^^ expected u16, found u8 + +fn main() {} From 174867295b8f7e9af18556bd7dd16b3d1fa9ba1e Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 10 Apr 2017 12:22:51 -0700 Subject: [PATCH 082/177] Test missing field in remote struct --- .../tests/compile-fail/remote/missing_field.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 test_suite/tests/compile-fail/remote/missing_field.rs diff --git a/test_suite/tests/compile-fail/remote/missing_field.rs b/test_suite/tests/compile-fail/remote/missing_field.rs new file mode 100644 index 00000000..3be802a6 --- /dev/null +++ b/test_suite/tests/compile-fail/remote/missing_field.rs @@ -0,0 +1,17 @@ +#[macro_use] +extern crate serde_derive; + +mod remote { + pub struct S { + pub a: u8, + pub b: u8, + } +} + +#[derive(Serialize, Deserialize)] //~ ERROR: missing field `b` in initializer of `remote::S` +#[serde(remote = "remote::S")] +struct S { + a: u8, //~^^^ ERROR: missing field `b` in initializer of `remote::S` +} + +fn main() {} From 6a6606cd64e04c47dc370218b59f6ada201e2b70 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 10 Apr 2017 12:23:02 -0700 Subject: [PATCH 083/177] Test unknown field in remote struct --- .../tests/compile-fail/remote/unknown_field.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 test_suite/tests/compile-fail/remote/unknown_field.rs diff --git a/test_suite/tests/compile-fail/remote/unknown_field.rs b/test_suite/tests/compile-fail/remote/unknown_field.rs new file mode 100644 index 00000000..8f2fa481 --- /dev/null +++ b/test_suite/tests/compile-fail/remote/unknown_field.rs @@ -0,0 +1,16 @@ +#[macro_use] +extern crate serde_derive; + +mod remote { + pub struct S { + pub a: u8, + } +} + +#[derive(Serialize, Deserialize)] +#[serde(remote = "remote::S")] +struct S { + b: u8, //~^^^ ERROR: no field `b` on type `&remote::S` +} + +fn main() {} From 8bbab627a0d56693c4137a16b54e72f12e1d6b2d Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 10 Apr 2017 16:38:11 -0700 Subject: [PATCH 084/177] Document the cargo cfgs --- serde/Cargo.toml | 60 +++++++++++++++++++++++++++++++++++++----------- travis.sh | 6 ++--- 2 files changed, 50 insertions(+), 16 deletions(-) diff --git a/serde/Cargo.toml b/serde/Cargo.toml index 277c6798..0c3f0c3b 100644 --- a/serde/Cargo.toml +++ b/serde/Cargo.toml @@ -16,21 +16,55 @@ publish = false # this branch contains breaking changes [badges] travis-ci = { repository = "serde-rs/serde" } -[features] -default = ["std"] -derive = ["serde_derive"] - -std = [] -unstable = [] -alloc = ["unstable"] -collections = ["alloc"] -unstable-testing = ["unstable", "std"] - -# to get serde_derive picked up by play.integer32.com -playground = ["serde_derive"] - [dependencies] serde_derive = { version = "0.9", optional = true, path = "../serde_derive" } [dev-dependencies] serde_derive = { version = "0.9", path = "../serde_derive" } + + +### FEATURES ################################################################# + +[features] +default = ["std"] + +# Re-export the derive(Serialize, Deserialize) macros. This is specifically +# intended for library crates that provide optional Serde impls behind a Cargo +# cfg of their own. All other crates should depend on serde_derive directly. +# +# Please refer to the long comment above the line `pub use serde_derive::*` in +# src/lib.rs before enabling this feature. If you think you need this feature +# and your use case does not precisely match the one described in the comment, +# please open an issue to let us know about your use case. +derive = ["serde_derive"] + +# Provide impls for common standard library types like Vec and HashMap. +# Requires a dependency on the Rust standard library. +std = [] + +# Provide impls for types that require unstable functionality. For tracking and +# discussion of unstable functionality please refer to this issue: +# +# https://github.com/serde-rs/serde/issues/812 +unstable = [] + +# Provide impls for types that require memory allocation like Box and Rc. +# This is a subset of std but may be enabled without depending on all of std. +# +# Requires a dependency on the unstable core allocation library: +# +# https://doc.rust-lang.org/alloc/ +alloc = ["unstable"] + +# Provide impls for collection types like String and Cow. This is a subset of +# std but may be enabled without depending on all of std. +# +# Requires a dependency on the unstable collections library: +# +# https://doc.rust-lang.org/collections/ +collections = ["alloc"] + +# Get serde_derive picked up by the Integer 32 playground. Not public API. +# +# http://play.integer32.com/ +playground = ["serde_derive"] diff --git a/travis.sh b/travis.sh index d5f62d28..a4023469 100755 --- a/travis.sh +++ b/travis.sh @@ -29,10 +29,10 @@ if [ -n "${CLIPPY}" ]; then fi cd "$DIR/serde" - cargo clippy --features unstable-testing -- -Dclippy + cargo clippy --features unstable -- -Dclippy cd "$DIR/serde_derive" - cargo clippy --features unstable-testing -- -Dclippy + cargo clippy --features unstable -- -Dclippy cd "$DIR/test_suite" cargo clippy --features unstable -- -Dclippy @@ -47,7 +47,7 @@ else channel build --no-default-features channel build --no-default-features --features alloc channel build --no-default-features --features collections - channel test --features unstable-testing + channel test --features unstable cd "$DIR/test_suite/deps" channel build cd "$DIR/test_suite" From 0f72d1a3888c14314133f56ea3b3617885a82338 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 10 Apr 2017 17:01:11 -0700 Subject: [PATCH 085/177] Put rc impls behind a cfg --- serde/Cargo.toml | 5 +++++ serde/src/de/impls.rs | 12 ++++++------ serde/src/ser/impls.rs | 12 ++++++------ travis.sh | 10 +++++----- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/serde/Cargo.toml b/serde/Cargo.toml index 0c3f0c3b..12020eeb 100644 --- a/serde/Cargo.toml +++ b/serde/Cargo.toml @@ -64,6 +64,11 @@ alloc = ["unstable"] # https://doc.rust-lang.org/collections/ collections = ["alloc"] +# Opt into impls for Rc and Arc. Serializing and deserializing these types +# 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 = [] + # Get serde_derive picked up by the Integer 32 playground. Not public API. # # http://play.integer32.com/ diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index ffe3291c..5416fab8 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -28,14 +28,14 @@ use std::ffi::{CString, OsString}; #[cfg(all(feature = "std", feature = "unstable"))] use std::ffi::CStr; -#[cfg(feature = "std")] +#[cfg(all(feature = "rc", feature = "std"))] use std::rc::Rc; -#[cfg(all(feature = "alloc", not(feature = "std")))] +#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))] use alloc::rc::Rc; -#[cfg(feature = "std")] +#[cfg(all(feature = "rc", feature = "std"))] use std::sync::Arc; -#[cfg(all(feature = "alloc", not(feature = "std")))] +#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))] use alloc::arc::Arc; #[cfg(all(feature = "alloc", not(feature = "std")))] @@ -1141,7 +1141,7 @@ impl<'de> Deserialize<'de> for Box { } } -#[cfg(any(feature = "std", feature = "alloc"))] +#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] impl<'de, T: Deserialize<'de>> Deserialize<'de> for Arc { fn deserialize(deserializer: D) -> Result, D::Error> where D: Deserializer<'de> @@ -1151,7 +1151,7 @@ impl<'de, T: Deserialize<'de>> Deserialize<'de> for Arc { } } -#[cfg(any(feature = "std", feature = "alloc"))] +#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] impl<'de, T: Deserialize<'de>> Deserialize<'de> for Rc { fn deserialize(deserializer: D) -> Result, D::Error> where D: Deserializer<'de> diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index d0a74b97..e51a2999 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -17,16 +17,16 @@ use core::hash::{Hash, BuildHasher}; use std::{net, ops, path}; #[cfg(feature = "std")] use std::ffi::{CString, CStr, OsString, OsStr}; -#[cfg(feature = "std")] +#[cfg(all(feature = "rc", feature = "std"))] use std::rc::Rc; -#[cfg(all(feature = "alloc", not(feature = "std")))] +#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))] use alloc::rc::Rc; #[cfg(feature = "std")] use std::time::Duration; -#[cfg(feature = "std")] +#[cfg(all(feature = "rc", feature = "std"))] use std::sync::Arc; -#[cfg(all(feature = "alloc", not(feature = "std")))] +#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))] use alloc::arc::Arc; #[cfg(all(feature = "alloc", not(feature = "std")))] @@ -555,7 +555,7 @@ impl Serialize for Box } } -#[cfg(any(feature = "std", feature = "alloc"))] +#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] impl Serialize for Rc where T: Serialize { @@ -567,7 +567,7 @@ impl Serialize for Rc } } -#[cfg(any(feature = "std", feature = "alloc"))] +#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] impl Serialize for Arc where T: Serialize { diff --git a/travis.sh b/travis.sh index a4023469..0f49838f 100755 --- a/travis.sh +++ b/travis.sh @@ -29,7 +29,7 @@ if [ -n "${CLIPPY}" ]; then fi cd "$DIR/serde" - cargo clippy --features unstable -- -Dclippy + cargo clippy --features 'rc unstable' -- -Dclippy cd "$DIR/serde_derive" cargo clippy --features unstable -- -Dclippy @@ -47,7 +47,7 @@ else channel build --no-default-features channel build --no-default-features --features alloc channel build --no-default-features --features collections - channel test --features unstable + channel test --features 'rc unstable' cd "$DIR/test_suite/deps" channel build cd "$DIR/test_suite" @@ -58,19 +58,19 @@ else CHANNEL=beta cargo clean cd "$DIR/serde" - channel build + channel build --features rc cd "$DIR/test_suite" channel test CHANNEL=stable cargo clean cd "$DIR/serde" - channel build + channel build --features rc channel build --no-default-features CHANNEL=1.13.0 cargo clean cd "$DIR/serde" - channel build + channel build --features rc channel build --no-default-features fi From 0b7accf86cbae032edba1818e5bf2dfa022bd5d1 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 10 Apr 2017 17:29:54 -0700 Subject: [PATCH 086/177] Remove unused unstable flag from serde_derive --- serde_derive/Cargo.toml | 3 --- travis.sh | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/serde_derive/Cargo.toml b/serde_derive/Cargo.toml index 23b0a134..866da94b 100644 --- a/serde_derive/Cargo.toml +++ b/serde_derive/Cargo.toml @@ -12,9 +12,6 @@ readme = "../README.md" include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] publish = false # this branch contains breaking changes -[features] -unstable = [] - [badges] travis-ci = { repository = "serde-rs/serde" } diff --git a/travis.sh b/travis.sh index 0f49838f..7a122feb 100755 --- a/travis.sh +++ b/travis.sh @@ -32,7 +32,7 @@ if [ -n "${CLIPPY}" ]; then cargo clippy --features 'rc unstable' -- -Dclippy cd "$DIR/serde_derive" - cargo clippy --features unstable -- -Dclippy + cargo clippy -- -Dclippy cd "$DIR/test_suite" cargo clippy --features unstable -- -Dclippy From f88db0f547ebdea78a90cdaf7946f86f8d729d23 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 10 Apr 2017 18:50:22 -0700 Subject: [PATCH 087/177] Centralize all import wrangling --- serde/src/de/from_primitive.rs | 4 +- serde/src/de/ignored_any.rs | 2 +- serde/src/de/impls.rs | 66 +++----------------------- serde/src/de/mod.rs | 11 +---- serde/src/de/utf8.rs | 4 +- serde/src/de/value.rs | 39 ++++------------ serde/src/export.rs | 27 ++++------- serde/src/lib.rs | 85 ++++++++++++++++++++++++++++++---- serde/src/private/de.rs | 28 +---------- serde/src/private/ser.rs | 16 +------ serde/src/ser/impls.rs | 51 +++----------------- serde/src/ser/impossible.rs | 2 +- serde/src/ser/mod.rs | 13 +----- 13 files changed, 122 insertions(+), 226 deletions(-) diff --git a/serde/src/de/from_primitive.rs b/serde/src/de/from_primitive.rs index 88f53e17..9ec25904 100644 --- a/serde/src/de/from_primitive.rs +++ b/serde/src/de/from_primitive.rs @@ -8,9 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::{usize, u8, u16, u32, u64}; -use core::{isize, i8, i16, i32, i64}; -use core::{f32, f64}; +use lib::*; macro_rules! int_to_int { ($dst:ident, $n:ident) => ( diff --git a/serde/src/de/ignored_any.rs b/serde/src/de/ignored_any.rs index 3ee68433..1bea30fd 100644 --- a/serde/src/de/ignored_any.rs +++ b/serde/src/de/ignored_any.rs @@ -1,4 +1,4 @@ -use core::fmt; +use lib::*; use de::{Deserialize, Deserializer, Visitor, SeqVisitor, MapVisitor, Error}; diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 5416fab8..e227fac7 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -1,63 +1,11 @@ -#[cfg(feature = "std")] -use std::borrow::Cow; -#[cfg(all(feature = "collections", not(feature = "std")))] -use collections::borrow::Cow; - -#[cfg(all(feature = "collections", not(feature = "std")))] -use collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque, Vec, String}; - -#[cfg(feature = "std")] -use std::collections::{HashMap, HashSet, BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque}; - -#[cfg(feature = "collections")] -use collections::borrow::ToOwned; - -#[cfg(any(feature = "std", feature = "collections"))] -use core::cmp; -use core::fmt; -#[cfg(feature = "std")] -use core::hash::{Hash, BuildHasher}; -use core::marker::PhantomData; -#[cfg(feature = "std")] -use std::net; -#[cfg(feature = "std")] -use std::path; -use core::str; -#[cfg(feature = "std")] -use std::ffi::{CString, OsString}; -#[cfg(all(feature = "std", feature = "unstable"))] -use std::ffi::CStr; - -#[cfg(all(feature = "rc", feature = "std"))] -use std::rc::Rc; -#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))] -use alloc::rc::Rc; - -#[cfg(all(feature = "rc", feature = "std"))] -use std::sync::Arc; -#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))] -use alloc::arc::Arc; - -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::boxed::Box; - -#[cfg(feature = "std")] -use std::time::Duration; - -#[cfg(feature = "std")] -use std; - -#[cfg(feature = "unstable")] -use core::nonzero::{NonZero, Zeroable}; - -#[cfg(feature = "unstable")] -#[allow(deprecated)] // required for impl Deserialize for NonZero -use core::num::Zero; +use lib::*; use de::{Deserialize, Deserializer, EnumVisitor, Error, SeqVisitor, Unexpected, VariantVisitor, Visitor}; + #[cfg(any(feature = "std", feature = "collections"))] use de::MapVisitor; + use de::from_primitive::FromPrimitive; /////////////////////////////////////////////////////////////////////////////// @@ -1312,7 +1260,7 @@ impl<'de> Deserialize<'de> for Duration { // end: u32, // } #[cfg(feature = "std")] -impl<'de, Idx: Deserialize<'de>> Deserialize<'de> for std::ops::Range { +impl<'de, Idx: Deserialize<'de>> Deserialize<'de> for ops::Range { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { @@ -1367,13 +1315,13 @@ impl<'de, Idx: Deserialize<'de>> Deserialize<'de> for std::ops::Range { } impl<'de, Idx: Deserialize<'de>> Visitor<'de> for RangeVisitor { - type Value = std::ops::Range; + type Value = ops::Range; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("struct Range") } - fn visit_seq(self, mut visitor: V) -> Result, V::Error> + fn visit_seq(self, mut visitor: V) -> Result, V::Error> where V: SeqVisitor<'de> { let start: Idx = match try!(visitor.visit()) { @@ -1391,7 +1339,7 @@ impl<'de, Idx: Deserialize<'de>> Deserialize<'de> for std::ops::Range { Ok(start..end) } - fn visit_map(self, mut visitor: V) -> Result, V::Error> + fn visit_map(self, mut visitor: V) -> Result, V::Error> where V: MapVisitor<'de> { let mut start: Option = None; diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 754fa12e..7e040490 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -94,16 +94,7 @@ //! [bincode]: https://github.com/TyOverby/bincode //! [data-formats]: https://serde.rs/#data-formats -#[cfg(feature = "std")] -use std::error; - -#[cfg(all(not(feature = "std"), feature = "collections"))] -use collections::{String, Vec}; - -use core::fmt::{self, Display}; -#[cfg(not(feature = "std"))] -use core::fmt::Debug; -use core::marker::PhantomData; +use lib::*; /////////////////////////////////////////////////////////////////////////////// diff --git a/serde/src/de/utf8.rs b/serde/src/de/utf8.rs index 8e02e253..27ad1b2d 100644 --- a/serde/src/de/utf8.rs +++ b/serde/src/de/utf8.rs @@ -1,3 +1,5 @@ +use lib::*; + const TAG_CONT: u8 = 0b1000_0000; const TAG_TWO_B: u8 = 0b1100_0000; const TAG_THREE_B: u8 = 0b1110_0000; @@ -43,6 +45,6 @@ pub struct Encode { impl Encode { // FIXME: use this from_utf8_unchecked, since we know it can never fail pub fn as_str(&self) -> &str { - ::core::str::from_utf8(&self.buf[self.pos..]).unwrap() + str::from_utf8(&self.buf[self.pos..]).unwrap() } } diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 1323450d..5a261334 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -1,30 +1,6 @@ //! This module supports deserializing from primitives with the `ValueDeserializer` trait. -#[cfg(feature = "std")] -use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, btree_map, btree_set, hash_map, - hash_set}; -#[cfg(feature = "std")] -use std::borrow::Cow; -#[cfg(feature = "std")] -use std::vec; - -#[cfg(all(feature = "collections", not(feature = "std")))] -use collections::{BTreeMap, BTreeSet, Vec, String, btree_map, btree_set, vec}; -#[cfg(all(feature = "collections", not(feature = "std")))] -use collections::borrow::Cow; -#[cfg(all(feature = "collections", not(feature = "std")))] -use collections::boxed::Box; -#[cfg(all(feature = "collections", not(feature = "std")))] -use collections::string::ToString; - -#[cfg(feature = "std")] -use core::hash::Hash; -#[cfg(feature = "std")] -use std::error; - -use core::fmt::{self, Display}; -use core::iter::{self, Iterator}; -use core::marker::PhantomData; +use lib::*; use de::{self, Expected, SeqVisitor}; @@ -542,7 +518,7 @@ impl<'de, T, E> ValueDeserializer<'de, E> for Vec where T: ValueDeserializer<'de, E>, E: de::Error { - type Deserializer = SeqDeserializer, E>; + type Deserializer = SeqDeserializer< as IntoIterator>::IntoIter, E>; fn into_deserializer(self) -> Self::Deserializer { SeqDeserializer::new(self.into_iter()) @@ -554,7 +530,7 @@ impl<'de, T, E> ValueDeserializer<'de, E> for BTreeSet where T: ValueDeserializer<'de, E> + Eq + Ord, E: de::Error { - type Deserializer = SeqDeserializer, E>; + type Deserializer = SeqDeserializer< as IntoIterator>::IntoIter, E>; fn into_deserializer(self) -> Self::Deserializer { SeqDeserializer::new(self.into_iter()) @@ -566,7 +542,7 @@ impl<'de, T, E> ValueDeserializer<'de, E> for HashSet where T: ValueDeserializer<'de, E> + Eq + Hash, E: de::Error { - type Deserializer = SeqDeserializer, E>; + type Deserializer = SeqDeserializer< as IntoIterator>::IntoIter, E>; fn into_deserializer(self) -> Self::Deserializer { SeqDeserializer::new(self.into_iter()) @@ -895,7 +871,7 @@ impl<'de, K, V, E> ValueDeserializer<'de, E> for BTreeMap V: ValueDeserializer<'de, E>, E: de::Error { - type Deserializer = MapDeserializer<'de, btree_map::IntoIter, E>; + type Deserializer = MapDeserializer<'de, as IntoIterator>::IntoIter, E>; fn into_deserializer(self) -> Self::Deserializer { MapDeserializer::new(self.into_iter()) @@ -908,7 +884,7 @@ impl<'de, K, V, E> ValueDeserializer<'de, E> for HashMap V: ValueDeserializer<'de, E>, E: de::Error { - type Deserializer = MapDeserializer<'de, hash_map::IntoIter, E>; + type Deserializer = MapDeserializer<'de, as IntoIterator>::IntoIter, E>; fn into_deserializer(self) -> Self::Deserializer { MapDeserializer::new(self.into_iter()) @@ -952,8 +928,9 @@ impl<'de, V_> de::Deserializer<'de> for MapVisitorDeserializer /////////////////////////////////////////////////////////////////////////////// mod private { + use lib::*; + use de::{self, Unexpected}; - use core::marker::PhantomData; pub struct UnitOnly { marker: PhantomData, diff --git a/serde/src/export.rs b/serde/src/export.rs index c4fd3c68..a2014233 100644 --- a/serde/src/export.rs +++ b/serde/src/export.rs @@ -1,20 +1,14 @@ -#[cfg(all(feature = "collections", not(feature = "std")))] -use collections::String; +use lib::*; -#[cfg(feature = "std")] -use std::borrow::Cow; -#[cfg(all(feature = "collections", not(feature = "std")))] -use collections::borrow::Cow; +pub use lib::clone::Clone; +pub use lib::convert::{From, Into}; +pub use lib::default::Default; +pub use lib::fmt; +pub use lib::marker::PhantomData; +pub use lib::option::Option::{self, None, Some}; +pub use lib::result::Result::{self, Ok, Err}; -pub use core::clone::Clone; -pub use core::convert::{From, Into}; -pub use core::default::Default; -pub use core::fmt; -pub use core::marker::PhantomData; -pub use core::option::Option::{self, None, Some}; -pub use core::result::Result::{self, Ok, Err}; - -#[cfg(any(feature = "collections", feature = "std"))] +#[cfg(any(feature = "std", feature = "collections"))] pub fn from_utf8_lossy(bytes: &[u8]) -> Cow { String::from_utf8_lossy(bytes) } @@ -26,9 +20,8 @@ pub fn from_utf8_lossy(bytes: &[u8]) -> Cow { // // so it is okay for the return type to be different from the std case as long // as the above works. -#[cfg(not(any(feature = "collections", feature = "std")))] +#[cfg(not(any(feature = "std", feature = "collections")))] pub fn from_utf8_lossy(bytes: &[u8]) -> &str { - use core::str; // Three unicode replacement characters if it fails. They look like a // white-on-black question mark. The user will recognize it as invalid // UTF-8. diff --git a/serde/src/lib.rs b/serde/src/lib.rs index fe9cfac4..873c9a17 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -74,16 +74,85 @@ extern crate collections; #[cfg(feature = "alloc")] extern crate alloc; -#[cfg(feature = "unstable")] -extern crate core as actual_core; +#[cfg(all(feature = "unstable", feature = "std"))] +extern crate core; + +/// A facade around all the types we need from the `std`, `core`, `alloc`, and +/// `collections` crates. This avoids elaborate import wrangling having to +/// happen in every module. +mod lib { + #[cfg(feature = "std")] + use std as core; + #[cfg(not(feature = "std"))] + use core; + + pub use self::core::{cmp, iter, mem, ops, str}; + pub use self::core::{i8, i16, i32, i64, isize}; + pub use self::core::{u8, u16, u32, u64, usize}; + pub use self::core::{f32, f64}; + + pub use self::core::clone::{self, Clone}; + pub use self::core::convert::{self, From, Into}; + pub use self::core::default::{self, Default}; + pub use self::core::fmt::{self, Debug, Display}; + pub use self::core::marker::{self, PhantomData}; + pub use self::core::option::{self, Option}; + pub use self::core::result::{self, Result}; + + #[cfg(feature = "std")] + pub use std::borrow::{Cow, ToOwned}; + #[cfg(all(feature = "collections", not(feature = "std")))] + pub use collections::borrow::{Cow, ToOwned}; + + #[cfg(feature = "std")] + pub use std::string::String; + #[cfg(all(feature = "collections", not(feature = "std")))] + pub use collections::string::{String, ToString}; + + #[cfg(feature = "std")] + pub use std::vec::Vec; + #[cfg(all(feature = "collections", not(feature = "std")))] + pub use collections::vec::Vec; + + #[cfg(feature = "std")] + pub use std::boxed::Box; + #[cfg(all(feature = "alloc", not(feature = "std")))] + pub use alloc::boxed::Box; + + #[cfg(all(feature = "rc", feature = "std"))] + pub use std::rc::Rc; + #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))] + pub use alloc::rc::Rc; + + #[cfg(all(feature = "rc", feature = "std"))] + pub use std::sync::Arc; + #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))] + pub use alloc::arc::Arc; + + #[cfg(feature = "std")] + pub use std::collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque}; + #[cfg(all(feature = "collections", not(feature = "std")))] + pub use collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque}; + + #[cfg(feature = "std")] + pub use std::{error, net, path}; + + #[cfg(feature = "std")] + pub use std::collections::{HashMap, HashSet}; + #[cfg(feature = "std")] + pub use std::ffi::{CString, CStr, OsString, OsStr}; + #[cfg(feature = "std")] + pub use std::hash::{Hash, BuildHasher}; + #[cfg(feature = "std")] + pub use std::io::Write; + #[cfg(feature = "std")] + pub use std::time::Duration; -#[cfg(feature = "std")] -mod core { - pub use std::{ops, hash, fmt, cmp, marker, mem, i8, i16, i32, i64, u8, u16, u32, u64, isize, - usize, f32, f64, char, str, num, slice, iter, cell, default, result, option, - clone, convert}; #[cfg(feature = "unstable")] - pub use actual_core::nonzero; + pub use core::nonzero::{NonZero, Zeroable}; + #[cfg(feature = "unstable")] + #[allow(deprecated)] // required for impl Deserialize for NonZero + pub use core::num::Zero; } #[doc(inline)] diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 2d019b42..394c72cb 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -1,18 +1,4 @@ -#[cfg(any(feature = "std", feature = "collections"))] -use core::{fmt, str}; - -use core::marker::PhantomData; - -#[cfg(feature = "collections")] -use collections::borrow::ToOwned; - -#[cfg(feature = "std")] -use std::borrow::Cow; -#[cfg(all(feature = "collections", not(feature = "std")))] -use collections::borrow::Cow; - -#[cfg(all(feature = "collections", not(feature = "std")))] -use collections::{String, Vec}; +use lib::*; use de::{Deserialize, Deserializer, Error, Visitor}; @@ -187,17 +173,7 @@ mod content { // This issue is tracking making some of this stuff public: // https://github.com/serde-rs/serde/issues/741 - #![doc(hidden)] - - use core::cmp; - use core::fmt; - use core::marker::PhantomData; - - #[cfg(all(not(feature = "std"), feature = "collections"))] - use collections::{String, Vec}; - - #[cfg(all(feature = "alloc", not(feature = "std")))] - use alloc::boxed::Box; + use lib::*; use de::{self, Deserialize, DeserializeSeed, Deserializer, Visitor, SeqVisitor, MapVisitor, EnumVisitor, Unexpected}; diff --git a/serde/src/private/ser.rs b/serde/src/private/ser.rs index f307d3d7..bf61b0b1 100644 --- a/serde/src/private/ser.rs +++ b/serde/src/private/ser.rs @@ -1,13 +1,10 @@ -use core::fmt::{self, Display}; +use lib::*; use ser::{self, Serialize, Serializer, SerializeMap, SerializeStruct, Impossible}; #[cfg(any(feature = "std", feature = "collections"))] use self::content::{SerializeTupleVariantAsMapValue, SerializeStructVariantAsMapValue}; -#[cfg(feature = "std")] -use std::error; - /// Used to check that serde(getter) attributes return the expected type. /// Not public API. pub fn constrain(t: &T) -> &T { @@ -340,16 +337,7 @@ impl Display for Error { #[cfg(any(feature = "std", feature = "collections"))] mod content { - use core::marker::PhantomData; - - #[cfg(all(not(feature = "std"), feature = "collections"))] - use collections::{String, Vec}; - - #[cfg(all(feature = "alloc", not(feature = "std")))] - use alloc::boxed::Box; - - #[cfg(feature = "collections")] - use collections::borrow::ToOwned; + use lib::*; use ser::{self, Serialize, Serializer}; diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index e51a2999..1d34254a 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -1,45 +1,9 @@ -#[cfg(feature = "std")] -use std::borrow::Cow; -#[cfg(all(feature = "collections", not(feature = "std")))] -use collections::borrow::Cow; +use lib::*; + +use ser::{Serialize, SerializeSeq, SerializeTuple, Serializer}; #[cfg(feature = "std")] -use std::collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, HashMap, HashSet, VecDeque}; -#[cfg(all(feature = "collections", not(feature = "std")))] -use collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque, String, Vec}; - -#[cfg(feature = "collections")] -use collections::borrow::ToOwned; - -#[cfg(feature = "std")] -use core::hash::{Hash, BuildHasher}; -#[cfg(feature = "std")] -use std::{net, ops, path}; -#[cfg(feature = "std")] -use std::ffi::{CString, CStr, OsString, OsStr}; -#[cfg(all(feature = "rc", feature = "std"))] -use std::rc::Rc; -#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))] -use alloc::rc::Rc; -#[cfg(feature = "std")] -use std::time::Duration; - -#[cfg(all(feature = "rc", feature = "std"))] -use std::sync::Arc; -#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))] -use alloc::arc::Arc; - -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::boxed::Box; - -use core::marker::PhantomData; - -#[cfg(feature = "unstable")] -use core::nonzero::{NonZero, Zeroable}; - -use super::{Serialize, SerializeSeq, SerializeTuple, Serializer}; -#[cfg(feature = "std")] -use super::Error; +use ser::Error; /////////////////////////////////////////////////////////////////////////////// @@ -635,8 +599,7 @@ impl Serialize for Duration { macro_rules! serialize_display_bounded_length { ($value: expr, $MAX_LEN: expr, $serializer: expr) => { { - use std::io::Write; - let mut buffer: [u8; $MAX_LEN] = unsafe { ::std::mem::uninitialized() }; + let mut buffer: [u8; $MAX_LEN] = unsafe { mem::uninitialized() }; let remaining_len; { let mut remaining = &mut buffer[..]; @@ -646,11 +609,11 @@ macro_rules! serialize_display_bounded_length { let written_len = buffer.len() - remaining_len; let written = &buffer[..written_len]; - // write! only provides std::fmt::Formatter to Display implementations, + // write! only provides fmt::Formatter to Display implementations, // which has methods write_str and write_char but no method to write arbitrary bytes. // Therefore, `written` is well-formed in UTF-8. let written_str = unsafe { - ::std::str::from_utf8_unchecked(written) + str::from_utf8_unchecked(written) }; $serializer.serialize_str(written_str) } diff --git a/serde/src/ser/impossible.rs b/serde/src/ser/impossible.rs index bc11ce66..f95348d6 100644 --- a/serde/src/ser/impossible.rs +++ b/serde/src/ser/impossible.rs @@ -1,6 +1,6 @@ //! This module contains `Impossible` serializer and its implementations. -use core::marker::PhantomData; +use lib::*; use ser::{self, Serialize, SerializeSeq, SerializeTuple, SerializeTupleStruct, SerializeTupleVariant, SerializeMap, SerializeStruct, SerializeStructVariant}; diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 1a20646a..21655493 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -92,17 +92,7 @@ //! [bincode]: https://github.com/TyOverby/bincode //! [data-formats]: https://serde.rs/#data-formats -#[cfg(feature = "std")] -use std::error; - -#[cfg(all(feature = "collections", not(feature = "std")))] -use collections::string::String; -#[cfg(not(feature = "std"))] -use core::fmt::Debug; -use core::fmt::Display; -#[cfg(any(feature = "std", feature = "collections"))] -use core::fmt::Write; -use core::iter::IntoIterator; +use lib::*; mod impls; mod impossible; @@ -876,6 +866,7 @@ pub trait Serializer: Sized { fn collect_str(self, value: &T) -> Result where T: Display { + use self::fmt::Write; let mut string = String::new(); write!(string, "{}", value).unwrap(); self.serialize_str(&string) From 2efb95015bab91c5b914a70e646725cd1b3b2358 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 10 Apr 2017 19:06:42 -0700 Subject: [PATCH 088/177] Appease Rust 1.13.0 --- serde/src/export.rs | 42 +++++++++++++++++++++++------------------- serde/src/lib.rs | 10 ++++++---- serde/src/ser/mod.rs | 2 +- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/serde/src/export.rs b/serde/src/export.rs index a2014233..0c88f5e3 100644 --- a/serde/src/export.rs +++ b/serde/src/export.rs @@ -1,5 +1,3 @@ -use lib::*; - pub use lib::clone::Clone; pub use lib::convert::{From, Into}; pub use lib::default::Default; @@ -8,22 +6,28 @@ pub use lib::marker::PhantomData; pub use lib::option::Option::{self, None, Some}; pub use lib::result::Result::{self, Ok, Err}; -#[cfg(any(feature = "std", feature = "collections"))] -pub fn from_utf8_lossy(bytes: &[u8]) -> Cow { - String::from_utf8_lossy(bytes) -} +pub use self::string::from_utf8_lossy; -// The generated code calls this like: -// -// let value = &_serde::export::from_utf8_lossy(bytes); -// Err(_serde::de::Error::unknown_variant(value, VARIANTS)) -// -// so it is okay for the return type to be different from the std case as long -// as the above works. -#[cfg(not(any(feature = "std", feature = "collections")))] -pub fn from_utf8_lossy(bytes: &[u8]) -> &str { - // Three unicode replacement characters if it fails. They look like a - // white-on-black question mark. The user will recognize it as invalid - // UTF-8. - str::from_utf8(bytes).unwrap_or("\u{fffd}\u{fffd}\u{fffd}") +mod string { + use lib::*; + + #[cfg(any(feature = "std", feature = "collections"))] + pub fn from_utf8_lossy(bytes: &[u8]) -> Cow { + String::from_utf8_lossy(bytes) + } + + // The generated code calls this like: + // + // let value = &_serde::export::from_utf8_lossy(bytes); + // Err(_serde::de::Error::unknown_variant(value, VARIANTS)) + // + // so it is okay for the return type to be different from the std case as long + // as the above works. + #[cfg(not(any(feature = "std", feature = "collections")))] + pub fn from_utf8_lossy(bytes: &[u8]) -> &str { + // Three unicode replacement characters if it fails. They look like a + // white-on-black question mark. The user will recognize it as invalid + // UTF-8. + str::from_utf8(bytes).unwrap_or("\u{fffd}\u{fffd}\u{fffd}") + } } diff --git a/serde/src/lib.rs b/serde/src/lib.rs index 873c9a17..92d65818 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -81,10 +81,12 @@ extern crate core; /// `collections` crates. This avoids elaborate import wrangling having to /// happen in every module. mod lib { - #[cfg(feature = "std")] - use std as core; - #[cfg(not(feature = "std"))] - use core; + mod core { + #[cfg(feature = "std")] + pub use std::*; + #[cfg(not(feature = "std"))] + pub use core::*; + } pub use self::core::{cmp, iter, mem, ops, str}; pub use self::core::{i8, i16, i32, i64, isize}; diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 21655493..5e44895a 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -866,7 +866,7 @@ pub trait Serializer: Sized { fn collect_str(self, value: &T) -> Result where T: Display { - use self::fmt::Write; + use lib::fmt::Write; let mut string = String::new(); write!(string, "{}", value).unwrap(); self.serialize_str(&string) From aed5a77540cda0365d245621876f69058445b7a3 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 10 Apr 2017 19:41:32 -0700 Subject: [PATCH 089/177] Fix assert_next_token on old rustc --- serde_test/src/ser.rs | 16 ++++++++-------- travis.sh | 4 ++++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/serde_test/src/ser.rs b/serde_test/src/ser.rs index f6c401ee..537393b5 100644 --- a/serde_test/src/ser.rs +++ b/serde_test/src/ser.rs @@ -28,17 +28,17 @@ impl<'a> Serializer<'a> { } macro_rules! assert_next_token { - ($self:ident, $expected:ident($a:expr)) => { - assert_next_token!($self, $expected { a: $a }); + ($ser:ident, $expected:ident($a:expr)) => { + assert_next_token!($ser, $expected { a: $a }); }; - ($self:ident, $expected:ident($a:expr, $b:expr)) => { - assert_next_token!($self, $expected { a: $a, b: $b }); + ($ser:ident, $expected:ident($a:expr, $b:expr)) => { + assert_next_token!($ser, $expected { a: $a, b: $b }); }; - ($self:ident, $expected:ident($a:expr, $b:expr, $c:expr)) => { - assert_next_token!($self, $expected { a: $a, b: $b, c: $c }); + ($ser:ident, $expected:ident($a:expr, $b:expr, $c:expr)) => { + assert_next_token!($ser, $expected { a: $a, b: $b, c: $c }); }; - ($self:ident, $expected:ident $({ $($n:ident: $v:expr),* })*) => { - match $self.next_token() { + ($ser:ident, $expected:ident $({ $($n:ident: $v:expr),* })*) => { + match $ser.next_token() { Some(Token::$expected $(($($n),*))*) $(if $($n == $v)&&*)* => {} Some(other) => { panic!("expected Token::{} but serialized as {:?}", diff --git a/travis.sh b/travis.sh index 7a122feb..fa760b57 100755 --- a/travis.sh +++ b/travis.sh @@ -67,10 +67,14 @@ else cd "$DIR/serde" channel build --features rc channel build --no-default-features + cd "$DIR/serde_test" + channel build CHANNEL=1.13.0 cargo clean cd "$DIR/serde" channel build --features rc channel build --no-default-features + cd "$DIR/serde_test" + channel build fi From 0d82bbf74fbc30d651651e74f9d975851bd1334b Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 11 Apr 2017 23:20:35 -0700 Subject: [PATCH 090/177] Rename ValueDeserializer trait to IntoDeserializer --- serde/src/de/mod.rs | 11 +++++ serde/src/de/value.rs | 81 +++++++++++++++------------------- serde/src/private/de.rs | 4 +- serde_test/src/de.rs | 6 +-- test_suite/tests/test_value.rs | 4 +- 5 files changed, 53 insertions(+), 53 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 7e040490..06ae2e45 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -1658,6 +1658,17 @@ pub trait VariantVisitor<'de>: Sized { /////////////////////////////////////////////////////////////////////////////// +/// This trait converts primitive types into a deserializer. +pub trait IntoDeserializer<'de, E: Error = value::Error> { + /// The actual deserializer type. + type Deserializer: Deserializer<'de, Error = E>; + + /// Convert this value into a deserializer. + fn into_deserializer(self) -> Self::Deserializer; +} + +/////////////////////////////////////////////////////////////////////////////// + /// Used in error messages. /// /// - expected `a` diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 5a261334..83e50a56 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -2,7 +2,7 @@ use lib::*; -use de::{self, Expected, SeqVisitor}; +use de::{self, IntoDeserializer, Expected, SeqVisitor}; /////////////////////////////////////////////////////////////////////////////// @@ -50,18 +50,7 @@ impl error::Error for Error { /////////////////////////////////////////////////////////////////////////////// -/// This trait converts primitive types into a deserializer. -pub trait ValueDeserializer<'de, E: de::Error = Error> { - /// The actual deserializer type. - type Deserializer: de::Deserializer<'de, Error = E>; - - /// Convert this value into a deserializer. - fn into_deserializer(self) -> Self::Deserializer; -} - -/////////////////////////////////////////////////////////////////////////////// - -impl<'de, E> ValueDeserializer<'de, E> for () +impl<'de, E> IntoDeserializer<'de, E> for () where E: de::Error { type Deserializer = UnitDeserializer; @@ -110,7 +99,7 @@ macro_rules! primitive_deserializer { marker: PhantomData } - impl<'de, E> ValueDeserializer<'de, E> for $ty + impl<'de, E> IntoDeserializer<'de, E> for $ty where E: de::Error, { type Deserializer = $name; @@ -163,7 +152,7 @@ pub struct U32Deserializer { marker: PhantomData, } -impl<'de, E> ValueDeserializer<'de, E> for u32 +impl<'de, E> IntoDeserializer<'de, E> for u32 where E: de::Error { type Deserializer = U32Deserializer; @@ -225,7 +214,7 @@ pub struct StrDeserializer<'a, E> { marker: PhantomData, } -impl<'de, 'a, E> ValueDeserializer<'de, E> for &'a str +impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a str where E: de::Error { type Deserializer = StrDeserializer<'a, E>; @@ -289,7 +278,7 @@ pub struct StringDeserializer { } #[cfg(any(feature = "std", feature = "collections"))] -impl<'de, E> ValueDeserializer<'de, E> for String +impl<'de, E> IntoDeserializer<'de, E> for String where E: de::Error { type Deserializer = StringDeserializer; @@ -355,7 +344,7 @@ pub struct CowStrDeserializer<'a, E> { } #[cfg(any(feature = "std", feature = "collections"))] -impl<'de, 'a, E> ValueDeserializer<'de, E> for Cow<'a, str> +impl<'de, 'a, E> IntoDeserializer<'de, E> for Cow<'a, str> where E: de::Error { type Deserializer = CowStrDeserializer<'a, E>; @@ -455,7 +444,7 @@ impl SeqDeserializer impl<'de, I, T, E> de::Deserializer<'de> for SeqDeserializer where I: Iterator, - T: ValueDeserializer<'de, E>, + T: IntoDeserializer<'de, E>, E: de::Error { type Error = E; @@ -477,7 +466,7 @@ impl<'de, I, T, E> de::Deserializer<'de> for SeqDeserializer impl<'de, I, T, E> de::SeqVisitor<'de> for SeqDeserializer where I: Iterator, - T: ValueDeserializer<'de, E>, + T: IntoDeserializer<'de, E>, E: de::Error { type Error = E; @@ -514,8 +503,8 @@ impl Expected for ExpectedInSeq { /////////////////////////////////////////////////////////////////////////////// #[cfg(any(feature = "std", feature = "collections"))] -impl<'de, T, E> ValueDeserializer<'de, E> for Vec - where T: ValueDeserializer<'de, E>, +impl<'de, T, E> IntoDeserializer<'de, E> for Vec + where T: IntoDeserializer<'de, E>, E: de::Error { type Deserializer = SeqDeserializer< as IntoIterator>::IntoIter, E>; @@ -526,8 +515,8 @@ impl<'de, T, E> ValueDeserializer<'de, E> for Vec } #[cfg(any(feature = "std", feature = "collections"))] -impl<'de, T, E> ValueDeserializer<'de, E> for BTreeSet - where T: ValueDeserializer<'de, E> + Eq + Ord, +impl<'de, T, E> IntoDeserializer<'de, E> for BTreeSet + where T: IntoDeserializer<'de, E> + Eq + Ord, E: de::Error { type Deserializer = SeqDeserializer< as IntoIterator>::IntoIter, E>; @@ -538,8 +527,8 @@ impl<'de, T, E> ValueDeserializer<'de, E> for BTreeSet } #[cfg(feature = "std")] -impl<'de, T, E> ValueDeserializer<'de, E> for HashSet - where T: ValueDeserializer<'de, E> + Eq + Hash, +impl<'de, T, E> IntoDeserializer<'de, E> for HashSet + where T: IntoDeserializer<'de, E> + Eq + Hash, E: de::Error { type Deserializer = SeqDeserializer< as IntoIterator>::IntoIter, E>; @@ -589,8 +578,8 @@ impl<'de, V_> de::Deserializer<'de> for SeqVisitorDeserializer pub struct MapDeserializer<'de, I, E> where I: Iterator, I::Item: private::Pair, - ::First: ValueDeserializer<'de, E>, - ::Second: ValueDeserializer<'de, E>, + ::First: IntoDeserializer<'de, E>, + ::Second: IntoDeserializer<'de, E>, E: de::Error { iter: iter::Fuse, @@ -603,8 +592,8 @@ pub struct MapDeserializer<'de, I, E> impl<'de, I, E> MapDeserializer<'de, I, E> where I: Iterator, I::Item: private::Pair, - ::First: ValueDeserializer<'de, E>, - ::Second: ValueDeserializer<'de, E>, + ::First: IntoDeserializer<'de, E>, + ::Second: IntoDeserializer<'de, E>, E: de::Error { /// Construct a new `MapDeserializer`. @@ -650,8 +639,8 @@ impl<'de, I, E> MapDeserializer<'de, I, E> impl<'de, I, E> de::Deserializer<'de> for MapDeserializer<'de, I, E> where I: Iterator, I::Item: private::Pair, - ::First: ValueDeserializer<'de, E>, - ::Second: ValueDeserializer<'de, E>, + ::First: IntoDeserializer<'de, E>, + ::Second: IntoDeserializer<'de, E>, E: de::Error { type Error = E; @@ -691,8 +680,8 @@ impl<'de, I, E> de::Deserializer<'de> for MapDeserializer<'de, I, E> impl<'de, I, E> de::MapVisitor<'de> for MapDeserializer<'de, I, E> where I: Iterator, I::Item: private::Pair, - ::First: ValueDeserializer<'de, E>, - ::Second: ValueDeserializer<'de, E>, + ::First: IntoDeserializer<'de, E>, + ::Second: IntoDeserializer<'de, E>, E: de::Error { type Error = E; @@ -744,8 +733,8 @@ impl<'de, I, E> de::MapVisitor<'de> for MapDeserializer<'de, I, E> impl<'de, I, E> de::SeqVisitor<'de> for MapDeserializer<'de, I, E> where I: Iterator, I::Item: private::Pair, - ::First: ValueDeserializer<'de, E>, - ::Second: ValueDeserializer<'de, E>, + ::First: IntoDeserializer<'de, E>, + ::Second: IntoDeserializer<'de, E>, E: de::Error { type Error = E; @@ -772,8 +761,8 @@ impl<'de, I, E> de::SeqVisitor<'de> for MapDeserializer<'de, I, E> struct PairDeserializer(A, B, PhantomData); impl<'de, A, B, E> de::Deserializer<'de> for PairDeserializer - where A: ValueDeserializer<'de, E>, - B: ValueDeserializer<'de, E>, + where A: IntoDeserializer<'de, E>, + B: IntoDeserializer<'de, E>, E: de::Error { type Error = E; @@ -821,8 +810,8 @@ impl<'de, A, B, E> de::Deserializer<'de> for PairDeserializer struct PairVisitor(Option, Option, PhantomData); impl<'de, A, B, E> de::SeqVisitor<'de> for PairVisitor - where A: ValueDeserializer<'de, E>, - B: ValueDeserializer<'de, E>, + where A: IntoDeserializer<'de, E>, + B: IntoDeserializer<'de, E>, E: de::Error { type Error = E; @@ -866,9 +855,9 @@ impl Expected for ExpectedInMap { /////////////////////////////////////////////////////////////////////////////// #[cfg(any(feature = "std", feature = "collections"))] -impl<'de, K, V, E> ValueDeserializer<'de, E> for BTreeMap - where K: ValueDeserializer<'de, E> + Eq + Ord, - V: ValueDeserializer<'de, E>, +impl<'de, K, V, E> IntoDeserializer<'de, E> for BTreeMap + where K: IntoDeserializer<'de, E> + Eq + Ord, + V: IntoDeserializer<'de, E>, E: de::Error { type Deserializer = MapDeserializer<'de, as IntoIterator>::IntoIter, E>; @@ -879,9 +868,9 @@ impl<'de, K, V, E> ValueDeserializer<'de, E> for BTreeMap } #[cfg(feature = "std")] -impl<'de, K, V, E> ValueDeserializer<'de, E> for HashMap - where K: ValueDeserializer<'de, E> + Eq + Hash, - V: ValueDeserializer<'de, E>, +impl<'de, K, V, E> IntoDeserializer<'de, E> for HashMap + where K: IntoDeserializer<'de, E> + Eq + Hash, + V: IntoDeserializer<'de, E>, E: de::Error { type Deserializer = MapDeserializer<'de, as IntoIterator>::IntoIter, E>; diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 394c72cb..9d56071d 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -1410,7 +1410,7 @@ mod content { } } - impl<'de, E> de::value::ValueDeserializer<'de, E> for ContentDeserializer + impl<'de, E> de::IntoDeserializer<'de, E> for ContentDeserializer where E: de::Error { type Deserializer = Self; @@ -1420,7 +1420,7 @@ mod content { } } - impl<'de, 'a, E> de::value::ValueDeserializer<'de, E> for ContentRefDeserializer<'a, E> + impl<'de, 'a, E> de::IntoDeserializer<'de, E> for ContentRefDeserializer<'a, E> where E: de::Error { type Deserializer = Self; diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index 243c8eb6..75996fc5 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -1,6 +1,6 @@ -use serde::de::{self, Deserialize, DeserializeSeed, EnumVisitor, MapVisitor, SeqVisitor, - VariantVisitor, Visitor}; -use serde::de::value::{ValueDeserializer, MapVisitorDeserializer, SeqVisitorDeserializer}; +use serde::de::{self, Deserialize, DeserializeSeed, EnumVisitor, IntoDeserializer, + MapVisitor, SeqVisitor, VariantVisitor, Visitor}; +use serde::de::value::{MapVisitorDeserializer, SeqVisitorDeserializer}; use error::Error; use token::Token; diff --git a/test_suite/tests/test_value.rs b/test_suite/tests/test_value.rs index fc444163..08b1c3c3 100644 --- a/test_suite/tests/test_value.rs +++ b/test_suite/tests/test_value.rs @@ -3,7 +3,7 @@ extern crate serde_derive; extern crate serde; use serde::Deserialize; -use serde::de::value::{self, ValueDeserializer}; +use serde::de::{value, IntoDeserializer}; #[test] fn test_u32_to_enum() { @@ -13,7 +13,7 @@ fn test_u32_to_enum() { B, } - let deserializer = ValueDeserializer::::into_deserializer(1u32); + let deserializer = IntoDeserializer::::into_deserializer(1u32); let e: E = E::deserialize(deserializer).unwrap(); assert_eq!(E::B, e); } From 304b598a058e241107df22eb90c6780cff108dea Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 10:26:47 -0700 Subject: [PATCH 091/177] Add appveyor badge to crates.io --- serde/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/serde/Cargo.toml b/serde/Cargo.toml index 12020eeb..b0e95667 100644 --- a/serde/Cargo.toml +++ b/serde/Cargo.toml @@ -15,6 +15,7 @@ publish = false # this branch contains breaking changes [badges] travis-ci = { repository = "serde-rs/serde" } +appveyor = { repository = "serde-rs/serde" } [dependencies] serde_derive = { version = "0.9", optional = true, path = "../serde_derive" } From 4f397662111c32a098713e4d5600ce462a3f5dda Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 10:37:24 -0700 Subject: [PATCH 092/177] Fix paths to readme files --- serde/Cargo.toml | 2 +- serde_codegen_internals/Cargo.toml | 2 +- serde_derive/Cargo.toml | 2 +- serde_test/Cargo.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/serde/Cargo.toml b/serde/Cargo.toml index b0e95667..3389dacf 100644 --- a/serde/Cargo.toml +++ b/serde/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/serde-rs/serde" documentation = "https://docs.serde.rs/serde/" keywords = ["serde", "serialization", "no_std"] categories = ["encoding"] -readme = "../README.md" +readme = "README.md" include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] publish = false # this branch contains breaking changes diff --git a/serde_codegen_internals/Cargo.toml b/serde_codegen_internals/Cargo.toml index 6f006914..f572d487 100644 --- a/serde_codegen_internals/Cargo.toml +++ b/serde_codegen_internals/Cargo.toml @@ -8,7 +8,7 @@ homepage = "https://serde.rs" repository = "https://github.com/serde-rs/serde" documentation = "https://docs.serde.rs/serde_codegen_internals/" keywords = ["serde", "serialization"] -readme = "../README.md" +readme = "README.md" include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] [dependencies] diff --git a/serde_derive/Cargo.toml b/serde_derive/Cargo.toml index 866da94b..92ac98d9 100644 --- a/serde_derive/Cargo.toml +++ b/serde_derive/Cargo.toml @@ -8,7 +8,7 @@ homepage = "https://serde.rs" repository = "https://github.com/serde-rs/serde" documentation = "https://serde.rs/codegen.html" keywords = ["serde", "serialization", "no_std"] -readme = "../README.md" +readme = "README.md" include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] publish = false # this branch contains breaking changes diff --git a/serde_test/Cargo.toml b/serde_test/Cargo.toml index 8907f973..7546cd4f 100644 --- a/serde_test/Cargo.toml +++ b/serde_test/Cargo.toml @@ -8,7 +8,7 @@ homepage = "https://serde.rs" repository = "https://github.com/serde-rs/serde" documentation = "https://docs.serde.rs/serde_test/" keywords = ["serde", "serialization"] -readme = "../README.md" +readme = "README.md" include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] publish = false # this branch contains breaking changes From 07154303edbe3ba01f61368e1cab474d47c053ae Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 11:04:16 -0700 Subject: [PATCH 093/177] Implement Debug for public types --- serde/src/de/ignored_any.rs | 1 + serde/src/de/value.rs | 31 +++++++++++++++++++++++++++++++ serde_test/src/de.rs | 1 + serde_test/src/ser.rs | 1 + 4 files changed, 34 insertions(+) diff --git a/serde/src/de/ignored_any.rs b/serde/src/de/ignored_any.rs index 1bea30fd..f7b4a55d 100644 --- a/serde/src/de/ignored_any.rs +++ b/serde/src/de/ignored_any.rs @@ -4,6 +4,7 @@ use de::{Deserialize, Deserializer, Visitor, SeqVisitor, MapVisitor, Error}; /// A target for deserializers that want to ignore data. Implements Deserialize /// and silently eats data given to it. +#[derive(Debug)] pub struct IgnoredAny; impl<'de> Deserialize<'de> for IgnoredAny { diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 83e50a56..6e2993e4 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -61,6 +61,7 @@ impl<'de, E> IntoDeserializer<'de, E> for () } /// A helper deserializer that deserializes a `()`. +#[derive(Debug)] pub struct UnitDeserializer { marker: PhantomData, } @@ -94,6 +95,7 @@ impl<'de, E> de::Deserializer<'de> for UnitDeserializer macro_rules! primitive_deserializer { ($ty:ty, $name:ident, $method:ident $($cast:tt)*) => { /// A helper deserializer that deserializes a number. + #[derive(Debug)] pub struct $name { value: $ty, marker: PhantomData @@ -147,6 +149,7 @@ primitive_deserializer!(f64, F64Deserializer, visit_f64); primitive_deserializer!(char, CharDeserializer, visit_char); /// A helper deserializer that deserializes a number. +#[derive(Debug)] pub struct U32Deserializer { value: u32, marker: PhantomData, @@ -209,6 +212,7 @@ impl<'de, E> de::EnumVisitor<'de> for U32Deserializer /////////////////////////////////////////////////////////////////////////////// /// A helper deserializer that deserializes a `&str`. +#[derive(Debug)] pub struct StrDeserializer<'a, E> { value: &'a str, marker: PhantomData, @@ -272,6 +276,7 @@ impl<'de, 'a, E> de::EnumVisitor<'de> for StrDeserializer<'a, E> /// A helper deserializer that deserializes a `String`. #[cfg(any(feature = "std", feature = "collections"))] +#[derive(Debug)] pub struct StringDeserializer { value: String, marker: PhantomData, @@ -338,6 +343,7 @@ impl<'de, 'a, E> de::EnumVisitor<'de> for StringDeserializer /// A helper deserializer that deserializes a `String`. #[cfg(any(feature = "std", feature = "collections"))] +#[derive(Debug)] pub struct CowStrDeserializer<'a, E> { value: Cow<'a, str>, marker: PhantomData, @@ -406,6 +412,7 @@ impl<'de, 'a, E> de::EnumVisitor<'de> for CowStrDeserializer<'a, E> /////////////////////////////////////////////////////////////////////////////// /// A helper deserializer that deserializes a sequence. +#[derive(Debug)] pub struct SeqDeserializer { iter: iter::Fuse, count: usize, @@ -541,6 +548,7 @@ impl<'de, T, E> IntoDeserializer<'de, E> for HashSet /////////////////////////////////////////////////////////////////////////////// /// A helper deserializer that deserializes a sequence using a `SeqVisitor`. +#[derive(Debug)] pub struct SeqVisitorDeserializer { visitor: V_, } @@ -756,6 +764,27 @@ impl<'de, I, E> de::SeqVisitor<'de> for MapDeserializer<'de, I, E> } } +// Cannot #[derive(Debug)] because of the bound: +// +// ::Second: Debug +impl<'de, I, E> Debug for MapDeserializer<'de, I, E> + where I: Iterator + Debug, + I::Item: private::Pair, + ::First: IntoDeserializer<'de, E>, + ::Second: IntoDeserializer<'de, E> + Debug, + E: de::Error +{ + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.debug_struct("MapDeserializer") + .field("iter", &self.iter) + .field("value", &self.value) + .field("count", &self.count) + .field("lifetime", &self.lifetime) + .field("error", &self.error) + .finish() + } +} + // Used in the `impl SeqVisitor for MapDeserializer` to visit the map as a // sequence of pairs. struct PairDeserializer(A, B, PhantomData); @@ -883,6 +912,7 @@ impl<'de, K, V, E> IntoDeserializer<'de, E> for HashMap /////////////////////////////////////////////////////////////////////////////// /// A helper deserializer that deserializes a map using a `MapVisitor`. +#[derive(Debug)] pub struct MapVisitorDeserializer { visitor: V_, } @@ -921,6 +951,7 @@ mod private { use de::{self, Unexpected}; + #[derive(Debug)] pub struct UnitOnly { marker: PhantomData, } diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index 75996fc5..3570a0cc 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -6,6 +6,7 @@ use error::Error; use token::Token; /// A `Deserializer` that reads from a list of tokens. +#[derive(Debug)] pub struct Deserializer<'de> { tokens: &'de [Token], } diff --git a/serde_test/src/ser.rs b/serde_test/src/ser.rs index 537393b5..3f5430c6 100644 --- a/serde_test/src/ser.rs +++ b/serde_test/src/ser.rs @@ -4,6 +4,7 @@ use error::Error; use token::Token; /// A `Serializer` that ensures that a value serializes to a given list of tokens. +#[derive(Debug)] pub struct Serializer<'a> { tokens: &'a [Token], } From 7d0a38270df8f89c651a7c598cad929fa367d80f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 11:06:48 -0700 Subject: [PATCH 094/177] Eagerly implement common traits for IgnoredAny --- serde/src/de/ignored_any.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serde/src/de/ignored_any.rs b/serde/src/de/ignored_any.rs index f7b4a55d..77dcc1e5 100644 --- a/serde/src/de/ignored_any.rs +++ b/serde/src/de/ignored_any.rs @@ -4,7 +4,7 @@ use de::{Deserialize, Deserializer, Visitor, SeqVisitor, MapVisitor, Error}; /// A target for deserializers that want to ignore data. Implements Deserialize /// and silently eats data given to it. -#[derive(Debug)] +#[derive(Copy, Clone, Debug, Default)] pub struct IgnoredAny; impl<'de> Deserialize<'de> for IgnoredAny { From aef136934be5ba062fc0dfb56b6a69a4b07d1a6e Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 11:11:09 -0700 Subject: [PATCH 095/177] Implement Clone for the value deserializers --- serde/src/de/value.rs | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 6e2993e4..9c5f9195 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -61,7 +61,7 @@ impl<'de, E> IntoDeserializer<'de, E> for () } /// A helper deserializer that deserializes a `()`. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct UnitDeserializer { marker: PhantomData, } @@ -95,7 +95,7 @@ impl<'de, E> de::Deserializer<'de> for UnitDeserializer macro_rules! primitive_deserializer { ($ty:ty, $name:ident, $method:ident $($cast:tt)*) => { /// A helper deserializer that deserializes a number. - #[derive(Debug)] + #[derive(Clone, Debug)] pub struct $name { value: $ty, marker: PhantomData @@ -149,7 +149,7 @@ primitive_deserializer!(f64, F64Deserializer, visit_f64); primitive_deserializer!(char, CharDeserializer, visit_char); /// A helper deserializer that deserializes a number. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct U32Deserializer { value: u32, marker: PhantomData, @@ -212,7 +212,7 @@ impl<'de, E> de::EnumVisitor<'de> for U32Deserializer /////////////////////////////////////////////////////////////////////////////// /// A helper deserializer that deserializes a `&str`. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct StrDeserializer<'a, E> { value: &'a str, marker: PhantomData, @@ -276,7 +276,7 @@ impl<'de, 'a, E> de::EnumVisitor<'de> for StrDeserializer<'a, E> /// A helper deserializer that deserializes a `String`. #[cfg(any(feature = "std", feature = "collections"))] -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct StringDeserializer { value: String, marker: PhantomData, @@ -343,7 +343,7 @@ impl<'de, 'a, E> de::EnumVisitor<'de> for StringDeserializer /// A helper deserializer that deserializes a `String`. #[cfg(any(feature = "std", feature = "collections"))] -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct CowStrDeserializer<'a, E> { value: Cow<'a, str>, marker: PhantomData, @@ -412,7 +412,7 @@ impl<'de, 'a, E> de::EnumVisitor<'de> for CowStrDeserializer<'a, E> /////////////////////////////////////////////////////////////////////////////// /// A helper deserializer that deserializes a sequence. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct SeqDeserializer { iter: iter::Fuse, count: usize, @@ -548,7 +548,7 @@ impl<'de, T, E> IntoDeserializer<'de, E> for HashSet /////////////////////////////////////////////////////////////////////////////// /// A helper deserializer that deserializes a sequence using a `SeqVisitor`. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct SeqVisitorDeserializer { visitor: V_, } @@ -764,6 +764,27 @@ impl<'de, I, E> de::SeqVisitor<'de> for MapDeserializer<'de, I, E> } } +// Cannot #[derive(Clone)] because of the bound: +// +// ::Second: Clone +impl<'de, I, E> Clone for MapDeserializer<'de, I, E> + where I: Iterator + Clone, + I::Item: private::Pair, + ::First: IntoDeserializer<'de, E>, + ::Second: IntoDeserializer<'de, E> + Clone, + E: de::Error +{ + fn clone(&self) -> Self { + MapDeserializer { + iter: self.iter.clone(), + value: self.value.clone(), + count: self.count, + lifetime: self.lifetime, + error: self.error, + } + } +} + // Cannot #[derive(Debug)] because of the bound: // // ::Second: Debug @@ -912,7 +933,7 @@ impl<'de, K, V, E> IntoDeserializer<'de, E> for HashMap /////////////////////////////////////////////////////////////////////////////// /// A helper deserializer that deserializes a map using a `MapVisitor`. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct MapVisitorDeserializer { visitor: V_, } @@ -951,7 +972,7 @@ mod private { use de::{self, Unexpected}; - #[derive(Debug)] + #[derive(Clone, Debug)] pub struct UnitOnly { marker: PhantomData, } From 14034968dfb79d880709767e409772cfe2dadf55 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 11:11:37 -0700 Subject: [PATCH 096/177] Implement Copy for de::Unexpected --- serde/src/de/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 06ae2e45..2104bcda 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -277,7 +277,7 @@ declare_error_trait!(Error: Sized + Debug + Display); /// } /// # } /// ``` -#[derive(Clone, PartialEq, Debug)] +#[derive(Copy, Clone, PartialEq, Debug)] pub enum Unexpected<'a> { /// The input contained a boolean value that was not expected. Bool(bool), From dc7ab2696a14fe5ca219ac09f8496bdc613ff602 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 11:31:29 -0700 Subject: [PATCH 097/177] Point html_root_url to docs.rs --- serde/Cargo.toml | 2 +- serde/src/lib.rs | 3 ++- serde_derive/Cargo.toml | 2 +- serde_derive/src/lib.rs | 2 ++ serde_test/Cargo.toml | 2 +- serde_test/src/lib.rs | 2 ++ 6 files changed, 9 insertions(+), 4 deletions(-) diff --git a/serde/Cargo.toml b/serde/Cargo.toml index 3389dacf..221fd016 100644 --- a/serde/Cargo.toml +++ b/serde/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde" -version = "0.9.13" +version = "0.9.13" # remember to update html_root_url authors = ["Erick Tryzelaar "] license = "MIT/Apache-2.0" description = "A generic serialization/deserialization framework" diff --git a/serde/src/lib.rs b/serde/src/lib.rs index 92d65818..797cd86c 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -59,7 +59,8 @@ //! Redis when using [redis-rs](https://crates.io/crates/redis). //! *(deserialization only)* -#![doc(html_root_url = "https://docs.serde.rs")] +#![doc(html_root_url = "https://docs.rs/serde/0.9.13")] + #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(feature = "unstable", feature(nonzero, specialization, zero_one))] #![cfg_attr(all(feature = "std", feature = "unstable"), feature(into_boxed_c_str))] diff --git a/serde_derive/Cargo.toml b/serde_derive/Cargo.toml index 92ac98d9..c9e42766 100644 --- a/serde_derive/Cargo.toml +++ b/serde_derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde_derive" -version = "0.9.13" +version = "0.9.13" # remember to update html_root_url authors = ["Erick Tryzelaar "] license = "MIT/Apache-2.0" description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" diff --git a/serde_derive/src/lib.rs b/serde_derive/src/lib.rs index d58271ad..b543732c 100644 --- a/serde_derive/src/lib.rs +++ b/serde_derive/src/lib.rs @@ -1,3 +1,5 @@ +#![doc(html_root_url = "https://docs.rs/serde_derive/0.9.13")] + #![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))] #![cfg_attr(feature = "cargo-clippy", allow(used_underscore_binding))] diff --git a/serde_test/Cargo.toml b/serde_test/Cargo.toml index 7546cd4f..c7600ead 100644 --- a/serde_test/Cargo.toml +++ b/serde_test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde_test" -version = "0.9.13" +version = "0.9.13" # remember to update html_root_url authors = ["Erick Tryzelaar "] license = "MIT/Apache-2.0" description = "Token De/Serializer for testing De/Serialize implementations" diff --git a/serde_test/src/lib.rs b/serde_test/src/lib.rs index 29668e8c..ac86f444 100644 --- a/serde_test/src/lib.rs +++ b/serde_test/src/lib.rs @@ -1,3 +1,5 @@ +#![doc(html_root_url = "https://docs.rs/serde_test/0.9.13")] + #[macro_use] extern crate serde; From 5141270346d66ff93d635a183275300bb7eaf9b7 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 11:52:33 -0700 Subject: [PATCH 098/177] Touch up the top-level documentation --- serde/src/lib.rs | 75 +++++++++++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/serde/src/lib.rs b/serde/src/lib.rs index 797cd86c..97df1cad 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -9,55 +9,64 @@ //! these two groups interact with each other, allowing any supported data //! structure to be serialized and deserialized using any supported data format. //! -//! See the Serde website https://serde.rs/ for additional documentation and +//! See the Serde website [https://serde.rs/] for additional documentation and //! usage examples. //! -//! ### Design +//! [https://serde.rs/]: https://serde.rs/ +//! +//! ## Design //! //! Where many other languages rely on runtime reflection for serializing data, //! Serde is instead built on Rust's powerful trait system. A data structure //! that knows how to serialize and deserialize itself is one that implements -//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's code -//! generation to automatically derive implementations at compile time). This +//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's derive +//! attribute to automatically generate implementations at compile time). This //! avoids any overhead of reflection or runtime type information. In fact in //! many situations the interaction between data structure and data format can //! be completely optimized away by the Rust compiler, leaving Serde -//! serialization to perform roughly the same speed as a handwritten serializer -//! for the specific selection of data structure and data format. +//! serialization to perform the same speed as a handwritten serializer for the +//! specific selection of data structure and data format. //! -//! ### Data formats +//! ## Data formats //! //! The following is a partial list of data formats that have been implemented //! for Serde by the community. //! -//! - [JSON](https://github.com/serde-rs/json), the ubiquitous JavaScript Object -//! Notation used by many HTTP APIs. -//! - [Bincode](https://github.com/TyOverby/bincode), a compact binary format +//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs. +//! - [Bincode], a compact binary format //! used for IPC within the Servo rendering engine. -//! - [CBOR](https://github.com/pyfisch/cbor), a Concise Binary Object -//! Representation designed for small message size without the need for -//! version negotiation. -//! - [YAML](https://github.com/dtolnay/serde-yaml), a popular human-friendly -//! configuration language that ain't markup language. -//! - [MessagePack](https://github.com/3Hren/msgpack-rust), an efficient binary -//! format that resembles a compact JSON. -//! - [TOML](https://github.com/alexcrichton/toml-rs), a minimal configuration -//! format used by [Cargo](http://doc.crates.io/manifest.html). -//! - [Pickle](https://github.com/birkenfeld/serde-pickle), a format common in -//! the Python world. -//! - [Hjson](https://github.com/laktak/hjson-rust), a variant of JSON designed -//! to be readable and writable by humans. -//! - [BSON](https://github.com/zonyitoo/bson-rs), the data storage and network -//! transfer format used by MongoDB. -//! - [URL](https://github.com/nox/serde_urlencoded), the x-www-form-urlencoded -//! format. -//! - [XML](https://github.com/serde-rs/xml), the flexible machine-friendly W3C -//! standard. *(deserialization only)* -//! - [Envy](https://github.com/softprops/envy), a way to deserialize -//! environment variables into Rust structs. *(deserialization only)* -//! - [Redis](https://github.com/OneSignal/serde-redis), deserialize values from -//! Redis when using [redis-rs](https://crates.io/crates/redis). +//! - [CBOR], a Concise Binary Object Representation designed for small message +//! size without the need for version negotiation. +//! - [YAML], a popular human-friendly configuration language that ain't markup +//! language. +//! - [MessagePack], an efficient binary format that resembles a compact JSON. +//! - [TOML], a minimal configuration format used by [Cargo]. +//! - [Pickle], a format common in the Python world. +//! - [Hjson], a variant of JSON designed to be readable and writable by humans. +//! - [BSON], the data storage and network transfer format used by MongoDB. +//! - [URL], the x-www-form-urlencoded format. +//! - [XML], the flexible machine-friendly W3C standard. //! *(deserialization only)* +//! - [Envy], a way to deserialize environment variables into Rust structs. +//! *(deserialization only)* +//! - [Redis], deserialize values from Redis when using [redis-rs]. +//! *(deserialization only)* +//! +//! [JSON]: https://github.com/serde-rs/json +//! [Bincode]: https://github.com/TyOverby/bincode +//! [CBOR]: https://github.com/pyfisch/cbor +//! [YAML]: https://github.com/dtolnay/serde-yaml +//! [MessagePack]: https://github.com/3Hren/msgpack-rust +//! [TOML]: https://github.com/alexcrichton/toml-rs +//! [Pickle]: https://github.com/birkenfeld/serde-pickle +//! [Hjson]: https://github.com/laktak/hjson-rust +//! [BSON]: https://github.com/zonyitoo/bson-rs +//! [URL]: https://github.com/nox/serde_urlencoded +//! [XML]:https://github.com/RReverser/serde-xml-rs +//! [Envy]: https://github.com/softprops/envy +//! [Redis]: https://github.com/OneSignal/serde-redis +//! [Cargo]: http://doc.crates.io/manifest.html +//! [redis-rs]: https://crates.io/crates/redis #![doc(html_root_url = "https://docs.rs/serde/0.9.13")] From 47a4e61b8b7c288498980525736fbd0d5919f404 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 11:59:42 -0700 Subject: [PATCH 099/177] Document the parts of lib.rs --- serde/src/lib.rs | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/serde/src/lib.rs b/serde/src/lib.rs index 97df1cad..703d41b9 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -68,16 +68,31 @@ //! [Cargo]: http://doc.crates.io/manifest.html //! [redis-rs]: https://crates.io/crates/redis +////////////////////////////////////////////////////////////////////////////// + +// Serde types in rustdoc of other crates get linked to here. #![doc(html_root_url = "https://docs.rs/serde/0.9.13")] +// Support using Serde without the standard library! #![cfg_attr(not(feature = "std"), no_std)] + +// Unstable functionality only if the user asks for it. For tracking and +// discussion of these features please refer to this issue: +// +// https://github.com/serde-rs/serde/issues/812 #![cfg_attr(feature = "unstable", feature(nonzero, specialization, zero_one))] #![cfg_attr(all(feature = "std", feature = "unstable"), feature(into_boxed_c_str))] #![cfg_attr(feature = "alloc", feature(alloc))] #![cfg_attr(feature = "collections", feature(collections))] + +// Whitelisted clippy lints. #![cfg_attr(feature = "cargo-clippy", allow(linkedlist, type_complexity, doc_markdown))] + +// Blacklisted Rust lints. #![deny(missing_docs, unused_imports)] +////////////////////////////////////////////////////////////////////////////// + #[cfg(feature = "collections")] extern crate collections; @@ -167,16 +182,18 @@ mod lib { pub use core::num::Zero; } -#[doc(inline)] -pub use ser::{Serialize, Serializer}; -#[doc(inline)] -pub use de::{Deserialize, Deserializer}; +////////////////////////////////////////////////////////////////////////////// #[macro_use] mod macros; -pub mod de; pub mod ser; +pub mod de; + +#[doc(inline)] +pub use ser::{Serialize, Serializer}; +#[doc(inline)] +pub use de::{Deserialize, Deserializer}; // Generated code uses these to support no_std. Not public API. #[doc(hidden)] From 78407e19a9596242b86b27b125f4a3dde565673a Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 12:02:16 -0700 Subject: [PATCH 100/177] Export Formatter directly for generated code --- serde/src/export.rs | 2 +- serde_derive/src/de.rs | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/serde/src/export.rs b/serde/src/export.rs index 0c88f5e3..cad039fd 100644 --- a/serde/src/export.rs +++ b/serde/src/export.rs @@ -1,7 +1,7 @@ pub use lib::clone::Clone; pub use lib::convert::{From, Into}; pub use lib::default::Default; -pub use lib::fmt; +pub use lib::fmt::{self, Formatter}; pub use lib::marker::PhantomData; pub use lib::option::Option::{self, None, Some}; pub use lib::result::Result::{self, Ok, Err}; diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 077b072f..a1f2ae4a 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -224,8 +224,8 @@ fn deserialize_unit_struct(params: &Parameters, item_attrs: &attr::Item) -> Frag impl<'de> _serde::de::Visitor<'de> for __Visitor { type Value = #this; - fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { - _serde::export::fmt::Formatter::write_str(formatter, #expecting) + fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result { + _serde::export::Formatter::write_str(formatter, #expecting) } #[inline] @@ -313,8 +313,8 @@ fn deserialize_tuple(variant_ident: Option<&syn::Ident>, impl #de_impl_generics _serde::de::Visitor<'de> for __Visitor #de_ty_generics #where_clause { type Value = #this #ty_generics; - fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { - _serde::export::fmt::Formatter::write_str(formatter, #expecting) + fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result { + _serde::export::Formatter::write_str(formatter, #expecting) } #visit_newtype_struct @@ -537,8 +537,8 @@ fn deserialize_struct(variant_ident: Option<&syn::Ident>, impl #de_impl_generics _serde::de::Visitor<'de> for __Visitor #de_ty_generics #where_clause { type Value = #this #ty_generics; - fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { - _serde::export::fmt::Formatter::write_str(formatter, #expecting) + fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result { + _serde::export::Formatter::write_str(formatter, #expecting) } #visit_seq @@ -657,8 +657,8 @@ fn deserialize_externally_tagged_enum(params: &Parameters, impl #de_impl_generics _serde::de::Visitor<'de> for __Visitor #de_ty_generics #where_clause { type Value = #this #ty_generics; - fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { - _serde::export::fmt::Formatter::write_str(formatter, #expecting) + fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result { + _serde::export::Formatter::write_str(formatter, #expecting) } fn visit_enum<__V>(self, __visitor: __V) -> _serde::export::Result @@ -865,8 +865,8 @@ fn deserialize_adjacently_tagged_enum(params: &Parameters, impl #de_impl_generics _serde::de::Visitor<'de> for __Visitor #de_ty_generics #where_clause { type Value = #this #ty_generics; - fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { - _serde::export::fmt::Formatter::write_str(formatter, #expecting) + fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result { + _serde::export::Formatter::write_str(formatter, #expecting) } fn visit_map<__V>(self, mut __visitor: __V) -> _serde::export::Result @@ -1242,8 +1242,8 @@ fn deserialize_field_visitor(fields: Vec<(String, Ident)>, impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { type Value = __Field; - fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result { - _serde::export::fmt::Formatter::write_str(formatter, "field name") + fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result { + _serde::export::Formatter::write_str(formatter, "field name") } #visit_index From 942642c0f4bff3808eb9f767dbea86e01b26dde3 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 12:09:42 -0700 Subject: [PATCH 101/177] Hyperlink the forward_to_deserialize documentation --- serde/src/macros.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/serde/src/macros.rs b/serde/src/macros.rs index 892c5034..bffd3250 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -113,11 +113,11 @@ macro_rules! forward_to_deserialize_helper { /// Helper macro when implementing the `Deserializer` part of a new data format /// for Serde. /// -/// Some `Deserializer` implementations for self-describing formats do not care -/// what hint the `Visitor` gives them, they just want to blindly call the -/// `Visitor` method corresponding to the data they can tell is in the input. -/// This requires repetitive implementations of all the `Deserializer` trait -/// methods. +/// Some [`Deserializer`] implementations for self-describing formats do not +/// care what hint the [`Visitor`] gives them, they just want to blindly call +/// the [`Visitor`] method corresponding to the data they can tell is in the +/// input. This requires repetitive implementations of all the [`Deserializer`] +/// trait methods. /// /// ```rust /// # #[macro_use] @@ -154,7 +154,7 @@ macro_rules! forward_to_deserialize_helper { /// ``` /// /// The `forward_to_deserialize!` macro implements these simple forwarding -/// methods so that they forward directly to `Deserializer::deserialize`. You +/// methods so that they forward directly to [`Deserializer::deserialize`]. You /// can choose which methods to forward. /// /// ```rust @@ -220,6 +220,10 @@ macro_rules! forward_to_deserialize_helper { /// # /// # fn main() {} /// ``` +/// +/// [`Deserializer`]: trait.Deserializer.html +/// [`Visitor`]: de/trait.Visitor.html +/// [`Deserializer::deserialize`]: trait.Deserializer.html#tymethod.deserialize #[macro_export] macro_rules! forward_to_deserialize { (<$visitor:ident: Visitor<$lifetime:tt>> $($func:ident)*) => { From c5bd76013335f925b2e4164e1fc246ceca18dfe7 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 12:15:12 -0700 Subject: [PATCH 102/177] Sort macros in a more readable order --- serde/src/macros.rs | 217 ++++++++++++++++++------------------ serde/src/private/macros.rs | 22 ++-- serde/src/private/mod.rs | 4 +- 3 files changed, 122 insertions(+), 121 deletions(-) diff --git a/serde/src/macros.rs b/serde/src/macros.rs index bffd3250..c2e43f1b 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -1,111 +1,3 @@ -#[doc(hidden)] -#[macro_export] -macro_rules! forward_to_deserialize_method { - ($func:ident<$l:tt, $v:ident>($($arg:ident : $ty:ty),*)) => { - #[inline] - fn $func<$v>(self, $($arg: $ty,)* visitor: $v) -> $crate::export::Result<$v::Value, Self::Error> - where $v: $crate::de::Visitor<$l> - { - $( - let _ = $arg; - )* - self.deserialize(visitor) - } - }; -} - -#[doc(hidden)] -#[macro_export] -macro_rules! forward_to_deserialize_helper { - (bool<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_bool<$l, $v>()} - }; - (u8<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_u8<$l, $v>()} - }; - (u16<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_u16<$l, $v>()} - }; - (u32<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_u32<$l, $v>()} - }; - (u64<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_u64<$l, $v>()} - }; - (i8<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_i8<$l, $v>()} - }; - (i16<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_i16<$l, $v>()} - }; - (i32<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_i32<$l, $v>()} - }; - (i64<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_i64<$l, $v>()} - }; - (f32<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_f32<$l, $v>()} - }; - (f64<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_f64<$l, $v>()} - }; - (char<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_char<$l, $v>()} - }; - (str<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_str<$l, $v>()} - }; - (string<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_string<$l, $v>()} - }; - (unit<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_unit<$l, $v>()} - }; - (option<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_option<$l, $v>()} - }; - (seq<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_seq<$l, $v>()} - }; - (seq_fixed_size<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_seq_fixed_size<$l, $v>(len: usize)} - }; - (bytes<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_bytes<$l, $v>()} - }; - (byte_buf<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_byte_buf<$l, $v>()} - }; - (map<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_map<$l, $v>()} - }; - (unit_struct<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_unit_struct<$l, $v>(name: &'static str)} - }; - (newtype_struct<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_newtype_struct<$l, $v>(name: &'static str)} - }; - (tuple_struct<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_tuple_struct<$l, $v>(name: &'static str, len: usize)} - }; - (struct<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_struct<$l, $v>(name: &'static str, fields: &'static [&'static str])} - }; - (identifier<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_identifier<$l, $v>()} - }; - (tuple<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_tuple<$l, $v>(len: usize)} - }; - (enum<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_enum<$l, $v>(name: &'static str, variants: &'static [&'static str])} - }; - (ignored_any<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_ignored_any<$l, $v>()} - }; -} - // Super explicit first paragraph because this shows up at the top level and // trips up people who are just looking for basic Serialize / Deserialize // documentation. @@ -229,7 +121,116 @@ macro_rules! forward_to_deserialize { (<$visitor:ident: Visitor<$lifetime:tt>> $($func:ident)*) => { $(forward_to_deserialize_helper!{$func<$lifetime, $visitor>})* }; + // This case must be after the previous one. ($($func:ident)*) => { $(forward_to_deserialize_helper!{$func<'de, V>})* }; } + +#[doc(hidden)] +#[macro_export] +macro_rules! forward_to_deserialize_method { + ($func:ident<$l:tt, $v:ident>($($arg:ident : $ty:ty),*)) => { + #[inline] + fn $func<$v>(self, $($arg: $ty,)* visitor: $v) -> $crate::export::Result<$v::Value, Self::Error> + where $v: $crate::de::Visitor<$l> + { + $( + let _ = $arg; + )* + self.deserialize(visitor) + } + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! forward_to_deserialize_helper { + (bool<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_bool<$l, $v>()} + }; + (u8<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_u8<$l, $v>()} + }; + (u16<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_u16<$l, $v>()} + }; + (u32<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_u32<$l, $v>()} + }; + (u64<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_u64<$l, $v>()} + }; + (i8<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_i8<$l, $v>()} + }; + (i16<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_i16<$l, $v>()} + }; + (i32<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_i32<$l, $v>()} + }; + (i64<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_i64<$l, $v>()} + }; + (f32<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_f32<$l, $v>()} + }; + (f64<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_f64<$l, $v>()} + }; + (char<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_char<$l, $v>()} + }; + (str<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_str<$l, $v>()} + }; + (string<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_string<$l, $v>()} + }; + (unit<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_unit<$l, $v>()} + }; + (option<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_option<$l, $v>()} + }; + (seq<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_seq<$l, $v>()} + }; + (seq_fixed_size<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_seq_fixed_size<$l, $v>(len: usize)} + }; + (bytes<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_bytes<$l, $v>()} + }; + (byte_buf<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_byte_buf<$l, $v>()} + }; + (map<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_map<$l, $v>()} + }; + (unit_struct<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_unit_struct<$l, $v>(name: &'static str)} + }; + (newtype_struct<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_newtype_struct<$l, $v>(name: &'static str)} + }; + (tuple_struct<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_tuple_struct<$l, $v>(name: &'static str, len: usize)} + }; + (struct<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_struct<$l, $v>(name: &'static str, fields: &'static [&'static str])} + }; + (identifier<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_identifier<$l, $v>()} + }; + (tuple<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_tuple<$l, $v>(len: usize)} + }; + (enum<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_enum<$l, $v>(name: &'static str, variants: &'static [&'static str])} + }; + (ignored_any<$l:tt, $v:ident>) => { + forward_to_deserialize_method!{deserialize_ignored_any<$l, $v>()} + }; +} diff --git a/serde/src/private/macros.rs b/serde/src/private/macros.rs index f0e0703a..cefe0a9d 100644 --- a/serde/src/private/macros.rs +++ b/serde/src/private/macros.rs @@ -1,3 +1,14 @@ +/// Used only by Serde doc tests. Not public API. +#[doc(hidden)] +#[macro_export] +macro_rules! __serialize_unimplemented { + ($($func:ident)*) => { + $( + __serialize_unimplemented_helper!($func); + )* + }; +} + #[doc(hidden)] #[macro_export] macro_rules! __serialize_unimplemented_method { @@ -106,14 +117,3 @@ macro_rules! __serialize_unimplemented_helper { __serialize_unimplemented_method!(serialize_struct_variant(&str, u32, &str, usize) -> SerializeStructVariant); }; } - -/// Used only by Serde doc tests. Not public API. -#[doc(hidden)] -#[macro_export] -macro_rules! __serialize_unimplemented { - ($($func:ident)*) => { - $( - __serialize_unimplemented_helper!($func); - )* - }; -} diff --git a/serde/src/private/mod.rs b/serde/src/private/mod.rs index 0d46e9cc..7e0a82de 100644 --- a/serde/src/private/mod.rs +++ b/serde/src/private/mod.rs @@ -1,4 +1,4 @@ +mod macros; + pub mod ser; pub mod de; - -mod macros; From ea8fb97beb0a512bdf049913d0bcb11a0196a282 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 12:28:23 -0700 Subject: [PATCH 103/177] Format in rfc style --- rustfmt.toml | 5 + serde/src/de/ignored_any.rs | 21 +- serde/src/de/impls.rs | 279 +++++++----- serde/src/de/mod.rs | 374 +++++++++------ serde/src/de/utf8.rs | 5 +- serde/src/de/value.rs | 285 +++++++----- serde/src/lib.rs | 2 +- serde/src/private/de.rs | 657 ++++++++++++++++++--------- serde/src/private/ser.rs | 446 ++++++++++-------- serde/src/ser/impls.rs | 161 ++++--- serde/src/ser/impossible.rs | 39 +- serde/src/ser/mod.rs | 126 ++--- serde_derive/src/bound.rs | 188 ++++---- serde_derive/src/de.rs | 574 ++++++++++++----------- serde_derive/src/ser.rs | 522 +++++++++++---------- serde_test/src/assert.rs | 15 +- serde_test/src/de.rs | 235 +++++----- serde_test/src/ser.rs | 105 +++-- test_suite/tests/test_annotations.rs | 353 +++++++------- test_suite/tests/test_borrow.rs | 67 +-- test_suite/tests/test_de.rs | 61 ++- test_suite/tests/test_gen.rs | 44 +- test_suite/tests/test_macros.rs | 330 +++++--------- test_suite/tests/test_remote.rs | 30 +- test_suite/tests/test_ser.rs | 29 +- 25 files changed, 2822 insertions(+), 2131 deletions(-) create mode 100644 rustfmt.toml diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 00000000..914d19d6 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,5 @@ +fn_args_layout = "Block" +array_layout = "Block" +where_style = "Rfc" +generics_indent = "Block" +fn_call_style = "Block" diff --git a/serde/src/de/ignored_any.rs b/serde/src/de/ignored_any.rs index 77dcc1e5..dff76273 100644 --- a/serde/src/de/ignored_any.rs +++ b/serde/src/de/ignored_any.rs @@ -10,7 +10,8 @@ pub struct IgnoredAny; impl<'de> Deserialize<'de> for IgnoredAny { #[inline] fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { struct IgnoredAnyVisitor; @@ -43,7 +44,8 @@ impl<'de> Deserialize<'de> for IgnoredAny { #[inline] fn visit_str(self, _: &str) -> Result - where E: Error + where + E: Error, { Ok(IgnoredAny) } @@ -55,14 +57,16 @@ impl<'de> Deserialize<'de> for IgnoredAny { #[inline] fn visit_some(self, deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { IgnoredAny::deserialize(deserializer) } #[inline] fn visit_newtype_struct(self, deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { IgnoredAny::deserialize(deserializer) } @@ -74,7 +78,8 @@ impl<'de> Deserialize<'de> for IgnoredAny { #[inline] fn visit_seq(self, mut visitor: V) -> Result - where V: SeqVisitor<'de> + where + V: SeqVisitor<'de>, { while let Some(_) = try!(visitor.visit::()) { // Gobble @@ -84,7 +89,8 @@ impl<'de> Deserialize<'de> for IgnoredAny { #[inline] fn visit_map(self, mut visitor: V) -> Result - where V: MapVisitor<'de> + where + V: MapVisitor<'de>, { while let Some((_, _)) = try!(visitor.visit::()) { // Gobble @@ -94,7 +100,8 @@ impl<'de> Deserialize<'de> for IgnoredAny { #[inline] fn visit_bytes(self, _: &[u8]) -> Result - where E: Error + where + E: Error, { Ok(IgnoredAny) } diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index e227fac7..da4a505a 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -1,7 +1,7 @@ use lib::*; -use de::{Deserialize, Deserializer, EnumVisitor, Error, SeqVisitor, Unexpected, - VariantVisitor, Visitor}; +use de::{Deserialize, Deserializer, EnumVisitor, Error, SeqVisitor, Unexpected, VariantVisitor, + Visitor}; #[cfg(any(feature = "std", feature = "collections"))] use de::MapVisitor; @@ -20,7 +20,8 @@ impl<'de> Visitor<'de> for UnitVisitor { } fn visit_unit(self) -> Result<(), E> - where E: Error + where + E: Error, { Ok(()) } @@ -28,7 +29,8 @@ impl<'de> Visitor<'de> for UnitVisitor { impl<'de> Deserialize<'de> for () { fn deserialize(deserializer: D) -> Result<(), D::Error> - where D: Deserializer<'de> + where + D: Deserializer<'de>, { deserializer.deserialize_unit(UnitVisitor) } @@ -46,7 +48,8 @@ impl<'de> Visitor<'de> for BoolVisitor { } fn visit_bool(self, v: bool) -> Result - where E: Error + where + E: Error, { Ok(v) } @@ -54,7 +57,8 @@ impl<'de> Visitor<'de> for BoolVisitor { impl<'de> Deserialize<'de> for bool { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { deserializer.deserialize_bool(BoolVisitor) } @@ -155,14 +159,16 @@ impl<'de> Visitor<'de> for CharVisitor { #[inline] fn visit_char(self, v: char) -> Result - where E: Error + where + E: Error, { Ok(v) } #[inline] fn visit_str(self, v: &str) -> Result - where E: Error + where + E: Error, { let mut iter = v.chars(); match (iter.next(), iter.next()) { @@ -175,7 +181,8 @@ impl<'de> Visitor<'de> for CharVisitor { impl<'de> Deserialize<'de> for char { #[inline] fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { deserializer.deserialize_char(CharVisitor) } @@ -195,19 +202,22 @@ impl<'de> Visitor<'de> for StringVisitor { } fn visit_str(self, v: &str) -> Result - where E: Error + where + E: Error, { Ok(v.to_owned()) } fn visit_string(self, v: String) -> Result - where E: Error + where + E: Error, { Ok(v) } fn visit_bytes(self, v: &[u8]) -> Result - where E: Error + where + E: Error, { match str::from_utf8(v) { Ok(s) => Ok(s.to_owned()), @@ -216,11 +226,12 @@ impl<'de> Visitor<'de> for StringVisitor { } fn visit_byte_buf(self, v: Vec) -> Result - where E: Error + where + E: Error, { match String::from_utf8(v) { Ok(s) => Ok(s), - Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self)), + Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self),), } } } @@ -228,7 +239,8 @@ impl<'de> Visitor<'de> for StringVisitor { #[cfg(any(feature = "std", feature = "collections"))] impl<'de> Deserialize<'de> for String { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { deserializer.deserialize_string(StringVisitor) } @@ -246,22 +258,24 @@ impl<'a> Visitor<'a> for StrVisitor { } fn visit_borrowed_str(self, v: &'a str) -> Result - where E: Error + where + E: Error, { Ok(v) // so easy } fn visit_borrowed_bytes(self, v: &'a [u8]) -> Result - where E: Error + where + E: Error, { - str::from_utf8(v) - .map_err(|_| Error::invalid_value(Unexpected::Bytes(v), &self)) + str::from_utf8(v).map_err(|_| Error::invalid_value(Unexpected::Bytes(v), &self)) } } impl<'de: 'a, 'a> Deserialize<'de> for &'a str { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { deserializer.deserialize_str(StrVisitor) } @@ -279,13 +293,15 @@ impl<'a> Visitor<'a> for BytesVisitor { } fn visit_borrowed_bytes(self, v: &'a [u8]) -> Result - where E: Error + where + E: Error, { Ok(v) } fn visit_borrowed_str(self, v: &'a str) -> Result - where E: Error + where + E: Error, { Ok(v.as_bytes()) } @@ -293,7 +309,8 @@ impl<'a> Visitor<'a> for BytesVisitor { impl<'de: 'a, 'a> Deserialize<'de> for &'a [u8] { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { deserializer.deserialize_bytes(BytesVisitor) } @@ -313,7 +330,8 @@ impl<'de> Visitor<'de> for CStringVisitor { } fn visit_seq(self, mut visitor: V) -> Result - where V: SeqVisitor<'de> + where + V: SeqVisitor<'de>, { let len = cmp::min(visitor.size_hint().0, 4096); let mut values = Vec::with_capacity(len); @@ -326,25 +344,29 @@ impl<'de> Visitor<'de> for CStringVisitor { } fn visit_bytes(self, v: &[u8]) -> Result - where E: Error + where + E: Error, { CString::new(v).map_err(Error::custom) } fn visit_byte_buf(self, v: Vec) -> Result - where E: Error + where + E: Error, { CString::new(v).map_err(Error::custom) } fn visit_str(self, v: &str) -> Result - where E: Error + where + E: Error, { CString::new(v).map_err(Error::custom) } fn visit_string(self, v: String) -> Result - where E: Error + where + E: Error, { CString::new(v).map_err(Error::custom) } @@ -353,7 +375,8 @@ impl<'de> Visitor<'de> for CStringVisitor { #[cfg(feature = "std")] impl<'de> Deserialize<'de> for CString { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { deserializer.deserialize_byte_buf(CStringVisitor) } @@ -362,7 +385,8 @@ impl<'de> Deserialize<'de> for CString { #[cfg(all(feature = "std", feature = "unstable"))] impl<'de> Deserialize<'de> for Box { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { let s = try!(CString::deserialize(deserializer)); Ok(s.into_boxed_c_str()) @@ -376,7 +400,8 @@ struct OptionVisitor { } impl<'de, T> Visitor<'de> for OptionVisitor - where T: Deserialize<'de> +where + T: Deserialize<'de>, { type Value = Option; @@ -386,31 +411,36 @@ impl<'de, T> Visitor<'de> for OptionVisitor #[inline] fn visit_unit(self) -> Result, E> - where E: Error + where + E: Error, { Ok(None) } #[inline] fn visit_none(self) -> Result, E> - where E: Error + where + E: Error, { Ok(None) } #[inline] fn visit_some(self, deserializer: D) -> Result, D::Error> - where D: Deserializer<'de> + where + D: Deserializer<'de>, { Ok(Some(try!(Deserialize::deserialize(deserializer)))) } } impl<'de, T> Deserialize<'de> for Option - where T: Deserialize<'de> +where + T: Deserialize<'de>, { fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer<'de> + where + D: Deserializer<'de>, { deserializer.deserialize_option(OptionVisitor { marker: PhantomData }) } @@ -431,7 +461,8 @@ impl<'de, T> Visitor<'de> for PhantomDataVisitor { #[inline] fn visit_unit(self) -> Result, E> - where E: Error + where + E: Error, { Ok(PhantomData) } @@ -439,7 +470,8 @@ impl<'de, T> Visitor<'de> for PhantomDataVisitor { impl<'de, T> Deserialize<'de> for PhantomData { fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer<'de> + where + D: Deserializer<'de>, { let visitor = PhantomDataVisitor { marker: PhantomData }; deserializer.deserialize_unit_struct("PhantomData", visitor) @@ -582,7 +614,8 @@ impl<'de, T> Visitor<'de> for ArrayVisitor<[T; 0]> { #[inline] fn visit_seq(self, _: V) -> Result<[T; 0], V::Error> - where V: SeqVisitor<'de> + where + V: SeqVisitor<'de>, { Ok([]) } @@ -591,7 +624,8 @@ impl<'de, T> Visitor<'de> for ArrayVisitor<[T; 0]> { // Does not require T: Deserialize<'de>. impl<'de, T> Deserialize<'de> for [T; 0] { fn deserialize(deserializer: D) -> Result<[T; 0], D::Error> - where D: Deserializer<'de> + where + D: Deserializer<'de>, { deserializer.deserialize_seq_fixed_size(0, ArrayVisitor::<[T; 0]>::new()) } @@ -824,7 +858,8 @@ map_impl!( #[cfg(feature = "std")] impl<'de> Deserialize<'de> for net::IpAddr { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { let s = try!(String::deserialize(deserializer)); match s.parse() { @@ -837,7 +872,8 @@ impl<'de> Deserialize<'de> for net::IpAddr { #[cfg(feature = "std")] impl<'de> Deserialize<'de> for net::Ipv4Addr { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { let s = try!(String::deserialize(deserializer)); match s.parse() { @@ -850,7 +886,8 @@ impl<'de> Deserialize<'de> for net::Ipv4Addr { #[cfg(feature = "std")] impl<'de> Deserialize<'de> for net::Ipv6Addr { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { let s = try!(String::deserialize(deserializer)); match s.parse() { @@ -865,7 +902,8 @@ impl<'de> Deserialize<'de> for net::Ipv6Addr { #[cfg(feature = "std")] impl<'de> Deserialize<'de> for net::SocketAddr { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { let s = try!(String::deserialize(deserializer)); match s.parse() { @@ -878,7 +916,8 @@ impl<'de> Deserialize<'de> for net::SocketAddr { #[cfg(feature = "std")] impl<'de> Deserialize<'de> for net::SocketAddrV4 { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { let s = try!(String::deserialize(deserializer)); match s.parse() { @@ -891,7 +930,8 @@ impl<'de> Deserialize<'de> for net::SocketAddrV4 { #[cfg(feature = "std")] impl<'de> Deserialize<'de> for net::SocketAddrV6 { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { let s = try!(String::deserialize(deserializer)); match s.parse() { @@ -915,13 +955,15 @@ impl<'de> Visitor<'de> for PathBufVisitor { } fn visit_str(self, v: &str) -> Result - where E: Error + where + E: Error, { Ok(From::from(v)) } fn visit_string(self, v: String) -> Result - where E: Error + where + E: Error, { Ok(From::from(v)) } @@ -931,7 +973,8 @@ impl<'de> Visitor<'de> for PathBufVisitor { #[cfg(feature = "std")] impl<'de> Deserialize<'de> for path::PathBuf { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { deserializer.deserialize_string(PathBufVisitor) } @@ -951,7 +994,8 @@ static OSSTR_VARIANTS: &'static [&'static str] = &["Unix", "Windows"]; #[cfg(all(feature = "std", any(unix, windows)))] impl<'de> Deserialize<'de> for OsStringKind { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { struct KindVisitor; @@ -963,17 +1007,19 @@ impl<'de> Deserialize<'de> for OsStringKind { } fn visit_u32(self, value: u32) -> Result - where E: Error, + where + E: Error, { match value { 0 => Ok(OsStringKind::Unix), 1 => Ok(OsStringKind::Windows), - _ => Err(Error::invalid_value(Unexpected::Unsigned(value as u64), &self)) + _ => Err(Error::invalid_value(Unexpected::Unsigned(value as u64), &self),), } } fn visit_str(self, value: &str) -> Result - where E: Error, + where + E: Error, { match value { "Unix" => Ok(OsStringKind::Unix), @@ -983,7 +1029,8 @@ impl<'de> Deserialize<'de> for OsStringKind { } fn visit_bytes(self, value: &[u8]) -> Result - where E: Error, + where + E: Error, { match value { b"Unix" => Ok(OsStringKind::Unix), @@ -991,9 +1038,7 @@ impl<'de> Deserialize<'de> for OsStringKind { _ => { match str::from_utf8(value) { Ok(value) => Err(Error::unknown_variant(value, OSSTR_VARIANTS)), - Err(_) => { - Err(Error::invalid_value(Unexpected::Bytes(value), &self)) - } + Err(_) => Err(Error::invalid_value(Unexpected::Bytes(value), &self)), } } } @@ -1017,33 +1062,31 @@ impl<'de> Visitor<'de> for OsStringVisitor { #[cfg(unix)] fn visit_enum(self, visitor: V) -> Result - where V: EnumVisitor<'de>, + where + V: EnumVisitor<'de>, { use std::os::unix::ffi::OsStringExt; match try!(visitor.visit_variant()) { - (OsStringKind::Unix, variant) => { - variant.visit_newtype().map(OsString::from_vec) - } - (OsStringKind::Windows, _) => { - Err(Error::custom("cannot deserialize Windows OS string on Unix")) - } + (OsStringKind::Unix, variant) => variant.visit_newtype().map(OsString::from_vec), + (OsStringKind::Windows, _) => Err(Error::custom("cannot deserialize Windows OS string on Unix",),), } } #[cfg(windows)] fn visit_enum(self, visitor: V) -> Result - where V: EnumVisitor<'de>, + where + V: EnumVisitor<'de>, { use std::os::windows::ffi::OsStringExt; match try!(visitor.visit_variant()) { (OsStringKind::Windows, variant) => { - variant.visit_newtype::>().map(|vec| OsString::from_wide(&vec)) - } - (OsStringKind::Unix, _) => { - Err(Error::custom("cannot deserialize Unix OS string on Windows")) + variant + .visit_newtype::>() + .map(|vec| OsString::from_wide(&vec)) } + (OsStringKind::Unix, _) => Err(Error::custom("cannot deserialize Unix OS string on Windows",),), } } } @@ -1051,7 +1094,8 @@ impl<'de> Visitor<'de> for OsStringVisitor { #[cfg(all(feature = "std", any(unix, windows)))] impl<'de> Deserialize<'de> for OsString { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { deserializer.deserialize_enum("OsString", OSSTR_VARIANTS, OsStringVisitor) } @@ -1062,7 +1106,8 @@ impl<'de> Deserialize<'de> for OsString { #[cfg(any(feature = "std", feature = "alloc"))] impl<'de, T: Deserialize<'de>> Deserialize<'de> for Box { fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer<'de> + where + D: Deserializer<'de>, { let val = try!(Deserialize::deserialize(deserializer)); Ok(Box::new(val)) @@ -1072,7 +1117,8 @@ impl<'de, T: Deserialize<'de>> Deserialize<'de> for Box { #[cfg(any(feature = "std", feature = "collections"))] impl<'de, T: Deserialize<'de>> Deserialize<'de> for Box<[T]> { fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer<'de> + where + D: Deserializer<'de>, { let v: Vec = try!(Deserialize::deserialize(deserializer)); Ok(v.into_boxed_slice()) @@ -1082,7 +1128,8 @@ impl<'de, T: Deserialize<'de>> Deserialize<'de> for Box<[T]> { #[cfg(any(feature = "std", feature = "collections"))] impl<'de> Deserialize<'de> for Box { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { let s = try!(String::deserialize(deserializer)); Ok(s.into_boxed_str()) @@ -1092,7 +1139,8 @@ impl<'de> Deserialize<'de> for Box { #[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] impl<'de, T: Deserialize<'de>> Deserialize<'de> for Arc { fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer<'de> + where + D: Deserializer<'de>, { let val = try!(Deserialize::deserialize(deserializer)); Ok(Arc::new(val)) @@ -1102,7 +1150,8 @@ impl<'de, T: Deserialize<'de>> Deserialize<'de> for Arc { #[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] impl<'de, T: Deserialize<'de>> Deserialize<'de> for Rc { fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer<'de> + where + D: Deserializer<'de>, { let val = try!(Deserialize::deserialize(deserializer)); Ok(Rc::new(val)) @@ -1111,12 +1160,14 @@ impl<'de, T: Deserialize<'de>> Deserialize<'de> for Rc { #[cfg(any(feature = "std", feature = "collections"))] impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T> - where T: ToOwned, - T::Owned: Deserialize<'de> +where + T: ToOwned, + T::Owned: Deserialize<'de>, { #[inline] fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer<'de> + where + D: Deserializer<'de>, { let val = try!(Deserialize::deserialize(deserializer)); Ok(Cow::Owned(val)) @@ -1136,7 +1187,8 @@ impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T> #[cfg(feature = "std")] impl<'de> Deserialize<'de> for Duration { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { enum Field { Secs, @@ -1145,7 +1197,8 @@ impl<'de> Deserialize<'de> for Duration { impl<'de> Deserialize<'de> for Field { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { struct FieldVisitor; @@ -1157,7 +1210,8 @@ impl<'de> Deserialize<'de> for Duration { } fn visit_str(self, value: &str) -> Result - where E: Error + where + E: Error, { match value { "secs" => Ok(Field::Secs), @@ -1167,7 +1221,8 @@ impl<'de> Deserialize<'de> for Duration { } fn visit_bytes(self, value: &[u8]) -> Result - where E: Error + where + E: Error, { match value { b"secs" => Ok(Field::Secs), @@ -1194,7 +1249,8 @@ impl<'de> Deserialize<'de> for Duration { } fn visit_seq(self, mut visitor: V) -> Result - where V: SeqVisitor<'de> + where + V: SeqVisitor<'de>, { let secs: u64 = match try!(visitor.visit()) { Some(value) => value, @@ -1212,7 +1268,8 @@ impl<'de> Deserialize<'de> for Duration { } fn visit_map(self, mut visitor: V) -> Result - where V: MapVisitor<'de> + where + V: MapVisitor<'de>, { let mut secs: Option = None; let mut nanos: Option = None; @@ -1262,7 +1319,8 @@ impl<'de> Deserialize<'de> for Duration { #[cfg(feature = "std")] impl<'de, Idx: Deserialize<'de>> Deserialize<'de> for ops::Range { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { enum Field { Start, @@ -1271,7 +1329,8 @@ impl<'de, Idx: Deserialize<'de>> Deserialize<'de> for ops::Range { impl<'de> Deserialize<'de> for Field { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { struct FieldVisitor; @@ -1283,7 +1342,8 @@ impl<'de, Idx: Deserialize<'de>> Deserialize<'de> for ops::Range { } fn visit_str(self, value: &str) -> Result - where E: Error + where + E: Error, { match value { "start" => Ok(Field::Start), @@ -1293,7 +1353,8 @@ impl<'de, Idx: Deserialize<'de>> Deserialize<'de> for ops::Range { } fn visit_bytes(self, value: &[u8]) -> Result - where E: Error + where + E: Error, { match value { b"start" => Ok(Field::Start), @@ -1322,7 +1383,8 @@ impl<'de, Idx: Deserialize<'de>> Deserialize<'de> for ops::Range { } fn visit_seq(self, mut visitor: V) -> Result, V::Error> - where V: SeqVisitor<'de> + where + V: SeqVisitor<'de>, { let start: Idx = match try!(visitor.visit()) { Some(value) => value, @@ -1340,7 +1402,8 @@ impl<'de, Idx: Deserialize<'de>> Deserialize<'de> for ops::Range { } fn visit_map(self, mut visitor: V) -> Result, V::Error> - where V: MapVisitor<'de> + where + V: MapVisitor<'de>, { let mut start: Option = None; let mut end: Option = None; @@ -1385,10 +1448,12 @@ impl<'de, Idx: Deserialize<'de>> Deserialize<'de> for ops::Range { #[cfg(feature = "unstable")] #[allow(deprecated)] // num::Zero is deprecated but there is no replacement impl<'de, T> Deserialize<'de> for NonZero - where T: Deserialize<'de> + PartialEq + Zeroable + Zero +where + T: Deserialize<'de> + PartialEq + Zeroable + Zero, { fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer<'de> + where + D: Deserializer<'de>, { let value = try!(Deserialize::deserialize(deserializer)); if value == Zero::zero() { @@ -1402,11 +1467,13 @@ impl<'de, T> Deserialize<'de> for NonZero impl<'de, T, E> Deserialize<'de> for Result - where T: Deserialize<'de>, - E: Deserialize<'de> +where + T: Deserialize<'de>, + E: Deserialize<'de>, { fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer<'de> + where + D: Deserializer<'de>, { enum Field { Ok, @@ -1416,7 +1483,8 @@ impl<'de, T, E> Deserialize<'de> for Result impl<'de> Deserialize<'de> for Field { #[inline] fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { struct FieldVisitor; @@ -1428,19 +1496,21 @@ impl<'de, T, E> Deserialize<'de> for Result } fn visit_u32(self, value: u32) -> Result - where E: Error + where + E: Error, { match value { 0 => Ok(Field::Ok), 1 => Ok(Field::Err), _ => { - Err(Error::invalid_value(Unexpected::Unsigned(value as u64), &self)) + Err(Error::invalid_value(Unexpected::Unsigned(value as u64), &self),) } } } fn visit_str(self, value: &str) -> Result - where E: Error + where + E: Error, { match value { "Ok" => Ok(Field::Ok), @@ -1450,7 +1520,8 @@ impl<'de, T, E> Deserialize<'de> for Result } fn visit_bytes(self, value: &[u8]) -> Result - where E: Error + where + E: Error, { match value { b"Ok" => Ok(Field::Ok), @@ -1474,8 +1545,9 @@ impl<'de, T, E> Deserialize<'de> for Result struct ResultVisitor(PhantomData>); impl<'de, T, E> Visitor<'de> for ResultVisitor - where T: Deserialize<'de>, - E: Deserialize<'de> + where + T: Deserialize<'de>, + E: Deserialize<'de>, { type Value = Result; @@ -1484,7 +1556,8 @@ impl<'de, T, E> Deserialize<'de> for Result } fn visit_enum(self, visitor: V) -> Result, V::Error> - where V: EnumVisitor<'de> + where + V: EnumVisitor<'de>, { match try!(visitor.visit_variant()) { (Field::Ok, variant) => variant.visit_newtype().map(Ok), diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 2104bcda..2da3d2d6 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -421,7 +421,8 @@ pub trait Expected { } impl<'de, T> Expected for T - where T: Visitor<'de> +where + T: Visitor<'de>, { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { self.expecting(formatter) @@ -474,7 +475,8 @@ pub trait Deserialize<'de>: Sized { /// /// [impl-deserialize]: https://serde.rs/impl-deserialize.html fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de>; + where + D: Deserializer<'de>; } /// A data structure that can be deserialized without borrowing any data from @@ -499,7 +501,11 @@ pub trait Deserialize<'de>: Sized { /// # } /// ``` pub trait DeserializeOwned: for<'de> Deserialize<'de> {} -impl DeserializeOwned for T where T: for<'de> Deserialize<'de> {} +impl DeserializeOwned for T +where + T: for<'de> Deserialize<'de>, +{ +} /// `DeserializeSeed` is the stateful form of the `Deserialize` trait. If you /// ever find yourself looking for a way to pass data into a `Deserialize` impl, @@ -651,17 +657,20 @@ pub trait DeserializeSeed<'de>: Sized { /// Equivalent to the more common `Deserialize::deserialize` method, except /// with some initial piece of data (the seed) passed in. fn deserialize(self, deserializer: D) -> Result - where D: Deserializer<'de>; + where + D: Deserializer<'de>; } impl<'de, T> DeserializeSeed<'de> for PhantomData - where T: Deserialize<'de> +where + T: Deserialize<'de>, { type Value = T; #[inline] fn deserialize(self, deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { T::deserialize(deserializer) } @@ -764,43 +773,69 @@ pub trait Deserializer<'de>: Sized { /// `Deserializer::deserialize` means your data type will be able to /// deserialize from self-describing formats only, ruling out Bincode and /// many others. - fn deserialize(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a `bool` value. - fn deserialize_bool(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize_bool(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a `u8` value. - fn deserialize_u8(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize_u8(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a `u16` value. - fn deserialize_u16(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize_u16(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a `u32` value. - fn deserialize_u32(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize_u32(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a `u64` value. - fn deserialize_u64(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize_u64(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting an `i8` value. - fn deserialize_i8(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize_i8(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting an `i16` value. - fn deserialize_i16(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize_i16(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting an `i32` value. - fn deserialize_i32(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize_i32(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting an `i64` value. - fn deserialize_i64(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize_i64(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a `f32` value. - fn deserialize_f32(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize_f32(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a `f64` value. - fn deserialize_f64(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize_f64(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a `char` value. - fn deserialize_char(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize_char(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a string value and does /// not benefit from taking ownership of buffered data owned by the @@ -809,7 +844,9 @@ pub trait Deserializer<'de>: Sized { /// If the `Visitor` would benefit from taking ownership of `String` data, /// indiciate this to the `Deserializer` by using `deserialize_string` /// instead. - fn deserialize_str(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize_str(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a string value and would /// benefit from taking ownership of buffered data owned by the @@ -818,7 +855,9 @@ pub trait Deserializer<'de>: Sized { /// If the `Visitor` would not benefit from taking ownership of `String` /// data, indicate that to the `Deserializer` by using `deserialize_str` /// instead. - fn deserialize_string(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize_string(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a byte array and does not /// benefit from taking ownership of buffered data owned by the @@ -827,7 +866,9 @@ pub trait Deserializer<'de>: Sized { /// If the `Visitor` would benefit from taking ownership of `Vec` data, /// indicate this to the `Deserializer` by using `deserialize_byte_buf` /// instead. - fn deserialize_bytes(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize_bytes(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a byte array and would /// benefit from taking ownership of buffered data owned by the @@ -836,91 +877,116 @@ pub trait Deserializer<'de>: Sized { /// If the `Visitor` would not benefit from taking ownership of `Vec` /// data, indicate that to the `Deserializer` by using `deserialize_bytes` /// instead. - fn deserialize_byte_buf(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize_byte_buf(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting an optional value. /// /// This allows deserializers that encode an optional value as a nullable /// value to convert the null value into `None` and a regular value into /// `Some(value)`. - fn deserialize_option(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a unit value. - fn deserialize_unit(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize_unit(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a unit struct with a /// particular name. - fn deserialize_unit_struct(self, - name: &'static str, - visitor: V) - -> Result - where V: Visitor<'de>; + fn deserialize_unit_struct( + self, + name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a newtype struct with a /// particular name. - fn deserialize_newtype_struct(self, - name: &'static str, - visitor: V) - -> Result - where V: Visitor<'de>; + fn deserialize_newtype_struct( + self, + name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a sequence of values. - fn deserialize_seq(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize_seq(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a sequence of values and /// knows how many values there are without looking at the serialized data. - fn deserialize_seq_fixed_size(self, - len: usize, - visitor: V) - -> Result - where V: Visitor<'de>; + fn deserialize_seq_fixed_size( + self, + len: usize, + visitor: V, + ) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a tuple value with a /// particular number of elements. fn deserialize_tuple(self, len: usize, visitor: V) -> Result - where V: Visitor<'de>; + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a tuple struct with a /// particular name and number of fields. - fn deserialize_tuple_struct(self, - name: &'static str, - len: usize, - visitor: V) - -> Result - where V: Visitor<'de>; + fn deserialize_tuple_struct( + self, + name: &'static str, + len: usize, + visitor: V, + ) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a map of key-value pairs. - fn deserialize_map(self, visitor: V) -> Result where V: Visitor<'de>; + fn deserialize_map(self, visitor: V) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting a struct with a particular /// name and fields. - fn deserialize_struct(self, - name: &'static str, - fields: &'static [&'static str], - visitor: V) - -> Result - where V: Visitor<'de>; + fn deserialize_struct( + self, + name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting the name of a struct /// field or the discriminant of an enum variant. fn deserialize_identifier(self, visitor: V) -> Result - where V: Visitor<'de>; + where + V: Visitor<'de>; /// Hint that the `Deserialize` type is expecting an enum value with a /// particular name and possible variants. - fn deserialize_enum(self, - name: &'static str, - variants: &'static [&'static str], - visitor: V) - -> Result - where V: Visitor<'de>; + fn deserialize_enum( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>; /// Hint that the `Deserialize` type needs to deserialize a value whose type /// doesn't matter because it is ignored. /// /// Deserializers for non-self-describing formats may not support this mode. fn deserialize_ignored_any(self, visitor: V) -> Result - where V: Visitor<'de>; + where + V: Visitor<'de>; } /////////////////////////////////////////////////////////////////////////////// @@ -986,77 +1052,88 @@ pub trait Visitor<'de>: Sized { /// Deserialize a `bool` into a `Value`. fn visit_bool(self, v: bool) -> Result - where E: Error + where + E: Error, { Err(Error::invalid_type(Unexpected::Bool(v), &self)) } /// Deserialize an `i8` into a `Value`. fn visit_i8(self, v: i8) -> Result - where E: Error + where + E: Error, { self.visit_i64(v as i64) } /// Deserialize an `i16` into a `Value`. fn visit_i16(self, v: i16) -> Result - where E: Error + where + E: Error, { self.visit_i64(v as i64) } /// Deserialize an `i32` into a `Value`. fn visit_i32(self, v: i32) -> Result - where E: Error + where + E: Error, { self.visit_i64(v as i64) } /// Deserialize an `i64` into a `Value`. fn visit_i64(self, v: i64) -> Result - where E: Error + where + E: Error, { Err(Error::invalid_type(Unexpected::Signed(v), &self)) } /// Deserialize a `u8` into a `Value`. fn visit_u8(self, v: u8) -> Result - where E: Error + where + E: Error, { self.visit_u64(v as u64) } /// Deserialize a `u16` into a `Value`. fn visit_u16(self, v: u16) -> Result - where E: Error + where + E: Error, { self.visit_u64(v as u64) } /// Deserialize a `u32` into a `Value`. fn visit_u32(self, v: u32) -> Result - where E: Error + where + E: Error, { self.visit_u64(v as u64) } /// Deserialize a `u64` into a `Value`. fn visit_u64(self, v: u64) -> Result - where E: Error + where + E: Error, { Err(Error::invalid_type(Unexpected::Unsigned(v), &self)) } /// Deserialize a `f32` into a `Value`. fn visit_f32(self, v: f32) -> Result - where E: Error + where + E: Error, { self.visit_f64(v as f64) } /// Deserialize a `f64` into a `Value`. fn visit_f64(self, v: f64) -> Result - where E: Error + where + E: Error, { Err(Error::invalid_type(Unexpected::Float(v), &self)) } @@ -1064,7 +1141,8 @@ pub trait Visitor<'de>: Sized { /// Deserialize a `char` into a `Value`. #[inline] fn visit_char(self, v: char) -> Result - where E: Error + where + E: Error, { self.visit_str(utf8::encode(v).as_str()) } @@ -1080,7 +1158,8 @@ pub trait Visitor<'de>: Sized { /// It is never correct to implement `visit_string` without implementing /// `visit_str`. Implement neither, both, or just `visit_str`. fn visit_str(self, v: &str) -> Result - where E: Error + where + E: Error, { Err(Error::invalid_type(Unexpected::Str(v), &self)) } @@ -1095,7 +1174,8 @@ pub trait Visitor<'de>: Sized { /// The default implementation forwards to `visit_str`. #[inline] fn visit_borrowed_str(self, v: &'de str) -> Result - where E: Error + where + E: Error, { self.visit_str(v) } @@ -1117,28 +1197,32 @@ pub trait Visitor<'de>: Sized { #[inline] #[cfg(any(feature = "std", feature = "collections"))] fn visit_string(self, v: String) -> Result - where E: Error + where + E: Error, { self.visit_str(&v) } /// Deserialize a `()` into a `Value`. fn visit_unit(self) -> Result - where E: Error + where + E: Error, { Err(Error::invalid_type(Unexpected::Unit, &self)) } /// Deserialize an absent optional `Value`. fn visit_none(self) -> Result - where E: Error + where + E: Error, { Err(Error::invalid_type(Unexpected::Option, &self)) } /// Deserialize a present optional `Value`. fn visit_some(self, deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { let _ = deserializer; Err(Error::invalid_type(Unexpected::Option, &self)) @@ -1146,7 +1230,8 @@ pub trait Visitor<'de>: Sized { /// Deserialize `Value` as a newtype struct. fn visit_newtype_struct(self, deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { let _ = deserializer; Err(Error::invalid_type(Unexpected::NewtypeStruct, &self)) @@ -1154,7 +1239,8 @@ pub trait Visitor<'de>: Sized { /// Deserialize `Value` as a sequence of elements. fn visit_seq(self, visitor: V) -> Result - where V: SeqVisitor<'de> + where + V: SeqVisitor<'de>, { let _ = visitor; Err(Error::invalid_type(Unexpected::Seq, &self)) @@ -1162,7 +1248,8 @@ pub trait Visitor<'de>: Sized { /// Deserialize `Value` as a key-value map. fn visit_map(self, visitor: V) -> Result - where V: MapVisitor<'de> + where + V: MapVisitor<'de>, { let _ = visitor; Err(Error::invalid_type(Unexpected::Map, &self)) @@ -1170,7 +1257,8 @@ pub trait Visitor<'de>: Sized { /// Deserialize `Value` as an enum. fn visit_enum(self, visitor: V) -> Result - where V: EnumVisitor<'de> + where + V: EnumVisitor<'de>, { let _ = visitor; Err(Error::invalid_type(Unexpected::Enum, &self)) @@ -1187,7 +1275,8 @@ pub trait Visitor<'de>: Sized { /// It is never correct to implement `visit_byte_buf` without implementing /// `visit_bytes`. Implement neither, both, or just `visit_bytes`. fn visit_bytes(self, v: &[u8]) -> Result - where E: Error + where + E: Error, { let _ = v; Err(Error::invalid_type(Unexpected::Bytes(v), &self)) @@ -1202,7 +1291,8 @@ pub trait Visitor<'de>: Sized { /// The default implementation forwards to `visit_bytes`. #[inline] fn visit_borrowed_bytes(self, v: &'de [u8]) -> Result - where E: Error + where + E: Error, { self.visit_bytes(v) } @@ -1224,7 +1314,8 @@ pub trait Visitor<'de>: Sized { /// `Vec`. #[cfg(any(feature = "std", feature = "collections"))] fn visit_byte_buf(self, v: Vec) -> Result - where E: Error + where + E: Error, { self.visit_bytes(&v) } @@ -1247,7 +1338,8 @@ pub trait SeqVisitor<'de> { /// `Deserialize` implementations should typically use `SeqVisitor::visit` /// instead. fn visit_seed(&mut self, seed: T) -> Result, Self::Error> - where T: DeserializeSeed<'de>; + where + T: DeserializeSeed<'de>; /// This returns `Ok(Some(value))` for the next value in the sequence, or /// `Ok(None)` if there are no more remaining items. @@ -1256,7 +1348,8 @@ pub trait SeqVisitor<'de> { /// `SeqVisitor` implementations should not override the default behavior. #[inline] fn visit(&mut self) -> Result, Self::Error> - where T: Deserialize<'de> + where + T: Deserialize<'de>, { self.visit_seed(PhantomData) } @@ -1269,20 +1362,23 @@ pub trait SeqVisitor<'de> { } impl<'de, 'a, V> SeqVisitor<'de> for &'a mut V - where V: SeqVisitor<'de> +where + V: SeqVisitor<'de>, { type Error = V::Error; #[inline] fn visit_seed(&mut self, seed: T) -> Result, V::Error> - where T: DeserializeSeed<'de> + where + T: DeserializeSeed<'de>, { (**self).visit_seed(seed) } #[inline] fn visit(&mut self) -> Result, V::Error> - where T: Deserialize<'de> + where + T: Deserialize<'de>, { (**self).visit() } @@ -1309,14 +1405,16 @@ pub trait MapVisitor<'de> { /// `Deserialize` implementations should typically use /// `MapVisitor::visit_key` or `MapVisitor::visit` instead. fn visit_key_seed(&mut self, seed: K) -> Result, Self::Error> - where K: DeserializeSeed<'de>; + where + K: DeserializeSeed<'de>; /// This returns a `Ok(value)` for the next value in the map. /// /// `Deserialize` implementations should typically use /// `MapVisitor::visit_value` instead. fn visit_value_seed(&mut self, seed: V) -> Result - where V: DeserializeSeed<'de>; + where + V: DeserializeSeed<'de>; /// This returns `Ok(Some((key, value)))` for the next (key-value) pair in /// the map, or `Ok(None)` if there are no more remaining items. @@ -1327,12 +1425,14 @@ pub trait MapVisitor<'de> { /// `Deserialize` implementations should typically use `MapVisitor::visit` /// instead. #[inline] - fn visit_seed(&mut self, - kseed: K, - vseed: V) - -> Result, Self::Error> - where K: DeserializeSeed<'de>, - V: DeserializeSeed<'de> + fn visit_seed( + &mut self, + kseed: K, + vseed: V, + ) -> Result, Self::Error> + where + K: DeserializeSeed<'de>, + V: DeserializeSeed<'de>, { match try!(self.visit_key_seed(kseed)) { Some(key) => { @@ -1350,7 +1450,8 @@ pub trait MapVisitor<'de> { /// `MapVisitor` implementations should not override the default behavior. #[inline] fn visit_key(&mut self) -> Result, Self::Error> - where K: Deserialize<'de> + where + K: Deserialize<'de>, { self.visit_key_seed(PhantomData) } @@ -1361,7 +1462,8 @@ pub trait MapVisitor<'de> { /// `MapVisitor` implementations should not override the default behavior. #[inline] fn visit_value(&mut self) -> Result - where V: Deserialize<'de> + where + V: Deserialize<'de>, { self.visit_value_seed(PhantomData) } @@ -1373,8 +1475,9 @@ pub trait MapVisitor<'de> { /// `MapVisitor` implementations should not override the default behavior. #[inline] fn visit(&mut self) -> Result, Self::Error> - where K: Deserialize<'de>, - V: Deserialize<'de> + where + K: Deserialize<'de>, + V: Deserialize<'de>, { self.visit_seed(PhantomData, PhantomData) } @@ -1387,53 +1490,61 @@ pub trait MapVisitor<'de> { } impl<'de, 'a, V_> MapVisitor<'de> for &'a mut V_ - where V_: MapVisitor<'de> +where + V_: MapVisitor<'de>, { type Error = V_::Error; #[inline] fn visit_key_seed(&mut self, seed: K) -> Result, Self::Error> - where K: DeserializeSeed<'de> + where + K: DeserializeSeed<'de>, { (**self).visit_key_seed(seed) } #[inline] fn visit_value_seed(&mut self, seed: V) -> Result - where V: DeserializeSeed<'de> + where + V: DeserializeSeed<'de>, { (**self).visit_value_seed(seed) } #[inline] - fn visit_seed(&mut self, - kseed: K, - vseed: V) - -> Result, Self::Error> - where K: DeserializeSeed<'de>, - V: DeserializeSeed<'de> + fn visit_seed( + &mut self, + kseed: K, + vseed: V, + ) -> Result, Self::Error> + where + K: DeserializeSeed<'de>, + V: DeserializeSeed<'de>, { (**self).visit_seed(kseed, vseed) } #[inline] fn visit(&mut self) -> Result, V_::Error> - where K: Deserialize<'de>, - V: Deserialize<'de> + where + K: Deserialize<'de>, + V: Deserialize<'de>, { (**self).visit() } #[inline] fn visit_key(&mut self) -> Result, V_::Error> - where K: Deserialize<'de> + where + K: Deserialize<'de>, { (**self).visit_key() } #[inline] fn visit_value(&mut self) -> Result - where V: Deserialize<'de> + where + V: Deserialize<'de>, { (**self).visit_value() } @@ -1462,7 +1573,8 @@ pub trait EnumVisitor<'de>: Sized { /// `Deserialize` implementations should typically use /// `EnumVisitor::visit_variant` instead. fn visit_variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> - where V: DeserializeSeed<'de>; + where + V: DeserializeSeed<'de>; /// `visit_variant` is called to identify which variant to deserialize. /// @@ -1470,7 +1582,8 @@ pub trait EnumVisitor<'de>: Sized { /// `EnumVisitor` implementations should not override the default behavior. #[inline] fn visit_variant(self) -> Result<(V, Self::Variant), Self::Error> - where V: Deserialize<'de> + where + V: Deserialize<'de>, { self.visit_variant_seed(PhantomData) } @@ -1556,7 +1669,8 @@ pub trait VariantVisitor<'de>: Sized { /// # } /// ``` fn visit_newtype_seed(self, seed: T) -> Result - where T: DeserializeSeed<'de>; + where + T: DeserializeSeed<'de>; /// Called when deserializing a variant with a single value. /// @@ -1565,7 +1679,8 @@ pub trait VariantVisitor<'de>: Sized { /// behavior. #[inline] fn visit_newtype(self) -> Result - where T: Deserialize<'de> + where + T: Deserialize<'de>, { self.visit_newtype_seed(PhantomData) } @@ -1609,7 +1724,8 @@ pub trait VariantVisitor<'de>: Sized { /// # } /// ``` fn visit_tuple(self, len: usize, visitor: V) -> Result - where V: Visitor<'de>; + where + V: Visitor<'de>; /// Called when deserializing a struct-like variant. /// @@ -1649,11 +1765,13 @@ pub trait VariantVisitor<'de>: Sized { /// } /// # } /// ``` - fn visit_struct(self, - fields: &'static [&'static str], - visitor: V) - -> Result - where V: Visitor<'de>; + fn visit_struct( + self, + fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>; } /////////////////////////////////////////////////////////////////////////////// diff --git a/serde/src/de/utf8.rs b/serde/src/de/utf8.rs index 27ad1b2d..be13f029 100644 --- a/serde/src/de/utf8.rs +++ b/serde/src/de/utf8.rs @@ -31,10 +31,7 @@ pub fn encode(c: char) -> Encode { buf[3] = (code & 0x3F) as u8 | TAG_CONT; 0 }; - Encode { - buf: buf, - pos: pos, - } + Encode { buf: buf, pos: pos } } pub struct Encode { diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 9c5f9195..1bdbefb9 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -51,7 +51,8 @@ impl error::Error for Error { /////////////////////////////////////////////////////////////////////////////// impl<'de, E> IntoDeserializer<'de, E> for () - where E: de::Error +where + E: de::Error, { type Deserializer = UnitDeserializer; @@ -67,7 +68,8 @@ pub struct UnitDeserializer { } impl<'de, E> de::Deserializer<'de> for UnitDeserializer - where E: de::Error +where + E: de::Error, { type Error = E; @@ -78,13 +80,15 @@ impl<'de, E> de::Deserializer<'de> for UnitDeserializer } fn deserialize(self, visitor: V) -> Result - where V: de::Visitor<'de> + where + V: de::Visitor<'de>, { visitor.visit_unit() } fn deserialize_option(self, visitor: V) -> Result - where V: de::Visitor<'de> + where + V: de::Visitor<'de>, { visitor.visit_none() } @@ -156,7 +160,8 @@ pub struct U32Deserializer { } impl<'de, E> IntoDeserializer<'de, E> for u32 - where E: de::Error +where + E: de::Error, { type Deserializer = U32Deserializer; @@ -169,7 +174,8 @@ impl<'de, E> IntoDeserializer<'de, E> for u32 } impl<'de, E> de::Deserializer<'de> for U32Deserializer - where E: de::Error +where + E: de::Error, { type Error = E; @@ -180,30 +186,35 @@ impl<'de, E> de::Deserializer<'de> for U32Deserializer } fn deserialize(self, visitor: V) -> Result - where V: de::Visitor<'de> + where + V: de::Visitor<'de>, { visitor.visit_u32(self.value) } - fn deserialize_enum(self, - _name: &str, - _variants: &'static [&'static str], - visitor: V) - -> Result - where V: de::Visitor<'de> + fn deserialize_enum( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, { visitor.visit_enum(self) } } impl<'de, E> de::EnumVisitor<'de> for U32Deserializer - where E: de::Error +where + E: de::Error, { type Error = E; type Variant = private::UnitOnly; fn visit_variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> - where T: de::DeserializeSeed<'de> + where + T: de::DeserializeSeed<'de>, { seed.deserialize(self).map(private::unit_only) } @@ -219,7 +230,8 @@ pub struct StrDeserializer<'a, E> { } impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a str - where E: de::Error +where + E: de::Error, { type Deserializer = StrDeserializer<'a, E>; @@ -232,22 +244,26 @@ impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a str } impl<'de, 'a, E> de::Deserializer<'de> for StrDeserializer<'a, E> - where E: de::Error +where + E: de::Error, { type Error = E; fn deserialize(self, visitor: V) -> Result - where V: de::Visitor<'de> + where + V: de::Visitor<'de>, { visitor.visit_str(self.value) } - fn deserialize_enum(self, - _name: &str, - _variants: &'static [&'static str], - visitor: V) - -> Result - where V: de::Visitor<'de> + fn deserialize_enum( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, { visitor.visit_enum(self) } @@ -260,13 +276,15 @@ impl<'de, 'a, E> de::Deserializer<'de> for StrDeserializer<'a, E> } impl<'de, 'a, E> de::EnumVisitor<'de> for StrDeserializer<'a, E> - where E: de::Error +where + E: de::Error, { type Error = E; type Variant = private::UnitOnly; fn visit_variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> - where T: de::DeserializeSeed<'de> + where + T: de::DeserializeSeed<'de>, { seed.deserialize(self).map(private::unit_only) } @@ -284,7 +302,8 @@ pub struct StringDeserializer { #[cfg(any(feature = "std", feature = "collections"))] impl<'de, E> IntoDeserializer<'de, E> for String - where E: de::Error +where + E: de::Error, { type Deserializer = StringDeserializer; @@ -298,22 +317,26 @@ impl<'de, E> IntoDeserializer<'de, E> for String #[cfg(any(feature = "std", feature = "collections"))] impl<'de, E> de::Deserializer<'de> for StringDeserializer - where E: de::Error +where + E: de::Error, { type Error = E; fn deserialize(self, visitor: V) -> Result - where V: de::Visitor<'de> + where + V: de::Visitor<'de>, { visitor.visit_string(self.value) } - fn deserialize_enum(self, - _name: &str, - _variants: &'static [&'static str], - visitor: V) - -> Result - where V: de::Visitor<'de> + fn deserialize_enum( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, { visitor.visit_enum(self) } @@ -327,13 +350,15 @@ impl<'de, E> de::Deserializer<'de> for StringDeserializer #[cfg(any(feature = "std", feature = "collections"))] impl<'de, 'a, E> de::EnumVisitor<'de> for StringDeserializer - where E: de::Error +where + E: de::Error, { type Error = E; type Variant = private::UnitOnly; fn visit_variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> - where T: de::DeserializeSeed<'de> + where + T: de::DeserializeSeed<'de>, { seed.deserialize(self).map(private::unit_only) } @@ -351,7 +376,8 @@ pub struct CowStrDeserializer<'a, E> { #[cfg(any(feature = "std", feature = "collections"))] impl<'de, 'a, E> IntoDeserializer<'de, E> for Cow<'a, str> - where E: de::Error +where + E: de::Error, { type Deserializer = CowStrDeserializer<'a, E>; @@ -365,12 +391,14 @@ impl<'de, 'a, E> IntoDeserializer<'de, E> for Cow<'a, str> #[cfg(any(feature = "std", feature = "collections"))] impl<'de, 'a, E> de::Deserializer<'de> for CowStrDeserializer<'a, E> - where E: de::Error +where + E: de::Error, { type Error = E; fn deserialize(self, visitor: V) -> Result - where V: de::Visitor<'de> + where + V: de::Visitor<'de>, { match self.value { Cow::Borrowed(string) => visitor.visit_str(string), @@ -378,12 +406,14 @@ impl<'de, 'a, E> de::Deserializer<'de> for CowStrDeserializer<'a, E> } } - fn deserialize_enum(self, - _name: &str, - _variants: &'static [&'static str], - visitor: V) - -> Result - where V: de::Visitor<'de> + fn deserialize_enum( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, { visitor.visit_enum(self) } @@ -397,13 +427,15 @@ impl<'de, 'a, E> de::Deserializer<'de> for CowStrDeserializer<'a, E> #[cfg(any(feature = "std", feature = "collections"))] impl<'de, 'a, E> de::EnumVisitor<'de> for CowStrDeserializer<'a, E> - where E: de::Error +where + E: de::Error, { type Error = E; type Variant = private::UnitOnly; fn visit_variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> - where T: de::DeserializeSeed<'de> + where + T: de::DeserializeSeed<'de>, { seed.deserialize(self).map(private::unit_only) } @@ -420,8 +452,9 @@ pub struct SeqDeserializer { } impl SeqDeserializer - where I: Iterator, - E: de::Error +where + I: Iterator, + E: de::Error, { /// Construct a new `SeqDeserializer`. pub fn new(iter: I) -> Self { @@ -444,20 +477,22 @@ impl SeqDeserializer } else { // First argument is the number of elements in the data, second // argument is the number of elements expected by the Deserialize. - Err(de::Error::invalid_length(self.count + remaining, &ExpectedInSeq(self.count))) + Err(de::Error::invalid_length(self.count + remaining, &ExpectedInSeq(self.count)),) } } } impl<'de, I, T, E> de::Deserializer<'de> for SeqDeserializer - where I: Iterator, - T: IntoDeserializer<'de, E>, - E: de::Error +where + I: Iterator, + T: IntoDeserializer<'de, E>, + E: de::Error, { type Error = E; fn deserialize(mut self, visitor: V) -> Result - where V: de::Visitor<'de> + where + V: de::Visitor<'de>, { let v = try!(visitor.visit_seq(&mut self)); try!(self.end()); @@ -472,14 +507,16 @@ impl<'de, I, T, E> de::Deserializer<'de> for SeqDeserializer } impl<'de, I, T, E> de::SeqVisitor<'de> for SeqDeserializer - where I: Iterator, - T: IntoDeserializer<'de, E>, - E: de::Error +where + I: Iterator, + T: IntoDeserializer<'de, E>, + E: de::Error, { type Error = E; fn visit_seed(&mut self, seed: V) -> Result, Self::Error> - where V: de::DeserializeSeed<'de> + where + V: de::DeserializeSeed<'de>, { match self.iter.next() { Some(value) => { @@ -511,8 +548,9 @@ impl Expected for ExpectedInSeq { #[cfg(any(feature = "std", feature = "collections"))] impl<'de, T, E> IntoDeserializer<'de, E> for Vec - where T: IntoDeserializer<'de, E>, - E: de::Error +where + T: IntoDeserializer<'de, E>, + E: de::Error, { type Deserializer = SeqDeserializer< as IntoIterator>::IntoIter, E>; @@ -523,8 +561,9 @@ impl<'de, T, E> IntoDeserializer<'de, E> for Vec #[cfg(any(feature = "std", feature = "collections"))] impl<'de, T, E> IntoDeserializer<'de, E> for BTreeSet - where T: IntoDeserializer<'de, E> + Eq + Ord, - E: de::Error +where + T: IntoDeserializer<'de, E> + Eq + Ord, + E: de::Error, { type Deserializer = SeqDeserializer< as IntoIterator>::IntoIter, E>; @@ -535,8 +574,9 @@ impl<'de, T, E> IntoDeserializer<'de, E> for BTreeSet #[cfg(feature = "std")] impl<'de, T, E> IntoDeserializer<'de, E> for HashSet - where T: IntoDeserializer<'de, E> + Eq + Hash, - E: de::Error +where + T: IntoDeserializer<'de, E> + Eq + Hash, + E: de::Error, { type Deserializer = SeqDeserializer< as IntoIterator>::IntoIter, E>; @@ -556,19 +596,19 @@ pub struct SeqVisitorDeserializer { impl SeqVisitorDeserializer { /// Construct a new `SeqVisitorDeserializer`. pub fn new(visitor: V_) -> Self { - SeqVisitorDeserializer { - visitor: visitor, - } + SeqVisitorDeserializer { visitor: visitor } } } impl<'de, V_> de::Deserializer<'de> for SeqVisitorDeserializer - where V_: de::SeqVisitor<'de> +where + V_: de::SeqVisitor<'de>, { type Error = V_::Error; fn deserialize(self, visitor: V) -> Result - where V: de::Visitor<'de> + where + V: de::Visitor<'de>, { visitor.visit_seq(self.visitor) } @@ -584,11 +624,12 @@ impl<'de, V_> de::Deserializer<'de> for SeqVisitorDeserializer /// A helper deserializer that deserializes a map. pub struct MapDeserializer<'de, I, E> - where I: Iterator, - I::Item: private::Pair, - ::First: IntoDeserializer<'de, E>, - ::Second: IntoDeserializer<'de, E>, - E: de::Error +where + I: Iterator, + I::Item: private::Pair, + ::First: IntoDeserializer<'de, E>, + ::Second: IntoDeserializer<'de, E>, + E: de::Error, { iter: iter::Fuse, value: Option<::Second>, @@ -598,11 +639,14 @@ pub struct MapDeserializer<'de, I, E> } impl<'de, I, E> MapDeserializer<'de, I, E> - where I: Iterator, - I::Item: private::Pair, - ::First: IntoDeserializer<'de, E>, - ::Second: IntoDeserializer<'de, E>, - E: de::Error +where + I: Iterator, + I::Item: private::Pair, + ::First: IntoDeserializer<'de, + E>, + ::Second: IntoDeserializer<'de, + E>, + E: de::Error, { /// Construct a new `MapDeserializer`. pub fn new(iter: I) -> Self { @@ -627,12 +671,12 @@ impl<'de, I, E> MapDeserializer<'de, I, E> } else { // First argument is the number of elements in the data, second // argument is the number of elements expected by the Deserialize. - Err(de::Error::invalid_length(self.count + remaining, &ExpectedInMap(self.count))) + Err(de::Error::invalid_length(self.count + remaining, &ExpectedInMap(self.count)),) } } fn next_pair - (&mut self) + (&mut self,) -> Option<(::First, ::Second)> { match self.iter.next() { Some(kv) => { @@ -811,9 +855,10 @@ impl<'de, I, E> Debug for MapDeserializer<'de, I, E> struct PairDeserializer(A, B, PhantomData); impl<'de, A, B, E> de::Deserializer<'de> for PairDeserializer - where A: IntoDeserializer<'de, E>, - B: IntoDeserializer<'de, E>, - E: de::Error +where + A: IntoDeserializer<'de, E>, + B: IntoDeserializer<'de, E>, + E: de::Error, { type Error = E; @@ -824,13 +869,15 @@ impl<'de, A, B, E> de::Deserializer<'de> for PairDeserializer } fn deserialize(self, visitor: V) -> Result - where V: de::Visitor<'de> + where + V: de::Visitor<'de>, { self.deserialize_seq(visitor) } fn deserialize_seq(self, visitor: V) -> Result - where V: de::Visitor<'de> + where + V: de::Visitor<'de>, { let mut pair_visitor = PairVisitor(Some(self.0), Some(self.1), PhantomData); let pair = try!(visitor.visit_seq(&mut pair_visitor)); @@ -845,7 +892,8 @@ impl<'de, A, B, E> de::Deserializer<'de> for PairDeserializer } fn deserialize_seq_fixed_size(self, len: usize, visitor: V) -> Result - where V: de::Visitor<'de> + where + V: de::Visitor<'de>, { if len == 2 { self.deserialize_seq(visitor) @@ -860,14 +908,16 @@ impl<'de, A, B, E> de::Deserializer<'de> for PairDeserializer struct PairVisitor(Option, Option, PhantomData); impl<'de, A, B, E> de::SeqVisitor<'de> for PairVisitor - where A: IntoDeserializer<'de, E>, - B: IntoDeserializer<'de, E>, - E: de::Error +where + A: IntoDeserializer<'de, E>, + B: IntoDeserializer<'de, E>, + E: de::Error, { type Error = E; fn visit_seed(&mut self, seed: T) -> Result, Self::Error> - where T: de::DeserializeSeed<'de> + where + T: de::DeserializeSeed<'de>, { if let Some(k) = self.0.take() { seed.deserialize(k.into_deserializer()).map(Some) @@ -906,9 +956,10 @@ impl Expected for ExpectedInMap { #[cfg(any(feature = "std", feature = "collections"))] impl<'de, K, V, E> IntoDeserializer<'de, E> for BTreeMap - where K: IntoDeserializer<'de, E> + Eq + Ord, - V: IntoDeserializer<'de, E>, - E: de::Error +where + K: IntoDeserializer<'de, E> + Eq + Ord, + V: IntoDeserializer<'de, E>, + E: de::Error, { type Deserializer = MapDeserializer<'de, as IntoIterator>::IntoIter, E>; @@ -919,9 +970,10 @@ impl<'de, K, V, E> IntoDeserializer<'de, E> for BTreeMap #[cfg(feature = "std")] impl<'de, K, V, E> IntoDeserializer<'de, E> for HashMap - where K: IntoDeserializer<'de, E> + Eq + Hash, - V: IntoDeserializer<'de, E>, - E: de::Error +where + K: IntoDeserializer<'de, E> + Eq + Hash, + V: IntoDeserializer<'de, E>, + E: de::Error, { type Deserializer = MapDeserializer<'de, as IntoIterator>::IntoIter, E>; @@ -941,19 +993,19 @@ pub struct MapVisitorDeserializer { impl MapVisitorDeserializer { /// Construct a new `MapVisitorDeserializer`. pub fn new(visitor: V_) -> Self { - MapVisitorDeserializer { - visitor: visitor, - } + MapVisitorDeserializer { visitor: visitor } } } impl<'de, V_> de::Deserializer<'de> for MapVisitorDeserializer - where V_: de::MapVisitor<'de> +where + V_: de::MapVisitor<'de>, { type Error = V_::Error; fn deserialize(self, visitor: V) -> Result - where V: de::Visitor<'de> + where + V: de::Visitor<'de>, { visitor.visit_map(self.visitor) } @@ -982,7 +1034,8 @@ mod private { } impl<'de, E> de::VariantVisitor<'de> for UnitOnly - where E: de::Error + where + E: de::Error, { type Error = E; @@ -991,24 +1044,28 @@ mod private { } fn visit_newtype_seed(self, _seed: T) -> Result - where T: de::DeserializeSeed<'de> + where + T: de::DeserializeSeed<'de>, { - Err(de::Error::invalid_type(Unexpected::UnitVariant, &"newtype variant")) + Err(de::Error::invalid_type(Unexpected::UnitVariant, &"newtype variant"),) } fn visit_tuple(self, _len: usize, _visitor: V) -> Result - where V: de::Visitor<'de> + where + V: de::Visitor<'de>, { - Err(de::Error::invalid_type(Unexpected::UnitVariant, &"tuple variant")) + Err(de::Error::invalid_type(Unexpected::UnitVariant, &"tuple variant"),) } - fn visit_struct(self, - _fields: &'static [&'static str], - _visitor: V) - -> Result - where V: de::Visitor<'de> + fn visit_struct( + self, + _fields: &'static [&'static str], + _visitor: V, + ) -> Result + where + V: de::Visitor<'de>, { - Err(de::Error::invalid_type(Unexpected::UnitVariant, &"struct variant")) + Err(de::Error::invalid_type(Unexpected::UnitVariant, &"struct variant"),) } } diff --git a/serde/src/lib.rs b/serde/src/lib.rs index 703d41b9..c6c51c89 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -135,7 +135,7 @@ mod lib { pub use std::string::String; #[cfg(all(feature = "collections", not(feature = "std")))] pub use collections::string::{String, ToString}; - + #[cfg(feature = "std")] pub use std::vec::Vec; #[cfg(all(feature = "collections", not(feature = "std")))] diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 9d56071d..0f0d2c4f 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -6,31 +6,35 @@ use de::{Deserialize, Deserializer, Error, Visitor}; use de::Unexpected; #[cfg(any(feature = "std", feature = "collections"))] -pub use self::content::{Content, ContentRefDeserializer, ContentDeserializer, TaggedContentVisitor, - TagOrContentField, TagOrContentFieldVisitor, InternallyTaggedUnitVisitor, - UntaggedUnitVisitor}; +pub use self::content::{Content, ContentRefDeserializer, ContentDeserializer, + TaggedContentVisitor, TagOrContentField, TagOrContentFieldVisitor, + InternallyTaggedUnitVisitor, UntaggedUnitVisitor}; /// If the missing field is of type `Option` then treat is as `None`, /// otherwise it is an error. pub fn missing_field<'de, V, E>(field: &'static str) -> Result - where V: Deserialize<'de>, - E: Error +where + V: Deserialize<'de>, + E: Error, { struct MissingFieldDeserializer(&'static str, PhantomData); impl<'de, E> Deserializer<'de> for MissingFieldDeserializer - where E: Error + where + E: Error, { type Error = E; fn deserialize(self, _visitor: V) -> Result - where V: Visitor<'de> + where + V: Visitor<'de>, { Err(Error::missing_field(self.0)) } fn deserialize_option(self, visitor: V) -> Result - where V: Visitor<'de> + where + V: Visitor<'de>, { visitor.visit_none() } @@ -48,7 +52,8 @@ pub fn missing_field<'de, V, E>(field: &'static str) -> Result #[cfg(any(feature = "std", feature = "collections"))] pub fn borrow_cow_str<'de: 'a, 'a, D>(deserializer: D) -> Result, D::Error> - where D: Deserializer<'de> +where + D: Deserializer<'de>, { struct CowStrVisitor; @@ -60,25 +65,29 @@ pub fn borrow_cow_str<'de: 'a, 'a, D>(deserializer: D) -> Result, D } fn visit_str(self, v: &str) -> Result - where E: Error + where + E: Error, { Ok(Cow::Owned(v.to_owned())) } fn visit_borrowed_str(self, v: &'a str) -> Result - where E: Error + where + E: Error, { Ok(Cow::Borrowed(v)) } fn visit_string(self, v: String) -> Result - where E: Error + where + E: Error, { Ok(Cow::Owned(v)) } fn visit_bytes(self, v: &[u8]) -> Result - where E: Error + where + E: Error, { match str::from_utf8(v) { Ok(s) => Ok(Cow::Owned(s.to_owned())), @@ -87,7 +96,8 @@ pub fn borrow_cow_str<'de: 'a, 'a, D>(deserializer: D) -> Result, D } fn visit_borrowed_bytes(self, v: &'a [u8]) -> Result - where E: Error + where + E: Error, { match str::from_utf8(v) { Ok(s) => Ok(Cow::Borrowed(s)), @@ -96,11 +106,12 @@ pub fn borrow_cow_str<'de: 'a, 'a, D>(deserializer: D) -> Result, D } fn visit_byte_buf(self, v: Vec) -> Result - where E: Error + where + E: Error, { match String::from_utf8(v) { Ok(s) => Ok(Cow::Owned(s)), - Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self)), + Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self),), } } } @@ -110,7 +121,8 @@ pub fn borrow_cow_str<'de: 'a, 'a, D>(deserializer: D) -> Result, D #[cfg(any(feature = "std", feature = "collections"))] pub fn borrow_cow_bytes<'de: 'a, 'a, D>(deserializer: D) -> Result, D::Error> - where D: Deserializer<'de> +where + D: Deserializer<'de>, { struct CowBytesVisitor; @@ -122,37 +134,43 @@ pub fn borrow_cow_bytes<'de: 'a, 'a, D>(deserializer: D) -> Result } fn visit_str(self, v: &str) -> Result - where E: Error + where + E: Error, { Ok(Cow::Owned(v.as_bytes().to_vec())) } fn visit_borrowed_str(self, v: &'a str) -> Result - where E: Error + where + E: Error, { Ok(Cow::Borrowed(v.as_bytes())) } fn visit_string(self, v: String) -> Result - where E: Error + where + E: Error, { Ok(Cow::Owned(v.into_bytes())) } fn visit_bytes(self, v: &[u8]) -> Result - where E: Error + where + E: Error, { Ok(Cow::Owned(v.to_vec())) } fn visit_borrowed_bytes(self, v: &'a [u8]) -> Result - where E: Error + where + E: Error, { Ok(Cow::Borrowed(v)) } fn visit_byte_buf(self, v: Vec) -> Result - where E: Error + where + E: Error, { Ok(Cow::Owned(v)) } @@ -176,7 +194,7 @@ mod content { use lib::*; use de::{self, Deserialize, DeserializeSeed, Deserializer, Visitor, SeqVisitor, MapVisitor, - EnumVisitor, Unexpected}; + EnumVisitor, Unexpected}; /// Used from generated code to buffer the contents of the Deserializer when /// deserializing untagged enums and internally tagged enums. @@ -240,7 +258,8 @@ mod content { impl<'de> Deserialize<'de> for Content { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { // Untagged and internally tagged enums are only supported in // self-describing formats. @@ -258,127 +277,148 @@ mod content { } fn visit_bool(self, value: bool) -> Result - where F: de::Error + where + F: de::Error, { Ok(Content::Bool(value)) } fn visit_i8(self, value: i8) -> Result - where F: de::Error + where + F: de::Error, { Ok(Content::I8(value)) } fn visit_i16(self, value: i16) -> Result - where F: de::Error + where + F: de::Error, { Ok(Content::I16(value)) } fn visit_i32(self, value: i32) -> Result - where F: de::Error + where + F: de::Error, { Ok(Content::I32(value)) } fn visit_i64(self, value: i64) -> Result - where F: de::Error + where + F: de::Error, { Ok(Content::I64(value)) } fn visit_u8(self, value: u8) -> Result - where F: de::Error + where + F: de::Error, { Ok(Content::U8(value)) } fn visit_u16(self, value: u16) -> Result - where F: de::Error + where + F: de::Error, { Ok(Content::U16(value)) } fn visit_u32(self, value: u32) -> Result - where F: de::Error + where + F: de::Error, { Ok(Content::U32(value)) } fn visit_u64(self, value: u64) -> Result - where F: de::Error + where + F: de::Error, { Ok(Content::U64(value)) } fn visit_f32(self, value: f32) -> Result - where F: de::Error + where + F: de::Error, { Ok(Content::F32(value)) } fn visit_f64(self, value: f64) -> Result - where F: de::Error + where + F: de::Error, { Ok(Content::F64(value)) } fn visit_char(self, value: char) -> Result - where F: de::Error + where + F: de::Error, { Ok(Content::Char(value)) } fn visit_str(self, value: &str) -> Result - where F: de::Error + where + F: de::Error, { Ok(Content::String(value.into())) } fn visit_string(self, value: String) -> Result - where F: de::Error + where + F: de::Error, { Ok(Content::String(value)) } fn visit_bytes(self, value: &[u8]) -> Result - where F: de::Error + where + F: de::Error, { Ok(Content::Bytes(value.into())) } fn visit_byte_buf(self, value: Vec) -> Result - where F: de::Error + where + F: de::Error, { Ok(Content::Bytes(value)) } fn visit_unit(self) -> Result - where F: de::Error + where + F: de::Error, { Ok(Content::Unit) } fn visit_none(self) -> Result - where F: de::Error + where + F: de::Error, { Ok(Content::None) } fn visit_some(self, deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { Deserialize::deserialize(deserializer).map(|v| Content::Some(Box::new(v))) } fn visit_newtype_struct(self, deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { Deserialize::deserialize(deserializer).map(|v| Content::Newtype(Box::new(v))) } fn visit_seq(self, mut visitor: V) -> Result - where V: SeqVisitor<'de> + where + V: SeqVisitor<'de>, { let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); while let Some(e) = try!(visitor.visit()) { @@ -388,7 +428,8 @@ mod content { } fn visit_map(self, mut visitor: V) -> Result - where V: MapVisitor<'de> + where + V: MapVisitor<'de>, { let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); while let Some(kv) = try!(visitor.visit()) { @@ -398,9 +439,10 @@ mod content { } fn visit_enum(self, _visitor: V) -> Result - where V: EnumVisitor<'de> + where + V: EnumVisitor<'de>, { - Err(de::Error::custom("untagged and internally tagged enums do not support enum input")) + Err(de::Error::custom("untagged and internally tagged enums do not support enum input",),) } } @@ -426,7 +468,8 @@ mod content { type Value = TagOrContent; fn deserialize(self, deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { // Internally tagged enums are only supported in self-describing // formats. @@ -442,157 +485,218 @@ mod content { } fn visit_bool(self, value: bool) -> Result - where F: de::Error + where + F: de::Error, { - ContentVisitor.visit_bool(value).map(TagOrContent::Content) + ContentVisitor + .visit_bool(value) + .map(TagOrContent::Content) } fn visit_i8(self, value: i8) -> Result - where F: de::Error + where + F: de::Error, { ContentVisitor.visit_i8(value).map(TagOrContent::Content) } fn visit_i16(self, value: i16) -> Result - where F: de::Error + where + F: de::Error, { - ContentVisitor.visit_i16(value).map(TagOrContent::Content) + ContentVisitor + .visit_i16(value) + .map(TagOrContent::Content) } fn visit_i32(self, value: i32) -> Result - where F: de::Error + where + F: de::Error, { - ContentVisitor.visit_i32(value).map(TagOrContent::Content) + ContentVisitor + .visit_i32(value) + .map(TagOrContent::Content) } fn visit_i64(self, value: i64) -> Result - where F: de::Error + where + F: de::Error, { - ContentVisitor.visit_i64(value).map(TagOrContent::Content) + ContentVisitor + .visit_i64(value) + .map(TagOrContent::Content) } fn visit_u8(self, value: u8) -> Result - where F: de::Error + where + F: de::Error, { ContentVisitor.visit_u8(value).map(TagOrContent::Content) } fn visit_u16(self, value: u16) -> Result - where F: de::Error + where + F: de::Error, { - ContentVisitor.visit_u16(value).map(TagOrContent::Content) + ContentVisitor + .visit_u16(value) + .map(TagOrContent::Content) } fn visit_u32(self, value: u32) -> Result - where F: de::Error + where + F: de::Error, { - ContentVisitor.visit_u32(value).map(TagOrContent::Content) + ContentVisitor + .visit_u32(value) + .map(TagOrContent::Content) } fn visit_u64(self, value: u64) -> Result - where F: de::Error + where + F: de::Error, { - ContentVisitor.visit_u64(value).map(TagOrContent::Content) + ContentVisitor + .visit_u64(value) + .map(TagOrContent::Content) } fn visit_f32(self, value: f32) -> Result - where F: de::Error + where + F: de::Error, { - ContentVisitor.visit_f32(value).map(TagOrContent::Content) + ContentVisitor + .visit_f32(value) + .map(TagOrContent::Content) } fn visit_f64(self, value: f64) -> Result - where F: de::Error + where + F: de::Error, { - ContentVisitor.visit_f64(value).map(TagOrContent::Content) + ContentVisitor + .visit_f64(value) + .map(TagOrContent::Content) } fn visit_char(self, value: char) -> Result - where F: de::Error + where + F: de::Error, { - ContentVisitor.visit_char(value).map(TagOrContent::Content) + ContentVisitor + .visit_char(value) + .map(TagOrContent::Content) } fn visit_str(self, value: &str) -> Result - where F: de::Error + where + F: de::Error, { if value == self.name { Ok(TagOrContent::Tag) } else { - ContentVisitor.visit_str(value).map(TagOrContent::Content) + ContentVisitor + .visit_str(value) + .map(TagOrContent::Content) } } fn visit_string(self, value: String) -> Result - where F: de::Error + where + F: de::Error, { if value == self.name { Ok(TagOrContent::Tag) } else { - ContentVisitor.visit_string(value).map(TagOrContent::Content) + ContentVisitor + .visit_string(value) + .map(TagOrContent::Content) } } fn visit_bytes(self, value: &[u8]) -> Result - where F: de::Error + where + F: de::Error, { if value == self.name.as_bytes() { Ok(TagOrContent::Tag) } else { - ContentVisitor.visit_bytes(value).map(TagOrContent::Content) + ContentVisitor + .visit_bytes(value) + .map(TagOrContent::Content) } } fn visit_byte_buf(self, value: Vec) -> Result - where F: de::Error + where + F: de::Error, { if value == self.name.as_bytes() { Ok(TagOrContent::Tag) } else { - ContentVisitor.visit_byte_buf(value).map(TagOrContent::Content) + ContentVisitor + .visit_byte_buf(value) + .map(TagOrContent::Content) } } fn visit_unit(self) -> Result - where F: de::Error + where + F: de::Error, { ContentVisitor.visit_unit().map(TagOrContent::Content) } fn visit_none(self) -> Result - where F: de::Error + where + F: de::Error, { ContentVisitor.visit_none().map(TagOrContent::Content) } fn visit_some(self, deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { - ContentVisitor.visit_some(deserializer).map(TagOrContent::Content) + ContentVisitor + .visit_some(deserializer) + .map(TagOrContent::Content) } fn visit_newtype_struct(self, deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { - ContentVisitor.visit_newtype_struct(deserializer).map(TagOrContent::Content) + ContentVisitor + .visit_newtype_struct(deserializer) + .map(TagOrContent::Content) } fn visit_seq(self, visitor: V) -> Result - where V: SeqVisitor<'de> + where + V: SeqVisitor<'de>, { - ContentVisitor.visit_seq(visitor).map(TagOrContent::Content) + ContentVisitor + .visit_seq(visitor) + .map(TagOrContent::Content) } fn visit_map(self, visitor: V) -> Result - where V: MapVisitor<'de> + where + V: MapVisitor<'de>, { - ContentVisitor.visit_map(visitor).map(TagOrContent::Content) + ContentVisitor + .visit_map(visitor) + .map(TagOrContent::Content) } fn visit_enum(self, visitor: V) -> Result - where V: EnumVisitor<'de> + where + V: EnumVisitor<'de>, { - ContentVisitor.visit_enum(visitor).map(TagOrContent::Content) + ContentVisitor + .visit_enum(visitor) + .map(TagOrContent::Content) } } @@ -622,12 +726,14 @@ mod content { } impl<'de, T> DeserializeSeed<'de> for TaggedContentVisitor - where T: Deserialize<'de> + where + T: Deserialize<'de>, { type Value = TaggedContent; fn deserialize(self, deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { // Internally tagged enums are only supported in self-describing // formats. @@ -636,7 +742,8 @@ mod content { } impl<'de, T> Visitor<'de> for TaggedContentVisitor - where T: Deserialize<'de> + where + T: Deserialize<'de>, { type Value = TaggedContent; @@ -645,11 +752,13 @@ mod content { } fn visit_map(self, mut visitor: V) -> Result - where V: MapVisitor<'de> + where + V: MapVisitor<'de>, { let mut tag = None; let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); - while let Some(k) = try!(visitor.visit_key_seed(TagOrContentVisitor::new(self.tag_name))) { + while let Some(k) = + try!(visitor.visit_key_seed(TagOrContentVisitor::new(self.tag_name))) { match k { TagOrContent::Tag => { if tag.is_some() { @@ -666,10 +775,12 @@ mod content { match tag { None => Err(de::Error::missing_field(self.tag_name)), Some(tag) => { - Ok(TaggedContent { - tag: tag, - content: Content::Map(vec), - }) + Ok( + TaggedContent { + tag: tag, + content: Content::Map(vec), + }, + ) } } } @@ -693,7 +804,8 @@ mod content { type Value = TagOrContentField; fn deserialize(self, deserializer: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { deserializer.deserialize_str(self) } @@ -707,7 +819,8 @@ mod content { } fn visit_str(self, field: &str) -> Result - where E: de::Error + where + E: de::Error, { if field == self.tag { Ok(TagOrContentField::Tag) @@ -728,12 +841,14 @@ mod content { /// Used when deserializing an internally tagged enum because the content will /// be used exactly once. impl<'de, E> Deserializer<'de> for ContentDeserializer - where E: de::Error + where + E: de::Error, { type Error = E; fn deserialize(self, visitor: V) -> Result - where V: Visitor<'de> + where + V: Visitor<'de>, { match self.content { Content::Bool(v) => visitor.visit_bool(v), @@ -775,7 +890,8 @@ mod content { } fn deserialize_option(self, visitor: V) -> Result - where V: Visitor<'de> + where + V: Visitor<'de>, { match self.content { Content::None => visitor.visit_none(), @@ -785,18 +901,25 @@ mod content { } } - fn deserialize_newtype_struct(self, _name: &str, visitor: V) -> Result - where V: Visitor<'de> + fn deserialize_newtype_struct( + self, + _name: &str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, { visitor.visit_newtype_struct(self) } - fn deserialize_enum(self, - _name: &str, - _variants: &'static [&'static str], - visitor: V) - -> Result - where V: Visitor<'de> + fn deserialize_enum( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, { let (variant, value) = match self.content { Content::Map(value) => { @@ -804,28 +927,38 @@ mod content { let (variant, value) = match iter.next() { Some(v) => v, None => { - return Err(de::Error::invalid_value(de::Unexpected::Map, - &"map with a single key")); + return Err( + de::Error::invalid_value( + de::Unexpected::Map, + &"map with a single key", + ), + ); } }; // enums are encoded in json as maps with a single key:value pair if iter.next().is_some() { - return Err(de::Error::invalid_value(de::Unexpected::Map, - &"map with a single key")); + return Err( + de::Error::invalid_value( + de::Unexpected::Map, + &"map with a single key", + ), + ); } (variant, Some(value)) } Content::String(variant) => (Content::String(variant), None), other => { - return Err(de::Error::invalid_type(other.unexpected(), &"string or map")); + return Err(de::Error::invalid_type(other.unexpected(), &"string or map"),); } }; - visitor.visit_enum(EnumDeserializer { - variant: variant, - value: value, - err: PhantomData, - }) + visitor.visit_enum( + EnumDeserializer { + variant: variant, + value: value, + err: PhantomData, + }, + ) } forward_to_deserialize! { @@ -846,7 +979,8 @@ mod content { } struct EnumDeserializer - where E: de::Error + where + E: de::Error, { variant: Content, value: Option, @@ -854,33 +988,39 @@ mod content { } impl<'de, E> de::EnumVisitor<'de> for EnumDeserializer - where E: de::Error + where + E: de::Error, { type Error = E; type Variant = VariantDeserializer; - fn visit_variant_seed(self, - seed: V) - -> Result<(V::Value, VariantDeserializer), Self::Error> - where V: de::DeserializeSeed<'de> + fn visit_variant_seed( + self, + seed: V, + ) -> Result<(V::Value, VariantDeserializer), Self::Error> + where + V: de::DeserializeSeed<'de>, { let visitor = VariantDeserializer { value: self.value, err: PhantomData, }; - seed.deserialize(ContentDeserializer::new(self.variant)).map(|v| (v, visitor)) + seed.deserialize(ContentDeserializer::new(self.variant)) + .map(|v| (v, visitor)) } } struct VariantDeserializer - where E: de::Error + where + E: de::Error, { value: Option, err: PhantomData, } impl<'de, E> de::VariantVisitor<'de> for VariantDeserializer - where E: de::Error + where + E: de::Error, { type Error = E; @@ -892,51 +1032,59 @@ mod content { } fn visit_newtype_seed(self, seed: T) -> Result - where T: de::DeserializeSeed<'de> + where + T: de::DeserializeSeed<'de>, { match self.value { Some(value) => seed.deserialize(ContentDeserializer::new(value)), - None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"newtype variant")), + None => { + Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"newtype variant"),) + } } } fn visit_tuple(self, _len: usize, visitor: V) -> Result - where V: de::Visitor<'de> + where + V: de::Visitor<'de>, { match self.value { Some(Content::Seq(v)) => { de::Deserializer::deserialize(SeqDeserializer::new(v), visitor) } - Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"tuple variant")), - None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"tuple variant")), + Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"tuple variant"),), + None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"tuple variant"),), } } - fn visit_struct(self, - _fields: &'static [&'static str], - visitor: V) - -> Result - where V: de::Visitor<'de> + fn visit_struct( + self, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, { match self.value { Some(Content::Map(v)) => { de::Deserializer::deserialize(MapDeserializer::new(v), visitor) } - Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant")), - _ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant")), + Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant"),), + _ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant"),), } } } struct SeqDeserializer - where E: de::Error + where + E: de::Error, { iter: as IntoIterator>::IntoIter, err: PhantomData, } impl SeqDeserializer - where E: de::Error + where + E: de::Error, { fn new(vec: Vec) -> Self { SeqDeserializer { @@ -947,13 +1095,15 @@ mod content { } impl<'de, E> de::Deserializer<'de> for SeqDeserializer - where E: de::Error + where + E: de::Error, { type Error = E; #[inline] fn deserialize(mut self, visitor: V) -> Result - where V: de::Visitor<'de> + where + V: de::Visitor<'de>, { let len = self.iter.len(); if len == 0 { @@ -977,15 +1127,20 @@ mod content { } impl<'de, E> de::SeqVisitor<'de> for SeqDeserializer - where E: de::Error + where + E: de::Error, { type Error = E; fn visit_seed(&mut self, seed: T) -> Result, Self::Error> - where T: de::DeserializeSeed<'de> + where + T: de::DeserializeSeed<'de>, { match self.iter.next() { - Some(value) => seed.deserialize(ContentDeserializer::new(value)).map(Some), + Some(value) => { + seed.deserialize(ContentDeserializer::new(value)) + .map(Some) + } None => Ok(None), } } @@ -996,7 +1151,8 @@ mod content { } struct MapDeserializer - where E: de::Error + where + E: de::Error, { iter: as IntoIterator>::IntoIter, value: Option, @@ -1004,7 +1160,8 @@ mod content { } impl MapDeserializer - where E: de::Error + where + E: de::Error, { fn new(map: Vec<(Content, Content)>) -> Self { MapDeserializer { @@ -1016,12 +1173,14 @@ mod content { } impl<'de, E> de::MapVisitor<'de> for MapDeserializer - where E: de::Error + where + E: de::Error, { type Error = E; fn visit_key_seed(&mut self, seed: T) -> Result, Self::Error> - where T: de::DeserializeSeed<'de> + where + T: de::DeserializeSeed<'de>, { match self.iter.next() { Some((key, value)) => { @@ -1033,7 +1192,8 @@ mod content { } fn visit_value_seed(&mut self, seed: T) -> Result - where T: de::DeserializeSeed<'de> + where + T: de::DeserializeSeed<'de>, { match self.value.take() { Some(value) => seed.deserialize(ContentDeserializer::new(value)), @@ -1047,13 +1207,15 @@ mod content { } impl<'de, E> de::Deserializer<'de> for MapDeserializer - where E: de::Error + where + E: de::Error, { type Error = E; #[inline] fn deserialize(self, visitor: V) -> Result - where V: de::Visitor<'de> + where + V: de::Visitor<'de>, { visitor.visit_map(self) } @@ -1075,12 +1237,14 @@ mod content { /// Used when deserializing an untagged enum because the content may need to be /// used more than once. impl<'de, 'a, E> Deserializer<'de> for ContentRefDeserializer<'a, E> - where E: de::Error + where + E: de::Error, { type Error = E; fn deserialize(self, visitor: V) -> Result - where V: Visitor<'de> + where + V: Visitor<'de>, { match *self.content { Content::Bool(v) => visitor.visit_bool(v), @@ -1099,7 +1263,9 @@ mod content { Content::Unit => visitor.visit_unit(), Content::None => visitor.visit_none(), Content::Some(ref v) => visitor.visit_some(ContentRefDeserializer::new(v)), - Content::Newtype(ref v) => visitor.visit_newtype_struct(ContentRefDeserializer::new(v)), + Content::Newtype(ref v) => { + visitor.visit_newtype_struct(ContentRefDeserializer::new(v)) + } Content::Seq(ref v) => { let seq = v.into_iter().map(ContentRefDeserializer::new); let mut seq_visitor = de::value::SeqDeserializer::new(seq); @@ -1108,10 +1274,12 @@ mod content { Ok(value) } Content::Map(ref v) => { - let map = v.into_iter().map(|&(ref k, ref v)| { - (ContentRefDeserializer::new(k), - ContentRefDeserializer::new(v)) - }); + let map = v.into_iter() + .map( + |&(ref k, ref v)| { + (ContentRefDeserializer::new(k), ContentRefDeserializer::new(v)) + }, + ); let mut map_visitor = de::value::MapDeserializer::new(map); let value = try!(visitor.visit_map(&mut map_visitor)); try!(map_visitor.end()); @@ -1122,7 +1290,8 @@ mod content { } fn deserialize_option(self, visitor: V) -> Result - where V: Visitor<'de> + where + V: Visitor<'de>, { match *self.content { Content::None => visitor.visit_none(), @@ -1133,17 +1302,20 @@ mod content { } fn deserialize_newtype_struct(self, _name: &str, visitor: V) -> Result - where V: Visitor<'de> + where + V: Visitor<'de>, { visitor.visit_newtype_struct(self) } - fn deserialize_enum(self, - _name: &str, - _variants: &'static [&'static str], - visitor: V) - -> Result - where V: Visitor<'de> + fn deserialize_enum( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, { let (variant, value) = match *self.content { Content::Map(ref value) => { @@ -1151,28 +1323,38 @@ mod content { let &(ref variant, ref value) = match iter.next() { Some(v) => v, None => { - return Err(de::Error::invalid_value(de::Unexpected::Map, - &"map with a single key")); + return Err( + de::Error::invalid_value( + de::Unexpected::Map, + &"map with a single key", + ), + ); } }; // enums are encoded in json as maps with a single key:value pair if iter.next().is_some() { - return Err(de::Error::invalid_value(de::Unexpected::Map, - &"map with a single key")); + return Err( + de::Error::invalid_value( + de::Unexpected::Map, + &"map with a single key", + ), + ); } (variant, Some(value)) } ref s @ Content::String(_) => (s, None), ref other => { - return Err(de::Error::invalid_type(other.unexpected(), &"string or map")); + return Err(de::Error::invalid_type(other.unexpected(), &"string or map"),); } }; - visitor.visit_enum(EnumRefDeserializer { - variant: variant, - value: value, - err: PhantomData, - }) + visitor.visit_enum( + EnumRefDeserializer { + variant: variant, + value: value, + err: PhantomData, + }, + ) } forward_to_deserialize! { @@ -1193,7 +1375,8 @@ mod content { } struct EnumRefDeserializer<'a, E> - where E: de::Error + where + E: de::Error, { variant: &'a Content, value: Option<&'a Content>, @@ -1201,31 +1384,36 @@ mod content { } impl<'de, 'a, E> de::EnumVisitor<'de> for EnumRefDeserializer<'a, E> - where E: de::Error + where + E: de::Error, { type Error = E; type Variant = VariantRefDeserializer<'a, Self::Error>; fn visit_variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> - where V: de::DeserializeSeed<'de> + where + V: de::DeserializeSeed<'de>, { let visitor = VariantRefDeserializer { value: self.value, err: PhantomData, }; - seed.deserialize(ContentRefDeserializer::new(self.variant)).map(|v| (v, visitor)) + seed.deserialize(ContentRefDeserializer::new(self.variant)) + .map(|v| (v, visitor)) } } struct VariantRefDeserializer<'a, E> - where E: de::Error + where + E: de::Error, { value: Option<&'a Content>, err: PhantomData, } impl<'de, 'a, E> de::VariantVisitor<'de> for VariantRefDeserializer<'a, E> - where E: de::Error + where + E: de::Error, { type Error = E; @@ -1237,51 +1425,59 @@ mod content { } fn visit_newtype_seed(self, seed: T) -> Result - where T: de::DeserializeSeed<'de> + where + T: de::DeserializeSeed<'de>, { match self.value { Some(value) => seed.deserialize(ContentRefDeserializer::new(value)), - None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"newtype variant")), + None => { + Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"newtype variant"),) + } } } fn visit_tuple(self, _len: usize, visitor: V) -> Result - where V: de::Visitor<'de> + where + V: de::Visitor<'de>, { match self.value { Some(&Content::Seq(ref v)) => { de::Deserializer::deserialize(SeqRefDeserializer::new(v), visitor) } - Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"tuple variant")), - None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"tuple variant")), + Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"tuple variant"),), + None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"tuple variant"),), } } - fn visit_struct(self, - _fields: &'static [&'static str], - visitor: V) - -> Result - where V: de::Visitor<'de> + fn visit_struct( + self, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, { match self.value { Some(&Content::Map(ref v)) => { de::Deserializer::deserialize(MapRefDeserializer::new(v), visitor) } - Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant")), - _ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant")), + Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant"),), + _ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant"),), } } } struct SeqRefDeserializer<'a, E> - where E: de::Error + where + E: de::Error, { iter: <&'a [Content] as IntoIterator>::IntoIter, err: PhantomData, } impl<'a, E> SeqRefDeserializer<'a, E> - where E: de::Error + where + E: de::Error, { fn new(vec: &'a [Content]) -> Self { SeqRefDeserializer { @@ -1292,13 +1488,15 @@ mod content { } impl<'de, 'a, E> de::Deserializer<'de> for SeqRefDeserializer<'a, E> - where E: de::Error + where + E: de::Error, { type Error = E; #[inline] fn deserialize(mut self, visitor: V) -> Result - where V: de::Visitor<'de> + where + V: de::Visitor<'de>, { let len = self.iter.len(); if len == 0 { @@ -1322,15 +1520,20 @@ mod content { } impl<'de, 'a, E> de::SeqVisitor<'de> for SeqRefDeserializer<'a, E> - where E: de::Error + where + E: de::Error, { type Error = E; fn visit_seed(&mut self, seed: T) -> Result, Self::Error> - where T: de::DeserializeSeed<'de> + where + T: de::DeserializeSeed<'de>, { match self.iter.next() { - Some(value) => seed.deserialize(ContentRefDeserializer::new(value)).map(Some), + Some(value) => { + seed.deserialize(ContentRefDeserializer::new(value)) + .map(Some) + } None => Ok(None), } } @@ -1341,7 +1544,8 @@ mod content { } struct MapRefDeserializer<'a, E> - where E: de::Error + where + E: de::Error, { iter: <&'a [(Content, Content)] as IntoIterator>::IntoIter, value: Option<&'a Content>, @@ -1349,7 +1553,8 @@ mod content { } impl<'a, E> MapRefDeserializer<'a, E> - where E: de::Error + where + E: de::Error, { fn new(map: &'a [(Content, Content)]) -> Self { MapRefDeserializer { @@ -1361,24 +1566,28 @@ mod content { } impl<'de, 'a, E> de::MapVisitor<'de> for MapRefDeserializer<'a, E> - where E: de::Error + where + E: de::Error, { type Error = E; fn visit_key_seed(&mut self, seed: T) -> Result, Self::Error> - where T: de::DeserializeSeed<'de> + where + T: de::DeserializeSeed<'de>, { match self.iter.next() { Some(&(ref key, ref value)) => { self.value = Some(value); - seed.deserialize(ContentRefDeserializer::new(key)).map(Some) + seed.deserialize(ContentRefDeserializer::new(key)) + .map(Some) } None => Ok(None), } } fn visit_value_seed(&mut self, seed: T) -> Result - where T: de::DeserializeSeed<'de> + where + T: de::DeserializeSeed<'de>, { match self.value.take() { Some(value) => seed.deserialize(ContentRefDeserializer::new(value)), @@ -1392,13 +1601,15 @@ mod content { } impl<'de, 'a, E> de::Deserializer<'de> for MapRefDeserializer<'a, E> - where E: de::Error + where + E: de::Error, { type Error = E; #[inline] fn deserialize(self, visitor: V) -> Result - where V: de::Visitor<'de> + where + V: de::Visitor<'de>, { visitor.visit_map(self) } @@ -1411,7 +1622,8 @@ mod content { } impl<'de, E> de::IntoDeserializer<'de, E> for ContentDeserializer - where E: de::Error + where + E: de::Error, { type Deserializer = Self; @@ -1421,7 +1633,8 @@ mod content { } impl<'de, 'a, E> de::IntoDeserializer<'de, E> for ContentRefDeserializer<'a, E> - where E: de::Error + where + E: de::Error, { type Deserializer = Self; @@ -1456,7 +1669,8 @@ mod content { } fn visit_map(self, _: V) -> Result<(), V::Error> - where V: MapVisitor<'de> + where + V: MapVisitor<'de>, { Ok(()) } @@ -1488,7 +1702,8 @@ mod content { } fn visit_unit(self) -> Result<(), E> - where E: de::Error + where + E: de::Error, { Ok(()) } diff --git a/serde/src/private/ser.rs b/serde/src/private/ser.rs index bf61b0b1..c4311562 100644 --- a/serde/src/private/ser.rs +++ b/serde/src/private/ser.rs @@ -12,23 +12,27 @@ pub fn constrain(t: &T) -> &T { } /// Not public API. -pub fn serialize_tagged_newtype(serializer: S, - type_ident: &'static str, - variant_ident: &'static str, - tag: &'static str, - variant_name: &'static str, - value: &T) - -> Result - where S: Serializer, - T: Serialize +pub fn serialize_tagged_newtype( + serializer: S, + type_ident: &'static str, + variant_ident: &'static str, + tag: &'static str, + variant_name: &'static str, + value: &T, +) -> Result +where + S: Serializer, + T: Serialize, { - value.serialize(TaggedSerializer { - type_ident: type_ident, - variant_ident: variant_ident, - tag: tag, - variant_name: variant_name, - delegate: serializer, - }) + value.serialize( + TaggedSerializer { + type_ident: type_ident, + variant_ident: variant_ident, + tag: tag, + variant_name: variant_name, + delegate: serializer, + }, + ) } struct TaggedSerializer { @@ -78,19 +82,23 @@ impl Display for Unsupported { } impl TaggedSerializer - where S: Serializer +where + S: Serializer, { fn bad_type(self, what: Unsupported) -> S::Error { - ser::Error::custom(format_args!( + ser::Error::custom( + format_args!( "cannot serialize tagged newtype variant {}::{} containing {}", self.type_ident, self.variant_ident, - what)) + what), + ) } } impl Serializer for TaggedSerializer - where S: Serializer +where + S: Serializer, { type Ok = S::Ok; type Error = S::Error; @@ -172,7 +180,8 @@ impl Serializer for TaggedSerializer } fn serialize_some(self, _: &T) -> Result - where T: Serialize + where + T: Serialize, { Err(self.bad_type(Unsupported::Optional)) } @@ -185,33 +194,38 @@ impl Serializer for TaggedSerializer Err(self.bad_type(Unsupported::UnitStruct)) } - fn serialize_unit_variant(self, - _: &'static str, - _: u32, - inner_variant: &'static str) - -> Result { + fn serialize_unit_variant( + self, + _: &'static str, + _: u32, + inner_variant: &'static str, + ) -> Result { let mut map = try!(self.delegate.serialize_map(Some(2))); try!(map.serialize_entry(self.tag, self.variant_name)); try!(map.serialize_entry(inner_variant, &())); map.end() } - fn serialize_newtype_struct(self, - _: &'static str, - value: &T) - -> Result - where T: Serialize + fn serialize_newtype_struct( + self, + _: &'static str, + value: &T, + ) -> Result + where + T: Serialize, { value.serialize(self) } - fn serialize_newtype_variant(self, - _: &'static str, - _: u32, - inner_variant: &'static str, - inner_value: &T) - -> Result - where T: Serialize + fn serialize_newtype_variant( + self, + _: &'static str, + _: u32, + inner_variant: &'static str, + inner_value: &T, + ) -> Result + where + T: Serialize, { let mut map = try!(self.delegate.serialize_map(Some(2))); try!(map.serialize_entry(self.tag, self.variant_name)); @@ -231,36 +245,39 @@ impl Serializer for TaggedSerializer Err(self.bad_type(Unsupported::Tuple)) } - fn serialize_tuple_struct(self, - _: &'static str, - _: usize) - -> Result { + fn serialize_tuple_struct( + self, + _: &'static str, + _: usize, + ) -> Result { Err(self.bad_type(Unsupported::TupleStruct)) } #[cfg(not(any(feature = "std", feature = "collections")))] - fn serialize_tuple_variant(self, - _: &'static str, - _: u32, - _: &'static str, - _: usize) - -> Result { + fn serialize_tuple_variant( + self, + _: &'static str, + _: u32, + _: &'static str, + _: usize, + ) -> Result { // Lack of push-based serialization means we need to buffer the content // of the tuple variant, so it requires std. Err(self.bad_type(Unsupported::Enum)) } #[cfg(any(feature = "std", feature = "collections"))] - fn serialize_tuple_variant(self, - _: &'static str, - _: u32, - inner_variant: &'static str, - len: usize) - -> Result { + fn serialize_tuple_variant( + self, + _: &'static str, + _: u32, + inner_variant: &'static str, + len: usize, + ) -> Result { let mut map = try!(self.delegate.serialize_map(Some(2))); try!(map.serialize_entry(self.tag, self.variant_name)); try!(map.serialize_key(inner_variant)); - Ok(SerializeTupleVariantAsMapValue::new(map, inner_variant, len)) + Ok(SerializeTupleVariantAsMapValue::new(map, inner_variant, len),) } fn serialize_map(self, len: Option) -> Result { @@ -269,43 +286,47 @@ impl Serializer for TaggedSerializer Ok(map) } - fn serialize_struct(self, - name: &'static str, - len: usize) - -> Result { + fn serialize_struct( + self, + name: &'static str, + len: usize, + ) -> Result { let mut state = try!(self.delegate.serialize_struct(name, len + 1)); try!(state.serialize_field(self.tag, self.variant_name)); Ok(state) } #[cfg(not(any(feature = "std", feature = "collections")))] - fn serialize_struct_variant(self, - _: &'static str, - _: u32, - _: &'static str, - _: usize) - -> Result { + fn serialize_struct_variant( + self, + _: &'static str, + _: u32, + _: &'static str, + _: usize, + ) -> Result { // Lack of push-based serialization means we need to buffer the content // of the struct variant, so it requires std. Err(self.bad_type(Unsupported::Enum)) } #[cfg(any(feature = "std", feature = "collections"))] - fn serialize_struct_variant(self, - _: &'static str, - _: u32, - inner_variant: &'static str, - len: usize) - -> Result { + fn serialize_struct_variant( + self, + _: &'static str, + _: u32, + inner_variant: &'static str, + len: usize, + ) -> Result { let mut map = try!(self.delegate.serialize_map(Some(2))); try!(map.serialize_entry(self.tag, self.variant_name)); try!(map.serialize_key(inner_variant)); - Ok(SerializeStructVariantAsMapValue::new(map, inner_variant, len)) + Ok(SerializeStructVariantAsMapValue::new(map, inner_variant, len),) } #[cfg(not(any(feature = "std", feature = "collections")))] fn collect_str(self, _: &T) -> Result - where T: Display + where + T: Display, { Err(self.bad_type(Unsupported::String)) } @@ -358,7 +379,8 @@ mod content { } impl ser::SerializeTupleVariant for SerializeTupleVariantAsMapValue - where M: ser::SerializeMap + where + M: ser::SerializeMap, { type Ok = M::Ok; type Error = M::Error; @@ -392,15 +414,17 @@ mod content { } impl ser::SerializeStructVariant for SerializeStructVariantAsMapValue - where M: ser::SerializeMap + where + M: ser::SerializeMap, { type Ok = M::Ok; type Error = M::Error; - fn serialize_field(&mut self, - key: &'static str, - value: &T) - -> Result<(), M::Error> { + fn serialize_field( + &mut self, + key: &'static str, + value: &T, + ) -> Result<(), M::Error> { let value = try!(value.serialize(ContentSerializer::::new())); self.fields.push((key, value)); Ok(()) @@ -454,7 +478,8 @@ mod content { impl Serialize for Content { fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { match *self { Content::Bool(b) => serializer.serialize_bool(b), @@ -552,7 +577,8 @@ mod content { } impl Serializer for ContentSerializer - where E: ser::Error + where + E: ser::Error, { type Ok = Content; type Error = E; @@ -637,111 +663,141 @@ mod content { Ok(Content::UnitStruct(name)) } - fn serialize_unit_variant(self, - name: &'static str, - variant_index: u32, - variant: &'static str) - -> Result { + fn serialize_unit_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + ) -> Result { Ok(Content::UnitVariant(name, variant_index, variant)) } - fn serialize_newtype_struct(self, - name: &'static str, - value: &T) - -> Result { - Ok(Content::NewtypeStruct(name, Box::new(try!(value.serialize(self))))) + fn serialize_newtype_struct( + self, + name: &'static str, + value: &T, + ) -> Result { + Ok(Content::NewtypeStruct(name, Box::new(try!(value.serialize(self)))),) } - fn serialize_newtype_variant(self, - name: &'static str, - variant_index: u32, - variant: &'static str, - value: &T) - -> Result { - Ok(Content::NewtypeVariant(name, - variant_index, - variant, - Box::new(try!(value.serialize(self))))) + fn serialize_newtype_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result { + Ok( + Content::NewtypeVariant( + name, + variant_index, + variant, + Box::new(try!(value.serialize(self))), + ), + ) } fn serialize_seq(self, len: Option) -> Result { - Ok(SerializeSeq { - fixed_size: false, - elements: Vec::with_capacity(len.unwrap_or(0)), - error: PhantomData, - }) + Ok( + SerializeSeq { + fixed_size: false, + elements: Vec::with_capacity(len.unwrap_or(0)), + error: PhantomData, + }, + ) } fn serialize_seq_fixed_size(self, size: usize) -> Result { - Ok(SerializeSeq { - fixed_size: true, - elements: Vec::with_capacity(size), - error: PhantomData, - }) + Ok( + SerializeSeq { + fixed_size: true, + elements: Vec::with_capacity(size), + error: PhantomData, + }, + ) } fn serialize_tuple(self, len: usize) -> Result { - Ok(SerializeTuple { - elements: Vec::with_capacity(len), - error: PhantomData, - }) + Ok( + SerializeTuple { + elements: Vec::with_capacity(len), + error: PhantomData, + }, + ) } - fn serialize_tuple_struct(self, - name: &'static str, - len: usize) - -> Result { - Ok(SerializeTupleStruct { - name: name, - fields: Vec::with_capacity(len), - error: PhantomData, - }) + fn serialize_tuple_struct( + self, + name: &'static str, + len: usize, + ) -> Result { + Ok( + SerializeTupleStruct { + name: name, + fields: Vec::with_capacity(len), + error: PhantomData, + }, + ) } - fn serialize_tuple_variant(self, - name: &'static str, - variant_index: u32, - variant: &'static str, - len: usize) - -> Result { - Ok(SerializeTupleVariant { - name: name, - variant_index: variant_index, - variant: variant, - fields: Vec::with_capacity(len), - error: PhantomData, - }) + fn serialize_tuple_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + Ok( + SerializeTupleVariant { + name: name, + variant_index: variant_index, + variant: variant, + fields: Vec::with_capacity(len), + error: PhantomData, + }, + ) } fn serialize_map(self, len: Option) -> Result { - Ok(SerializeMap { - entries: Vec::with_capacity(len.unwrap_or(0)), - key: None, - error: PhantomData, - }) + Ok( + SerializeMap { + entries: Vec::with_capacity(len.unwrap_or(0)), + key: None, + error: PhantomData, + }, + ) } - fn serialize_struct(self, name: &'static str, len: usize) -> Result { - Ok(SerializeStruct { - name: name, - fields: Vec::with_capacity(len), - error: PhantomData, - }) + fn serialize_struct( + self, + name: &'static str, + len: usize, + ) -> Result { + Ok( + SerializeStruct { + name: name, + fields: Vec::with_capacity(len), + error: PhantomData, + }, + ) } - fn serialize_struct_variant(self, - name: &'static str, - variant_index: u32, - variant: &'static str, - len: usize) - -> Result { - Ok(SerializeStructVariant { - name: name, - variant_index: variant_index, - variant: variant, - fields: Vec::with_capacity(len), - error: PhantomData, - }) + fn serialize_struct_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + Ok( + SerializeStructVariant { + name: name, + variant_index: variant_index, + variant: variant, + fields: Vec::with_capacity(len), + error: PhantomData, + }, + ) } } @@ -752,7 +808,8 @@ mod content { } impl ser::SerializeSeq for SerializeSeq - where E: ser::Error + where + E: ser::Error, { type Ok = Content; type Error = E; @@ -764,11 +821,13 @@ mod content { } fn end(self) -> Result { - Ok(if self.fixed_size { - Content::SeqFixedSize(self.elements) - } else { - Content::Seq(self.elements) - }) + Ok( + if self.fixed_size { + Content::SeqFixedSize(self.elements) + } else { + Content::Seq(self.elements) + }, + ) } } @@ -778,7 +837,8 @@ mod content { } impl ser::SerializeTuple for SerializeTuple - where E: ser::Error + where + E: ser::Error, { type Ok = Content; type Error = E; @@ -801,7 +861,8 @@ mod content { } impl ser::SerializeTupleStruct for SerializeTupleStruct - where E: ser::Error + where + E: ser::Error, { type Ok = Content; type Error = E; @@ -826,7 +887,8 @@ mod content { } impl ser::SerializeTupleVariant for SerializeTupleVariant - where E: ser::Error + where + E: ser::Error, { type Ok = Content; type Error = E; @@ -838,7 +900,7 @@ mod content { } fn end(self) -> Result { - Ok(Content::TupleVariant(self.name, self.variant_index, self.variant, self.fields)) + Ok(Content::TupleVariant(self.name, self.variant_index, self.variant, self.fields),) } } @@ -849,7 +911,8 @@ mod content { } impl ser::SerializeMap for SerializeMap - where E: ser::Error + where + E: ser::Error, { type Ok = Content; type Error = E; @@ -861,7 +924,9 @@ mod content { } fn serialize_value(&mut self, value: &T) -> Result<(), E> { - let key = self.key.take().expect("serialize_value called before serialize_key"); + let key = self.key + .take() + .expect("serialize_value called before serialize_key"); let value = try!(value.serialize(ContentSerializer::::new())); self.entries.push((key, value)); Ok(()) @@ -871,10 +936,11 @@ mod content { Ok(Content::Map(self.entries)) } - fn serialize_entry(&mut self, - key: &K, - value: &V) - -> Result<(), E> { + fn serialize_entry( + &mut self, + key: &K, + value: &V, + ) -> Result<(), E> { let key = try!(key.serialize(ContentSerializer::::new())); let value = try!(value.serialize(ContentSerializer::::new())); self.entries.push((key, value)); @@ -889,15 +955,17 @@ mod content { } impl ser::SerializeStruct for SerializeStruct - where E: ser::Error + where + E: ser::Error, { type Ok = Content; type Error = E; - fn serialize_field(&mut self, - key: &'static str, - value: &T) - -> Result<(), E> { + fn serialize_field( + &mut self, + key: &'static str, + value: &T, + ) -> Result<(), E> { let value = try!(value.serialize(ContentSerializer::::new())); self.fields.push((key, value)); Ok(()) @@ -917,22 +985,24 @@ mod content { } impl ser::SerializeStructVariant for SerializeStructVariant - where E: ser::Error + where + E: ser::Error, { type Ok = Content; type Error = E; - fn serialize_field(&mut self, - key: &'static str, - value: &T) - -> Result<(), E> { + fn serialize_field( + &mut self, + key: &'static str, + value: &T, + ) -> Result<(), E> { let value = try!(value.serialize(ContentSerializer::::new())); self.fields.push((key, value)); Ok(()) } fn end(self) -> Result { - Ok(Content::StructVariant(self.name, self.variant_index, self.variant, self.fields)) + Ok(Content::StructVariant(self.name, self.variant_index, self.variant, self.fields),) } } } diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 1d34254a..16379e63 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -40,7 +40,8 @@ impl_visit!(char, serialize_char); impl Serialize for str { #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { serializer.serialize_str(self) } @@ -50,7 +51,8 @@ impl Serialize for str { impl Serialize for String { #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { (&self[..]).serialize(serializer) } @@ -62,7 +64,8 @@ impl Serialize for String { impl Serialize for CStr { #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { serializer.serialize_bytes(self.to_bytes()) } @@ -72,7 +75,8 @@ impl Serialize for CStr { impl Serialize for CString { #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { serializer.serialize_bytes(self.to_bytes()) } @@ -81,11 +85,13 @@ impl Serialize for CString { /////////////////////////////////////////////////////////////////////////////// impl Serialize for Option - where T: Serialize +where + T: Serialize, { #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { match *self { Some(ref value) => serializer.serialize_some(value), @@ -99,7 +105,8 @@ impl Serialize for Option impl Serialize for PhantomData { #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { serializer.serialize_unit_struct("PhantomData") } @@ -111,7 +118,8 @@ impl Serialize for PhantomData { impl Serialize for [T; 0] { #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { try!(serializer.serialize_seq_fixed_size(0)).end() } @@ -181,50 +189,57 @@ macro_rules! serialize_seq { } impl Serialize for [T] - where T: Serialize +where + T: Serialize, { serialize_seq!(); } #[cfg(any(feature = "std", feature = "collections"))] impl Serialize for BinaryHeap - where T: Serialize + Ord +where + T: Serialize + Ord, { serialize_seq!(); } #[cfg(any(feature = "std", feature = "collections"))] impl Serialize for BTreeSet - where T: Serialize + Ord +where + T: Serialize + Ord, { serialize_seq!(); } #[cfg(feature = "std")] impl Serialize for HashSet - where T: Serialize + Eq + Hash, - H: BuildHasher +where + T: Serialize + Eq + Hash, + H: BuildHasher, { serialize_seq!(); } #[cfg(any(feature = "std", feature = "collections"))] impl Serialize for LinkedList - where T: Serialize +where + T: Serialize, { serialize_seq!(); } #[cfg(any(feature = "std", feature = "collections"))] impl Serialize for Vec - where T: Serialize +where + T: Serialize, { serialize_seq!(); } #[cfg(any(feature = "std", feature = "collections"))] impl Serialize for VecDeque - where T: Serialize +where + T: Serialize, { serialize_seq!(); } @@ -234,7 +249,8 @@ impl Serialize for VecDeque #[cfg(feature = "std")] impl Serialize for ops::Range { fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { use super::SerializeStruct; let mut state = try!(serializer.serialize_struct("Range", 2)); @@ -249,7 +265,8 @@ impl Serialize for ops::Range { impl Serialize for () { #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { serializer.serialize_unit() } @@ -468,17 +485,19 @@ macro_rules! serialize_map { #[cfg(any(feature = "std", feature = "collections"))] impl Serialize for BTreeMap - where K: Serialize + Ord, - V: Serialize +where + K: Serialize + Ord, + V: Serialize, { serialize_map!(); } #[cfg(feature = "std")] impl Serialize for HashMap - where K: Serialize + Eq + Hash, - V: Serialize, - H: BuildHasher +where + K: Serialize + Eq + Hash, + V: Serialize, + H: BuildHasher, { serialize_map!(); } @@ -486,22 +505,26 @@ impl Serialize for HashMap /////////////////////////////////////////////////////////////////////////////// impl<'a, T: ?Sized> Serialize for &'a T - where T: Serialize +where + T: Serialize, { #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { (**self).serialize(serializer) } } impl<'a, T: ?Sized> Serialize for &'a mut T - where T: Serialize +where + T: Serialize, { #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { (**self).serialize(serializer) } @@ -509,11 +532,13 @@ impl<'a, T: ?Sized> Serialize for &'a mut T #[cfg(any(feature = "std", feature = "alloc"))] impl Serialize for Box - where T: Serialize +where + T: Serialize, { #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { (**self).serialize(serializer) } @@ -521,11 +546,13 @@ impl Serialize for Box #[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] impl Serialize for Rc - where T: Serialize +where + T: Serialize, { #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { (**self).serialize(serializer) } @@ -533,11 +560,13 @@ impl Serialize for Rc #[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] impl Serialize for Arc - where T: Serialize +where + T: Serialize, { #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { (**self).serialize(serializer) } @@ -545,11 +574,13 @@ impl Serialize for Arc #[cfg(any(feature = "std", feature = "collections"))] impl<'a, T: ?Sized> Serialize for Cow<'a, T> - where T: Serialize + ToOwned +where + T: Serialize + ToOwned, { #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { (**self).serialize(serializer) } @@ -558,11 +589,13 @@ impl<'a, T: ?Sized> Serialize for Cow<'a, T> /////////////////////////////////////////////////////////////////////////////// impl Serialize for Result - where T: Serialize, - E: Serialize +where + T: Serialize, + E: Serialize, { fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { match *self { Result::Ok(ref value) => serializer.serialize_newtype_variant("Result", 0, "Ok", value), @@ -578,7 +611,8 @@ impl Serialize for Result #[cfg(feature = "std")] impl Serialize for Duration { fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { use super::SerializeStruct; let mut state = try!(serializer.serialize_struct("Duration", 2)); @@ -623,7 +657,8 @@ macro_rules! serialize_display_bounded_length { #[cfg(feature = "std")] impl Serialize for net::IpAddr { fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { match *self { net::IpAddr::V4(ref a) => a.serialize(serializer), @@ -635,7 +670,8 @@ impl Serialize for net::IpAddr { #[cfg(feature = "std")] impl Serialize for net::Ipv4Addr { fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { /// "101.102.103.104".len() const MAX_LEN: usize = 15; @@ -646,7 +682,8 @@ impl Serialize for net::Ipv4Addr { #[cfg(feature = "std")] impl Serialize for net::Ipv6Addr { fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { /// "1000:1002:1003:1004:1005:1006:1007:1008".len() const MAX_LEN: usize = 39; @@ -659,7 +696,8 @@ impl Serialize for net::Ipv6Addr { #[cfg(feature = "std")] impl Serialize for net::SocketAddr { fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { match *self { net::SocketAddr::V4(ref addr) => addr.serialize(serializer), @@ -671,7 +709,8 @@ impl Serialize for net::SocketAddr { #[cfg(feature = "std")] impl Serialize for net::SocketAddrV4 { fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { /// "101.102.103.104:65000".len() const MAX_LEN: usize = 21; @@ -682,7 +721,8 @@ impl Serialize for net::SocketAddrV4 { #[cfg(feature = "std")] impl Serialize for net::SocketAddrV6 { fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { /// "[1000:1002:1003:1004:1005:1006:1007:1008]:65000".len() const MAX_LEN: usize = 47; @@ -695,7 +735,8 @@ impl Serialize for net::SocketAddrV6 { #[cfg(feature = "std")] impl Serialize for path::Path { fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { match self.to_str() { Some(s) => s.serialize(serializer), @@ -707,7 +748,8 @@ impl Serialize for path::Path { #[cfg(feature = "std")] impl Serialize for path::PathBuf { fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { self.as_path().serialize(serializer) } @@ -717,24 +759,20 @@ impl Serialize for path::PathBuf { impl Serialize for OsStr { #[cfg(unix)] fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { use std::os::unix::ffi::OsStrExt; - serializer.serialize_newtype_variant("OsString", - 0, - "Unix", - self.as_bytes()) + serializer.serialize_newtype_variant("OsString", 0, "Unix", self.as_bytes()) } #[cfg(windows)] fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { use std::os::windows::ffi::OsStrExt; let val = self.encode_wide().collect::>(); - serializer.serialize_newtype_variant("OsString", - 1, - "Windows", - &val) + serializer.serialize_newtype_variant("OsString", 1, "Windows", &val) } } @@ -742,7 +780,8 @@ impl Serialize for OsStr { #[cfg(feature = "std")] impl Serialize for OsString { fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { self.as_os_str().serialize(serializer) } @@ -750,10 +789,12 @@ impl Serialize for OsString { #[cfg(feature = "unstable")] impl Serialize for NonZero - where T: Serialize + Zeroable +where + T: Serialize + Zeroable, { fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { (**self).serialize(serializer) } diff --git a/serde/src/ser/impossible.rs b/serde/src/ser/impossible.rs index f95348d6..867963a2 100644 --- a/serde/src/ser/impossible.rs +++ b/serde/src/ser/impossible.rs @@ -60,7 +60,8 @@ pub struct Impossible { enum Void {} impl SerializeSeq for Impossible - where E: ser::Error +where + E: ser::Error, { type Ok = Ok; type Error = E; @@ -75,7 +76,8 @@ impl SerializeSeq for Impossible } impl SerializeTuple for Impossible - where E: ser::Error +where + E: ser::Error, { type Ok = Ok; type Error = E; @@ -90,7 +92,8 @@ impl SerializeTuple for Impossible } impl SerializeTupleStruct for Impossible - where E: ser::Error +where + E: ser::Error, { type Ok = Ok; type Error = E; @@ -105,7 +108,8 @@ impl SerializeTupleStruct for Impossible } impl SerializeTupleVariant for Impossible - where E: ser::Error +where + E: ser::Error, { type Ok = Ok; type Error = E; @@ -120,7 +124,8 @@ impl SerializeTupleVariant for Impossible } impl SerializeMap for Impossible - where E: ser::Error +where + E: ser::Error, { type Ok = Ok; type Error = E; @@ -139,15 +144,17 @@ impl SerializeMap for Impossible } impl SerializeStruct for Impossible - where E: ser::Error +where + E: ser::Error, { type Ok = Ok; type Error = E; - fn serialize_field(&mut self, - _key: &'static str, - _value: &T) - -> Result<(), E> { + fn serialize_field( + &mut self, + _key: &'static str, + _value: &T, + ) -> Result<(), E> { match self.void {} } @@ -157,15 +164,17 @@ impl SerializeStruct for Impossible } impl SerializeStructVariant for Impossible - where E: ser::Error +where + E: ser::Error, { type Ok = Ok; type Error = E; - fn serialize_field(&mut self, - _key: &'static str, - _value: &T) - -> Result<(), E> { + fn serialize_field( + &mut self, + _key: &'static str, + _value: &T, + ) -> Result<(), E> { match self.void {} } diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 5e44895a..14262c29 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -182,7 +182,9 @@ pub trait Serialize { /// for more information about how to implement this method. /// /// [impl-serialize]: https://serde.rs/impl-serialize.html - fn serialize(&self, serializer: S) -> Result where S: Serializer; + fn serialize(&self, serializer: S) -> Result + where + S: Serializer; } /////////////////////////////////////////////////////////////////////////////// @@ -437,11 +439,12 @@ pub trait Serializer: Sized { /// } /// } /// ``` - fn serialize_unit_variant(self, - name: &'static str, - variant_index: u32, - variant: &'static str) - -> Result; + fn serialize_unit_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + ) -> Result; /// Serialize a newtype struct like `struct Millimeters(u8)`. /// @@ -462,10 +465,11 @@ pub trait Serializer: Sized { /// } /// } /// ``` - fn serialize_newtype_struct(self, - name: &'static str, - value: &T) - -> Result; + fn serialize_newtype_struct( + self, + name: &'static str, + value: &T, + ) -> Result; /// Serialize a newtype variant like `E::N` in `enum E { N(u8) }`. /// @@ -492,12 +496,13 @@ pub trait Serializer: Sized { /// } /// } /// ``` - fn serialize_newtype_variant(self, - name: &'static str, - variant_index: u32, - variant: &'static str, - value: &T) - -> Result; + fn serialize_newtype_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result; /// Begin to serialize a dynamically sized sequence. This call must be /// followed by zero or more calls to `serialize_element`, then a call to @@ -630,10 +635,11 @@ pub trait Serializer: Sized { /// } /// } /// ``` - fn serialize_tuple_struct(self, - name: &'static str, - len: usize) - -> Result; + fn serialize_tuple_struct( + self, + name: &'static str, + len: usize, + ) -> Result; /// Begin to serialize a tuple variant like `E::T` in `enum E { T(u8, u8) /// }`. This call must be followed by zero or more calls to @@ -674,12 +680,13 @@ pub trait Serializer: Sized { /// } /// } /// ``` - fn serialize_tuple_variant(self, - name: &'static str, - variant_index: u32, - variant: &'static str, - len: usize) - -> Result; + fn serialize_tuple_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result; /// Begin to serialize a map. This call must be followed by zero or more /// calls to `serialize_key` and `serialize_value`, then a call to `end`. @@ -757,10 +764,11 @@ pub trait Serializer: Sized { /// } /// } /// ``` - fn serialize_struct(self, - name: &'static str, - len: usize) - -> Result; + fn serialize_struct( + self, + name: &'static str, + len: usize, + ) -> Result; /// Begin to serialize a struct variant like `E::S` in `enum E { S { r: u8, /// g: u8, b: u8 } }`. This call must be followed by zero or more calls to @@ -794,12 +802,13 @@ pub trait Serializer: Sized { /// } /// } /// ``` - fn serialize_struct_variant(self, - name: &'static str, - variant_index: u32, - variant: &'static str, - len: usize) - -> Result; + fn serialize_struct_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result; /// Collect an iterator as a sequence. /// @@ -807,8 +816,9 @@ pub trait Serializer: Sized { /// using `Self::SerializeSeq`. Implementors should not need to override /// this method. fn collect_seq(self, iter: I) -> Result - where I: IntoIterator, - ::Item: Serialize + where + I: IntoIterator, + ::Item: Serialize, { let iter = iter.into_iter(); let mut serializer = try!(self.serialize_seq(iter.len_hint())); @@ -824,9 +834,10 @@ pub trait Serializer: Sized { /// using `Self::SerializeMap`. Implementors should not need to override /// this method. fn collect_map(self, iter: I) -> Result - where K: Serialize, - V: Serialize, - I: IntoIterator + where + K: Serialize, + V: Serialize, + I: IntoIterator, { let iter = iter.into_iter(); let mut serializer = try!(self.serialize_map(iter.len_hint())); @@ -864,7 +875,8 @@ pub trait Serializer: Sized { /// ``` #[cfg(any(feature = "std", feature = "collections"))] fn collect_str(self, value: &T) -> Result - where T: Display + where + T: Display, { use lib::fmt::Write; let mut string = String::new(); @@ -900,7 +912,8 @@ pub trait Serializer: Sized { /// ``` #[cfg(not(any(feature = "std", feature = "collections")))] fn collect_str(self, value: &T) -> Result - where T: Display; + where + T: Display; } /// Returned from `Serializer::serialize_seq` and @@ -1174,10 +1187,11 @@ pub trait SerializeMap { /// `serialize_value`. This is appropriate for serializers that do not care /// about performance or are not able to optimize `serialize_entry` any /// better than this. - fn serialize_entry(&mut self, - key: &K, - value: &V) - -> Result<(), Self::Error> { + fn serialize_entry( + &mut self, + key: &K, + value: &V, + ) -> Result<(), Self::Error> { try!(self.serialize_key(key)); self.serialize_value(value) } @@ -1218,10 +1232,11 @@ pub trait SerializeStruct { type Error: Error; /// Serialize a struct field. - fn serialize_field(&mut self, - key: &'static str, - value: &T) - -> Result<(), Self::Error>; + fn serialize_field( + &mut self, + key: &'static str, + value: &T, + ) -> Result<(), Self::Error>; /// Finish serializing a struct. fn end(self) -> Result; @@ -1261,10 +1276,11 @@ pub trait SerializeStructVariant { type Error: Error; /// Serialize a struct variant field. - fn serialize_field(&mut self, - key: &'static str, - value: &T) - -> Result<(), Self::Error>; + fn serialize_field( + &mut self, + key: &'static str, + value: &T, + ) -> Result<(), Self::Error>; /// Finish serializing a struct variant. fn end(self) -> Result; diff --git a/serde_derive/src/bound.rs b/serde_derive/src/bound.rs index fe45344f..c980d3df 100644 --- a/serde_derive/src/bound.rs +++ b/serde_derive/src/bound.rs @@ -16,27 +16,41 @@ macro_rules! path { // allowed here". pub fn without_defaults(generics: &syn::Generics) -> syn::Generics { syn::Generics { - ty_params: generics.ty_params + ty_params: generics + .ty_params .iter() - .map(|ty_param| syn::TyParam { default: None, ..ty_param.clone() }) + .map( + |ty_param| { + syn::TyParam { + default: None, + ..ty_param.clone() + } + }, + ) .collect(), ..generics.clone() } } -pub fn with_where_predicates(generics: &syn::Generics, - predicates: &[syn::WherePredicate]) - -> syn::Generics { +pub fn with_where_predicates( + generics: &syn::Generics, + predicates: &[syn::WherePredicate], +) -> syn::Generics { let mut generics = generics.clone(); - generics.where_clause.predicates.extend_from_slice(predicates); + generics + .where_clause + .predicates + .extend_from_slice(predicates); generics } -pub fn with_where_predicates_from_fields(item: &Item, - generics: &syn::Generics, - from_field: F) - -> syn::Generics - where F: Fn(&attr::Field) -> Option<&[syn::WherePredicate]> +pub fn with_where_predicates_from_fields( + item: &Item, + generics: &syn::Generics, + from_field: F, +) -> syn::Generics +where + F: Fn(&attr::Field) -> Option<&[syn::WherePredicate]>, { let predicates = item.body .all_fields() @@ -59,12 +73,14 @@ pub fn with_where_predicates_from_fields(item: &Item, // #[serde(skip_serializing)] // c: C, // } -pub fn with_bound(item: &Item, - generics: &syn::Generics, - filter: F, - bound: &syn::Path) - -> syn::Generics - where F: Fn(&attr::Field) -> bool +pub fn with_bound( + item: &Item, + generics: &syn::Generics, + filter: F, + bound: &syn::Path, +) -> syn::Generics +where + F: Fn(&attr::Field) -> bool, { struct FindTyParams { // Set of all generic type parameters on the current struct (A, B, C in @@ -94,7 +110,8 @@ pub fn with_bound(item: &Item, } } - let all_ty_params: HashSet<_> = generics.ty_params + let all_ty_params: HashSet<_> = generics + .ty_params .iter() .map(|ty_param| ty_param.ident.clone()) .collect(); @@ -112,58 +129,66 @@ pub fn with_bound(item: &Item, visit::walk_ty(&mut visitor, ty); } - let new_predicates = generics.ty_params + let new_predicates = generics + .ty_params .iter() .map(|ty_param| ty_param.ident.clone()) .filter(|id| visitor.relevant_ty_params.contains(id)) - .map(|id| { - syn::WherePredicate::BoundPredicate(syn::WhereBoundPredicate { - bound_lifetimes: Vec::new(), - // the type parameter that is being bounded e.g. T - bounded_ty: syn::Ty::Path(None, id.into()), - // the bound e.g. Serialize - bounds: vec![syn::TyParamBound::Trait( - syn::PolyTraitRef { + .map( + |id| { + syn::WherePredicate::BoundPredicate( + syn::WhereBoundPredicate { bound_lifetimes: Vec::new(), - trait_ref: bound.clone(), + // the type parameter that is being bounded e.g. T + bounded_ty: syn::Ty::Path(None, id.into()), + // the bound e.g. Serialize + bounds: vec![ + syn::TyParamBound::Trait( + syn::PolyTraitRef { + bound_lifetimes: Vec::new(), + trait_ref: bound.clone(), + }, + syn::TraitBoundModifier::None, + ), + ], }, - syn::TraitBoundModifier::None - )], - }) - }); + ) + }, + ); let mut generics = generics.clone(); generics.where_clause.predicates.extend(new_predicates); generics } -pub fn with_self_bound(item: &Item, - generics: &syn::Generics, - bound: &syn::Path) - -> syn::Generics -{ +pub fn with_self_bound(item: &Item, generics: &syn::Generics, bound: &syn::Path) -> syn::Generics { let mut generics = generics.clone(); - generics.where_clause.predicates.push( - syn::WherePredicate::BoundPredicate(syn::WhereBoundPredicate { - bound_lifetimes: Vec::new(), - // the type that is being bounded e.g. MyStruct<'a, T> - bounded_ty: type_of_item(item), - // the bound e.g. Default - bounds: vec![syn::TyParamBound::Trait( - syn::PolyTraitRef { + generics + .where_clause + .predicates + .push( + syn::WherePredicate::BoundPredicate( + syn::WhereBoundPredicate { bound_lifetimes: Vec::new(), - trait_ref: bound.clone(), + // the type that is being bounded e.g. MyStruct<'a, T> + bounded_ty: type_of_item(item), + // the bound e.g. Default + bounds: vec![ + syn::TyParamBound::Trait( + syn::PolyTraitRef { + bound_lifetimes: Vec::new(), + trait_ref: bound.clone(), + }, + syn::TraitBoundModifier::None, + ), + ], }, - syn::TraitBoundModifier::None - )], - }) - ); + ), + ); generics } -pub fn with_lifetime_bound(generics: &syn::Generics, - lifetime: &str) - -> syn::Generics { +pub fn with_lifetime_bound(generics: &syn::Generics, lifetime: &str) -> syn::Generics { let mut generics = generics.clone(); for lifetime_def in &mut generics.lifetimes { @@ -171,38 +196,49 @@ pub fn with_lifetime_bound(generics: &syn::Generics, } for ty_param in &mut generics.ty_params { - ty_param.bounds.push(syn::TyParamBound::Region(syn::Lifetime::new(lifetime))); + ty_param + .bounds + .push(syn::TyParamBound::Region(syn::Lifetime::new(lifetime))); } - generics.lifetimes.push(syn::LifetimeDef { - attrs: Vec::new(), - lifetime: syn::Lifetime::new(lifetime), - bounds: Vec::new(), - }); + generics + .lifetimes + .push( + syn::LifetimeDef { + attrs: Vec::new(), + lifetime: syn::Lifetime::new(lifetime), + bounds: Vec::new(), + }, + ); generics } fn type_of_item(item: &Item) -> syn::Ty { - syn::Ty::Path(None, syn::Path { - global: false, - segments: vec![ - syn::PathSegment { - ident: item.ident.clone(), - parameters: syn::PathParameters::AngleBracketed(syn::AngleBracketedParameterData { - lifetimes: item.generics - .lifetimes - .iter() - .map(|def| def.lifetime.clone()) - .collect(), - types: item.generics + syn::Ty::Path( + None, + syn::Path { + global: false, + segments: vec![ + syn::PathSegment { + ident: item.ident.clone(), + parameters: syn::PathParameters::AngleBracketed( + syn::AngleBracketedParameterData { + lifetimes: item.generics + .lifetimes + .iter() + .map(|def| def.lifetime.clone()) + .collect(), + types: item.generics .ty_params .iter() .map(|param| syn::Ty::Path(None, param.ident.clone().into())) .collect(), - bindings: Vec::new(), - }), - } - ] - }) + bindings: Vec::new(), + }, + ), + }, + ], + }, + ) } diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index a1f2ae4a..7493e000 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -44,13 +44,15 @@ pub fn expand_derive_deserialize(item: &syn::DeriveInput) -> Result syn::Generics { let generics = bound::without_defaults(item.generics); - let generics = - bound::with_where_predicates_from_fields(item, &generics, attr::Field::de_bound); + let generics = bound::with_where_predicates_from_fields(item, &generics, attr::Field::de_bound); match item.attrs.de_bound() { Some(predicates) => bound::with_where_predicates(&generics, predicates), @@ -125,19 +126,23 @@ fn build_generics(item: &Item) -> syn::Generics { attr::Default::Default => { bound::with_self_bound(item, &generics, &path!(_serde::export::Default)) } - attr::Default::None | attr::Default::Path(_) => generics, + attr::Default::None | + attr::Default::Path(_) => generics, }; - let generics = - bound::with_bound(item, - &generics, - needs_deserialize_bound, - &path!(_serde::Deserialize<'de>)); + let generics = bound::with_bound( + item, + &generics, + needs_deserialize_bound, + &path!(_serde::Deserialize<'de>), + ); - bound::with_bound(item, - &generics, - requires_default, - &path!(_serde::export::Default)) + bound::with_bound( + item, + &generics, + requires_default, + &path!(_serde::export::Default), + ) } } } @@ -175,29 +180,19 @@ fn deserialize_body(item: &Item, params: &Parameters) -> Fragment { deserialize_from(from_type) } else { match item.body { - Body::Enum(ref variants) => { - deserialize_item_enum(params, variants, &item.attrs) - } + Body::Enum(ref variants) => deserialize_item_enum(params, variants, &item.attrs), Body::Struct(Style::Struct, ref fields) => { if fields.iter().any(|field| field.ident.is_none()) { panic!("struct has unnamed fields"); } - deserialize_struct(None, - params, - fields, - &item.attrs, - None) + deserialize_struct(None, params, fields, &item.attrs, None) } Body::Struct(Style::Tuple, ref fields) | Body::Struct(Style::Newtype, ref fields) => { if fields.iter().any(|field| field.ident.is_some()) { panic!("tuple struct has named fields"); } - deserialize_tuple(None, - params, - fields, - &item.attrs, - None) + deserialize_tuple(None, params, fields, &item.attrs, None) } Body::Struct(Style::Unit, _) => deserialize_unit_struct(params, &item.attrs), } @@ -240,14 +235,15 @@ fn deserialize_unit_struct(params: &Parameters, item_attrs: &attr::Item) -> Frag } } -fn deserialize_tuple(variant_ident: Option<&syn::Ident>, - params: &Parameters, - fields: &[Field], - item_attrs: &attr::Item, - deserializer: Option) - -> Fragment { +fn deserialize_tuple( + variant_ident: Option<&syn::Ident>, + params: &Parameters, + fields: &[Field], + item_attrs: &attr::Item, + deserializer: Option, +) -> Fragment { let this = ¶ms.this; - let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params); + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,); // If there are getters (implying private fields), construct the local type // and use an `Into` conversion to get the remote type. If there are no @@ -277,7 +273,7 @@ fn deserialize_tuple(variant_ident: Option<&syn::Ident>, None }; - let visit_seq = Stmts(deserialize_seq(&type_path, params, fields, false, item_attrs)); + let visit_seq = Stmts(deserialize_seq(&type_path, params, fields, false, item_attrs),); let visitor_expr = quote! { __Visitor { @@ -297,7 +293,9 @@ fn deserialize_tuple(variant_ident: Option<&syn::Ident>, quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #nfields, #visitor_expr)) }; - let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); + let all_skipped = fields + .iter() + .all(|field| field.attrs.skip_deserializing()); let visitor_var = if all_skipped { quote!(_) } else { @@ -331,15 +329,17 @@ fn deserialize_tuple(variant_ident: Option<&syn::Ident>, } } -fn deserialize_seq(type_path: &Tokens, - params: &Parameters, - fields: &[Field], - is_struct: bool, - item_attrs: &attr::Item) - -> Fragment { +fn deserialize_seq( + type_path: &Tokens, + params: &Parameters, + fields: &[Field], + is_struct: bool, + item_attrs: &attr::Item, +) -> Fragment { let vars = (0..fields.len()).map(field_i as fn(_) -> _); - let deserialized_count = fields.iter() + let deserialized_count = fields + .iter() .filter(|field| !field.attrs.skip_deserializing()) .count(); let expecting = format!("tuple of {} elements", deserialized_count); @@ -406,10 +406,7 @@ fn deserialize_seq(type_path: &Tokens, } } -fn deserialize_newtype_struct(type_path: &Tokens, - params: &Parameters, - field: &Field) - -> Tokens { +fn deserialize_newtype_struct(type_path: &Tokens, params: &Parameters, field: &Field) -> Tokens { let value = match field.attrs.deserialize_with() { None => { let field_ty = &field.ty; @@ -418,8 +415,7 @@ fn deserialize_newtype_struct(type_path: &Tokens, } } Some(path) => { - let (wrapper, wrapper_ty) = - wrap_deserialize_with(params, field.ty, path); + let (wrapper, wrapper_ty) = wrap_deserialize_with(params, field.ty, path); quote!({ #wrapper try!(<#wrapper_ty as _serde::Deserialize>::deserialize(__e)).value @@ -445,17 +441,18 @@ fn deserialize_newtype_struct(type_path: &Tokens, } } -fn deserialize_struct(variant_ident: Option<&syn::Ident>, - params: &Parameters, - fields: &[Field], - item_attrs: &attr::Item, - deserializer: Option) - -> Fragment { +fn deserialize_struct( + variant_ident: Option<&syn::Ident>, + params: &Parameters, + fields: &[Field], + item_attrs: &attr::Item, + deserializer: Option, +) -> Fragment { let is_enum = variant_ident.is_some(); let is_untagged = deserializer.is_some(); let this = ¶ms.this; - let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params); + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,); // If there are getters (implying private fields), construct the local type // and use an `Into` conversion to get the remote type. If there are no @@ -476,7 +473,7 @@ fn deserialize_struct(variant_ident: Option<&syn::Ident>, None => format!("struct {}", params.type_name()), }; - let visit_seq = Stmts(deserialize_seq(&type_path, params, fields, true, item_attrs)); + let visit_seq = Stmts(deserialize_seq(&type_path, params, fields, true, item_attrs),); let (field_visitor, fields_stmt, visit_map) = deserialize_struct_visitor(type_path, params, fields, item_attrs); @@ -505,7 +502,9 @@ fn deserialize_struct(variant_ident: Option<&syn::Ident>, } }; - let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); + let all_skipped = fields + .iter() + .all(|field| field.attrs.skip_deserializing()); let visitor_var = if all_skipped { quote!(_) } else { @@ -557,48 +556,41 @@ fn deserialize_struct(variant_ident: Option<&syn::Ident>, } } -fn deserialize_item_enum(params: &Parameters, - variants: &[Variant], - item_attrs: &attr::Item) - -> Fragment { +fn deserialize_item_enum( + params: &Parameters, + variants: &[Variant], + item_attrs: &attr::Item, +) -> Fragment { match *item_attrs.tag() { - attr::EnumTag::External => { - deserialize_externally_tagged_enum(params, variants, item_attrs) - } + attr::EnumTag::External => deserialize_externally_tagged_enum(params, variants, item_attrs), attr::EnumTag::Internal { ref tag } => { - deserialize_internally_tagged_enum(params, - variants, - item_attrs, - tag) - } - attr::EnumTag::Adjacent { ref tag, ref content } => { - deserialize_adjacently_tagged_enum(params, - variants, - item_attrs, - tag, - content) - } - attr::EnumTag::None => { - deserialize_untagged_enum(params, variants, item_attrs) + deserialize_internally_tagged_enum(params, variants, item_attrs, tag) } + attr::EnumTag::Adjacent { + ref tag, + ref content, + } => deserialize_adjacently_tagged_enum(params, variants, item_attrs, tag, content), + attr::EnumTag::None => deserialize_untagged_enum(params, variants, item_attrs), } } -fn deserialize_externally_tagged_enum(params: &Parameters, - variants: &[Variant], - item_attrs: &attr::Item) - -> Fragment { +fn deserialize_externally_tagged_enum( + params: &Parameters, + variants: &[Variant], + item_attrs: &attr::Item, +) -> Fragment { let this = ¶ms.this; - let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params); + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,); let type_name = item_attrs.name().deserialize_name(); let expecting = format!("enum {}", params.type_name()); - let variant_names_idents: Vec<_> = variants.iter() + let variant_names_idents: Vec<_> = variants + .iter() .enumerate() .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) - .map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i))) + .map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)),) .collect(); let variants_stmt = { @@ -608,25 +600,30 @@ fn deserialize_externally_tagged_enum(params: &Parameters, } }; - let variant_visitor = Stmts(deserialize_field_visitor(variant_names_idents, item_attrs, true)); + let variant_visitor = Stmts(deserialize_field_visitor(variant_names_idents, item_attrs, true),); // Match arms to extract a variant from a string - let variant_arms = variants.iter() - .enumerate() - .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) - .map(|(i, variant)| { - let variant_name = field_i(i); + let variant_arms = + variants + .iter() + .enumerate() + .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) + .map( + |(i, variant)| { + let variant_name = field_i(i); - let block = Match(deserialize_externally_tagged_variant(params, - variant, - item_attrs)); + let block = + Match(deserialize_externally_tagged_variant(params, variant, item_attrs),); - quote! { + quote! { (__Field::#variant_name, __visitor) => #block } - }); + }, + ); - let all_skipped = variants.iter().all(|variant| variant.attrs.skip_deserializing()); + let all_skipped = variants + .iter() + .all(|variant| variant.attrs.skip_deserializing()); let match_variant = if all_skipped { // This is an empty enum like `enum Impossible {}` or an enum in which // all variants have `#[serde(skip_deserializing)]`. @@ -678,15 +675,17 @@ fn deserialize_externally_tagged_enum(params: &Parameters, } } -fn deserialize_internally_tagged_enum(params: &Parameters, - variants: &[Variant], - item_attrs: &attr::Item, - tag: &str) - -> Fragment { - let variant_names_idents: Vec<_> = variants.iter() +fn deserialize_internally_tagged_enum( + params: &Parameters, + variants: &[Variant], + item_attrs: &attr::Item, + tag: &str, +) -> Fragment { + let variant_names_idents: Vec<_> = variants + .iter() .enumerate() .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) - .map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i))) + .map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)),) .collect(); let variants_stmt = { @@ -696,7 +695,7 @@ fn deserialize_internally_tagged_enum(params: &Parameters, } }; - let variant_visitor = Stmts(deserialize_field_visitor(variant_names_idents, item_attrs, true)); + let variant_visitor = Stmts(deserialize_field_visitor(variant_names_idents, item_attrs, true),); // Match arms to extract a variant from a string let variant_arms = variants.iter() @@ -732,19 +731,21 @@ fn deserialize_internally_tagged_enum(params: &Parameters, } } -fn deserialize_adjacently_tagged_enum(params: &Parameters, - variants: &[Variant], - item_attrs: &attr::Item, - tag: &str, - content: &str) - -> Fragment { +fn deserialize_adjacently_tagged_enum( + params: &Parameters, + variants: &[Variant], + item_attrs: &attr::Item, + tag: &str, + content: &str, +) -> Fragment { let this = ¶ms.this; - let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params); + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,); - let variant_names_idents: Vec<_> = variants.iter() + let variant_names_idents: Vec<_> = variants + .iter() .enumerate() .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) - .map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i))) + .map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)),) .collect(); let variants_stmt = { @@ -754,25 +755,30 @@ fn deserialize_adjacently_tagged_enum(params: &Parameters, } }; - let variant_visitor = Stmts(deserialize_field_visitor(variant_names_idents, item_attrs, true)); + let variant_visitor = Stmts(deserialize_field_visitor(variant_names_idents, item_attrs, true),); - let ref variant_arms: Vec<_> = variants.iter() + let ref variant_arms: Vec<_> = variants + .iter() .enumerate() .filter(|&(_, variant)| !variant.attrs.skip_deserializing()) - .map(|(i, variant)| { - let variant_index = field_i(i); + .map( + |(i, variant)| { + let variant_index = field_i(i); - let block = Match(deserialize_untagged_variant( - params, - variant, - item_attrs, - quote!(__deserializer), - )); + let block = Match( + deserialize_untagged_variant( + params, + variant, + item_attrs, + quote!(__deserializer), + ), + ); - quote! { + quote! { __Field::#variant_index => #block } - }) + }, + ) .collect(); let expecting = format!("adjacently tagged enum {}", params.type_name()); @@ -799,20 +805,25 @@ fn deserialize_adjacently_tagged_enum(params: &Parameters, let fallthrough = if variants.iter().all(is_unit) { None } else { - Some(quote! { - _ => #missing_content - }) - }; - let arms = variants.iter() - .enumerate() - .filter(|&(_, variant)| !variant.attrs.skip_deserializing() && is_unit(variant)) - .map(|(i, variant)| { - let variant_index = field_i(i); - let variant_ident = &variant.ident; + Some( quote! { + _ => #missing_content + }, + ) + }; + let arms = variants + .iter() + .enumerate() + .filter(|&(_, variant)| !variant.attrs.skip_deserializing() && is_unit(variant),) + .map( + |(i, variant)| { + let variant_index = field_i(i); + let variant_ident = &variant.ident; + quote! { __Field::#variant_index => _serde::export::Ok(#this::#variant_ident), } - }); + }, + ); missing_content = quote! { match __field { #(#arms)* @@ -970,20 +981,24 @@ fn deserialize_adjacently_tagged_enum(params: &Parameters, } } -fn deserialize_untagged_enum(params: &Parameters, - variants: &[Variant], - item_attrs: &attr::Item) - -> Fragment { - let attempts = variants.iter() +fn deserialize_untagged_enum( + params: &Parameters, + variants: &[Variant], + item_attrs: &attr::Item, +) -> Fragment { + let attempts = variants + .iter() .filter(|variant| !variant.attrs.skip_deserializing()) - .map(|variant| { - Expr(deserialize_untagged_variant( + .map( + |variant| { + Expr(deserialize_untagged_variant( params, variant, item_attrs, quote!(_serde::private::de::ContentRefDeserializer::<__D::Error>::new(&__content)), )) - }); + }, + ); // TODO this message could be better by saving the errors from the failed // attempts. The heuristic used by TOML was to count the number of fields @@ -991,7 +1006,8 @@ fn deserialize_untagged_enum(params: &Parameters, // largest number of fields. I'm not sure I like that. Maybe it would be // better to save all the errors and combine them into one message that // explains why none of the variants matched. - let fallthrough_msg = format!("data did not match any variant of untagged enum {}", params.type_name()); + let fallthrough_msg = + format!("data did not match any variant of untagged enum {}", params.type_name()); quote_block! { let __content = try!(<_serde::private::de::Content as _serde::Deserialize>::deserialize(__deserializer)); @@ -1006,10 +1022,11 @@ fn deserialize_untagged_enum(params: &Parameters, } } -fn deserialize_externally_tagged_variant(params: &Parameters, - variant: &Variant, - item_attrs: &attr::Item) - -> Fragment { +fn deserialize_externally_tagged_variant( + params: &Parameters, + variant: &Variant, + item_attrs: &attr::Item, +) -> Fragment { let variant_ident = &variant.ident; match variant.style { @@ -1021,32 +1038,35 @@ fn deserialize_externally_tagged_variant(params: &Parameters, } } Style::Newtype => { - deserialize_externally_tagged_newtype_variant(variant_ident, - params, - &variant.fields[0]) + deserialize_externally_tagged_newtype_variant(variant_ident, params, &variant.fields[0]) } Style::Tuple => { - deserialize_tuple(Some(variant_ident), - params, - &variant.fields, - item_attrs, - None) + deserialize_tuple( + Some(variant_ident), + params, + &variant.fields, + item_attrs, + None, + ) } Style::Struct => { - deserialize_struct(Some(variant_ident), - params, - &variant.fields, - item_attrs, - None) + deserialize_struct( + Some(variant_ident), + params, + &variant.fields, + item_attrs, + None, + ) } } } -fn deserialize_internally_tagged_variant(params: &Parameters, - variant: &Variant, - item_attrs: &attr::Item, - deserializer: Tokens) - -> Fragment { +fn deserialize_internally_tagged_variant( + params: &Parameters, + variant: &Variant, + item_attrs: &attr::Item, + deserializer: Tokens, +) -> Fragment { let variant_ident = &variant.ident; match variant.style { @@ -1060,20 +1080,18 @@ fn deserialize_internally_tagged_variant(params: &Parameters, } } Style::Newtype | Style::Struct => { - deserialize_untagged_variant(params, - variant, - item_attrs, - deserializer) + deserialize_untagged_variant(params, variant, item_attrs, deserializer) } Style::Tuple => unreachable!("checked in serde_codegen_internals"), } } -fn deserialize_untagged_variant(params: &Parameters, - variant: &Variant, - item_attrs: &attr::Item, - deserializer: Tokens) - -> Fragment { +fn deserialize_untagged_variant( + params: &Parameters, + variant: &Variant, + item_attrs: &attr::Item, + deserializer: Tokens, +) -> Fragment { let variant_ident = &variant.ident; match variant.style { @@ -1091,32 +1109,39 @@ fn deserialize_untagged_variant(params: &Parameters, } } Style::Newtype => { - deserialize_untagged_newtype_variant(variant_ident, - params, - &variant.fields[0], - deserializer) + deserialize_untagged_newtype_variant( + variant_ident, + params, + &variant.fields[0], + deserializer, + ) } Style::Tuple => { - deserialize_tuple(Some(variant_ident), - params, - &variant.fields, - item_attrs, - Some(deserializer)) + deserialize_tuple( + Some(variant_ident), + params, + &variant.fields, + item_attrs, + Some(deserializer), + ) } Style::Struct => { - deserialize_struct(Some(variant_ident), - params, - &variant.fields, - item_attrs, - Some(deserializer)) + deserialize_struct( + Some(variant_ident), + params, + &variant.fields, + item_attrs, + Some(deserializer), + ) } } } -fn deserialize_externally_tagged_newtype_variant(variant_ident: &syn::Ident, - params: &Parameters, - field: &Field) - -> Fragment { +fn deserialize_externally_tagged_newtype_variant( + variant_ident: &syn::Ident, + params: &Parameters, + field: &Field, +) -> Fragment { let this = ¶ms.this; match field.attrs.deserialize_with() { None => { @@ -1128,8 +1153,7 @@ fn deserialize_externally_tagged_newtype_variant(variant_ident: &syn::Ident, } } Some(path) => { - let (wrapper, wrapper_ty) = - wrap_deserialize_with(params, field.ty, path); + let (wrapper, wrapper_ty) = wrap_deserialize_with(params, field.ty, path); quote_block! { #wrapper _serde::export::Result::map( @@ -1140,11 +1164,12 @@ fn deserialize_externally_tagged_newtype_variant(variant_ident: &syn::Ident, } } -fn deserialize_untagged_newtype_variant(variant_ident: &syn::Ident, - params: &Parameters, - field: &Field, - deserializer: Tokens) - -> Fragment { +fn deserialize_untagged_newtype_variant( + variant_ident: &syn::Ident, + params: &Parameters, + field: &Field, + deserializer: Tokens, +) -> Fragment { let this = ¶ms.this; match field.attrs.deserialize_with() { None => { @@ -1156,8 +1181,7 @@ fn deserialize_untagged_newtype_variant(variant_ident: &syn::Ident, } } Some(path) => { - let (wrapper, wrapper_ty) = - wrap_deserialize_with(params, field.ty, path); + let (wrapper, wrapper_ty) = wrap_deserialize_with(params, field.ty, path); quote_block! { #wrapper _serde::export::Result::map( @@ -1168,10 +1192,11 @@ fn deserialize_untagged_newtype_variant(variant_ident: &syn::Ident, } } -fn deserialize_field_visitor(fields: Vec<(String, Ident)>, - item_attrs: &attr::Item, - is_variant: bool) - -> Fragment { +fn deserialize_field_visitor( + fields: Vec<(String, Ident)>, + item_attrs: &attr::Item, + is_variant: bool, +) -> Fragment { let field_strs = fields.iter().map(|&(ref name, _)| name); let field_bytes = fields.iter().map(|&(ref name, _)| quote::ByteStr(name)); let field_idents: &Vec<_> = &fields.iter().map(|&(_, ref ident)| ident).collect(); @@ -1185,7 +1210,8 @@ fn deserialize_field_visitor(fields: Vec<(String, Ident)>, let visit_index = if is_variant { let variant_indices = 0u32..; let fallthrough_msg = format!("variant index 0 <= i < {}", fields.len()); - Some(quote! { + Some( + quote! { fn visit_u32<__E>(self, __value: u32) -> _serde::export::Result<__Field, __E> where __E: _serde::de::Error { @@ -1198,7 +1224,8 @@ fn deserialize_field_visitor(fields: Vec<(String, Ident)>, &#fallthrough_msg)) } } - }) + }, + ) } else { None }; @@ -1218,9 +1245,11 @@ fn deserialize_field_visitor(fields: Vec<(String, Ident)>, }; let bytes_to_str = if is_variant || item_attrs.deny_unknown_fields() { - Some(quote! { + Some( + quote! { let __value = &_serde::export::from_utf8_lossy(__value); - }) + }, + ) } else { None }; @@ -1280,15 +1309,17 @@ fn deserialize_field_visitor(fields: Vec<(String, Ident)>, } } -fn deserialize_struct_visitor(struct_path: Tokens, - params: &Parameters, - fields: &[Field], - item_attrs: &attr::Item) - -> (Fragment, Fragment, Fragment) { - let field_names_idents: Vec<_> = fields.iter() +fn deserialize_struct_visitor( + struct_path: Tokens, + params: &Parameters, + fields: &[Field], + item_attrs: &attr::Item, +) -> (Fragment, Fragment, Fragment) { + let field_names_idents: Vec<_> = fields + .iter() .enumerate() .filter(|&(_, field)| !field.attrs.skip_deserializing()) - .map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i))) + .map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i)),) .collect(); let fields_stmt = { @@ -1305,26 +1336,31 @@ fn deserialize_struct_visitor(struct_path: Tokens, (field_visitor, fields_stmt, visit_map) } -fn deserialize_map(struct_path: Tokens, - params: &Parameters, - fields: &[Field], - item_attrs: &attr::Item) - -> Fragment { +fn deserialize_map( + struct_path: Tokens, + params: &Parameters, + fields: &[Field], + item_attrs: &attr::Item, +) -> Fragment { // Create the field names for the fields. - let fields_names: Vec<_> = fields.iter() + let fields_names: Vec<_> = fields + .iter() .enumerate() .map(|(i, field)| (field, field_i(i))) .collect(); // Declare each field that will be deserialized. - let let_values = fields_names.iter() + let let_values = fields_names + .iter() .filter(|&&(field, _)| !field.attrs.skip_deserializing()) - .map(|&(field, ref name)| { - let field_ty = &field.ty; - quote! { + .map( + |&(field, ref name)| { + let field_ty = &field.ty; + quote! { let mut #name: _serde::export::Option<#field_ty> = _serde::export::None; } - }); + }, + ); // Match arms to extract a value for a field. let value_arms = fields_names.iter() @@ -1367,7 +1403,9 @@ fn deserialize_map(struct_path: Tokens, }) }; - let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); + let all_skipped = fields + .iter() + .all(|field| field.attrs.skip_deserializing()); let match_keys = if item_attrs.deny_unknown_fields() && all_skipped { quote! { // FIXME: Once we drop support for Rust 1.15: @@ -1387,40 +1425,53 @@ fn deserialize_map(struct_path: Tokens, } }; - let extract_values = fields_names.iter() + let extract_values = fields_names + .iter() .filter(|&&(field, _)| !field.attrs.skip_deserializing()) - .map(|&(field, ref name)| { - let missing_expr = Match(expr_is_missing(&field, item_attrs)); + .map( + |&(field, ref name)| { + let missing_expr = Match(expr_is_missing(&field, item_attrs)); - quote! { + quote! { let #name = match #name { _serde::export::Some(#name) => #name, _serde::export::None => #missing_expr }; } - }); + }, + ); - let result = fields_names.iter() - .map(|&(field, ref name)| { - let ident = field.ident.clone().expect("struct contains unnamed fields"); - if field.attrs.skip_deserializing() { - let value = Expr(expr_is_missing(&field, item_attrs)); - quote!(#ident: #value) - } else { - quote!(#ident: #name) - } - }); + let result = fields_names + .iter() + .map( + |&(field, ref name)| { + let ident = field + .ident + .clone() + .expect("struct contains unnamed fields"); + if field.attrs.skip_deserializing() { + let value = Expr(expr_is_missing(&field, item_attrs)); + quote!(#ident: #value) + } else { + quote!(#ident: #name) + } + }, + ); let let_default = match *item_attrs.default() { attr::Default::Default => { - Some(quote!( + Some( + quote!( let __default: Self::Value = _serde::export::Default::default(); - )) + ), + ) } attr::Default::Path(ref path) => { - Some(quote!( + Some( + quote!( let __default: Self::Value = #path(); - )) + ), + ) } attr::Default::None => { // We don't need the default value, to prevent an unused variable warning @@ -1456,12 +1507,13 @@ fn field_i(i: usize) -> Ident { /// This function wraps the expression in `#[serde(deserialize_with = "...")]` /// in a trait to prevent it from accessing the internal `Deserialize` state. -fn wrap_deserialize_with(params: &Parameters, - field_ty: &syn::Ty, - deserialize_with: &syn::Path) - -> (Tokens, Tokens) { +fn wrap_deserialize_with( + params: &Parameters, + field_ty: &syn::Ty, + deserialize_with: &syn::Path, +) -> (Tokens, Tokens) { let this = ¶ms.this; - let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params); + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,); let wrapper = quote! { struct __DeserializeWith #de_impl_generics #where_clause { @@ -1500,7 +1552,8 @@ fn expr_is_missing(field: &Field, item_attrs: &attr::Item) -> Fragment { } match *item_attrs.default() { - attr::Default::Default | attr::Default::Path(_) => { + attr::Default::Default | + attr::Default::Path(_) => { let ident = &field.ident; return quote_expr!(__default.#ident); } @@ -1538,13 +1591,16 @@ struct DeTyGenerics<'a>(&'a syn::Generics); impl<'a> ToTokens for DeTyGenerics<'a> { fn to_tokens(&self, tokens: &mut Tokens) { let mut generics = self.0.clone(); - generics.lifetimes.insert(0, syn::LifetimeDef::new("'de")); + generics + .lifetimes + .insert(0, syn::LifetimeDef::new("'de")); let (_, ty_generics, _) = generics.split_for_impl(); ty_generics.to_tokens(tokens); } } -fn split_with_de_lifetime(params: &Parameters) -> (DeImplGenerics, DeTyGenerics, syn::TyGenerics, &syn::WhereClause) { +fn split_with_de_lifetime(params: &Parameters,) + -> (DeImplGenerics, DeTyGenerics, syn::TyGenerics, &syn::WhereClause) { let de_impl_generics = DeImplGenerics(¶ms); let de_ty_generics = DeTyGenerics(¶ms.generics); let (_, ty_generics, where_clause) = params.generics.split_for_impl(); diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index cb5e8e85..45293cdb 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -42,13 +42,15 @@ pub fn expand_derive_serialize(item: &syn::DeriveInput) -> Result syn::Generics { match item.attrs.ser_bound() { Some(predicates) => bound::with_where_predicates(&generics, predicates), None => { - bound::with_bound(item, - &generics, - needs_serialize_bound, - &path!(_serde::Serialize)) + bound::with_bound( + item, + &generics, + needs_serialize_bound, + &path!(_serde::Serialize), + ) } } } @@ -131,9 +135,7 @@ fn serialize_body(item: &Item, params: &Parameters) -> Fragment { serialize_into(params, into_type) } else { match item.body { - Body::Enum(ref variants) => { - serialize_item_enum(params, variants, &item.attrs) - } + Body::Enum(ref variants) => serialize_item_enum(params, variants, &item.attrs), Body::Struct(Style::Struct, ref fields) => { if fields.iter().any(|field| field.ident.is_none()) { panic!("struct has unnamed fields"); @@ -171,10 +173,11 @@ fn serialize_unit_struct(item_attrs: &attr::Item) -> Fragment { } } -fn serialize_newtype_struct(params: &Parameters, - field: &Field, - item_attrs: &attr::Item) - -> Fragment { +fn serialize_newtype_struct( + params: &Parameters, + field: &Field, + item_attrs: &attr::Item, +) -> Fragment { let type_name = item_attrs.name().serialize_name(); let mut field_expr = get_field(params, field, 0); @@ -187,15 +190,17 @@ fn serialize_newtype_struct(params: &Parameters, } } -fn serialize_tuple_struct(params: &Parameters, - fields: &[Field], - item_attrs: &attr::Item) - -> Fragment { - let serialize_stmts = - serialize_tuple_struct_visitor(fields, - params, - false, - quote!(_serde::ser::SerializeTupleStruct::serialize_field)); +fn serialize_tuple_struct( + params: &Parameters, + fields: &[Field], + item_attrs: &attr::Item, +) -> Fragment { + let serialize_stmts = serialize_tuple_struct_visitor( + fields, + params, + false, + quote!(_serde::ser::SerializeTupleStruct::serialize_field), + ); let type_name = item_attrs.name().serialize_name(); let len = serialize_stmts.len(); @@ -208,36 +213,36 @@ fn serialize_tuple_struct(params: &Parameters, } } -fn serialize_struct(params: &Parameters, - fields: &[Field], - item_attrs: &attr::Item) - -> Fragment { +fn serialize_struct(params: &Parameters, fields: &[Field], item_attrs: &attr::Item) -> Fragment { assert!(fields.len() as u64 <= u32::MAX as u64); - let serialize_fields = - serialize_struct_visitor(fields, - params, - false, - quote!(_serde::ser::SerializeStruct::serialize_field)); + let serialize_fields = serialize_struct_visitor( + fields, + params, + false, + quote!(_serde::ser::SerializeStruct::serialize_field), + ); let type_name = item_attrs.name().serialize_name(); - let mut serialized_fields = fields.iter() + let mut serialized_fields = fields + .iter() .filter(|&field| !field.attrs.skip_serializing()) .peekable(); let let_mut = mut_if(serialized_fields.peek().is_some()); - let len = serialized_fields.map(|field| { - match field.attrs.skip_serializing_if() { + let len = serialized_fields + .map( + |field| match field.attrs.skip_serializing_if() { None => quote!(1), Some(path) => { let ident = field.ident.clone().expect("struct has unnamed fields"); let field_expr = get_field(params, field, ident); quote!(if #path(#field_expr) { 0 } else { 1 }) } - } - }) + }, + ) .fold(quote!(0), |sum, expr| quote!(#sum + #expr)); quote_block! { @@ -247,22 +252,23 @@ fn serialize_struct(params: &Parameters, } } -fn serialize_item_enum(params: &Parameters, - variants: &[Variant], - item_attrs: &attr::Item) - -> Fragment { +fn serialize_item_enum( + params: &Parameters, + variants: &[Variant], + item_attrs: &attr::Item, +) -> Fragment { assert!(variants.len() as u64 <= u32::MAX as u64); let self_var = ¶ms.self_var; - let arms: Vec<_> = variants.iter() + let arms: Vec<_> = variants + .iter() .enumerate() - .map(|(variant_index, variant)| { - serialize_variant(params, - variant, - variant_index as u32, - item_attrs) - }) + .map( + |(variant_index, variant)| { + serialize_variant(params, variant, variant_index as u32, item_attrs) + }, + ) .collect(); quote_expr! { @@ -272,24 +278,34 @@ fn serialize_item_enum(params: &Parameters, } } -fn serialize_variant(params: &Parameters, - variant: &Variant, - variant_index: u32, - item_attrs: &attr::Item) - -> Tokens { +fn serialize_variant( + params: &Parameters, + variant: &Variant, + variant_index: u32, + item_attrs: &attr::Item, +) -> Tokens { let this = ¶ms.this; let variant_ident = variant.ident.clone(); if variant.attrs.skip_serializing() { - let skipped_msg = format!("the enum variant {}::{} cannot be serialized", - params.type_name(), variant_ident); + let skipped_msg = format!( + "the enum variant {}::{} cannot be serialized", + params.type_name(), + variant_ident + ); let skipped_err = quote! { _serde::export::Err(_serde::ser::Error::custom(#skipped_msg)) }; let fields_pat = match variant.style { Style::Unit => quote!(), - Style::Newtype | Style::Tuple => quote!( (..) ), - Style::Struct => quote!( {..} ), + Style::Newtype | Style::Tuple => quote!((..)), + Style::Struct => { + quote!( + { + .. + } + ) + } }; quote! { #this::#variant_ident #fields_pat => #skipped_err, @@ -308,44 +324,44 @@ fn serialize_variant(params: &Parameters, } } Style::Tuple => { - let field_names = (0..variant.fields.len()) - .map(|i| Ident::new(format!("__field{}", i))); + let field_names = + (0..variant.fields.len()).map(|i| Ident::new(format!("__field{}", i))); quote! { #this::#variant_ident(#(ref #field_names),*) } } Style::Struct => { - let fields = variant.fields + let fields = variant + .fields .iter() - .map(|f| f.ident.clone().expect("struct variant has unnamed fields")); + .map( + |f| { + f.ident + .clone() + .expect("struct variant has unnamed fields") + }, + ); quote! { #this::#variant_ident { #(ref #fields),* } } } }; - let body = Match(match *item_attrs.tag() { - attr::EnumTag::External => { - serialize_externally_tagged_variant(params, - variant, - variant_index, - item_attrs) - } - attr::EnumTag::Internal { ref tag } => { - serialize_internally_tagged_variant(params, - variant, - item_attrs, - tag) - } - attr::EnumTag::Adjacent { ref tag, ref content } => { - serialize_adjacently_tagged_variant(params, - variant, - item_attrs, - tag, - content) - } - attr::EnumTag::None => serialize_untagged_variant(params, variant, item_attrs), - }); + let body = Match( + match *item_attrs.tag() { + attr::EnumTag::External => { + serialize_externally_tagged_variant(params, variant, variant_index, item_attrs) + } + attr::EnumTag::Internal { ref tag } => { + serialize_internally_tagged_variant(params, variant, item_attrs, tag) + } + attr::EnumTag::Adjacent { + ref tag, + ref content, + } => serialize_adjacently_tagged_variant(params, variant, item_attrs, tag, content), + attr::EnumTag::None => serialize_untagged_variant(params, variant, item_attrs), + }, + ); quote! { #case => #body @@ -353,11 +369,12 @@ fn serialize_variant(params: &Parameters, } } -fn serialize_externally_tagged_variant(params: &Parameters, - variant: &Variant, - variant_index: u32, - item_attrs: &attr::Item) - -> Fragment { +fn serialize_externally_tagged_variant( + params: &Parameters, + variant: &Variant, + variant_index: u32, + item_attrs: &attr::Item, +) -> Fragment { let type_name = item_attrs.name().serialize_name(); let variant_name = variant.attrs.name().serialize_name(); @@ -390,31 +407,36 @@ fn serialize_externally_tagged_variant(params: &Parameters, } } Style::Tuple => { - serialize_tuple_variant(TupleVariant::ExternallyTagged { - type_name: type_name, - variant_index: variant_index, - variant_name: variant_name, - }, - params, - &variant.fields) + serialize_tuple_variant( + TupleVariant::ExternallyTagged { + type_name: type_name, + variant_index: variant_index, + variant_name: variant_name, + }, + params, + &variant.fields, + ) } Style::Struct => { - serialize_struct_variant(StructVariant::ExternallyTagged { - variant_index: variant_index, - variant_name: variant_name, - }, - params, - &variant.fields, - &type_name) + serialize_struct_variant( + StructVariant::ExternallyTagged { + variant_index: variant_index, + variant_name: variant_name, + }, + params, + &variant.fields, + &type_name, + ) } } } -fn serialize_internally_tagged_variant(params: &Parameters, - variant: &Variant, - item_attrs: &attr::Item, - tag: &str) - -> Fragment { +fn serialize_internally_tagged_variant( + params: &Parameters, + variant: &Variant, + item_attrs: &attr::Item, + tag: &str, +) -> Fragment { let type_name = item_attrs.name().serialize_name(); let variant_name = variant.attrs.name().serialize_name(); @@ -450,61 +472,66 @@ fn serialize_internally_tagged_variant(params: &Parameters, } } Style::Struct => { - serialize_struct_variant(StructVariant::InternallyTagged { - tag: tag, - variant_name: variant_name, - }, - params, - &variant.fields, - &type_name) + serialize_struct_variant( + StructVariant::InternallyTagged { + tag: tag, + variant_name: variant_name, + }, + params, + &variant.fields, + &type_name, + ) } Style::Tuple => unreachable!("checked in serde_codegen_internals"), } } -fn serialize_adjacently_tagged_variant(params: &Parameters, - variant: &Variant, - item_attrs: &attr::Item, - tag: &str, - content: &str) - -> Fragment { +fn serialize_adjacently_tagged_variant( + params: &Parameters, + variant: &Variant, + item_attrs: &attr::Item, + tag: &str, + content: &str, +) -> Fragment { let this = ¶ms.this; let type_name = item_attrs.name().serialize_name(); let variant_name = variant.attrs.name().serialize_name(); - let inner = Stmts(match variant.style { - Style::Unit => { - return quote_block! { + let inner = Stmts( + match variant.style { + Style::Unit => { + return quote_block! { let mut __struct = try!(_serde::Serializer::serialize_struct( __serializer, #type_name, 1)); try!(_serde::ser::SerializeStruct::serialize_field( &mut __struct, #tag, #variant_name)); _serde::ser::SerializeStruct::end(__struct) }; - } - Style::Newtype => { - let field = &variant.fields[0]; - let mut field_expr = quote!(__field0); - if let Some(path) = field.attrs.serialize_with() { - field_expr = wrap_serialize_with(params, field.ty, path, field_expr); } + Style::Newtype => { + let field = &variant.fields[0]; + let mut field_expr = quote!(__field0); + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_with(params, field.ty, path, field_expr); + } - quote_expr! { + quote_expr! { _serde::Serialize::serialize(#field_expr, __serializer) } - } - Style::Tuple => { - serialize_tuple_variant(TupleVariant::Untagged, - params, - &variant.fields) - } - Style::Struct => { - serialize_struct_variant(StructVariant::Untagged, - params, - &variant.fields, - &variant_name) - } - }); + } + Style::Tuple => { + serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields) + } + Style::Struct => { + serialize_struct_variant( + StructVariant::Untagged, + params, + &variant.fields, + &variant_name, + ) + } + }, + ); let fields_ty = variant.fields.iter().map(|f| &f.ty); let ref fields_ident: Vec<_> = match variant.style { @@ -516,9 +543,16 @@ fn serialize_adjacently_tagged_variant(params: &Parameters, .collect() } Style::Struct => { - variant.fields + variant + .fields .iter() - .map(|f| f.ident.clone().expect("struct variant has unnamed fields")) + .map( + |f| { + f.ident + .clone() + .expect("struct variant has unnamed fields") + }, + ) .collect() } }; @@ -556,10 +590,11 @@ fn serialize_adjacently_tagged_variant(params: &Parameters, } } -fn serialize_untagged_variant(params: &Parameters, - variant: &Variant, - item_attrs: &attr::Item) - -> Fragment { +fn serialize_untagged_variant( + params: &Parameters, + variant: &Variant, + item_attrs: &attr::Item, +) -> Fragment { match variant.style { Style::Unit => { quote_expr! { @@ -577,15 +612,10 @@ fn serialize_untagged_variant(params: &Parameters, _serde::Serialize::serialize(#field_expr, __serializer) } } - Style::Tuple => { - serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields) - } + Style::Tuple => serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields), Style::Struct => { let type_name = item_attrs.name().serialize_name(); - serialize_struct_variant(StructVariant::Untagged, - params, - &variant.fields, - &type_name) + serialize_struct_variant(StructVariant::Untagged, params, &variant.fields, &type_name) } } } @@ -599,10 +629,11 @@ enum TupleVariant { Untagged, } -fn serialize_tuple_variant(context: TupleVariant, - params: &Parameters, - fields: &[Field]) - -> Fragment { +fn serialize_tuple_variant( + context: TupleVariant, + params: &Parameters, + fields: &[Field], +) -> Fragment { let method = match context { TupleVariant::ExternallyTagged { .. } => { quote!(_serde::ser::SerializeTupleVariant::serialize_field) @@ -610,14 +641,17 @@ fn serialize_tuple_variant(context: TupleVariant, TupleVariant::Untagged => quote!(_serde::ser::SerializeTuple::serialize_element), }; - let serialize_stmts = - serialize_tuple_struct_visitor(fields, params, true, method); + let serialize_stmts = serialize_tuple_struct_visitor(fields, params, true, method); let len = serialize_stmts.len(); let let_mut = mut_if(len > 0); match context { - TupleVariant::ExternallyTagged { type_name, variant_index, variant_name } => { + TupleVariant::ExternallyTagged { + type_name, + variant_index, + variant_name, + } => { quote_block! { let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple_variant( __serializer, @@ -650,11 +684,12 @@ enum StructVariant<'a> { Untagged, } -fn serialize_struct_variant<'a>(context: StructVariant<'a>, - params: &Parameters, - fields: &[Field], - name: &str) - -> Fragment { +fn serialize_struct_variant<'a>( + context: StructVariant<'a>, + params: &Parameters, + fields: &[Field], + name: &str, +) -> Fragment { let method = match context { StructVariant::ExternallyTagged { .. } => { quote!(_serde::ser::SerializeStructVariant::serialize_field) @@ -665,24 +700,31 @@ fn serialize_struct_variant<'a>(context: StructVariant<'a>, let serialize_fields = serialize_struct_visitor(fields, params, true, method); - let mut serialized_fields = fields.iter() + let mut serialized_fields = fields + .iter() .filter(|&field| !field.attrs.skip_serializing()) .peekable(); let let_mut = mut_if(serialized_fields.peek().is_some()); - let len = serialized_fields.map(|field| { - let ident = field.ident.clone().expect("struct has unnamed fields"); + let len = serialized_fields + .map( + |field| { + let ident = field.ident.clone().expect("struct has unnamed fields"); - match field.attrs.skip_serializing_if() { - Some(path) => quote!(if #path(#ident) { 0 } else { 1 }), - None => quote!(1), - } - }) + match field.attrs.skip_serializing_if() { + Some(path) => quote!(if #path(#ident) { 0 } else { 1 }), + None => quote!(1), + } + }, + ) .fold(quote!(0), |sum, expr| quote!(#sum + #expr)); match context { - StructVariant::ExternallyTagged { variant_index, variant_name } => { + StructVariant::ExternallyTagged { + variant_index, + variant_name, + } => { quote_block! { let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct_variant( __serializer, @@ -725,85 +767,94 @@ fn serialize_struct_variant<'a>(context: StructVariant<'a>, } } -fn serialize_tuple_struct_visitor(fields: &[Field], - params: &Parameters, - is_enum: bool, - func: Tokens) - -> Vec { - fields.iter() +fn serialize_tuple_struct_visitor( + fields: &[Field], + params: &Parameters, + is_enum: bool, + func: Tokens, +) -> Vec { + fields + .iter() .enumerate() - .map(|(i, field)| { - let mut field_expr = if is_enum { - let id = Ident::new(format!("__field{}", i)); - quote!(#id) - } else { - get_field(params, field, i) - }; + .map( + |(i, field)| { + let mut field_expr = if is_enum { + let id = Ident::new(format!("__field{}", i)); + quote!(#id) + } else { + get_field(params, field, i) + }; - let skip = field.attrs - .skip_serializing_if() - .map(|path| quote!(#path(#field_expr))); + let skip = field + .attrs + .skip_serializing_if() + .map(|path| quote!(#path(#field_expr))); - if let Some(path) = field.attrs.serialize_with() { - field_expr = - wrap_serialize_with(params, field.ty, path, field_expr); - } + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_with(params, field.ty, path, field_expr); + } - let ser = quote! { + let ser = quote! { try!(#func(&mut __serde_state, #field_expr)); }; - match skip { - None => ser, - Some(skip) => quote!(if !#skip { #ser }), - } - }) + match skip { + None => ser, + Some(skip) => quote!(if !#skip { #ser }), + } + }, + ) .collect() } -fn serialize_struct_visitor(fields: &[Field], - params: &Parameters, - is_enum: bool, - func: Tokens) - -> Vec { - fields.iter() +fn serialize_struct_visitor( + fields: &[Field], + params: &Parameters, + is_enum: bool, + func: Tokens, +) -> Vec { + fields + .iter() .filter(|&field| !field.attrs.skip_serializing()) - .map(|field| { - let field_ident = field.ident.clone().expect("struct has unnamed field"); - let mut field_expr = if is_enum { - quote!(#field_ident) - } else { - get_field(params, field, field_ident) - }; + .map( + |field| { + let field_ident = field.ident.clone().expect("struct has unnamed field"); + let mut field_expr = if is_enum { + quote!(#field_ident) + } else { + get_field(params, field, field_ident) + }; - let key_expr = field.attrs.name().serialize_name(); + let key_expr = field.attrs.name().serialize_name(); - let skip = field.attrs - .skip_serializing_if() - .map(|path| quote!(#path(#field_expr))); + let skip = field + .attrs + .skip_serializing_if() + .map(|path| quote!(#path(#field_expr))); - if let Some(path) = field.attrs.serialize_with() { - field_expr = - wrap_serialize_with(params, field.ty, path, field_expr) - } + if let Some(path) = field.attrs.serialize_with() { + field_expr = wrap_serialize_with(params, field.ty, path, field_expr) + } - let ser = quote! { + let ser = quote! { try!(#func(&mut __serde_state, #key_expr, #field_expr)); }; - match skip { - None => ser, - Some(skip) => quote!(if !#skip { #ser }), - } - }) + match skip { + None => ser, + Some(skip) => quote!(if !#skip { #ser }), + } + }, + ) .collect() } -fn wrap_serialize_with(params: &Parameters, - field_ty: &syn::Ty, - serialize_with: &syn::Path, - value: Tokens) - -> Tokens { +fn wrap_serialize_with( + params: &Parameters, + field_ty: &syn::Ty, + serialize_with: &syn::Path, + value: Tokens, +) -> Tokens { let this = ¶ms.this; let (_, ty_generics, where_clause) = params.generics.split_for_impl(); @@ -842,7 +893,8 @@ fn mut_if(is_mut: bool) -> Option { } fn get_field(params: &Parameters, field: &Field, ident: I) -> Tokens - where I: Into +where + I: Into, { let self_var = ¶ms.self_var; match (params.is_remote, field.attrs.getter()) { diff --git a/serde_test/src/assert.rs b/serde_test/src/assert.rs index ccfa4c26..6715c5b1 100644 --- a/serde_test/src/assert.rs +++ b/serde_test/src/assert.rs @@ -9,7 +9,8 @@ use std::fmt::Debug; /// Runs both `assert_ser_tokens` and `assert_de_tokens`. pub fn assert_tokens<'de, T>(value: &T, tokens: &'de [Token]) - where T: Serialize + Deserialize<'de> + PartialEq + Debug +where + T: Serialize + Deserialize<'de> + PartialEq + Debug, { assert_ser_tokens(value, tokens); assert_de_tokens(value, tokens); @@ -17,7 +18,8 @@ pub fn assert_tokens<'de, T>(value: &T, tokens: &'de [Token]) /// Asserts that `value` serializes to the given `tokens`. pub fn assert_ser_tokens(value: &T, tokens: &[Token]) - where T: Serialize +where + T: Serialize, { let mut ser = Serializer::new(tokens); assert_eq!(Serialize::serialize(value, &mut ser), Ok(())); @@ -26,7 +28,8 @@ pub fn assert_ser_tokens(value: &T, tokens: &[Token]) /// Asserts that `value` serializes to the given `tokens`, and then yields `error`. pub fn assert_ser_tokens_error(value: &T, tokens: &[Token], error: Error) - where T: Serialize + PartialEq + Debug +where + T: Serialize + PartialEq + Debug, { let mut ser = Serializer::new(tokens); let v: Result<(), Error> = Serialize::serialize(value, &mut ser); @@ -36,7 +39,8 @@ pub fn assert_ser_tokens_error(value: &T, tokens: &[Token], error: Error) /// Asserts that the given `tokens` deserialize into `value`. pub fn assert_de_tokens<'de, T>(value: &T, tokens: &'de [Token]) - where T: Deserialize<'de> + PartialEq + Debug +where + T: Deserialize<'de> + PartialEq + Debug, { let mut de = Deserializer::new(tokens); let v: Result = Deserialize::deserialize(&mut de); @@ -46,7 +50,8 @@ pub fn assert_de_tokens<'de, T>(value: &T, tokens: &'de [Token]) /// Asserts that the given `tokens` yield `error` when deserializing. pub fn assert_de_tokens_error<'de, T>(tokens: &'de [Token], error: Error) - where T: Deserialize<'de> + PartialEq + Debug +where + T: Deserialize<'de> + PartialEq + Debug, { let mut de = Deserializer::new(tokens); let v: Result = Deserialize::deserialize(&mut de); diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index 3570a0cc..5727b889 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -1,5 +1,5 @@ -use serde::de::{self, Deserialize, DeserializeSeed, EnumVisitor, IntoDeserializer, - MapVisitor, SeqVisitor, VariantVisitor, Visitor}; +use serde::de::{self, Deserialize, DeserializeSeed, EnumVisitor, IntoDeserializer, MapVisitor, + SeqVisitor, VariantVisitor, Visitor}; use serde::de::value::{MapVisitorDeserializer, SeqVisitorDeserializer}; use error::Error; @@ -41,34 +41,46 @@ impl<'de> Deserializer<'de> { } } - fn visit_seq(&mut self, - len: Option, - end: Token, - visitor: V) - -> Result - where V: Visitor<'de> + fn visit_seq( + &mut self, + len: Option, + end: Token, + visitor: V, + ) -> Result + where + V: Visitor<'de>, { - let value = try!(visitor.visit_seq(DeserializerSeqVisitor { - de: self, - len: len, - end: end.clone(), - })); + let value = try!( + visitor.visit_seq( + DeserializerSeqVisitor { + de: self, + len: len, + end: end.clone(), + }, + ) + ); try!(self.expect_token(end)); Ok(value) } - fn visit_map(&mut self, - len: Option, - end: Token, - visitor: V) - -> Result - where V: Visitor<'de> + fn visit_map( + &mut self, + len: Option, + end: Token, + visitor: V, + ) -> Result + where + V: Visitor<'de>, { - let value = try!(visitor.visit_map(DeserializerMapVisitor { - de: self, - len: len, - end: end.clone(), - })); + let value = try!( + visitor.visit_map( + DeserializerMapVisitor { + de: self, + len: len, + end: end.clone(), + }, + ) + ); try!(self.expect_token(end)); Ok(value) } @@ -83,7 +95,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } fn deserialize(self, visitor: V) -> Result - where V: Visitor<'de> + where + V: Visitor<'de>, { let token = self.next_token().ok_or(Error::EndOfTokens)?; match token { @@ -110,26 +123,12 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { Token::Unit => visitor.visit_unit(), Token::UnitStruct(_name) => visitor.visit_unit(), Token::NewtypeStruct(_name) => visitor.visit_newtype_struct(self), - Token::Seq(len) => { - self.visit_seq(len, Token::SeqEnd, visitor) - } - Token::SeqFixedSize(len) => { - self.visit_seq(Some(len), Token::SeqEnd, visitor) - } - Token::Tuple(len) => { - self.visit_seq(Some(len), Token::TupleEnd, visitor) - } - Token::TupleStruct(_, len) => { - self.visit_seq(Some(len), - Token::TupleStructEnd, - visitor) - } - Token::Map(len) => { - self.visit_map(len, Token::MapEnd, visitor) - } - Token::Struct(_, len) => { - self.visit_map(Some(len), Token::StructEnd, visitor) - } + Token::Seq(len) => self.visit_seq(len, Token::SeqEnd, visitor), + Token::SeqFixedSize(len) => self.visit_seq(Some(len), Token::SeqEnd, visitor), + Token::Tuple(len) => self.visit_seq(Some(len), Token::TupleEnd, visitor), + Token::TupleStruct(_, len) => self.visit_seq(Some(len), Token::TupleStructEnd, visitor), + Token::Map(len) => self.visit_map(len, Token::MapEnd, visitor), + Token::Struct(_, len) => self.visit_map(Some(len), Token::StructEnd, visitor), Token::Enum(_) => { let variant = self.next_token().ok_or(Error::EndOfTokens)?; let next = *self.tokens.first().ok_or(Error::EndOfTokens)?; @@ -146,9 +145,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { self.next_token(); visitor.visit_u32(variant) } - (variant, Token::Unit) => { - Err(Error::UnexpectedToken(variant)) - } + (variant, Token::Unit) => Err(Error::UnexpectedToken(variant)), (variant, _) => { visitor.visit_map(EnumMapVisitor::new(self, variant, EnumFormat::Any)) } @@ -156,28 +153,26 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } Token::UnitVariant(_, variant) => visitor.visit_str(variant), Token::NewtypeVariant(_, variant) => { - visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Any)) + visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Any),) } Token::TupleVariant(_, variant, _) => { - visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Seq)) + visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Seq),) } Token::StructVariant(_, variant, _) => { - visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Map)) + visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Map),) + } + Token::SeqEnd | Token::TupleEnd | Token::TupleStructEnd | Token::MapEnd | + Token::StructEnd | Token::TupleVariantEnd | Token::StructVariantEnd => { + Err(Error::UnexpectedToken(token)) } - Token::SeqEnd | - Token::TupleEnd | - Token::TupleStructEnd | - Token::MapEnd | - Token::StructEnd | - Token::TupleVariantEnd | - Token::StructVariantEnd => Err(Error::UnexpectedToken(token)), } } /// Hook into `Option` deserializing so we can treat `Unit` as a /// `None`, or a regular value as `Some(value)`. fn deserialize_option(self, visitor: V) -> Result - where V: Visitor<'de> + where + V: Visitor<'de>, { match self.tokens.first() { Some(&Token::Unit) | @@ -194,12 +189,14 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } } - fn deserialize_enum(self, - name: &str, - _variants: &'static [&'static str], - visitor: V) - -> Result - where V: Visitor<'de> + fn deserialize_enum( + self, + name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, { match self.tokens.first() { Some(&Token::Enum(n)) if name == n => { @@ -222,7 +219,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } fn deserialize_unit_struct(self, name: &str, visitor: V) -> Result - where V: Visitor<'de> + where + V: Visitor<'de>, { match self.tokens.first() { Some(&Token::UnitStruct(n)) => { @@ -239,7 +237,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } fn deserialize_newtype_struct(self, name: &str, visitor: V) -> Result - where V: Visitor<'de> + where + V: Visitor<'de>, { match self.tokens.first() { Some(&Token::NewtypeStruct(n)) => { @@ -256,7 +255,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } fn deserialize_seq_fixed_size(self, len: usize, visitor: V) -> Result - where V: Visitor<'de> + where + V: Visitor<'de>, { match self.tokens.first() { Some(&Token::SeqFixedSize(_)) => { @@ -269,7 +269,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } fn deserialize_tuple(self, len: usize, visitor: V) -> Result - where V: Visitor<'de> + where + V: Visitor<'de>, { match self.tokens.first() { Some(&Token::Unit) | @@ -291,21 +292,21 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } Some(&Token::TupleStruct(_, _)) => { self.next_token(); - self.visit_seq(Some(len), - Token::TupleStructEnd, - visitor) + self.visit_seq(Some(len), Token::TupleStructEnd, visitor) } Some(_) => self.deserialize(visitor), None => Err(Error::EndOfTokens), } } - fn deserialize_tuple_struct(self, - name: &str, - len: usize, - visitor: V) - -> Result - where V: Visitor<'de> + fn deserialize_tuple_struct( + self, + name: &str, + len: usize, + visitor: V, + ) -> Result + where + V: Visitor<'de>, { match self.tokens.first() { Some(&Token::Unit) => { @@ -335,9 +336,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { Some(&Token::TupleStruct(n, _)) => { self.next_token(); if name == n { - self.visit_seq(Some(len), - Token::TupleStructEnd, - visitor) + self.visit_seq(Some(len), Token::TupleStructEnd, visitor) } else { Err(Error::InvalidName(n)) } @@ -347,20 +346,20 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } } - fn deserialize_struct(self, - name: &str, - fields: &'static [&'static str], - visitor: V) - -> Result - where V: Visitor<'de> + fn deserialize_struct( + self, + name: &str, + fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, { match self.tokens.first() { Some(&Token::Struct(n, _)) => { self.next_token(); if name == n { - self.visit_map(Some(fields.len()), - Token::StructEnd, - visitor) + self.visit_map(Some(fields.len()), Token::StructEnd, visitor) } else { Err(Error::InvalidName(n)) } @@ -387,7 +386,8 @@ impl<'de, 'a> SeqVisitor<'de> for DeserializerSeqVisitor<'a, 'de> { type Error = Error; fn visit_seed(&mut self, seed: T) -> Result, Error> - where T: DeserializeSeed<'de> + where + T: DeserializeSeed<'de>, { if self.de.tokens.first() == Some(&self.end) { return Ok(None); @@ -414,7 +414,8 @@ impl<'de, 'a> MapVisitor<'de> for DeserializerMapVisitor<'a, 'de> { type Error = Error; fn visit_key_seed(&mut self, seed: K) -> Result, Error> - where K: DeserializeSeed<'de> + where + K: DeserializeSeed<'de>, { if self.de.tokens.first() == Some(&self.end) { return Ok(None); @@ -424,7 +425,8 @@ impl<'de, 'a> MapVisitor<'de> for DeserializerMapVisitor<'a, 'de> { } fn visit_value_seed(&mut self, seed: V) -> Result - where V: DeserializeSeed<'de> + where + V: DeserializeSeed<'de>, { seed.deserialize(&mut *self.de) } @@ -446,7 +448,8 @@ impl<'de, 'a> EnumVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { type Variant = Self; fn visit_variant_seed(self, seed: V) -> Result<(V::Value, Self), Error> - where V: DeserializeSeed<'de> + where + V: DeserializeSeed<'de>, { match self.de.tokens.first() { Some(&Token::UnitVariant(_, v)) | @@ -481,7 +484,8 @@ impl<'de, 'a> VariantVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { } fn visit_newtype_seed(self, seed: T) -> Result - where T: DeserializeSeed<'de> + where + T: DeserializeSeed<'de>, { match self.de.tokens.first() { Some(&Token::NewtypeVariant(_, _)) => { @@ -494,14 +498,16 @@ impl<'de, 'a> VariantVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { } fn visit_tuple(self, len: usize, visitor: V) -> Result - where V: Visitor<'de> + where + V: Visitor<'de>, { match self.de.tokens.first() { Some(&Token::TupleVariant(_, _, enum_len)) => { let token = self.de.next_token().unwrap(); if len == enum_len { - self.de.visit_seq(Some(len), Token::TupleVariantEnd, visitor) + self.de + .visit_seq(Some(len), Token::TupleVariantEnd, visitor) } else { Err(Error::UnexpectedToken(token)) } @@ -521,16 +527,16 @@ impl<'de, 'a> VariantVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { } fn visit_struct(self, fields: &'static [&'static str], visitor: V) -> Result - where V: Visitor<'de> + where + V: Visitor<'de>, { match self.de.tokens.first() { Some(&Token::StructVariant(_, _, enum_len)) => { let token = self.de.next_token().unwrap(); if fields.len() == enum_len { - self.de.visit_map(Some(fields.len()), - Token::StructVariantEnd, - visitor) + self.de + .visit_map(Some(fields.len()), Token::StructVariantEnd, visitor) } else { Err(Error::UnexpectedToken(token)) } @@ -539,7 +545,8 @@ impl<'de, 'a> VariantVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { let token = self.de.next_token().unwrap(); if fields.len() == enum_len { - self.de.visit_map(Some(fields.len()), Token::MapEnd, visitor) + self.de + .visit_map(Some(fields.len()), Token::MapEnd, visitor) } else { Err(Error::UnexpectedToken(token)) } @@ -578,27 +585,24 @@ impl<'de, 'a> MapVisitor<'de> for EnumMapVisitor<'a, 'de> { type Error = Error; fn visit_key_seed(&mut self, seed: K) -> Result, Error> - where K: DeserializeSeed<'de> + where + K: DeserializeSeed<'de>, { match self.variant.take() { - Some(Token::Str(variant)) => { - seed.deserialize(variant.into_deserializer()).map(Some) - } + Some(Token::Str(variant)) => seed.deserialize(variant.into_deserializer()).map(Some), Some(Token::Bytes(variant)) => { - seed.deserialize(BytesDeserializer { value: variant }).map(Some) - } - Some(Token::U32(variant)) => { - seed.deserialize(variant.into_deserializer()).map(Some) - } - Some(other) => { - Err(Error::UnexpectedToken(other)) + seed.deserialize(BytesDeserializer { value: variant }) + .map(Some) } + Some(Token::U32(variant)) => seed.deserialize(variant.into_deserializer()).map(Some), + Some(other) => Err(Error::UnexpectedToken(other)), None => Ok(None), } } fn visit_value_seed(&mut self, seed: V) -> Result - where V: DeserializeSeed<'de> + where + V: DeserializeSeed<'de>, { match self.format { EnumFormat::Seq => { @@ -638,7 +642,8 @@ impl<'de> de::Deserializer<'de> for BytesDeserializer { type Error = Error; fn deserialize(self, visitor: V) -> Result - where V: de::Visitor<'de> + where + V: de::Visitor<'de>, { visitor.visit_bytes(self.value) } diff --git a/serde_test/src/ser.rs b/serde_test/src/ser.rs index 3f5430c6..4e733fcf 100644 --- a/serde_test/src/ser.rs +++ b/serde_test/src/ser.rs @@ -12,9 +12,7 @@ pub struct Serializer<'a> { impl<'a> Serializer<'a> { /// Creates the serializer. pub fn new(tokens: &'a [Token]) -> Self { - Serializer { - tokens: tokens, - } + Serializer { tokens: tokens } } /// Pulls the next token off of the serializer, ignoring it. @@ -145,11 +143,12 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { Ok(()) } - fn serialize_unit_variant(self, - name: &'static str, - _variant_index: u32, - variant: &'static str) - -> Result<(), Error> { + fn serialize_unit_variant( + self, + name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result<(), Error> { if self.tokens.first() == Some(&Token::Enum(name)) { self.next_token(); assert_next_token!(self, Str(variant)); @@ -161,19 +160,22 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { } fn serialize_newtype_struct(self, name: &'static str, value: &T) -> Result<(), Error> - where T: Serialize + where + T: Serialize, { assert_next_token!(self, NewtypeStruct(name)); value.serialize(self) } - fn serialize_newtype_variant(self, - name: &'static str, - _variant_index: u32, - variant: &'static str, - value: &T) - -> Result<(), Error> - where T: Serialize + fn serialize_newtype_variant( + self, + name: &'static str, + _variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result<(), Error> + where + T: Serialize, { if self.tokens.first() == Some(&Token::Enum(name)) { self.next_token(); @@ -190,7 +192,8 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { } fn serialize_some(self, value: &T) -> Result<(), Error> - where T: Serialize + where + T: Serialize, { assert_next_token!(self, Some); value.serialize(self) @@ -216,12 +219,13 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { Ok(self) } - fn serialize_tuple_variant(self, - name: &'static str, - _variant_index: u32, - variant: &'static str, - len: usize) - -> Result { + fn serialize_tuple_variant( + self, + name: &'static str, + _variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { assert_next_token!(self, TupleVariant(name, variant, len)); Ok(self) } @@ -236,12 +240,13 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { Ok(self) } - fn serialize_struct_variant(self, - name: &'static str, - _variant_index: u32, - variant: &'static str, - len: usize) - -> Result { + fn serialize_struct_variant( + self, + name: &'static str, + _variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { assert_next_token!(self, StructVariant(name, variant, len)); Ok(self) } @@ -252,7 +257,8 @@ impl<'s, 'a> ser::SerializeSeq for &'s mut Serializer<'a> { type Error = Error; fn serialize_element(&mut self, value: &T) -> Result<(), Error> - where T: Serialize + where + T: Serialize, { value.serialize(&mut **self) } @@ -268,7 +274,8 @@ impl<'s, 'a> ser::SerializeTuple for &'s mut Serializer<'a> { type Error = Error; fn serialize_element(&mut self, value: &T) -> Result<(), Error> - where T: Serialize + where + T: Serialize, { value.serialize(&mut **self) } @@ -284,7 +291,8 @@ impl<'s, 'a> ser::SerializeTupleStruct for &'s mut Serializer<'a> { type Error = Error; fn serialize_field(&mut self, value: &T) -> Result<(), Error> - where T: Serialize + where + T: Serialize, { value.serialize(&mut **self) } @@ -300,7 +308,8 @@ impl<'s, 'a> ser::SerializeTupleVariant for &'s mut Serializer<'a> { type Error = Error; fn serialize_field(&mut self, value: &T) -> Result<(), Error> - where T: Serialize + where + T: Serialize, { value.serialize(&mut **self) } @@ -316,13 +325,15 @@ impl<'s, 'a> ser::SerializeMap for &'s mut Serializer<'a> { type Error = Error; fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> - where T: Serialize + where + T: Serialize, { key.serialize(&mut **self) } fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> - where T: Serialize + where + T: Serialize, { value.serialize(&mut **self) } @@ -337,11 +348,13 @@ impl<'s, 'a> ser::SerializeStruct for &'s mut Serializer<'a> { type Ok = (); type Error = Error; - fn serialize_field(&mut self, - key: &'static str, - value: &T) - -> Result<(), Self::Error> - where T: Serialize + fn serialize_field( + &mut self, + key: &'static str, + value: &T, + ) -> Result<(), Self::Error> + where + T: Serialize, { try!(key.serialize(&mut **self)); value.serialize(&mut **self) @@ -357,11 +370,13 @@ impl<'s, 'a> ser::SerializeStructVariant for &'s mut Serializer<'a> { type Ok = (); type Error = Error; - fn serialize_field(&mut self, - key: &'static str, - value: &T) - -> Result<(), Self::Error> - where T: Serialize + fn serialize_field( + &mut self, + key: &'static str, + value: &T, + ) -> Result<(), Self::Error> + where + T: Serialize, { try!(key.serialize(&mut **self)); value.serialize(&mut **self) diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index 490fb724..45e9b441 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -5,14 +5,8 @@ extern crate serde; use self::serde::{Serialize, Serializer, Deserialize, Deserializer}; extern crate serde_test; -use self::serde_test::{ - Error, - Token, - assert_tokens, - assert_ser_tokens, - assert_de_tokens, - assert_de_tokens_error -}; +use self::serde_test::{Error, Token, assert_tokens, assert_ser_tokens, assert_de_tokens, + assert_de_tokens_error}; trait MyDefault: Sized { fn my_default() -> Self; @@ -24,25 +18,32 @@ trait ShouldSkip: Sized { trait SerializeWith: Sized { fn serialize_with(&self, ser: S) -> Result - where S: Serializer; + where + S: Serializer; } trait DeserializeWith: Sized { fn deserialize_with<'de, D>(de: D) -> Result - where D: Deserializer<'de>; + where + D: Deserializer<'de>; } impl MyDefault for i32 { - fn my_default() -> Self { 123 } + fn my_default() -> Self { + 123 + } } impl ShouldSkip for i32 { - fn should_skip(&self) -> bool { *self == 123 } + fn should_skip(&self) -> bool { + *self == 123 + } } impl SerializeWith for i32 { fn serialize_with(&self, ser: S) -> Result - where S: Serializer + where + S: Serializer, { if *self == 123 { true.serialize(ser) @@ -54,7 +55,8 @@ impl SerializeWith for i32 { impl DeserializeWith for i32 { fn deserialize_with<'de, D>(de: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { if try!(Deserialize::deserialize(de)) { Ok(123) @@ -66,8 +68,9 @@ impl DeserializeWith for i32 { #[derive(Debug, PartialEq, Serialize, Deserialize)] struct DefaultStruct - where C: MyDefault, - E: MyDefault, +where + C: MyDefault, + E: MyDefault, { a1: A, #[serde(default)] @@ -83,7 +86,13 @@ struct DefaultStruct #[test] fn test_default_struct() { assert_de_tokens( - &DefaultStruct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 }, + &DefaultStruct { + a1: 1, + a2: 2, + a3: 3, + a4: 0, + a5: 123, + }, &[ Token::Struct("DefaultStruct", 3), @@ -103,11 +112,17 @@ fn test_default_struct() { Token::I32(5), Token::StructEnd, - ] + ], ); assert_de_tokens( - &DefaultStruct { a1: 1, a2: 0, a3: 123, a4: 0, a5: 123 }, + &DefaultStruct { + a1: 1, + a2: 0, + a3: 123, + a4: 0, + a5: 123, + }, &[ Token::Struct("DefaultStruct", 1), @@ -115,14 +130,15 @@ fn test_default_struct() { Token::I32(1), Token::StructEnd, - ] + ], ); } #[derive(Debug, PartialEq, Serialize, Deserialize)] enum DefaultEnum - where C: MyDefault, - E: MyDefault +where + C: MyDefault, + E: MyDefault, { Struct { a1: A, @@ -134,13 +150,19 @@ enum DefaultEnum a4: D, #[serde(skip_deserializing, default="MyDefault::my_default")] a5: E, - } + }, } #[test] fn test_default_enum() { assert_de_tokens( - &DefaultEnum::Struct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 }, + &DefaultEnum::Struct { + a1: 1, + a2: 2, + a3: 3, + a4: 0, + a5: 123, + }, &[ Token::StructVariant("DefaultEnum", "Struct", 3), @@ -160,11 +182,17 @@ fn test_default_enum() { Token::I32(5), Token::StructVariantEnd, - ] + ], ); assert_de_tokens( - &DefaultEnum::Struct { a1: 1, a2: 0, a3: 123, a4: 0, a5: 123 }, + &DefaultEnum::Struct { + a1: 1, + a2: 0, + a3: 123, + a4: 0, + a5: 123, + }, &[ Token::StructVariant("DefaultEnum", "Struct", 3), @@ -172,7 +200,7 @@ fn test_default_enum() { Token::I32(1), Token::StructVariantEnd, - ] + ], ); } @@ -198,10 +226,7 @@ struct ContainsNoStdDefault { fn test_no_std_default() { assert_de_tokens( &ContainsNoStdDefault { a: NoStdDefault(123) }, - &[ - Token::Struct("ContainsNoStdDefault", 1), - Token::StructEnd, - ] + &[Token::Struct("ContainsNoStdDefault", 1), Token::StructEnd], ); assert_de_tokens( @@ -214,7 +239,7 @@ fn test_no_std_default() { Token::I8(8), Token::StructEnd, - ] + ], ); } @@ -230,7 +255,8 @@ impl Default for NotDeserializeStruct { impl DeserializeWith for NotDeserializeStruct { fn deserialize_with<'de, D>(_: D) -> Result - where D: Deserializer<'de> + where + D: Deserializer<'de>, { panic!() } @@ -238,7 +264,9 @@ impl DeserializeWith for NotDeserializeStruct { // Does not implement Deserialize. #[derive(Debug, PartialEq)] -enum NotDeserializeEnum { Trouble } +enum NotDeserializeEnum { + Trouble, +} impl MyDefault for NotDeserializeEnum { fn my_default() -> Self { @@ -265,15 +293,12 @@ struct ContainsNotDeserialize { fn test_elt_not_deserialize() { assert_de_tokens( &ContainsNotDeserialize { - a: NotDeserializeStruct(123), - b: NotDeserializeStruct(123), - c: NotDeserializeStruct(123), - e: NotDeserializeEnum::Trouble, - }, - &[ - Token::Struct("ContainsNotDeserialize", 3), - Token::StructEnd, - ] + a: NotDeserializeStruct(123), + b: NotDeserializeStruct(123), + c: NotDeserializeStruct(123), + e: NotDeserializeEnum::Trouble, + }, + &[Token::Struct("ContainsNotDeserialize", 3), Token::StructEnd], ); } @@ -287,7 +312,13 @@ struct DenyUnknown { fn test_ignore_unknown() { // 'Default' allows unknown. Basic smoke test of ignore... assert_de_tokens( - &DefaultStruct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 }, + &DefaultStruct { + a1: 1, + a2: 2, + a3: 3, + a4: 0, + a5: 123, + }, &[ Token::Struct("DefaultStruct", 5), @@ -312,7 +343,7 @@ fn test_ignore_unknown() { Token::I32(3), Token::StructEnd, - ] + ], ); assert_de_tokens_error::( @@ -324,7 +355,7 @@ fn test_ignore_unknown() { Token::Str("whoops"), ], - Error::Message("unknown field `whoops`, expected `a1`".to_owned()) + Error::Message("unknown field `whoops`, expected `a1`".to_owned()), ); } @@ -358,7 +389,7 @@ fn test_rename_struct() { Token::I32(2), Token::StructEnd, - ] + ], ); assert_ser_tokens( @@ -373,7 +404,7 @@ fn test_rename_struct() { Token::I32(2), Token::StructEnd, - ] + ], ); assert_de_tokens( @@ -388,7 +419,7 @@ fn test_rename_struct() { Token::I32(2), Token::StructEnd, - ] + ], ); } @@ -424,9 +455,7 @@ enum RenameEnumSerializeDeserialize { fn test_rename_enum() { assert_tokens( &RenameEnum::Batman, - &[ - Token::UnitVariant("Superhero", "bruce_wayne"), - ] + &[Token::UnitVariant("Superhero", "bruce_wayne")], ); assert_tokens( @@ -434,7 +463,7 @@ fn test_rename_enum() { &[ Token::NewtypeVariant("Superhero", "clark_kent"), Token::I8(0), - ] + ], ); assert_tokens( @@ -444,7 +473,7 @@ fn test_rename_enum() { Token::I8(0), Token::I8(1), Token::TupleVariantEnd, - ] + ], ); assert_tokens( @@ -456,14 +485,14 @@ fn test_rename_enum() { Token::I32(1), Token::StructVariantEnd, - ] + ], ); assert_ser_tokens( &RenameEnumSerializeDeserialize::Robin { - a: 0, - b: String::new(), - }, + a: 0, + b: String::new(), + }, &[ Token::StructVariant("SuperheroSer", "dick_grayson", 2), @@ -474,14 +503,14 @@ fn test_rename_enum() { Token::Str(""), Token::StructVariantEnd, - ] + ], ); assert_de_tokens( &RenameEnumSerializeDeserialize::Robin { - a: 0, - b: String::new(), - }, + a: 0, + b: String::new(), + }, &[ Token::StructVariant("SuperheroDe", "jason_todd", 2), @@ -492,12 +521,15 @@ fn test_rename_enum() { Token::Str(""), Token::StructVariantEnd, - ] + ], ); } #[derive(Debug, PartialEq, Serialize)] -struct SkipSerializingStruct<'a, B, C> where C: ShouldSkip { +struct SkipSerializingStruct<'a, B, C> +where + C: ShouldSkip, +{ a: &'a i8, #[serde(skip_serializing)] b: B, @@ -509,11 +541,7 @@ struct SkipSerializingStruct<'a, B, C> where C: ShouldSkip { fn test_skip_serializing_struct() { let a = 1; assert_ser_tokens( - &SkipSerializingStruct { - a: &a, - b: 2, - c: 3, - }, + &SkipSerializingStruct { a: &a, b: 2, c: 3 }, &[ Token::Struct("SkipSerializingStruct", 2), @@ -524,15 +552,15 @@ fn test_skip_serializing_struct() { Token::I32(3), Token::StructEnd, - ] + ], ); assert_ser_tokens( &SkipSerializingStruct { - a: &a, - b: 2, - c: 123, - }, + a: &a, + b: 2, + c: 123, + }, &[ Token::Struct("SkipSerializingStruct", 1), @@ -540,30 +568,29 @@ fn test_skip_serializing_struct() { Token::I8(1), Token::StructEnd, - ] + ], ); } #[derive(Debug, PartialEq, Serialize)] -enum SkipSerializingEnum<'a, B, C> where C: ShouldSkip { +enum SkipSerializingEnum<'a, B, C> +where + C: ShouldSkip, +{ Struct { a: &'a i8, #[serde(skip_serializing)] _b: B, #[serde(skip_serializing_if="ShouldSkip::should_skip")] c: C, - } + }, } #[test] fn test_skip_serializing_enum() { let a = 1; assert_ser_tokens( - &SkipSerializingEnum::Struct { - a: &a, - _b: 2, - c: 3, - }, + &SkipSerializingEnum::Struct { a: &a, _b: 2, c: 3 }, &[ Token::StructVariant("SkipSerializingEnum", "Struct", 2), @@ -574,15 +601,15 @@ fn test_skip_serializing_enum() { Token::I32(3), Token::StructVariantEnd, - ] + ], ); assert_ser_tokens( &SkipSerializingEnum::Struct { - a: &a, - _b: 2, - c: 123, - }, + a: &a, + _b: 2, + c: 123, + }, &[ Token::StructVariant("SkipSerializingEnum", "Struct", 1), @@ -590,7 +617,7 @@ fn test_skip_serializing_enum() { Token::I8(1), Token::StructVariantEnd, - ] + ], ); } @@ -598,18 +625,25 @@ fn test_skip_serializing_enum() { struct NotSerializeStruct(i8); #[derive(Debug, PartialEq)] -enum NotSerializeEnum { Trouble } +enum NotSerializeEnum { + Trouble, +} impl SerializeWith for NotSerializeEnum { fn serialize_with(&self, ser: S) -> Result - where S: Serializer + where + S: Serializer, { "trouble".serialize(ser) } } #[derive(Debug, PartialEq, Serialize)] -struct ContainsNotSerialize<'a, B, C, D> where B: 'a, D: SerializeWith { +struct ContainsNotSerialize<'a, B, C, D> +where + B: 'a, + D: SerializeWith, +{ a: &'a Option, #[serde(skip_serializing)] b: &'a B, @@ -624,11 +658,11 @@ fn test_elt_not_serialize() { let a = 1; assert_ser_tokens( &ContainsNotSerialize { - a: &Some(a), - b: &NotSerializeStruct(2), - c: Some(NotSerializeEnum::Trouble), - d: NotSerializeEnum::Trouble, - }, + a: &Some(a), + b: &NotSerializeStruct(2), + c: Some(NotSerializeEnum::Trouble), + d: NotSerializeEnum::Trouble, + }, &[ Token::Struct("ContainsNotSerialize", 2), @@ -640,12 +674,15 @@ fn test_elt_not_serialize() { Token::Str("trouble"), Token::StructEnd, - ] + ], ); } #[derive(Debug, PartialEq, Serialize)] -struct SerializeWithStruct<'a, B> where B: SerializeWith { +struct SerializeWithStruct<'a, B> +where + B: SerializeWith, +{ a: &'a i8, #[serde(serialize_with="SerializeWith::serialize_with")] b: B, @@ -655,10 +692,7 @@ struct SerializeWithStruct<'a, B> where B: SerializeWith { fn test_serialize_with_struct() { let a = 1; assert_ser_tokens( - &SerializeWithStruct { - a: &a, - b: 2, - }, + &SerializeWithStruct { a: &a, b: 2 }, &[ Token::Struct("SerializeWithStruct", 2), @@ -669,14 +703,11 @@ fn test_serialize_with_struct() { Token::Bool(false), Token::StructEnd, - ] + ], ); assert_ser_tokens( - &SerializeWithStruct { - a: &a, - b: 123, - }, + &SerializeWithStruct { a: &a, b: 123 }, &[ Token::Struct("SerializeWithStruct", 2), @@ -687,27 +718,27 @@ fn test_serialize_with_struct() { Token::Bool(true), Token::StructEnd, - ] + ], ); } #[derive(Debug, PartialEq, Serialize)] -enum SerializeWithEnum<'a, B> where B: SerializeWith { +enum SerializeWithEnum<'a, B> +where + B: SerializeWith, +{ Struct { a: &'a i8, #[serde(serialize_with="SerializeWith::serialize_with")] b: B, - } + }, } #[test] fn test_serialize_with_enum() { let a = 1; assert_ser_tokens( - &SerializeWithEnum::Struct { - a: &a, - b: 2, - }, + &SerializeWithEnum::Struct { a: &a, b: 2 }, &[ Token::StructVariant("SerializeWithEnum", "Struct", 2), @@ -718,14 +749,11 @@ fn test_serialize_with_enum() { Token::Bool(false), Token::StructVariantEnd, - ] + ], ); assert_ser_tokens( - &SerializeWithEnum::Struct { - a: &a, - b: 123, - }, + &SerializeWithEnum::Struct { a: &a, b: 123 }, &[ Token::StructVariant("SerializeWithEnum", "Struct", 2), @@ -736,12 +764,15 @@ fn test_serialize_with_enum() { Token::Bool(true), Token::StructVariantEnd, - ] + ], ); } #[derive(Debug, PartialEq, Deserialize)] -struct DeserializeWithStruct where B: DeserializeWith { +struct DeserializeWithStruct +where + B: DeserializeWith, +{ a: i8, #[serde(deserialize_with="DeserializeWith::deserialize_with")] b: B, @@ -750,10 +781,7 @@ struct DeserializeWithStruct where B: DeserializeWith { #[test] fn test_deserialize_with_struct() { assert_de_tokens( - &DeserializeWithStruct { - a: 1, - b: 2, - }, + &DeserializeWithStruct { a: 1, b: 2 }, &[ Token::Struct("DeserializeWithStruct", 2), @@ -764,14 +792,11 @@ fn test_deserialize_with_struct() { Token::Bool(false), Token::StructEnd, - ] + ], ); assert_de_tokens( - &DeserializeWithStruct { - a: 1, - b: 123, - }, + &DeserializeWithStruct { a: 1, b: 123 }, &[ Token::Struct("DeserializeWithStruct", 2), @@ -782,26 +807,26 @@ fn test_deserialize_with_struct() { Token::Bool(true), Token::StructEnd, - ] + ], ); } #[derive(Debug, PartialEq, Deserialize)] -enum DeserializeWithEnum where B: DeserializeWith { +enum DeserializeWithEnum +where + B: DeserializeWith, +{ Struct { a: i8, #[serde(deserialize_with="DeserializeWith::deserialize_with")] b: B, - } + }, } #[test] fn test_deserialize_with_enum() { assert_de_tokens( - &DeserializeWithEnum::Struct { - a: 1, - b: 2, - }, + &DeserializeWithEnum::Struct { a: 1, b: 2 }, &[ Token::StructVariant("DeserializeWithEnum", "Struct", 2), @@ -812,14 +837,11 @@ fn test_deserialize_with_enum() { Token::Bool(false), Token::StructVariantEnd, - ] + ], ); assert_de_tokens( - &DeserializeWithEnum::Struct { - a: 1, - b: 123, - }, + &DeserializeWithEnum::Struct { a: 1, b: 123 }, &[ Token::StructVariant("DeserializeWithEnum", "Struct", 2), @@ -830,7 +852,7 @@ fn test_deserialize_with_enum() { Token::Bool(true), Token::StructVariantEnd, - ] + ], ); } @@ -888,7 +910,12 @@ fn test_missing_renamed_field_enum() { #[derive(Debug, PartialEq, Deserialize)] enum InvalidLengthEnum { A(i32, i32, i32), - B(#[serde(skip_deserializing)] i32, i32, i32), + B( + #[serde(skip_deserializing)] + i32, + i32, + i32 + ), } #[test] @@ -918,7 +945,7 @@ struct StructFromEnum(Option); impl Into for StructFromEnum { fn into(self) -> EnumToU32 { match self { - StructFromEnum(v) => v.into() + StructFromEnum(v) => v.into(), } } } @@ -936,7 +963,7 @@ enum EnumToU32 { Two, Three, Four, - Nothing + Nothing, } impl Into> for EnumToU32 { @@ -946,7 +973,7 @@ impl Into> for EnumToU32 { EnumToU32::Two => Some(2), EnumToU32::Three => Some(3), EnumToU32::Four => Some(4), - EnumToU32::Nothing => None + EnumToU32::Nothing => None, } } } @@ -958,35 +985,17 @@ impl From> for EnumToU32 { Some(2) => EnumToU32::Two, Some(3) => EnumToU32::Three, Some(4) => EnumToU32::Four, - _ => EnumToU32::Nothing + _ => EnumToU32::Nothing, } } } #[test] fn test_from_into_traits() { - assert_ser_tokens::(&EnumToU32::One, - &[Token::Some, - Token::U32(1) - ] - ); - assert_ser_tokens::(&EnumToU32::Nothing, - &[Token::None] - ); - assert_de_tokens::(&EnumToU32::Two, - &[Token::Some, - Token::U32(2) - ] - ); - assert_ser_tokens::(&StructFromEnum(Some(5)), - &[Token::None] - ); - assert_ser_tokens::(&StructFromEnum(None), - &[Token::None] - ); - assert_de_tokens::(&StructFromEnum(Some(2)), - &[Token::Some, - Token::U32(2) - ] - ); + assert_ser_tokens::(&EnumToU32::One, &[Token::Some, Token::U32(1)]); + assert_ser_tokens::(&EnumToU32::Nothing, &[Token::None]); + assert_de_tokens::(&EnumToU32::Two, &[Token::Some, Token::U32(2)]); + assert_ser_tokens::(&StructFromEnum(Some(5)), &[Token::None]); + assert_ser_tokens::(&StructFromEnum(None), &[Token::None]); + assert_de_tokens::(&StructFromEnum(Some(2)), &[Token::Some, Token::U32(2)]); } diff --git a/test_suite/tests/test_borrow.rs b/test_suite/tests/test_borrow.rs index b440a380..47c58844 100644 --- a/test_suite/tests/test_borrow.rs +++ b/test_suite/tests/test_borrow.rs @@ -5,82 +5,54 @@ extern crate serde; use serde::{Deserialize, Deserializer}; extern crate serde_test; -use serde_test::{ - Error, - Token, - assert_de_tokens, - assert_de_tokens_error, -}; +use serde_test::{Error, Token, assert_de_tokens, assert_de_tokens_error}; use std::borrow::Cow; #[test] fn test_borrowed_str() { - assert_de_tokens( - &"borrowed", - &[ - Token::BorrowedStr("borrowed"), - ] - ); + assert_de_tokens(&"borrowed", &[Token::BorrowedStr("borrowed")]); } #[test] fn test_borrowed_str_from_string() { assert_de_tokens_error::<&str>( - &[ - Token::String("borrowed"), - ], - Error::Message("invalid type: string \"borrowed\", expected a borrowed string".to_owned()), + &[Token::String("borrowed")], + Error::Message("invalid type: string \"borrowed\", expected a borrowed string".to_owned(),), ); } #[test] fn test_borrowed_str_from_str() { assert_de_tokens_error::<&str>( - &[ - Token::Str("borrowed"), - ], - Error::Message("invalid type: string \"borrowed\", expected a borrowed string".to_owned()), + &[Token::Str("borrowed")], + Error::Message("invalid type: string \"borrowed\", expected a borrowed string".to_owned(),), ); } #[test] fn test_string_from_borrowed_str() { - assert_de_tokens( - &"owned".to_owned(), - &[ - Token::BorrowedStr("owned"), - ] - ); + assert_de_tokens(&"owned".to_owned(), &[Token::BorrowedStr("owned")]); } #[test] fn test_borrowed_bytes() { - assert_de_tokens( - &&b"borrowed"[..], - &[ - Token::BorrowedBytes(b"borrowed"), - ] - ); + assert_de_tokens(&&b"borrowed"[..], &[Token::BorrowedBytes(b"borrowed")]); } #[test] fn test_borrowed_bytes_from_bytebuf() { assert_de_tokens_error::<&[u8]>( - &[ - Token::ByteBuf(b"borrowed"), - ], - Error::Message("invalid type: byte array, expected a borrowed byte array".to_owned()), + &[Token::ByteBuf(b"borrowed")], + Error::Message("invalid type: byte array, expected a borrowed byte array".to_owned(),), ); } #[test] fn test_borrowed_bytes_from_bytes() { assert_de_tokens_error::<&[u8]>( - &[ - Token::Bytes(b"borrowed"), - ], - Error::Message("invalid type: byte array, expected a borrowed byte array".to_owned()), + &[Token::Bytes(b"borrowed")], + Error::Message("invalid type: byte array, expected a borrowed byte array".to_owned(),), ); } @@ -93,7 +65,7 @@ fn test_tuple() { Token::BorrowedStr("str"), Token::BorrowedBytes(b"bytes"), Token::TupleEnd, - ] + ], ); } @@ -106,7 +78,10 @@ fn test_struct() { } assert_de_tokens( - &Borrowing { bs: "str", bb: b"bytes" }, + &Borrowing { + bs: "str", + bb: b"bytes", + }, &[ Token::Struct("Borrowing", 2), @@ -117,7 +92,7 @@ fn test_struct() { Token::BorrowedBytes(b"bytes"), Token::StructEnd, - ] + ], ); } @@ -170,7 +145,8 @@ fn test_lifetimes() { // Tests that `'de: 'a` is not required by the Deserialize impl. fn _cows_lifetimes<'de: 'b, 'a, 'b, D>(deserializer: D) -> Cows<'a, 'b> - where D: Deserializer<'de> + where + D: Deserializer<'de>, { Deserialize::deserialize(deserializer).unwrap() } @@ -183,7 +159,8 @@ fn test_lifetimes() { // Tests that `'de: 'a` is not required by the Deserialize impl. fn _wrap_lifetimes<'de: 'b, 'a, 'b, D>(deserializer: D) -> Wrap<'a, 'b> - where D: Deserializer<'de> + where + D: Deserializer<'de>, { Deserialize::deserialize(deserializer).unwrap() } diff --git a/test_suite/tests/test_de.rs b/test_suite/tests/test_de.rs index 43fa0bf3..dc2662fb 100644 --- a/test_suite/tests/test_de.rs +++ b/test_suite/tests/test_de.rs @@ -20,12 +20,7 @@ extern crate fnv; use self::fnv::FnvHasher; extern crate serde_test; -use self::serde_test::{ - Error, - Token, - assert_de_tokens, - assert_de_tokens_error, -}; +use self::serde_test::{Error, Token, assert_de_tokens, assert_de_tokens_error}; #[macro_use] mod macros; @@ -146,23 +141,21 @@ fn assert_de_tokens_ignore(ignorable_tokens: &[Token]) { a: i32, } - let expected = IgnoreBase{a: 1}; + let expected = IgnoreBase { a: 1 }; // Embed the tokens to be ignored in the normal token // stream for an IgnoreBase type - let concated_tokens : Vec = vec![ - Token::Map(Some(2)), - Token::Str("a"), - Token::I32(1), + let concated_tokens: Vec = vec![ + Token::Map(Some(2)), + Token::Str("a"), + Token::I32(1), - Token::Str("ignored") - ] - .into_iter() - .chain(ignorable_tokens.to_vec().into_iter()) - .chain(vec![ - Token::MapEnd, - ].into_iter()) - .collect(); + Token::Str("ignored"), + ] + .into_iter() + .chain(ignorable_tokens.to_vec().into_iter()) + .chain(vec![Token::MapEnd].into_iter()) + .collect(); let mut de = serde_test::Deserializer::new(&concated_tokens); let v: Result = Deserialize::deserialize(&mut de); @@ -735,9 +728,9 @@ fn test_osstring() { Token::Enum("OsString"), Token::Str("Unix"), Token::Seq(Some(2)), - Token::U8(1), - Token::U8(2), - Token::U8(3), + Token::U8(1), + Token::U8(2), + Token::U8(3), Token::SeqEnd, ]; @@ -755,9 +748,9 @@ fn test_osstring() { Token::Enum("OsString"), Token::Str("Windows"), Token::Seq(Some(2)), - Token::U16(1), - Token::U16(2), - Token::U16(3), + Token::U16(1), + Token::U16(2), + Token::U16(3), Token::SeqEnd, ]; @@ -768,8 +761,10 @@ fn test_osstring() { #[cfg(feature = "unstable")] #[test] fn test_cstr() { - assert_de_tokens::>(&CString::new("abc").unwrap().into_boxed_c_str(), - &[Token::Bytes(b"abc")]); + assert_de_tokens::>( + &CString::new("abc").unwrap().into_boxed_c_str(), + &[Token::Bytes(b"abc")], + ); } #[cfg(feature = "unstable")] @@ -785,10 +780,8 @@ fn test_net_ipaddr() { #[test] fn test_cstr_internal_null() { assert_de_tokens_error::>( - &[ - Token::Bytes(b"a\0c"), - ], - Error::Message("nul byte found in provided data at position: 1".into()) + &[Token::Bytes(b"a\0c")], + Error::Message("nul byte found in provided data at position: 1".into()), ); } @@ -796,10 +789,8 @@ fn test_cstr_internal_null() { #[test] fn test_cstr_internal_null_end() { assert_de_tokens_error::>( - &[ - Token::Bytes(b"ac\0"), - ], - Error::Message("nul byte found in provided data at position: 2".into()) + &[Token::Bytes(b"ac\0")], + Error::Message("nul byte found in provided data at position: 2".into()), ); } diff --git a/test_suite/tests/test_gen.rs b/test_suite/tests/test_gen.rs index 10b952e4..b4cddfa5 100644 --- a/test_suite/tests/test_gen.rs +++ b/test_suite/tests/test_gen.rs @@ -82,20 +82,28 @@ fn test_gen() { Unit, Newtype( #[serde(serialize_with="ser_x", deserialize_with="de_x")] - X), + X + ), Tuple( T, #[serde(serialize_with="ser_x", deserialize_with="de_x")] - X), + X + ), Struct { t: T, #[serde(serialize_with="ser_x", deserialize_with="de_x")] - x: X }, + x: X, + }, } assert::>(); #[derive(Serialize)] - struct MultipleRef<'a, 'b, 'c, T> where T: 'c, 'c: 'b, 'b: 'a { + struct MultipleRef<'a, 'b, 'c, T> + where + T: 'c, + 'c: 'b, + 'b: 'a, + { t: T, rrrt: &'a &'b &'c T, } @@ -112,7 +120,7 @@ fn test_gen() { struct Tuple( T, #[serde(serialize_with="ser_x", deserialize_with="de_x")] - X, + X ); assert::>(); @@ -122,9 +130,7 @@ fn test_gen() { left: Box>, right: Box>, }, - Leaf { - data: D, - }, + Leaf { data: D }, } assert::>(); @@ -218,7 +224,7 @@ fn test_gen() { #[cfg(feature = "unstable")] #[derive(Serialize, Deserialize)] struct NonAsciiIdents { - σ: f64 + σ: f64, } #[derive(Serialize, Deserialize)] @@ -251,11 +257,17 @@ fn test_gen() { struct EmptyTupleDenyUnknown(); #[derive(Serialize, Deserialize)] - struct TupleSkipAll(#[serde(skip_deserializing)] u8); + struct TupleSkipAll( + #[serde(skip_deserializing)] + u8 + ); #[derive(Serialize, Deserialize)] #[serde(deny_unknown_fields)] - struct TupleSkipAllDenyUnknown(#[serde(skip_deserializing)] u8); + struct TupleSkipAllDenyUnknown( + #[serde(skip_deserializing)] + u8 + ); #[derive(Serialize, Deserialize)] enum EmptyEnum {} @@ -280,7 +292,10 @@ fn test_gen() { #[serde(skip_deserializing)] f: u8, }, - TupleSkip(#[serde(skip_deserializing)] u8), + TupleSkip( + #[serde(skip_deserializing)] + u8 + ), } #[cfg(feature = "unstable")] @@ -293,7 +308,10 @@ fn test_gen() { #[serde(skip_deserializing)] f: u8, }, - TupleSkip(#[serde(skip_deserializing)] u8), + TupleSkip( + #[serde(skip_deserializing)] + u8 + ), } #[derive(Serialize, Deserialize)] diff --git a/test_suite/tests/test_macros.rs b/test_suite/tests/test_macros.rs index 344b5832..e16a54d5 100644 --- a/test_suite/tests/test_macros.rs +++ b/test_suite/tests/test_macros.rs @@ -2,14 +2,8 @@ extern crate serde_derive; extern crate serde_test; -use self::serde_test::{ - Error, - Token, - assert_tokens, - assert_ser_tokens, - assert_de_tokens, - assert_de_tokens_error, -}; +use self::serde_test::{Error, Token, assert_tokens, assert_ser_tokens, assert_de_tokens, + assert_de_tokens_error}; use std::collections::BTreeMap; use std::marker::PhantomData; @@ -45,67 +39,30 @@ struct DeNamedMap { } #[derive(Debug, PartialEq, Serialize)] -enum SerEnum<'a, B: 'a, C: 'a, D> where D: 'a { +enum SerEnum<'a, B: 'a, C: 'a, D> +where + D: 'a, +{ Unit, - Seq( - i8, - B, - &'a C, - &'a mut D, - ), - Map { - a: i8, - b: B, - c: &'a C, - d: &'a mut D, - }, + Seq(i8, B, &'a C, &'a mut D), + Map { a: i8, b: B, c: &'a C, d: &'a mut D }, // Make sure we can support more than one variant. _Unit2, - _Seq2( - i8, - B, - &'a C, - &'a mut D, - ), - _Map2 { - a: i8, - b: B, - c: &'a C, - d: &'a mut D, - }, + _Seq2(i8, B, &'a C, &'a mut D), + _Map2 { a: i8, b: B, c: &'a C, d: &'a mut D }, } #[derive(Debug, PartialEq, Serialize, Deserialize)] enum DeEnum { Unit, - Seq( - i8, - B, - C, - D, - ), - Map { - a: i8, - b: B, - c: C, - d: D, - }, + Seq(i8, B, C, D), + Map { a: i8, b: B, c: C, d: D }, // Make sure we can support more than one variant. _Unit2, - _Seq2( - i8, - B, - C, - D, - ), - _Map2 { - a: i8, - b: B, - c: C, - d: D, - }, + _Seq2(i8, B, C, D), + _Map2 { a: i8, b: B, c: C, d: D }, } #[derive(Serialize)] @@ -144,16 +101,13 @@ impl AssociatedType for i32 { } #[derive(Debug, PartialEq, Serialize, Deserialize)] -struct DefaultTyParam = i32> { - phantom: PhantomData +struct DefaultTyParam = i32> { + phantom: PhantomData, } #[test] fn test_named_unit() { - assert_tokens( - &NamedUnit, - &[Token::UnitStruct("NamedUnit")] - ); + assert_tokens(&NamedUnit, &[Token::UnitStruct("NamedUnit")]); } #[test] @@ -183,7 +137,7 @@ fn test_de_named_tuple() { Token::I32(6), Token::I32(7), Token::SeqEnd, - ] + ], ); assert_de_tokens( @@ -194,7 +148,7 @@ fn test_de_named_tuple() { Token::I32(6), Token::I32(7), Token::TupleStructEnd, - ] + ], ); } @@ -206,10 +160,10 @@ fn test_ser_named_map() { assert_ser_tokens( &SerNamedMap { - a: &a, - b: &mut b, - c: c, - }, + a: &a, + b: &mut b, + c: c, + }, &[ Token::Struct("SerNamedMap", 3), @@ -223,18 +177,14 @@ fn test_ser_named_map() { Token::I32(7), Token::StructEnd, - ] + ], ); } #[test] fn test_de_named_map() { assert_de_tokens( - &DeNamedMap { - a: 5, - b: 6, - c: 7, - }, + &DeNamedMap { a: 5, b: 6, c: 7 }, &[ Token::Struct("DeNamedMap", 3), @@ -248,7 +198,7 @@ fn test_de_named_map() { Token::I32(7), Token::StructEnd, - ] + ], ); } @@ -256,9 +206,7 @@ fn test_de_named_map() { fn test_ser_enum_unit() { assert_ser_tokens( &SerEnum::Unit::, - &[ - Token::UnitVariant("SerEnum", "Unit"), - ] + &[Token::UnitVariant("SerEnum", "Unit")], ); } @@ -270,12 +218,7 @@ fn test_ser_enum_seq() { let mut d = 4; assert_ser_tokens( - &SerEnum::Seq( - a, - b, - &c, - &mut d, - ), + &SerEnum::Seq(a, b, &c, &mut d), &[ Token::TupleVariant("SerEnum", "Seq", 4), Token::I8(1), @@ -296,11 +239,11 @@ fn test_ser_enum_map() { assert_ser_tokens( &SerEnum::Map { - a: a, - b: b, - c: &c, - d: &mut d, - }, + a: a, + b: b, + c: &c, + d: &mut d, + }, &[ Token::StructVariant("SerEnum", "Map", 4), @@ -325,9 +268,7 @@ fn test_ser_enum_map() { fn test_de_enum_unit() { assert_tokens( &DeEnum::Unit::, - &[ - Token::UnitVariant("DeEnum", "Unit"), - ], + &[Token::UnitVariant("DeEnum", "Unit")], ); } @@ -339,12 +280,7 @@ fn test_de_enum_seq() { let d = 4; assert_tokens( - &DeEnum::Seq( - a, - b, - c, - d, - ), + &DeEnum::Seq(a, b, c, d), &[ Token::TupleVariant("DeEnum", "Seq", 4), Token::I8(1), @@ -365,11 +301,11 @@ fn test_de_enum_map() { assert_tokens( &DeEnum::Map { - a: a, - b: b, - c: c, - d: d, - }, + a: a, + b: b, + c: c, + d: d, + }, &[ Token::StructVariant("DeEnum", "Map", 4), @@ -399,7 +335,7 @@ fn test_lifetimes() { &[ Token::NewtypeVariant("Lifetimes", "LifetimeSeq"), Token::I32(5), - ] + ], ); assert_ser_tokens( @@ -407,7 +343,7 @@ fn test_lifetimes() { &[ Token::NewtypeVariant("Lifetimes", "NoLifetimeSeq"), Token::I32(5), - ] + ], ); assert_ser_tokens( @@ -419,7 +355,7 @@ fn test_lifetimes() { Token::I32(5), Token::StructVariantEnd, - ] + ], ); assert_ser_tokens( @@ -431,7 +367,7 @@ fn test_lifetimes() { Token::I32(5), Token::StructVariantEnd, - ] + ], ); } @@ -446,7 +382,7 @@ fn test_generic_struct() { Token::U32(5), Token::StructEnd, - ] + ], ); } @@ -454,10 +390,7 @@ fn test_generic_struct() { fn test_generic_newtype_struct() { assert_tokens( &GenericNewTypeStruct(5u32), - &[ - Token::NewtypeStruct("GenericNewTypeStruct"), - Token::U32(5), - ] + &[Token::NewtypeStruct("GenericNewTypeStruct"), Token::U32(5)], ); } @@ -470,7 +403,7 @@ fn test_generic_tuple_struct() { Token::U32(5), Token::U32(6), Token::TupleStructEnd, - ] + ], ); } @@ -478,9 +411,7 @@ fn test_generic_tuple_struct() { fn test_generic_enum_unit() { assert_tokens( &GenericEnum::Unit::, - &[ - Token::UnitVariant("GenericEnum", "Unit"), - ] + &[Token::UnitVariant("GenericEnum", "Unit")], ); } @@ -491,7 +422,7 @@ fn test_generic_enum_newtype() { &[ Token::NewtypeVariant("GenericEnum", "NewType"), Token::U32(5), - ] + ], ); } @@ -504,7 +435,7 @@ fn test_generic_enum_seq() { Token::U32(5), Token::U32(6), Token::TupleVariantEnd, - ] + ], ); } @@ -522,7 +453,7 @@ fn test_generic_enum_map() { Token::U32(6), Token::StructVariantEnd, - ] + ], ); } @@ -537,7 +468,7 @@ fn test_default_ty_param() { Token::UnitStruct("PhantomData"), Token::StructEnd, - ] + ], ); } @@ -549,7 +480,10 @@ fn test_enum_state_field() { } assert_tokens( - &SomeEnum::Key { key: 'a', state: true }, + &SomeEnum::Key { + key: 'a', + state: true, + }, &[ Token::StructVariant("SomeEnum", "Key", 2), @@ -560,7 +494,7 @@ fn test_enum_state_field() { Token::Bool(true), Token::StructVariantEnd, - ] + ], ); } @@ -569,12 +503,8 @@ fn test_untagged_enum() { #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(untagged)] enum Untagged { - A { - a: u8, - }, - B { - b: u8, - }, + A { a: u8 }, + B { b: u8 }, C, D(u8), E(String), @@ -590,7 +520,7 @@ fn test_untagged_enum() { Token::U8(1), Token::StructEnd, - ] + ], ); assert_tokens( @@ -602,53 +532,27 @@ fn test_untagged_enum() { Token::U8(2), Token::StructEnd, - ] + ], ); - assert_tokens( - &Untagged::C, - &[ - Token::Unit, - ] - ); + assert_tokens(&Untagged::C, &[Token::Unit]); - assert_tokens( - &Untagged::D(4), - &[ - Token::U8(4), - ] - ); - assert_tokens( - &Untagged::E("e".to_owned()), - &[ - Token::Str("e"), - ] - ); + assert_tokens(&Untagged::D(4), &[Token::U8(4)]); + assert_tokens(&Untagged::E("e".to_owned()), &[Token::Str("e")]); assert_tokens( &Untagged::F(1, 2), - &[ - Token::Tuple(2), - Token::U8(1), - Token::U8(2), - Token::TupleEnd, - ] + &[Token::Tuple(2), Token::U8(1), Token::U8(2), Token::TupleEnd], ); assert_de_tokens_error::( - &[ - Token::None, - ], - Error::Message("data did not match any variant of untagged enum Untagged".to_owned()), + &[Token::None], + Error::Message("data did not match any variant of untagged enum Untagged".to_owned(),), ); assert_de_tokens_error::( - &[ - Token::Tuple(1), - Token::U8(1), - Token::TupleEnd, - ], - Error::Message("data did not match any variant of untagged enum Untagged".to_owned()), + &[Token::Tuple(1), Token::U8(1), Token::TupleEnd], + Error::Message("data did not match any variant of untagged enum Untagged".to_owned(),), ); assert_de_tokens_error::( @@ -659,7 +563,7 @@ fn test_untagged_enum() { Token::U8(3), Token::TupleEnd, ], - Error::Message("data did not match any variant of untagged enum Untagged".to_owned()), + Error::Message("data did not match any variant of untagged enum Untagged".to_owned(),), ); } @@ -676,12 +580,8 @@ fn test_internally_tagged_enum() { #[derive(Debug, PartialEq, Serialize, Deserialize)] #[serde(tag = "type")] enum InternallyTagged { - A { - a: u8, - }, - B { - b: u8, - }, + A { a: u8 }, + B { b: u8 }, C, D(BTreeMap), E(Newtype), @@ -700,7 +600,7 @@ fn test_internally_tagged_enum() { Token::U8(1), Token::StructEnd, - ] + ], ); assert_tokens( @@ -715,7 +615,7 @@ fn test_internally_tagged_enum() { Token::U8(2), Token::StructEnd, - ] + ], ); assert_tokens( @@ -727,7 +627,7 @@ fn test_internally_tagged_enum() { Token::Str("C"), Token::StructEnd, - ] + ], ); assert_tokens( @@ -739,7 +639,7 @@ fn test_internally_tagged_enum() { Token::Str("D"), Token::MapEnd, - ] + ], ); assert_tokens( @@ -751,7 +651,7 @@ fn test_internally_tagged_enum() { Token::Str("E"), Token::MapEnd, - ] + ], ); assert_tokens( @@ -766,14 +666,11 @@ fn test_internally_tagged_enum() { Token::U8(6), Token::StructEnd, - ] + ], ); assert_de_tokens_error::( - &[ - Token::Map(Some(0)), - Token::MapEnd, - ], + &[Token::Map(Some(0)), Token::MapEnd], Error::Message("missing field `type`".to_owned()), ); @@ -786,7 +683,7 @@ fn test_internally_tagged_enum() { Token::MapEnd, ], - Error::Message("unknown variant `Z`, expected one of `A`, `B`, `C`, `D`, `E`, `F`".to_owned()), + Error::Message("unknown variant `Z`, expected one of `A`, `B`, `C`, `D`, `E`, `F`".to_owned(),), ); } @@ -811,7 +708,7 @@ fn test_adjacently_tagged_enum() { Token::Str("Unit"), Token::StructEnd, - ] + ], ); // unit with tag first @@ -827,7 +724,7 @@ fn test_adjacently_tagged_enum() { Token::Unit, Token::StructEnd, - ] + ], ); // unit with content first @@ -843,7 +740,7 @@ fn test_adjacently_tagged_enum() { Token::Str("Unit"), Token::StructEnd, - ] + ], ); // newtype with tag first @@ -859,7 +756,7 @@ fn test_adjacently_tagged_enum() { Token::U8(1), Token::StructEnd, - ] + ], ); // newtype with content first @@ -875,7 +772,7 @@ fn test_adjacently_tagged_enum() { Token::Str("Newtype"), Token::StructEnd, - ] + ], ); // tuple with tag first @@ -894,7 +791,7 @@ fn test_adjacently_tagged_enum() { Token::TupleEnd, Token::StructEnd, - ] + ], ); // tuple with content first @@ -913,7 +810,7 @@ fn test_adjacently_tagged_enum() { Token::Str("Tuple"), Token::StructEnd, - ] + ], ); // struct with tag first @@ -932,7 +829,7 @@ fn test_adjacently_tagged_enum() { Token::StructEnd, Token::StructEnd, - ] + ], ); // struct with content first @@ -951,7 +848,7 @@ fn test_adjacently_tagged_enum() { Token::Str("Struct"), Token::StructEnd, - ] + ], ); } @@ -983,7 +880,7 @@ fn test_enum_in_internally_tagged_enum() { Token::Unit, Token::MapEnd, - ] + ], ); assert_tokens( @@ -998,7 +895,7 @@ fn test_enum_in_internally_tagged_enum() { Token::U8(1), Token::MapEnd, - ] + ], ); assert_tokens( @@ -1016,7 +913,7 @@ fn test_enum_in_internally_tagged_enum() { Token::TupleStructEnd, Token::MapEnd, - ] + ], ); assert_tokens( @@ -1034,7 +931,7 @@ fn test_enum_in_internally_tagged_enum() { Token::StructEnd, Token::MapEnd, - ] + ], ); } @@ -1056,17 +953,12 @@ fn test_enum_in_untagged_enum() { assert_tokens( &Outer::Inner(Inner::Unit), - &[ - Token::UnitVariant("Inner", "Unit"), - ] + &[Token::UnitVariant("Inner", "Unit")], ); assert_tokens( &Outer::Inner(Inner::Newtype(1)), - &[ - Token::NewtypeVariant("Inner", "Newtype"), - Token::U8(1), - ] + &[Token::NewtypeVariant("Inner", "Newtype"), Token::U8(1)], ); assert_tokens( @@ -1076,7 +968,7 @@ fn test_enum_in_untagged_enum() { Token::U8(1), Token::U8(1), Token::TupleVariantEnd, - ] + ], ); assert_tokens( @@ -1088,7 +980,7 @@ fn test_enum_in_untagged_enum() { Token::U8(1), Token::StructVariantEnd, - ] + ], ); } @@ -1122,7 +1014,10 @@ fn test_rename_all() { } assert_tokens( - &E::Serialize { serialize: true, serialize_seq: true }, + &E::Serialize { + serialize: true, + serialize_seq: true, + }, &[ Token::StructVariant("E", "serialize", 2), Token::Str("serialize"), @@ -1130,11 +1025,14 @@ fn test_rename_all() { Token::Str("serializeSeq"), Token::Bool(true), Token::StructVariantEnd, - ] + ], ); assert_tokens( - &E::SerializeSeq { serialize: true, serialize_seq: true }, + &E::SerializeSeq { + serialize: true, + serialize_seq: true, + }, &[ Token::StructVariant("E", "serialize_seq", 2), Token::Str("serialize"), @@ -1142,11 +1040,14 @@ fn test_rename_all() { Token::Str("serialize-seq"), Token::Bool(true), Token::StructVariantEnd, - ] + ], ); assert_tokens( - &E::SerializeMap { serialize: true, serialize_seq: true }, + &E::SerializeMap { + serialize: true, + serialize_seq: true, + }, &[ Token::StructVariant("E", "serialize_map", 2), Token::Str("SERIALIZE"), @@ -1154,11 +1055,14 @@ fn test_rename_all() { Token::Str("SERIALIZE_SEQ"), Token::Bool(true), Token::StructVariantEnd, - ] + ], ); assert_tokens( - &S { serialize: true, serialize_seq: true }, + &S { + serialize: true, + serialize_seq: true, + }, &[ Token::Struct("S", 2), Token::Str("Serialize"), @@ -1166,6 +1070,6 @@ fn test_rename_all() { Token::Str("SerializeSeq"), Token::Bool(true), Token::StructEnd, - ] + ], ); } diff --git a/test_suite/tests/test_remote.rs b/test_suite/tests/test_remote.rs index 4f21a09a..3e3217c8 100644 --- a/test_suite/tests/test_remote.rs +++ b/test_suite/tests/test_remote.rs @@ -23,7 +23,7 @@ mod remote { b: Unit, } - pub struct StructPub { + pub struct StructPub { pub a: u8, pub b: Unit, } @@ -113,7 +113,10 @@ struct UnitDef; #[derive(Serialize, Deserialize)] #[serde(remote = "remote::PrimitivePriv")] -struct PrimitivePrivDef(#[serde(getter = "remote::PrimitivePriv::get")] u8); +struct PrimitivePrivDef( + #[serde(getter = "remote::PrimitivePriv::get")] + u8 +); #[derive(Serialize, Deserialize)] #[serde(remote = "remote::PrimitivePub")] @@ -121,21 +124,34 @@ struct PrimitivePubDef(u8); #[derive(Serialize, Deserialize)] #[serde(remote = "remote::NewtypePriv")] -struct NewtypePrivDef(#[serde(getter = "remote::NewtypePriv::get", with = "UnitDef")] remote::Unit); +struct NewtypePrivDef( + #[serde(getter = "remote::NewtypePriv::get", with = "UnitDef")] + remote::Unit +); #[derive(Serialize, Deserialize)] #[serde(remote = "remote::NewtypePub")] -struct NewtypePubDef(#[serde(with = "UnitDef")] remote::Unit); +struct NewtypePubDef( + #[serde(with = "UnitDef")] + remote::Unit +); #[derive(Serialize, Deserialize)] #[serde(remote = "remote::TuplePriv")] struct TuplePrivDef( - #[serde(getter = "remote::TuplePriv::first")] u8, - #[serde(getter = "remote::TuplePriv::second", with = "UnitDef")] remote::Unit); + #[serde(getter = "remote::TuplePriv::first")] + u8, + #[serde(getter = "remote::TuplePriv::second", with = "UnitDef")] + remote::Unit +); #[derive(Serialize, Deserialize)] #[serde(remote = "remote::TuplePub")] -struct TuplePubDef(u8, #[serde(with = "UnitDef")] remote::Unit); +struct TuplePubDef( + u8, + #[serde(with = "UnitDef")] + remote::Unit +); #[derive(Serialize, Deserialize)] #[serde(remote = "remote::StructPriv")] diff --git a/test_suite/tests/test_ser.rs b/test_suite/tests/test_ser.rs index a01af687..46a7c3fa 100644 --- a/test_suite/tests/test_ser.rs +++ b/test_suite/tests/test_ser.rs @@ -13,12 +13,7 @@ use std::str; extern crate serde; extern crate serde_test; -use self::serde_test::{ - Error, - Token, - assert_ser_tokens, - assert_ser_tokens_error, -}; +use self::serde_test::{Error, Token, assert_ser_tokens, assert_ser_tokens_error}; extern crate fnv; use self::fnv::FnvHasher; @@ -372,13 +367,12 @@ fn test_net_ipaddr() { #[test] #[cfg(unix)] fn test_cannot_serialize_paths() { - let path = unsafe { - str::from_utf8_unchecked(b"Hello \xF0\x90\x80World") - }; + let path = unsafe { str::from_utf8_unchecked(b"Hello \xF0\x90\x80World") }; assert_ser_tokens_error( &Path::new(path), &[], - Error::Message("path contains invalid UTF-8 characters".to_owned())); + Error::Message("path contains invalid UTF-8 characters".to_owned()), + ); let mut path_buf = PathBuf::new(); path_buf.push(path); @@ -386,7 +380,8 @@ fn test_cannot_serialize_paths() { assert_ser_tokens_error( &path_buf, &[], - Error::Message("path contains invalid UTF-8 characters".to_owned())); + Error::Message("path contains invalid UTF-8 characters".to_owned()), + ); } #[test] @@ -394,17 +389,21 @@ fn test_enum_skipped() { assert_ser_tokens_error( &Enum::SkippedUnit, &[], - Error::Message("the enum variant Enum::SkippedUnit cannot be serialized".to_owned())); + Error::Message("the enum variant Enum::SkippedUnit cannot be serialized".to_owned(),), + ); assert_ser_tokens_error( &Enum::SkippedOne(42), &[], - Error::Message("the enum variant Enum::SkippedOne cannot be serialized".to_owned())); + Error::Message("the enum variant Enum::SkippedOne cannot be serialized".to_owned(),), + ); assert_ser_tokens_error( &Enum::SkippedSeq(1, 2), &[], - Error::Message("the enum variant Enum::SkippedSeq cannot be serialized".to_owned())); + Error::Message("the enum variant Enum::SkippedSeq cannot be serialized".to_owned(),), + ); assert_ser_tokens_error( &Enum::SkippedMap { _a: 1, _b: 2 }, &[], - Error::Message("the enum variant Enum::SkippedMap cannot be serialized".to_owned())); + Error::Message("the enum variant Enum::SkippedMap cannot be serialized".to_owned(),), + ); } From 2887c379de507d68d510efd670fa9dc93b4c9165 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 12:42:36 -0700 Subject: [PATCH 104/177] Hyperlink the Impossible documentation --- serde/src/ser/impossible.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/serde/src/ser/impossible.rs b/serde/src/ser/impossible.rs index 867963a2..975c4af1 100644 --- a/serde/src/ser/impossible.rs +++ b/serde/src/ser/impossible.rs @@ -9,9 +9,9 @@ use ser::{self, Serialize, SerializeSeq, SerializeTuple, SerializeTupleStruct, /// serializing one of the compound types. /// /// This type cannot be instantiated, but implements every one of the traits -/// corresponding to the `Serializer` compound types: `SerializeSeq`, -/// `SerializeTuple`, `SerializeTupleStruct`, `SerializeTupleVariant`, -/// `SerializeMap`, `SerializeStruct`, and `SerializeStructVariant`. +/// corresponding to the [`Serializer`] compound types: [`SerializeSeq`], +/// [`SerializeTuple`], [`SerializeTupleStruct`], [`SerializeTupleVariant`], +/// [`SerializeMap`], [`SerializeStruct`], and [`SerializeStructVariant`]. /// /// ```rust /// # #[macro_use] @@ -52,6 +52,15 @@ use ser::{self, Serialize, SerializeSeq, SerializeTuple, SerializeTupleStruct, /// # /// # fn main() {} /// ``` +/// +/// [`Serializer`]: trait.Serializer.html +/// [`SerializeSeq`]: trait.SerializeSeq.html +/// [`SerializeTuple`]: trait.SerializeTuple.html +/// [`SerializeTupleStruct`]: trait.SerializeTupleStruct.html +/// [`SerializeTupleVariant`]: trait.SerializeTupleVariant.html +/// [`SerializeMap`]: trait.SerializeMap.html +/// [`SerializeStruct`]: trait.SerializeStruct.html +/// [`SerializeStructVariant`]: trait.SerializeStructVariant.html pub struct Impossible { void: Void, _marker: PhantomData<(Ok, E)>, From c4e31bd968a19cbaeb53761f13840d4b7b77234f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 12:43:24 -0700 Subject: [PATCH 105/177] Match the associated types from the Serializer trait --- serde/src/ser/impossible.rs | 76 ++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/serde/src/ser/impossible.rs b/serde/src/ser/impossible.rs index 975c4af1..c90c98f5 100644 --- a/serde/src/ser/impossible.rs +++ b/serde/src/ser/impossible.rs @@ -61,133 +61,133 @@ use ser::{self, Serialize, SerializeSeq, SerializeTuple, SerializeTupleStruct, /// [`SerializeMap`]: trait.SerializeMap.html /// [`SerializeStruct`]: trait.SerializeStruct.html /// [`SerializeStructVariant`]: trait.SerializeStructVariant.html -pub struct Impossible { +pub struct Impossible { void: Void, - _marker: PhantomData<(Ok, E)>, + _marker: PhantomData<(Ok, Error)>, } enum Void {} -impl SerializeSeq for Impossible +impl SerializeSeq for Impossible where - E: ser::Error, + Error: ser::Error, { type Ok = Ok; - type Error = E; + type Error = Error; - fn serialize_element(&mut self, _value: &T) -> Result<(), E> { + fn serialize_element(&mut self, _value: &T) -> Result<(), Error> { match self.void {} } - fn end(self) -> Result { + fn end(self) -> Result { match self.void {} } } -impl SerializeTuple for Impossible +impl SerializeTuple for Impossible where - E: ser::Error, + Error: ser::Error, { type Ok = Ok; - type Error = E; + type Error = Error; - fn serialize_element(&mut self, _value: &T) -> Result<(), E> { + fn serialize_element(&mut self, _value: &T) -> Result<(), Error> { match self.void {} } - fn end(self) -> Result { + fn end(self) -> Result { match self.void {} } } -impl SerializeTupleStruct for Impossible +impl SerializeTupleStruct for Impossible where - E: ser::Error, + Error: ser::Error, { type Ok = Ok; - type Error = E; + type Error = Error; - fn serialize_field(&mut self, _value: &T) -> Result<(), E> { + fn serialize_field(&mut self, _value: &T) -> Result<(), Error> { match self.void {} } - fn end(self) -> Result { + fn end(self) -> Result { match self.void {} } } -impl SerializeTupleVariant for Impossible +impl SerializeTupleVariant for Impossible where - E: ser::Error, + Error: ser::Error, { type Ok = Ok; - type Error = E; + type Error = Error; - fn serialize_field(&mut self, _value: &T) -> Result<(), E> { + fn serialize_field(&mut self, _value: &T) -> Result<(), Error> { match self.void {} } - fn end(self) -> Result { + fn end(self) -> Result { match self.void {} } } -impl SerializeMap for Impossible +impl SerializeMap for Impossible where - E: ser::Error, + Error: ser::Error, { type Ok = Ok; - type Error = E; + type Error = Error; - fn serialize_key(&mut self, _key: &T) -> Result<(), E> { + fn serialize_key(&mut self, _key: &T) -> Result<(), Error> { match self.void {} } - fn serialize_value(&mut self, _value: &T) -> Result<(), E> { + fn serialize_value(&mut self, _value: &T) -> Result<(), Error> { match self.void {} } - fn end(self) -> Result { + fn end(self) -> Result { match self.void {} } } -impl SerializeStruct for Impossible +impl SerializeStruct for Impossible where - E: ser::Error, + Error: ser::Error, { type Ok = Ok; - type Error = E; + type Error = Error; fn serialize_field( &mut self, _key: &'static str, _value: &T, - ) -> Result<(), E> { + ) -> Result<(), Error> { match self.void {} } - fn end(self) -> Result { + fn end(self) -> Result { match self.void {} } } -impl SerializeStructVariant for Impossible +impl SerializeStructVariant for Impossible where - E: ser::Error, + Error: ser::Error, { type Ok = Ok; - type Error = E; + type Error = Error; fn serialize_field( &mut self, _key: &'static str, _value: &T, - ) -> Result<(), E> { + ) -> Result<(), Error> { match self.void {} } - fn end(self) -> Result { + fn end(self) -> Result { match self.void {} } } From 5bb6de80b252e03dd3ddaa07f04a42e97d88eec2 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 12:45:42 -0700 Subject: [PATCH 106/177] Use better names for the sake of the documentation --- serde/src/ser/impossible.rs | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/serde/src/ser/impossible.rs b/serde/src/ser/impossible.rs index c90c98f5..84fe1d51 100644 --- a/serde/src/ser/impossible.rs +++ b/serde/src/ser/impossible.rs @@ -63,7 +63,8 @@ use ser::{self, Serialize, SerializeSeq, SerializeTuple, SerializeTupleStruct, /// [`SerializeStructVariant`]: trait.SerializeStructVariant.html pub struct Impossible { void: Void, - _marker: PhantomData<(Ok, Error)>, + ok: PhantomData, + error: PhantomData, } enum Void {} @@ -75,7 +76,8 @@ where type Ok = Ok; type Error = Error; - fn serialize_element(&mut self, _value: &T) -> Result<(), Error> { + fn serialize_element(&mut self, value: &T) -> Result<(), Error> { + let _ = value; match self.void {} } @@ -91,7 +93,8 @@ where type Ok = Ok; type Error = Error; - fn serialize_element(&mut self, _value: &T) -> Result<(), Error> { + fn serialize_element(&mut self, value: &T) -> Result<(), Error> { + let _ = value; match self.void {} } @@ -107,7 +110,8 @@ where type Ok = Ok; type Error = Error; - fn serialize_field(&mut self, _value: &T) -> Result<(), Error> { + fn serialize_field(&mut self, value: &T) -> Result<(), Error> { + let _ = value; match self.void {} } @@ -123,7 +127,8 @@ where type Ok = Ok; type Error = Error; - fn serialize_field(&mut self, _value: &T) -> Result<(), Error> { + fn serialize_field(&mut self, value: &T) -> Result<(), Error> { + let _ = value; match self.void {} } @@ -139,11 +144,13 @@ where type Ok = Ok; type Error = Error; - fn serialize_key(&mut self, _key: &T) -> Result<(), Error> { + fn serialize_key(&mut self, key: &T) -> Result<(), Error> { + let _ = key; match self.void {} } - fn serialize_value(&mut self, _value: &T) -> Result<(), Error> { + fn serialize_value(&mut self, value: &T) -> Result<(), Error> { + let _ = value; match self.void {} } @@ -161,9 +168,11 @@ where fn serialize_field( &mut self, - _key: &'static str, - _value: &T, + key: &'static str, + value: &T, ) -> Result<(), Error> { + let _ = key; + let _ = value; match self.void {} } @@ -181,9 +190,11 @@ where fn serialize_field( &mut self, - _key: &'static str, - _value: &T, + key: &'static str, + value: &T, ) -> Result<(), Error> { + let _ = key; + let _ = value; match self.void {} } From c5854f19f70b6534bcadb17f104f727f48fc7361 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 12:47:46 -0700 Subject: [PATCH 107/177] Prefer where clauses --- serde/src/de/impls.rs | 30 +++++++++--- serde/src/de/mod.rs | 4 +- serde/src/de/value.rs | 10 +++- serde/src/private/ser.rs | 94 +++++++++++++++++++++++++------------ serde/src/ser/impls.rs | 5 +- serde/src/ser/impossible.rs | 48 ++++++++++++------- serde/src/ser/mod.rs | 79 ++++++++++++++++++++++--------- 7 files changed, 193 insertions(+), 77 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index da4a505a..fdba4b58 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -1104,7 +1104,10 @@ impl<'de> Deserialize<'de> for OsString { /////////////////////////////////////////////////////////////////////////////// #[cfg(any(feature = "std", feature = "alloc"))] -impl<'de, T: Deserialize<'de>> Deserialize<'de> for Box { +impl<'de, T> Deserialize<'de> for Box +where + T: Deserialize<'de>, +{ fn deserialize(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, @@ -1115,7 +1118,10 @@ impl<'de, T: Deserialize<'de>> Deserialize<'de> for Box { } #[cfg(any(feature = "std", feature = "collections"))] -impl<'de, T: Deserialize<'de>> Deserialize<'de> for Box<[T]> { +impl<'de, T> Deserialize<'de> for Box<[T]> +where + T: Deserialize<'de>, +{ fn deserialize(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, @@ -1137,7 +1143,10 @@ impl<'de> Deserialize<'de> for Box { } #[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] -impl<'de, T: Deserialize<'de>> Deserialize<'de> for Arc { +impl<'de, T> Deserialize<'de> for Arc +where + T: Deserialize<'de>, +{ fn deserialize(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, @@ -1148,7 +1157,10 @@ impl<'de, T: Deserialize<'de>> Deserialize<'de> for Arc { } #[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] -impl<'de, T: Deserialize<'de>> Deserialize<'de> for Rc { +impl<'de, T> Deserialize<'de> for Rc +where + T: Deserialize<'de>, +{ fn deserialize(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, @@ -1317,7 +1329,10 @@ impl<'de> Deserialize<'de> for Duration { // end: u32, // } #[cfg(feature = "std")] -impl<'de, Idx: Deserialize<'de>> Deserialize<'de> for ops::Range { +impl<'de, Idx> Deserialize<'de> for ops::Range +where + Idx: Deserialize<'de>, +{ fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, @@ -1375,7 +1390,10 @@ impl<'de, Idx: Deserialize<'de>> Deserialize<'de> for ops::Range { phantom: PhantomData, } - impl<'de, Idx: Deserialize<'de>> Visitor<'de> for RangeVisitor { + impl<'de, Idx> Visitor<'de> for RangeVisitor + where + Idx: Deserialize<'de>, + { type Value = ops::Range; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 2da3d2d6..68de8c04 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -153,7 +153,9 @@ macro_rules! declare_error_trait { /// } /// } /// ``` - fn custom(msg: T) -> Self; + fn custom(msg: T) -> Self + where + T: Display; /// Raised when a `Deserialize` receives a type different from what it was /// expecting. diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 1bdbefb9..73d65be4 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -19,12 +19,18 @@ type ErrorImpl = (); impl de::Error for Error { #[cfg(any(feature = "std", feature = "collections"))] - fn custom(msg: T) -> Self { + fn custom(msg: T) -> Self + where + T: Display, + { Error { err: msg.to_string().into_boxed_str() } } #[cfg(not(any(feature = "std", feature = "collections")))] - fn custom(_msg: T) -> Self { + fn custom(_msg: T) -> Self + where + T: Display, + { Error { err: () } } } diff --git a/serde/src/private/ser.rs b/serde/src/private/ser.rs index c4311562..ccf77723 100644 --- a/serde/src/private/ser.rs +++ b/serde/src/private/ser.rs @@ -338,7 +338,10 @@ where pub struct Error; impl ser::Error for Error { - fn custom(_: T) -> Self { + fn custom(_: T) -> Self + where + T: Display, + { unimplemented!() } } @@ -385,7 +388,10 @@ mod content { type Ok = M::Ok; type Error = M::Error; - fn serialize_field(&mut self, value: &T) -> Result<(), M::Error> { + fn serialize_field(&mut self, value: &T) -> Result<(), M::Error> + where + T: Serialize, + { let value = try!(value.serialize(ContentSerializer::::new())); self.fields.push(value); Ok(()) @@ -420,11 +426,14 @@ mod content { type Ok = M::Ok; type Error = M::Error; - fn serialize_field( + fn serialize_field( &mut self, key: &'static str, value: &T, - ) -> Result<(), M::Error> { + ) -> Result<(), M::Error> + where + T: Serialize, + { let value = try!(value.serialize(ContentSerializer::::new())); self.fields.push((key, value)); Ok(()) @@ -651,7 +660,10 @@ mod content { Ok(Content::None) } - fn serialize_some(self, value: &T) -> Result { + fn serialize_some(self, value: &T) -> Result + where + T: Serialize, + { Ok(Content::Some(Box::new(try!(value.serialize(self))))) } @@ -672,21 +684,27 @@ mod content { Ok(Content::UnitVariant(name, variant_index, variant)) } - fn serialize_newtype_struct( + fn serialize_newtype_struct( self, name: &'static str, value: &T, - ) -> Result { + ) -> Result + where + T: Serialize, + { Ok(Content::NewtypeStruct(name, Box::new(try!(value.serialize(self)))),) } - fn serialize_newtype_variant( + fn serialize_newtype_variant( self, name: &'static str, variant_index: u32, variant: &'static str, value: &T, - ) -> Result { + ) -> Result + where + T: Serialize, + { Ok( Content::NewtypeVariant( name, @@ -814,7 +832,10 @@ mod content { type Ok = Content; type Error = E; - fn serialize_element(&mut self, value: &T) -> Result<(), E> { + fn serialize_element(&mut self, value: &T) -> Result<(), E> + where + T: Serialize, + { let value = try!(value.serialize(ContentSerializer::::new())); self.elements.push(value); Ok(()) @@ -843,7 +864,10 @@ mod content { type Ok = Content; type Error = E; - fn serialize_element(&mut self, value: &T) -> Result<(), E> { + fn serialize_element(&mut self, value: &T) -> Result<(), E> + where + T: Serialize, + { let value = try!(value.serialize(ContentSerializer::::new())); self.elements.push(value); Ok(()) @@ -867,7 +891,10 @@ mod content { type Ok = Content; type Error = E; - fn serialize_field(&mut self, value: &T) -> Result<(), E> { + fn serialize_field(&mut self, value: &T) -> Result<(), E> + where + T: Serialize, + { let value = try!(value.serialize(ContentSerializer::::new())); self.fields.push(value); Ok(()) @@ -893,7 +920,10 @@ mod content { type Ok = Content; type Error = E; - fn serialize_field(&mut self, value: &T) -> Result<(), E> { + fn serialize_field(&mut self, value: &T) -> Result<(), E> + where + T: Serialize, + { let value = try!(value.serialize(ContentSerializer::::new())); self.fields.push(value); Ok(()) @@ -917,13 +947,19 @@ mod content { type Ok = Content; type Error = E; - fn serialize_key(&mut self, key: &T) -> Result<(), E> { + fn serialize_key(&mut self, key: &T) -> Result<(), E> + where + T: Serialize, + { let key = try!(key.serialize(ContentSerializer::::new())); self.key = Some(key); Ok(()) } - fn serialize_value(&mut self, value: &T) -> Result<(), E> { + fn serialize_value(&mut self, value: &T) -> Result<(), E> + where + T: Serialize, + { let key = self.key .take() .expect("serialize_value called before serialize_key"); @@ -936,11 +972,11 @@ mod content { Ok(Content::Map(self.entries)) } - fn serialize_entry( - &mut self, - key: &K, - value: &V, - ) -> Result<(), E> { + fn serialize_entry(&mut self, key: &K, value: &V) -> Result<(), E> + where + K: Serialize, + V: Serialize, + { let key = try!(key.serialize(ContentSerializer::::new())); let value = try!(value.serialize(ContentSerializer::::new())); self.entries.push((key, value)); @@ -961,11 +997,10 @@ mod content { type Ok = Content; type Error = E; - fn serialize_field( - &mut self, - key: &'static str, - value: &T, - ) -> Result<(), E> { + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), E> + where + T: Serialize, + { let value = try!(value.serialize(ContentSerializer::::new())); self.fields.push((key, value)); Ok(()) @@ -991,11 +1026,10 @@ mod content { type Ok = Content; type Error = E; - fn serialize_field( - &mut self, - key: &'static str, - value: &T, - ) -> Result<(), E> { + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), E> + where + T: Serialize, + { let value = try!(value.serialize(ContentSerializer::::new())); self.fields.push((key, value)); Ok(()) diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 16379e63..9d383976 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -247,7 +247,10 @@ where /////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "std")] -impl Serialize for ops::Range { +impl Serialize for ops::Range +where + Idx: Serialize, +{ fn serialize(&self, serializer: S) -> Result where S: Serializer, diff --git a/serde/src/ser/impossible.rs b/serde/src/ser/impossible.rs index 84fe1d51..36fa421f 100644 --- a/serde/src/ser/impossible.rs +++ b/serde/src/ser/impossible.rs @@ -76,7 +76,10 @@ where type Ok = Ok; type Error = Error; - fn serialize_element(&mut self, value: &T) -> Result<(), Error> { + fn serialize_element(&mut self, value: &T) -> Result<(), Error> + where + T: Serialize, + { let _ = value; match self.void {} } @@ -93,7 +96,10 @@ where type Ok = Ok; type Error = Error; - fn serialize_element(&mut self, value: &T) -> Result<(), Error> { + fn serialize_element(&mut self, value: &T) -> Result<(), Error> + where + T: Serialize, + { let _ = value; match self.void {} } @@ -110,7 +116,10 @@ where type Ok = Ok; type Error = Error; - fn serialize_field(&mut self, value: &T) -> Result<(), Error> { + fn serialize_field(&mut self, value: &T) -> Result<(), Error> + where + T: Serialize, + { let _ = value; match self.void {} } @@ -127,7 +136,10 @@ where type Ok = Ok; type Error = Error; - fn serialize_field(&mut self, value: &T) -> Result<(), Error> { + fn serialize_field(&mut self, value: &T) -> Result<(), Error> + where + T: Serialize, + { let _ = value; match self.void {} } @@ -144,12 +156,18 @@ where type Ok = Ok; type Error = Error; - fn serialize_key(&mut self, key: &T) -> Result<(), Error> { + fn serialize_key(&mut self, key: &T) -> Result<(), Error> + where + T: Serialize, + { let _ = key; match self.void {} } - fn serialize_value(&mut self, value: &T) -> Result<(), Error> { + fn serialize_value(&mut self, value: &T) -> Result<(), Error> + where + T: Serialize, + { let _ = value; match self.void {} } @@ -166,11 +184,10 @@ where type Ok = Ok; type Error = Error; - fn serialize_field( - &mut self, - key: &'static str, - value: &T, - ) -> Result<(), Error> { + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Error> + where + T: Serialize, + { let _ = key; let _ = value; match self.void {} @@ -188,11 +205,10 @@ where type Ok = Ok; type Error = Error; - fn serialize_field( - &mut self, - key: &'static str, - value: &T, - ) -> Result<(), Error> { + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Error> + where + T: Serialize, + { let _ = key; let _ = value; match self.void {} diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 14262c29..cdc689c9 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -138,7 +138,9 @@ macro_rules! declare_error_trait { /// } /// } /// ``` - fn custom(msg: T) -> Self; + fn custom(msg: T) -> Self + where + T: Display; } } } @@ -404,7 +406,9 @@ pub trait Serializer: Sized { fn serialize_none(self) -> Result; /// Serialize a `Some(T)` value. - fn serialize_some(self, value: &T) -> Result; + fn serialize_some(self, value: &T) -> Result + where + T: Serialize; /// Serialize a `()` value. fn serialize_unit(self) -> Result; @@ -465,11 +469,13 @@ pub trait Serializer: Sized { /// } /// } /// ``` - fn serialize_newtype_struct( + fn serialize_newtype_struct( self, name: &'static str, value: &T, - ) -> Result; + ) -> Result + where + T: Serialize; /// Serialize a newtype variant like `E::N` in `enum E { N(u8) }`. /// @@ -496,13 +502,15 @@ pub trait Serializer: Sized { /// } /// } /// ``` - fn serialize_newtype_variant( + fn serialize_newtype_variant( self, name: &'static str, variant_index: u32, variant: &'static str, value: &T, - ) -> Result; + ) -> Result + where + T: Serialize; /// Begin to serialize a dynamically sized sequence. This call must be /// followed by zero or more calls to `serialize_element`, then a call to @@ -990,7 +998,9 @@ pub trait SerializeSeq { type Error: Error; /// Serialize a sequence element. - fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error>; + fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize; /// Finish serializing a sequence. fn end(self) -> Result; @@ -1034,7 +1044,9 @@ pub trait SerializeTuple { type Error: Error; /// Serialize a tuple element. - fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error>; + fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize; /// Finish serializing a tuple. fn end(self) -> Result; @@ -1068,7 +1080,9 @@ pub trait SerializeTupleStruct { type Error: Error; /// Serialize a tuple struct field. - fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error>; + fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize; /// Finish serializing a tuple struct. fn end(self) -> Result; @@ -1115,7 +1129,9 @@ pub trait SerializeTupleVariant { type Error: Error; /// Serialize a tuple variant field. - fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error>; + fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize; /// Finish serializing a tuple variant. fn end(self) -> Result; @@ -1169,10 +1185,14 @@ pub trait SerializeMap { type Error: Error; /// Serialize a map key. - fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error>; + fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> + where + T: Serialize; /// Serialize a map value. - fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error>; + fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize; /// Serialize a map entry consisting of a key and a value. /// @@ -1187,11 +1207,15 @@ pub trait SerializeMap { /// `serialize_value`. This is appropriate for serializers that do not care /// about performance or are not able to optimize `serialize_entry` any /// better than this. - fn serialize_entry( + fn serialize_entry( &mut self, key: &K, value: &V, - ) -> Result<(), Self::Error> { + ) -> Result<(), Self::Error> + where + K: Serialize, + V: Serialize, + { try!(self.serialize_key(key)); self.serialize_value(value) } @@ -1232,11 +1256,13 @@ pub trait SerializeStruct { type Error: Error; /// Serialize a struct field. - fn serialize_field( + fn serialize_field( &mut self, key: &'static str, value: &T, - ) -> Result<(), Self::Error>; + ) -> Result<(), Self::Error> + where + T: Serialize; /// Finish serializing a struct. fn end(self) -> Result; @@ -1276,11 +1302,13 @@ pub trait SerializeStructVariant { type Error: Error; /// Serialize a struct variant field. - fn serialize_field( + fn serialize_field( &mut self, key: &'static str, value: &T, - ) -> Result<(), Self::Error>; + ) -> Result<(), Self::Error> + where + T: Serialize; /// Finish serializing a struct variant. fn end(self) -> Result; @@ -1290,7 +1318,10 @@ trait LenHint: Iterator { fn len_hint(&self) -> Option; } -impl LenHint for I { +impl LenHint for I +where + I: Iterator, +{ #[cfg(not(feature = "unstable"))] fn len_hint(&self) -> Option { iterator_len_hint(self) @@ -1303,13 +1334,19 @@ impl LenHint for I { } #[cfg(feature = "unstable")] -impl LenHint for I { +impl LenHint for I +where + I: ExactSizeIterator, +{ fn len_hint(&self) -> Option { Some(self.len()) } } -fn iterator_len_hint(iter: &I) -> Option { +fn iterator_len_hint(iter: &I) -> Option +where + I: Iterator, +{ match iter.size_hint() { (lo, Some(hi)) if lo == hi => Some(lo), _ => None, From f8e53e837d1d315ba81dfe52f433d1332920c0bf Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 13:15:23 -0700 Subject: [PATCH 108/177] Hyperlink the ser module documentation --- serde/src/ser/mod.rs | 61 +++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index cdc689c9..5598e11d 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -1,7 +1,7 @@ //! Generic data structure serialization framework. //! -//! The two most important traits in this module are `Serialize` and -//! `Serializer`. +//! The two most important traits in this module are [`Serialize`] and +//! [`Serializer`]. //! //! - **A type that implements `Serialize` is a data structure** that can be //! serialized to any data format supported by Serde, and conversely @@ -10,39 +10,38 @@ //! //! # The Serialize trait //! -//! Serde provides `Serialize` implementations for many Rust primitive and +//! Serde provides [`Serialize`] implementations for many Rust primitive and //! standard library types. The complete list is below. All of these can be //! serialized using Serde out of the box. //! -//! Additionally, Serde provides a procedural macro called `serde_derive` to -//! automatically generate `Serialize` implementations for structs and enums in -//! your program. See the [codegen section of the manual][codegen] for how to -//! use this. +//! Additionally, Serde provides a procedural macro called [`serde_derive`] to +//! automatically generate [`Serialize`] implementations for structs and enums +//! in your program. See the [codegen section of the manual] for how to use +//! this. //! -//! In rare cases it may be necessary to implement `Serialize` manually for some -//! type in your program. See the [Implementing `Serialize`][impl-serialize] -//! section of the manual for more about this. +//! In rare cases it may be necessary to implement [`Serialize`] manually for +//! some type in your program. See the [Implementing `Serialize`] section of the +//! manual for more about this. //! -//! Third-party crates may provide `Serialize` implementations for types that -//! they expose. For example the `linked-hash-map` crate provides a -//! `LinkedHashMap` type that is serializable by Serde because the crate -//! provides an implementation of `Serialize` for it. +//! Third-party crates may provide [`Serialize`] implementations for types that +//! they expose. For example the [`linked-hash-map`] crate provides a +//! [`LinkedHashMap`] type that is serializable by Serde because the crate +//! provides an implementation of [`Serialize`] for it. //! //! # The Serializer trait //! -//! `Serializer` implementations are provided by third-party crates, for example -//! [`serde_json`][serde_json], [`serde_yaml`][serde_yaml] and -//! [`bincode`][bincode]. +//! [`Serializer`] implementations are provided by third-party crates, for +//! example [`serde_json`], [`serde_yaml`] and [`bincode`]. //! //! A partial list of well-maintained formats is given on the [Serde -//! website][data-formats]. +//! website][data formats]. //! //! # Implementations of Serialize provided by Serde //! //! - **Primitive types**: //! - bool -//! - isize, i8, i16, i32, i64 -//! - usize, u8, u16, u32, u64 +//! - i8, i16, i32, i64, isize +//! - u8, u16, u32, u64, usize //! - f32, f64 //! - char //! - str @@ -71,6 +70,11 @@ //! - VecDeque\ //! - Vec\ //! - EnumSet\ (unstable) +//! - **FFI types**: +//! - CStr +//! - CString +//! - OsStr +//! - OsString //! - **Miscellaneous standard library types**: //! - Duration //! - Path @@ -85,12 +89,17 @@ //! - SocketAddrV4 //! - SocketAddrV6 //! -//! [codegen]: https://serde.rs/codegen.html -//! [impl-serialize]: https://serde.rs/impl-serialize.html -//! [serde_json]: https://github.com/serde-rs/json -//! [serde_yaml]: https://github.com/dtolnay/serde-yaml -//! [bincode]: https://github.com/TyOverby/bincode -//! [data-formats]: https://serde.rs/#data-formats +//! [Implementing `Serialize`]: https://serde.rs/impl-serialize.html +//! [`LinkedHashMap`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html +//! [`Serialize`]: ../trait.Serialize.html +//! [`Serializer`]: ../trait.Serializer.html +//! [`bincode`]: https://github.com/TyOverby/bincode +//! [`linked-hash-map`]: https://crates.io/crates/linked-hash-map +//! [`serde_derive`]: https://crates.io/crates/serde_derive +//! [`serde_json`]: https://github.com/serde-rs/json +//! [`serde_yaml`]: https://github.com/dtolnay/serde-yaml +//! [codegen section of the manual]: https://serde.rs/codegen.html +//! [data formats]: https://serde.rs/#data-formats use lib::*; From 4f6518dad726f31384b49ac01b5f173b7713a6f4 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 13:20:12 -0700 Subject: [PATCH 109/177] Hyperlink the ser::Error documentation --- serde/src/ser/mod.rs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 5598e11d..bf73a422 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -112,18 +112,21 @@ pub use self::impossible::Impossible; macro_rules! declare_error_trait { (Error: Sized $(+ $($supertrait:ident)::+)*) => { - /// Trait used by `Serialize` implementations to generically construct - /// errors belonging to the `Serializer` against which they are + /// Trait used by [`Serialize`] implementations to generically construct + /// errors belonging to the [`Serializer`] against which they are /// currently running. + /// + /// [`Serialize`]: ../trait.Serialize.html + /// [`Serializer`]: ../trait.Serializer.html pub trait Error: Sized $(+ $($supertrait)::+)* { - /// Raised when a `Serialize` implementation encounters a general - /// error while serializing a type. + /// Used when a [`Serialize`] implementation encounters any error + /// while serializing a type. /// /// The message should not be capitalized and should not end with a /// period. /// - /// For example, a filesystem `Path` may refuse to serialize itself - /// if it contains invalid UTF-8 data. + /// For example, a filesystem [`Path`] may refuse to serialize + /// itself if it contains invalid UTF-8 data. /// /// ```rust /// # struct Path; @@ -141,12 +144,15 @@ macro_rules! declare_error_trait { /// where S: Serializer /// { /// match self.to_str() { - /// Some(s) => s.serialize(serializer), + /// Some(s) => serializer.serialize_str(s), /// None => Err(ser::Error::custom("path contains invalid UTF-8 characters")), /// } /// } /// } /// ``` + /// + /// [`Path`]: https://doc.rust-lang.org/std/path/struct.Path.html + /// [`Serialize`]: ../trait.Serialize.html fn custom(msg: T) -> Self where T: Display; From eab771cd1a1b4cd17374d3def83cc2d5f46692f3 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 13:24:44 -0700 Subject: [PATCH 110/177] Standardize on 80 characters per line Per Mozilla coding style: https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Coding_Style --- serde/src/de/impls.rs | 48 +++++++++++++++++++++--------------------- serde/src/de/mod.rs | 20 +++++++++--------- serde/src/de/value.rs | 26 +++++++++++------------ serde/src/lib.rs | 6 +++--- serde/src/ser/impls.rs | 34 +++++++++++++++--------------- serde/src/ser/mod.rs | 6 +++--- 6 files changed, 70 insertions(+), 70 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index fdba4b58..156169de 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -8,7 +8,7 @@ use de::MapVisitor; use de::from_primitive::FromPrimitive; -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// struct UnitVisitor; @@ -36,7 +36,7 @@ impl<'de> Deserialize<'de> for () { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// struct BoolVisitor; @@ -64,7 +64,7 @@ impl<'de> Deserialize<'de> for bool { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// macro_rules! visit_integer_method { ($src_ty:ident, $method:ident, $from_method:ident, $group:ident, $group_ty:ident) => { @@ -146,7 +146,7 @@ impl_deserialize_num!(u64, deserialize_u64, integer); impl_deserialize_num!(f32, deserialize_f32, integer, float); impl_deserialize_num!(f64, deserialize_f64, integer, float); -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// struct CharVisitor; @@ -188,7 +188,7 @@ impl<'de> Deserialize<'de> for char { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// #[cfg(any(feature = "std", feature = "collections"))] struct StringVisitor; @@ -246,7 +246,7 @@ impl<'de> Deserialize<'de> for String { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// struct StrVisitor; @@ -281,7 +281,7 @@ impl<'de: 'a, 'a> Deserialize<'de> for &'a str { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// struct BytesVisitor; @@ -316,7 +316,7 @@ impl<'de: 'a, 'a> Deserialize<'de> for &'a [u8] { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "std")] struct CStringVisitor; @@ -393,7 +393,7 @@ impl<'de> Deserialize<'de> for Box { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// struct OptionVisitor { marker: PhantomData, @@ -446,7 +446,7 @@ where } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// struct PhantomDataVisitor { marker: PhantomData, @@ -478,7 +478,7 @@ impl<'de, T> Deserialize<'de> for PhantomData { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// macro_rules! seq_impl { ( @@ -593,7 +593,7 @@ seq_impl!( VecDeque::with_capacity(cmp::min(visitor.size_hint().0, 4096)), VecDeque::push_back); -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// struct ArrayVisitor { marker: PhantomData, @@ -706,7 +706,7 @@ array_impls! { 32 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s 19 t 20 u 21 v 22 w 23 x 24 y 25 z 26 aa 27 ab 28 ac 29 ad 30 ae 31 af) } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// macro_rules! tuple_impls { ($($len:expr => $visitor:ident => ($($n:tt $name:ident)+))+) => { @@ -775,7 +775,7 @@ tuple_impls! { 16 => TupleVisitor16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15) } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// macro_rules! map_impl { ( @@ -853,7 +853,7 @@ map_impl!( HashMap::with_hasher(S::default()), HashMap::with_capacity_and_hasher(cmp::min(visitor.size_hint().0, 4096), S::default())); -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "std")] impl<'de> Deserialize<'de> for net::IpAddr { @@ -897,7 +897,7 @@ impl<'de> Deserialize<'de> for net::Ipv6Addr { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "std")] impl<'de> Deserialize<'de> for net::SocketAddr { @@ -941,7 +941,7 @@ impl<'de> Deserialize<'de> for net::SocketAddrV6 { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "std")] struct PathBufVisitor; @@ -980,7 +980,7 @@ impl<'de> Deserialize<'de> for path::PathBuf { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// #[cfg(all(feature = "std", any(unix, windows)))] enum OsStringKind { @@ -1101,7 +1101,7 @@ impl<'de> Deserialize<'de> for OsString { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// #[cfg(any(feature = "std", feature = "alloc"))] impl<'de, T> Deserialize<'de> for Box @@ -1186,7 +1186,7 @@ where } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // This is a cleaned-up version of the impl generated by: // @@ -1318,7 +1318,7 @@ impl<'de> Deserialize<'de> for Duration { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // Similar to: // @@ -1458,10 +1458,10 @@ where } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "unstable")] #[allow(deprecated)] // num::Zero is deprecated but there is no replacement @@ -1481,7 +1481,7 @@ where } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// impl<'de, T, E> Deserialize<'de> for Result diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 68de8c04..625ed450 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -96,7 +96,7 @@ use lib::*; -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// pub mod value; @@ -107,7 +107,7 @@ mod utf8; pub use self::ignored_any::IgnoredAny; -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// macro_rules! declare_error_trait { (Error: Sized $(+ $($supertrait:ident)::+)*) => { @@ -443,7 +443,7 @@ impl<'a> Display for Expected + 'a { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// /// A **data structure** that can be deserialized from any data format supported /// by Serde. @@ -678,7 +678,7 @@ where } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// /// A **data format** that can deserialize any data structure supported by /// Serde. @@ -991,7 +991,7 @@ pub trait Deserializer<'de>: Sized { V: Visitor<'de>; } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// /// This trait represents a visitor that walks through a deserializer. /// @@ -1323,7 +1323,7 @@ pub trait Visitor<'de>: Sized { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// /// `SeqVisitor` visits each item in a sequence. /// @@ -1391,7 +1391,7 @@ where } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// /// `MapVisitor` visits each item in a sequence. /// @@ -1557,7 +1557,7 @@ where } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// /// `EnumVisitor` is a visitor that is created by the `Deserializer` and passed /// to the `Deserialize` in order to identify which variant of an enum to @@ -1776,7 +1776,7 @@ pub trait VariantVisitor<'de>: Sized { V: Visitor<'de>; } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// /// This trait converts primitive types into a deserializer. pub trait IntoDeserializer<'de, E: Error = value::Error> { @@ -1787,7 +1787,7 @@ pub trait IntoDeserializer<'de, E: Error = value::Error> { fn into_deserializer(self) -> Self::Deserializer; } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// /// Used in error messages. /// diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 73d65be4..34802e02 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -4,7 +4,7 @@ use lib::*; use de::{self, IntoDeserializer, Expected, SeqVisitor}; -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// /// This represents all the possible errors that can occur using the `ValueDeserializer`. #[derive(Clone, Debug, PartialEq)] @@ -54,7 +54,7 @@ impl error::Error for Error { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// impl<'de, E> IntoDeserializer<'de, E> for () where @@ -100,7 +100,7 @@ where } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// macro_rules! primitive_deserializer { ($ty:ty, $name:ident, $method:ident $($cast:tt)*) => { @@ -226,7 +226,7 @@ where } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// /// A helper deserializer that deserializes a `&str`. #[derive(Clone, Debug)] @@ -296,7 +296,7 @@ where } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// /// A helper deserializer that deserializes a `String`. #[cfg(any(feature = "std", feature = "collections"))] @@ -370,7 +370,7 @@ where } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// /// A helper deserializer that deserializes a `String`. #[cfg(any(feature = "std", feature = "collections"))] @@ -447,7 +447,7 @@ where } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// /// A helper deserializer that deserializes a sequence. #[derive(Clone, Debug)] @@ -550,7 +550,7 @@ impl Expected for ExpectedInSeq { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// #[cfg(any(feature = "std", feature = "collections"))] impl<'de, T, E> IntoDeserializer<'de, E> for Vec @@ -591,7 +591,7 @@ where } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// /// A helper deserializer that deserializes a sequence using a `SeqVisitor`. #[derive(Clone, Debug)] @@ -626,7 +626,7 @@ where } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// /// A helper deserializer that deserializes a map. pub struct MapDeserializer<'de, I, E> @@ -958,7 +958,7 @@ impl Expected for ExpectedInMap { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// #[cfg(any(feature = "std", feature = "collections"))] impl<'de, K, V, E> IntoDeserializer<'de, E> for BTreeMap @@ -988,7 +988,7 @@ where } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// /// A helper deserializer that deserializes a map using a `MapVisitor`. #[derive(Clone, Debug)] @@ -1023,7 +1023,7 @@ where } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// mod private { use lib::*; diff --git a/serde/src/lib.rs b/serde/src/lib.rs index c6c51c89..de44550b 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -68,7 +68,7 @@ //! [Cargo]: http://doc.crates.io/manifest.html //! [redis-rs]: https://crates.io/crates/redis -////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // Serde types in rustdoc of other crates get linked to here. #![doc(html_root_url = "https://docs.rs/serde/0.9.13")] @@ -91,7 +91,7 @@ // Blacklisted Rust lints. #![deny(missing_docs, unused_imports)] -////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "collections")] extern crate collections; @@ -182,7 +182,7 @@ mod lib { pub use core::num::Zero; } -////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// #[macro_use] mod macros; diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 9d383976..c148b56e 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -5,7 +5,7 @@ use ser::{Serialize, SerializeSeq, SerializeTuple, Serializer}; #[cfg(feature = "std")] use ser::Error; -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// macro_rules! impl_visit { ($ty:ty, $method:ident $($cast:tt)*) => { @@ -35,7 +35,7 @@ impl_visit!(f32, serialize_f32); impl_visit!(f64, serialize_f64); impl_visit!(char, serialize_char); -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// impl Serialize for str { #[inline] @@ -58,7 +58,7 @@ impl Serialize for String { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "std")] impl Serialize for CStr { @@ -82,7 +82,7 @@ impl Serialize for CString { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// impl Serialize for Option where @@ -100,7 +100,7 @@ where } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// impl Serialize for PhantomData { #[inline] @@ -112,7 +112,7 @@ impl Serialize for PhantomData { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // Does not require T: Serialize. impl Serialize for [T; 0] { @@ -175,7 +175,7 @@ array_impls!(30); array_impls!(31); array_impls!(32); -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// macro_rules! serialize_seq { () => { @@ -244,7 +244,7 @@ where serialize_seq!(); } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "std")] impl Serialize for ops::Range @@ -263,7 +263,7 @@ where } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// impl Serialize for () { #[inline] @@ -275,7 +275,7 @@ impl Serialize for () { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// macro_rules! tuple_impls { ($( @@ -473,7 +473,7 @@ tuple_impls! { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// macro_rules! serialize_map { () => { @@ -505,7 +505,7 @@ where serialize_map!(); } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// impl<'a, T: ?Sized> Serialize for &'a T where @@ -589,7 +589,7 @@ where } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// impl Serialize for Result where @@ -609,7 +609,7 @@ where } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "std")] impl Serialize for Duration { @@ -625,7 +625,7 @@ impl Serialize for Duration { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// /// Seralize the `$value` that implements Display as a string, /// when that string is statically known to never have more than @@ -694,7 +694,7 @@ impl Serialize for net::Ipv6Addr { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "std")] impl Serialize for net::SocketAddr { @@ -733,7 +733,7 @@ impl Serialize for net::SocketAddrV6 { } } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "std")] impl Serialize for path::Path { diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index bf73a422..f12831da 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -108,7 +108,7 @@ mod impossible; pub use self::impossible::Impossible; -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// macro_rules! declare_error_trait { (Error: Sized $(+ $($supertrait:ident)::+)*) => { @@ -166,7 +166,7 @@ declare_error_trait!(Error: Sized + error::Error); #[cfg(not(feature = "std"))] declare_error_trait!(Error: Sized + Debug + Display); -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// /// A **data structure** that can be serialized into any data format supported /// by Serde. @@ -204,7 +204,7 @@ pub trait Serialize { S: Serializer; } -/////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// /// A **data format** that can serialize any data structure supported by Serde. /// From 9253fccf04400c3ddbd5dacbfdbe6e5cd7de643c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 13:55:34 -0700 Subject: [PATCH 111/177] Hyperlink the Serialize documentation --- serde/src/ser/mod.rs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index f12831da..d329e17d 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -175,30 +175,32 @@ declare_error_trait!(Error: Sized + Debug + Display); /// standard library types. The complete list is [here][ser]. All of these can /// be serialized using Serde out of the box. /// -/// Additionally, Serde provides a procedural macro called `serde_derive` to +/// Additionally, Serde provides a procedural macro called [`serde_derive`] to /// automatically generate `Serialize` implementations for structs and enums in -/// your program. See the [codegen section of the manual][codegen] for how to -/// use this. +/// your program. See the [codegen section of the manual] for how to use this. /// /// In rare cases it may be necessary to implement `Serialize` manually for some -/// type in your program. See the [Implementing `Serialize`][impl-serialize] -/// section of the manual for more about this. +/// type in your program. See the [Implementing `Serialize`] section of the +/// manual for more about this. /// /// Third-party crates may provide `Serialize` implementations for types that -/// they expose. For example the `linked-hash-map` crate provides a -/// `LinkedHashMap` type that is serializable by Serde because the crate +/// they expose. For example the [`linked-hash-map`] crate provides a +/// [`LinkedHashMap`] type that is serializable by Serde because the crate /// provides an implementation of `Serialize` for it. /// +/// [Implementing `Serialize`]: https://serde.rs/impl-serialize.html +/// [`LinkedHashMap`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html +/// [`linked-hash-map`]: https://crates.io/crates/linked-hash-map +/// [`serde_derive`]: https://crates.io/crates/serde_derive +/// [codegen section of the manual]: https://serde.rs/codegen.html /// [ser]: https://docs.serde.rs/serde/ser/index.html -/// [codegen]: https://serde.rs/codegen.html -/// [impl-serialize]: https://serde.rs/impl-serialize.html pub trait Serialize { /// Serialize this value into the given Serde serializer. /// - /// See the [Implementing `Serialize`][impl-serialize] section of the manual - /// for more information about how to implement this method. + /// See the [Implementing `Serialize`] section of the manual for more + /// information about how to implement this method. /// - /// [impl-serialize]: https://serde.rs/impl-serialize.html + /// [Implementing `Serialize`]: https://serde.rs/impl-serialize.html fn serialize(&self, serializer: S) -> Result where S: Serializer; From 7d16710fb4d1acae24cc43133762d2af040a3082 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 13:55:51 -0700 Subject: [PATCH 112/177] Add an example to Serialize --- serde/src/ser/mod.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index d329e17d..e3549207 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -200,6 +200,29 @@ pub trait Serialize { /// See the [Implementing `Serialize`] section of the manual for more /// information about how to implement this method. /// + /// ```rust + /// use serde::ser::{Serialize, Serializer, SerializeStruct}; + /// + /// struct Person { + /// name: String, + /// age: u8, + /// phones: Vec, + /// } + /// + /// // This is what #[derive(Serialize)] would generate. + /// impl Serialize for Person { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// let mut s = serializer.serialize_struct("Person", 3)?; + /// s.serialize_field("name", &self.name)?; + /// s.serialize_field("age", &self.age)?; + /// s.serialize_field("phones", &self.phones)?; + /// s.end() + /// } + /// } + /// ``` + /// /// [Implementing `Serialize`]: https://serde.rs/impl-serialize.html fn serialize(&self, serializer: S) -> Result where From 0cf8eadef82408596a4027897a698af2297aa1a9 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 13:56:12 -0700 Subject: [PATCH 113/177] Dynamically sized means something else --- serde/src/de/mod.rs | 2 +- serde/src/ser/mod.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 625ed450..89d4a792 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -715,7 +715,7 @@ where /// - newtype_variant /// - the `E::N` in `enum E { N(u8) }` /// - seq -/// - a dynamically sized sequence of values, for example `Vec` or +/// - a variably sized sequence of values, for example `Vec` or /// `HashSet` /// - seq_fixed_size /// - a statically sized sequence of values for which the size will be known diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index e3549207..4978703a 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -264,7 +264,7 @@ pub trait Serialize { /// - newtype_variant /// - the `E::N` in `enum E { N(u8) }` /// - seq -/// - a dynamically sized sequence of values, for example `Vec` or +/// - a variably sized sequence of values, for example `Vec` or /// `HashSet` /// - seq_fixed_size /// - a statically sized sequence of values for which the size will be known @@ -552,7 +552,7 @@ pub trait Serializer: Sized { where T: Serialize; - /// Begin to serialize a dynamically sized sequence. This call must be + /// Begin to serialize a variably sized sequence. This call must be /// followed by zero or more calls to `serialize_element`, then a call to /// `end`. /// From dec6b6723670cf6ea110db82becb5b128662ca94 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 14:02:13 -0700 Subject: [PATCH 114/177] Hyperlink the Serializer associated types --- serde/src/ser/mod.rs | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 4978703a..d83b729f 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -294,41 +294,58 @@ pub trait Serialize { pub trait Serializer: Sized { /// The output type produced by this `Serializer` during successful /// serialization. Most serializers that produce text or binary output - /// should set `Ok = ()` and serialize into an `io::Write` or buffer + /// should set `Ok = ()` and serialize into an [`io::Write`] or buffer /// contained within the `Serializer` instance. Serializers that build /// in-memory data structures may be simplified by using `Ok` to propagate /// the data structure around. + /// + /// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html type Ok; /// The error type when some error occurs during serialization. type Error: Error; - /// Type returned from `serialize_seq` and `serialize_seq_fixed_size` for - /// serializing the content of the sequence. + /// Type returned from [`serialize_seq`] and [`serialize_seq_fixed_size`] + /// for serializing the content of the sequence. + /// + /// [`serialize_seq`]: #tymethod.serialize_seq + /// [`serialize_seq_fixed_size`]: #tymethod.serialize_seq_fixed_size type SerializeSeq: SerializeSeq; - /// Type returned from `serialize_tuple` for serializing the content of the - /// tuple. + /// Type returned from [`serialize_tuple`] for serializing the content of + /// the tuple. + /// + /// [`serialize_tuple`]: #tymethod.serialize_tuple type SerializeTuple: SerializeTuple; - /// Type returned from `serialize_tuple_struct` for serializing the content - /// of the tuple struct. + /// Type returned from [`serialize_tuple_struct`] for serializing the + /// content of the tuple struct. + /// + /// [`serialize_tuple_struct`]: #tymethod.serialize_tuple_struct type SerializeTupleStruct: SerializeTupleStruct; - /// Type returned from `serialize_tuple_variant` for serializing the content - /// of the tuple variant. + /// Type returned from [`serialize_tuple_variant`] for serializing the + /// content of the tuple variant. + /// + /// [`serialize_tuple_variant`]: #tymethod.serialize_tuple_variant type SerializeTupleVariant: SerializeTupleVariant; - /// Type returned from `serialize_map` for serializing the content of the + /// Type returned from [`serialize_map`] for serializing the content of the /// map. + /// + /// [`serialize_map`]: #tymethod.serialize_map type SerializeMap: SerializeMap; - /// Type returned from `serialize_struct` for serializing the content of the - /// struct. + /// Type returned from [`serialize_struct`] for serializing the content of + /// the struct. + /// + /// [`serialize_struct`]: #tymethod.serialize_struct type SerializeStruct: SerializeStruct; - /// Type returned from `serialize_struct_variant` for serializing the + /// Type returned from [`serialize_struct_variant`] for serializing the /// content of the struct variant. + /// + /// [`serialize_struct_variant`]: #tymethod.serialize_struct_variant type SerializeStructVariant: SerializeStructVariant; /// Serialize a `bool` value. From 8d1f8825122bfad17547dab001d51a646e3dc415 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 14:16:28 -0700 Subject: [PATCH 115/177] Hyperlink the collect methods --- serde/src/ser/mod.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index d83b729f..b787437e 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -878,8 +878,10 @@ pub trait Serializer: Sized { /// Collect an iterator as a sequence. /// /// The default implementation serializes each item yielded by the iterator - /// using `Self::SerializeSeq`. Implementors should not need to override - /// this method. + /// using [`serialize_seq`]. Implementors should not need to override this + /// method. + /// + /// [`serialize_seq`]: #tymethod.serialize_seq fn collect_seq(self, iter: I) -> Result where I: IntoIterator, @@ -896,8 +898,10 @@ pub trait Serializer: Sized { /// Collect an iterator as a map. /// /// The default implementation serializes each pair yielded by the iterator - /// using `Self::SerializeMap`. Implementors should not need to override - /// this method. + /// using [`serialize_map`]. Implementors should not need to override this + /// method. + /// + /// [`serialize_map`]: #tymethod.serialize_map fn collect_map(self, iter: I) -> Result where K: Serialize, @@ -914,8 +918,8 @@ pub trait Serializer: Sized { /// Serialize a string produced by an implementation of `Display`. /// - /// The default implementation builds a heap-allocated `String` and - /// delegates to `serialize_str`. Serializers are encouraged to provide a + /// The default implementation builds a heap-allocated [`String`] and + /// delegates to [`serialize_str`]. Serializers are encouraged to provide a /// more efficient implementation if possible. /// /// ```rust @@ -938,6 +942,9 @@ pub trait Serializer: Sized { /// } /// } /// ``` + /// + /// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html + /// [`serialize_str`]: #tymethod.serialize_str #[cfg(any(feature = "std", feature = "collections"))] fn collect_str(self, value: &T) -> Result where From 41488252ff2c0fa574d1dbf76f520a58a7385725 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 14:19:17 -0700 Subject: [PATCH 116/177] Add a collect_seq example --- serde/src/ser/mod.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index b787437e..d6ee65ae 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -881,6 +881,22 @@ pub trait Serializer: Sized { /// using [`serialize_seq`]. Implementors should not need to override this /// method. /// + /// ```rust + /// use serde::{Serialize, Serializer}; + /// + /// struct SecretlyOneHigher { + /// data: Vec, + /// } + /// + /// impl Serialize for SecretlyOneHigher { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// serializer.collect_seq(self.data.iter().map(|x| x + 1)) + /// } + /// } + /// ``` + /// /// [`serialize_seq`]: #tymethod.serialize_seq fn collect_seq(self, iter: I) -> Result where From 07bce54ad34392cac80b37d673e3e96be80d689d Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 14:21:28 -0700 Subject: [PATCH 117/177] Add a collect_map example --- serde/src/ser/mod.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index d6ee65ae..189cf766 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -917,6 +917,24 @@ pub trait Serializer: Sized { /// using [`serialize_map`]. Implementors should not need to override this /// method. /// + /// ```rust + /// use std::collections::BTreeSet; + /// use serde::{Serialize, Serializer}; + /// + /// struct MapToUnit { + /// keys: BTreeSet, + /// } + /// + /// // Serializes as a map in which the values are all unit. + /// impl Serialize for MapToUnit { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// serializer.collect_map(self.keys.iter().map(|k| (k, ()))) + /// } + /// } + /// ``` + /// /// [`serialize_map`]: #tymethod.serialize_map fn collect_map(self, iter: I) -> Result where From 35313257c55b3d7bd958ebddc5405a866fa316b2 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 14:23:00 -0700 Subject: [PATCH 118/177] Do not hyperlink first sentence because it shows up in index --- serde/src/ser/mod.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 189cf766..32e202e9 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -112,12 +112,9 @@ pub use self::impossible::Impossible; macro_rules! declare_error_trait { (Error: Sized $(+ $($supertrait:ident)::+)*) => { - /// Trait used by [`Serialize`] implementations to generically construct - /// errors belonging to the [`Serializer`] against which they are + /// Trait used by `Serialize` implementations to generically construct + /// errors belonging to the `Serializer` against which they are /// currently running. - /// - /// [`Serialize`]: ../trait.Serialize.html - /// [`Serializer`]: ../trait.Serializer.html pub trait Error: Sized $(+ $($supertrait)::+)* { /// Used when a [`Serialize`] implementation encounters any error /// while serializing a type. From 09bd8287e7670ee9970ed21fa8df900af955c609 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 14:27:13 -0700 Subject: [PATCH 119/177] Hyperlink the serialize_entry documentation --- serde/src/ser/mod.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 32e202e9..e3684200 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -1291,17 +1291,21 @@ pub trait SerializeMap { /// Serialize a map entry consisting of a key and a value. /// - /// Some `Serialize` types are not able to hold a key and value in memory at - /// the same time so `SerializeMap` implementations are required to support - /// `serialize_key` and `serialize_value` individually. The + /// Some [`Serialize`] types are not able to hold a key and value in memory + /// at the same time so `SerializeMap` implementations are required to + /// support [`serialize_key`] and [`serialize_value`] individually. The /// `serialize_entry` method allows serializers to optimize for the case - /// where key and value are both available. `Serialize` implementations are - /// encouraged to use `serialize_entry` if possible. + /// where key and value are both available. [`Serialize`] implementations + /// are encouraged to use `serialize_entry` if possible. /// - /// The default implementation delegates to `serialize_key` and - /// `serialize_value`. This is appropriate for serializers that do not care - /// about performance or are not able to optimize `serialize_entry` any + /// The default implementation delegates to [`serialize_key`] and + /// [`serialize_value`]. This is appropriate for serializers that do not + /// care about performance or are not able to optimize `serialize_entry` any /// better than this. + /// + /// [`Serialize`]: ../trait.Serialize.html + /// [`serialize_key`]: #tymethod.serialize_key + /// [`serialize_value`]: #tymethod.serialize_value fn serialize_entry( &mut self, key: &K, From 13f273ad744faebd7a38bfbe0127ba7fd275cfe8 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 14:51:39 -0700 Subject: [PATCH 120/177] Examples for the primitive serializer methods --- serde/src/private/macros.rs | 24 ++++ serde/src/ser/mod.rs | 247 ++++++++++++++++++++++++++++++++++++ 2 files changed, 271 insertions(+) diff --git a/serde/src/private/macros.rs b/serde/src/private/macros.rs index cefe0a9d..a25de638 100644 --- a/serde/src/private/macros.rs +++ b/serde/src/private/macros.rs @@ -1,3 +1,27 @@ +#[doc(hidden)] +#[macro_export] +macro_rules! __private_serialize { + () => { + trait Serialize { + fn serialize(&self, serializer: S) -> Result + where + S: $crate::Serializer; + } + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __private_deserialize { + () => { + trait Deserialize<'de>: Sized { + fn deserialize(deserializer: D) -> Result + where + D: $crate::Deserializer<'de>; + } + }; +} + /// Used only by Serde doc tests. Not public API. #[doc(hidden)] #[macro_export] diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index e3684200..6ec41edd 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -346,6 +346,25 @@ pub trait Serializer: Sized { type SerializeStructVariant: SerializeStructVariant; /// Serialize a `bool` value. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde; + /// # + /// # use serde::Serializer; + /// # + /// # __private_serialize!(); + /// # + /// impl Serialize for bool { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// serializer.serialize_bool(*self) + /// } + /// } + /// # + /// # fn main() {} + /// ``` fn serialize_bool(self, v: bool) -> Result; /// Serialize an `i8` value. @@ -353,6 +372,25 @@ pub trait Serializer: Sized { /// If the format does not differentiate between `i8` and `i64`, a /// reasonable implementation would be to cast the value to `i64` and /// forward to `serialize_i64`. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde; + /// # + /// # use serde::Serializer; + /// # + /// # __private_serialize!(); + /// # + /// impl Serialize for i8 { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// serializer.serialize_i8(*self) + /// } + /// } + /// # + /// # fn main() {} + /// ``` fn serialize_i8(self, v: i8) -> Result; /// Serialize an `i16` value. @@ -360,6 +398,25 @@ pub trait Serializer: Sized { /// If the format does not differentiate between `i16` and `i64`, a /// reasonable implementation would be to cast the value to `i64` and /// forward to `serialize_i64`. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde; + /// # + /// # use serde::Serializer; + /// # + /// # __private_serialize!(); + /// # + /// impl Serialize for i16 { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// serializer.serialize_i16(*self) + /// } + /// } + /// # + /// # fn main() {} + /// ``` fn serialize_i16(self, v: i16) -> Result; /// Serialize an `i32` value. @@ -367,9 +424,47 @@ pub trait Serializer: Sized { /// If the format does not differentiate between `i32` and `i64`, a /// reasonable implementation would be to cast the value to `i64` and /// forward to `serialize_i64`. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde; + /// # + /// # use serde::Serializer; + /// # + /// # __private_serialize!(); + /// # + /// impl Serialize for i32 { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// serializer.serialize_i32(*self) + /// } + /// } + /// # + /// # fn main() {} + /// ``` fn serialize_i32(self, v: i32) -> Result; /// Serialize an `i64` value. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde; + /// # + /// # use serde::Serializer; + /// # + /// # __private_serialize!(); + /// # + /// impl Serialize for i64 { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// serializer.serialize_i64(*self) + /// } + /// } + /// # + /// # fn main() {} + /// ``` fn serialize_i64(self, v: i64) -> Result; /// Serialize a `u8` value. @@ -377,6 +472,25 @@ pub trait Serializer: Sized { /// If the format does not differentiate between `u8` and `u64`, a /// reasonable implementation would be to cast the value to `u64` and /// forward to `serialize_u64`. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde; + /// # + /// # use serde::Serializer; + /// # + /// # __private_serialize!(); + /// # + /// impl Serialize for u8 { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// serializer.serialize_u8(*self) + /// } + /// } + /// # + /// # fn main() {} + /// ``` fn serialize_u8(self, v: u8) -> Result; /// Serialize a `u16` value. @@ -384,6 +498,25 @@ pub trait Serializer: Sized { /// If the format does not differentiate between `u16` and `u64`, a /// reasonable implementation would be to cast the value to `u64` and /// forward to `serialize_u64`. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde; + /// # + /// # use serde::Serializer; + /// # + /// # __private_serialize!(); + /// # + /// impl Serialize for u16 { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// serializer.serialize_u16(*self) + /// } + /// } + /// # + /// # fn main() {} + /// ``` fn serialize_u16(self, v: u16) -> Result; /// Serialize a `u32` value. @@ -391,9 +524,47 @@ pub trait Serializer: Sized { /// If the format does not differentiate between `u32` and `u64`, a /// reasonable implementation would be to cast the value to `u64` and /// forward to `serialize_u64`. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde; + /// # + /// # use serde::Serializer; + /// # + /// # __private_serialize!(); + /// # + /// impl Serialize for u32 { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// serializer.serialize_u32(*self) + /// } + /// } + /// # + /// # fn main() {} + /// ``` fn serialize_u32(self, v: u32) -> Result; /// Serialize a `u64` value. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde; + /// # + /// # use serde::Serializer; + /// # + /// # __private_serialize!(); + /// # + /// impl Serialize for u64 { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// serializer.serialize_u64(*self) + /// } + /// } + /// # + /// # fn main() {} + /// ``` fn serialize_u64(self, v: u64) -> Result; /// Serialize an `f32` value. @@ -401,18 +572,94 @@ pub trait Serializer: Sized { /// If the format does not differentiate between `f32` and `f64`, a /// reasonable implementation would be to cast the value to `f64` and /// forward to `serialize_f64`. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde; + /// # + /// # use serde::Serializer; + /// # + /// # __private_serialize!(); + /// # + /// impl Serialize for f32 { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// serializer.serialize_f32(*self) + /// } + /// } + /// # + /// # fn main() {} + /// ``` fn serialize_f32(self, v: f32) -> Result; /// Serialize an `f64` value. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde; + /// # + /// # use serde::Serializer; + /// # + /// # __private_serialize!(); + /// # + /// impl Serialize for f64 { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// serializer.serialize_f64(*self) + /// } + /// } + /// # + /// # fn main() {} + /// ``` fn serialize_f64(self, v: f64) -> Result; /// Serialize a character. /// /// If the format does not support characters, it is reasonable to serialize /// it as a single element `str` or a `u32`. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde; + /// # + /// # use serde::Serializer; + /// # + /// # __private_serialize!(); + /// # + /// impl Serialize for char { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// serializer.serialize_char(*self) + /// } + /// } + /// # + /// # fn main() {} + /// ``` fn serialize_char(self, v: char) -> Result; /// Serialize a `&str`. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde; + /// # + /// # use serde::Serializer; + /// # + /// # __private_serialize!(); + /// # + /// impl Serialize for str { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// serializer.serialize_str(self) + /// } + /// } + /// # + /// # fn main() {} + /// ``` fn serialize_str(self, value: &str) -> Result; /// Serialize a chunk of raw byte data. From 50f5ef2fb63161f490a2c286b2b7a36703130370 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 14:54:59 -0700 Subject: [PATCH 121/177] Condense some serializer imports --- serde/src/ser/mod.rs | 45 +++++++++++++++----------------------------- 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 6ec41edd..f72eba4d 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -841,8 +841,7 @@ pub trait Serializer: Sized { /// # } /// # } /// # - /// use serde::{Serialize, Serializer}; - /// use serde::ser::SerializeSeq; + /// use serde::ser::{Serialize, Serializer, SerializeSeq}; /// /// impl Serialize for Vec /// where T: Serialize @@ -866,8 +865,7 @@ pub trait Serializer: Sized { /// then a call to `end`. /// /// ```rust - /// use serde::{Serialize, Serializer}; - /// use serde::ser::SerializeSeq; + /// use serde::ser::{Serialize, Serializer, SerializeSeq}; /// /// const VRAM_SIZE: usize = 386; /// struct Vram([u16; VRAM_SIZE]); @@ -890,8 +888,7 @@ pub trait Serializer: Sized { /// calls to `serialize_element`, then a call to `end`. /// /// ```rust - /// use serde::{Serialize, Serializer}; - /// use serde::ser::SerializeTuple; + /// use serde::ser::{Serialize, Serializer, SerializeTuple}; /// /// # mod fool { /// # trait Serialize {} @@ -927,8 +924,7 @@ pub trait Serializer: Sized { /// of data fields that will be serialized. /// /// ```rust - /// use serde::{Serialize, Serializer}; - /// use serde::ser::SerializeTupleStruct; + /// use serde::ser::{Serialize, Serializer, SerializeTupleStruct}; /// /// struct Rgb(u8, u8, u8); /// @@ -959,8 +955,7 @@ pub trait Serializer: Sized { /// and the `len` is the number of data fields that will be serialized. /// /// ```rust - /// use serde::{Serialize, Serializer}; - /// use serde::ser::SerializeTupleVariant; + /// use serde::ser::{Serialize, Serializer, SerializeTupleVariant}; /// /// enum E { /// T(u8, u8), @@ -1024,8 +1019,7 @@ pub trait Serializer: Sized { /// # } /// # } /// # - /// use serde::{Serialize, Serializer}; - /// use serde::ser::SerializeMap; + /// use serde::ser::{Serialize, Serializer, SerializeMap}; /// /// impl Serialize for HashMap /// where K: Serialize, @@ -1052,8 +1046,7 @@ pub trait Serializer: Sized { /// data fields that will be serialized. /// /// ```rust - /// use serde::{Serialize, Serializer}; - /// use serde::ser::SerializeStruct; + /// use serde::ser::{Serialize, Serializer, SerializeStruct}; /// /// struct Rgb { /// r: u8, @@ -1088,8 +1081,7 @@ pub trait Serializer: Sized { /// and the `len` is the number of data fields that will be serialized. /// /// ```rust - /// use serde::{Serialize, Serializer}; - /// use serde::ser::SerializeStructVariant; + /// use serde::ser::{Serialize, Serializer, SerializeStructVariant}; /// /// enum E { /// S { r: u8, g: u8, b: u8 } @@ -1295,8 +1287,7 @@ pub trait Serializer: Sized { /// # unimplemented_vec!(Vec); /// # unimplemented_vec!(Array); /// # -/// use serde::{Serialize, Serializer}; -/// use serde::ser::SerializeSeq; +/// use serde::ser::{Serialize, Serializer, SerializeSeq}; /// /// impl Serialize for Vec /// where T: Serialize @@ -1351,8 +1342,7 @@ pub trait SerializeSeq { /// Returned from `Serializer::serialize_tuple`. /// /// ```rust -/// use serde::{Serialize, Serializer}; -/// use serde::ser::SerializeTuple; +/// use serde::ser::{Serialize, Serializer, SerializeTuple}; /// /// # mod fool { /// # trait Serialize {} @@ -1397,8 +1387,7 @@ pub trait SerializeTuple { /// Returned from `Serializer::serialize_tuple_struct`. /// /// ```rust -/// use serde::{Serialize, Serializer}; -/// use serde::ser::SerializeTupleStruct; +/// use serde::ser::{Serialize, Serializer, SerializeTupleStruct}; /// /// struct Rgb(u8, u8, u8); /// @@ -1433,8 +1422,7 @@ pub trait SerializeTupleStruct { /// Returned from `Serializer::serialize_tuple_variant`. /// /// ```rust -/// use serde::{Serialize, Serializer}; -/// use serde::ser::SerializeTupleVariant; +/// use serde::ser::{Serialize, Serializer, SerializeTupleVariant}; /// /// enum E { /// T(u8, u8), @@ -1501,8 +1489,7 @@ pub trait SerializeTupleVariant { /// # } /// # } /// # -/// use serde::{Serialize, Serializer}; -/// use serde::ser::SerializeMap; +/// use serde::ser::{Serialize, Serializer, SerializeMap}; /// /// impl Serialize for HashMap /// where K: Serialize, @@ -1573,8 +1560,7 @@ pub trait SerializeMap { /// Returned from `Serializer::serialize_struct`. /// /// ```rust -/// use serde::{Serialize, Serializer}; -/// use serde::ser::SerializeStruct; +/// use serde::ser::{Serialize, Serializer, SerializeStruct}; /// /// struct Rgb { /// r: u8, @@ -1617,8 +1603,7 @@ pub trait SerializeStruct { /// Returned from `Serializer::serialize_struct_variant`. /// /// ```rust -/// use serde::{Serialize, Serializer}; -/// use serde::ser::SerializeStructVariant; +/// use serde::ser::{Serialize, Serializer, SerializeStructVariant}; /// /// enum E { /// S { r: u8, g: u8, b: u8 } From 385f83a7dec7f34368c013b8efcf2b2f490d50a9 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 15:16:43 -0700 Subject: [PATCH 122/177] Examples and links for Option --- serde/src/ser/mod.rs | 64 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index f72eba4d..1eaae172 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -703,10 +703,70 @@ pub trait Serializer: Sized { /// ``` fn serialize_bytes(self, value: &[u8]) -> Result; - /// Serialize a `None` value. + /// Serialize a [`None`] value. + /// + /// ```rust + /// # extern crate serde; + /// # + /// # use serde::{Serialize, Serializer}; + /// # + /// # enum Option { + /// # Some(T), + /// # None, + /// # } + /// # + /// # use Option::{Some, None}; + /// # + /// impl Serialize for Option + /// where T: Serialize + /// { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// match *self { + /// Some(ref value) => serializer.serialize_some(value), + /// None => serializer.serialize_none(), + /// } + /// } + /// } + /// # + /// # fn main() {} + /// ``` + /// + /// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None fn serialize_none(self) -> Result; - /// Serialize a `Some(T)` value. + /// Serialize a [`Some(T)`] value. + /// + /// ```rust + /// # extern crate serde; + /// # + /// # use serde::{Serialize, Serializer}; + /// # + /// # enum Option { + /// # Some(T), + /// # None, + /// # } + /// # + /// # use Option::{Some, None}; + /// # + /// impl Serialize for Option + /// where T: Serialize + /// { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// match *self { + /// Some(ref value) => serializer.serialize_some(value), + /// None => serializer.serialize_none(), + /// } + /// } + /// } + /// # + /// # fn main() {} + /// ``` + /// + /// [`Some(T)`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.Some fn serialize_some(self, value: &T) -> Result where T: Serialize; From 2afbffa924e3515759ec1418e795627e402fac64 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 15:20:01 -0700 Subject: [PATCH 123/177] Example for serialize_unit_struct --- serde/src/ser/mod.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 1eaae172..31fbb748 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -777,6 +777,20 @@ pub trait Serializer: Sized { /// Serialize a unit struct like `struct Unit` or `PhantomData`. /// /// A reasonable implementation would be to forward to `serialize_unit`. + /// + /// ```rust + /// use serde::{Serialize, Serializer}; + /// + /// struct Nothing; + /// + /// impl Serialize for Nothing { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// serializer.serialize_unit_struct("Nothing") + /// } + /// } + /// ``` fn serialize_unit_struct(self, name: &'static str) -> Result; /// Serialize a unit variant like `E::A` in `enum E { A, B }`. From e4b21e6caa8bbd555ad96b26acffebffc2421102 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 15:20:09 -0700 Subject: [PATCH 124/177] Example for serialize_unit --- serde/src/ser/mod.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 31fbb748..fd1c0f0d 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -772,6 +772,25 @@ pub trait Serializer: Sized { T: Serialize; /// Serialize a `()` value. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde; + /// # + /// # use serde::Serializer; + /// # + /// # __private_serialize!(); + /// # + /// impl Serialize for () { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// serializer.serialize_unit() + /// } + /// } + /// # + /// # fn main() {} + /// ``` fn serialize_unit(self) -> Result; /// Serialize a unit struct like `struct Unit` or `PhantomData`. From 7dd01dd54a69cd92b6b13020593f567e4350c2a1 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 15:26:12 -0700 Subject: [PATCH 125/177] This macro serializes a primitive --- serde/src/ser/impls.rs | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index c148b56e..dfda1f05 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -7,12 +7,13 @@ use ser::Error; //////////////////////////////////////////////////////////////////////////////// -macro_rules! impl_visit { - ($ty:ty, $method:ident $($cast:tt)*) => { +macro_rules! primitive_impl { + ($ty:ident, $method:ident $($cast:tt)*) => { impl Serialize for $ty { #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer, + where + S: Serializer, { serializer.$method(*self $($cast)*) } @@ -20,20 +21,20 @@ macro_rules! impl_visit { } } -impl_visit!(bool, serialize_bool); -impl_visit!(isize, serialize_i64 as i64); -impl_visit!(i8, serialize_i8); -impl_visit!(i16, serialize_i16); -impl_visit!(i32, serialize_i32); -impl_visit!(i64, serialize_i64); -impl_visit!(usize, serialize_u64 as u64); -impl_visit!(u8, serialize_u8); -impl_visit!(u16, serialize_u16); -impl_visit!(u32, serialize_u32); -impl_visit!(u64, serialize_u64); -impl_visit!(f32, serialize_f32); -impl_visit!(f64, serialize_f64); -impl_visit!(char, serialize_char); +primitive_impl!(bool, serialize_bool); +primitive_impl!(isize, serialize_i64 as i64); +primitive_impl!(i8, serialize_i8); +primitive_impl!(i16, serialize_i16); +primitive_impl!(i32, serialize_i32); +primitive_impl!(i64, serialize_i64); +primitive_impl!(usize, serialize_u64 as u64); +primitive_impl!(u8, serialize_u8); +primitive_impl!(u16, serialize_u16); +primitive_impl!(u32, serialize_u32); +primitive_impl!(u64, serialize_u64); +primitive_impl!(f32, serialize_f32); +primitive_impl!(f64, serialize_f64); +primitive_impl!(char, serialize_char); //////////////////////////////////////////////////////////////////////////////// From bdccde5c9b2a53bca36cf8a500a899f95906430a Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 15:34:20 -0700 Subject: [PATCH 126/177] Simplify serialize impl for String --- serde/src/ser/impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index dfda1f05..29003a90 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -55,7 +55,7 @@ impl Serialize for String { where S: Serializer, { - (&self[..]).serialize(serializer) + serializer.serialize_str(self) } } From 5d396c4e3b6a878ab16d86d52d5f195be6d55df5 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 15:41:26 -0700 Subject: [PATCH 127/177] Condense the array impls --- serde/src/ser/impls.rs | 60 ++++++++++++------------------------------ 1 file changed, 17 insertions(+), 43 deletions(-) diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 29003a90..1590ad60 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -127,54 +127,28 @@ impl Serialize for [T; 0] { } macro_rules! array_impls { - ($len:expr) => { - impl Serialize for [T; $len] where T: Serialize { - #[inline] - fn serialize(&self, serializer: S) -> Result - where S: Serializer, - { - let mut seq = try!(serializer.serialize_seq_fixed_size($len)); - for e in self { - try!(seq.serialize_element(e)); + ($($len:tt)+) => { + $( + impl Serialize for [T; $len] where T: Serialize { + #[inline] + fn serialize(&self, serializer: S) -> Result + where S: Serializer, + { + let mut seq = try!(serializer.serialize_seq_fixed_size($len)); + for e in self { + try!(seq.serialize_element(e)); + } + seq.end() } - seq.end() } - } + )+ } } -array_impls!(1); -array_impls!(2); -array_impls!(3); -array_impls!(4); -array_impls!(5); -array_impls!(6); -array_impls!(7); -array_impls!(8); -array_impls!(9); -array_impls!(10); -array_impls!(11); -array_impls!(12); -array_impls!(13); -array_impls!(14); -array_impls!(15); -array_impls!(16); -array_impls!(17); -array_impls!(18); -array_impls!(19); -array_impls!(20); -array_impls!(21); -array_impls!(22); -array_impls!(23); -array_impls!(24); -array_impls!(25); -array_impls!(26); -array_impls!(27); -array_impls!(28); -array_impls!(29); -array_impls!(30); -array_impls!(31); -array_impls!(32); +array_impls!(01 02 03 04 05 06 07 08 09 10 + 11 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27 28 29 30 + 31 32); //////////////////////////////////////////////////////////////////////////////// From a15636f808dc95064108bb4814145dc1f8ec33ee Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 15:55:34 -0700 Subject: [PATCH 128/177] More like the Deserialize impls for sequences --- serde/src/ser/impls.rs | 78 ++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 49 deletions(-) diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 1590ad60..9105d386 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -152,72 +152,52 @@ array_impls!(01 02 03 04 05 06 07 08 09 10 //////////////////////////////////////////////////////////////////////////////// -macro_rules! serialize_seq { - () => { - #[inline] - fn serialize(&self, serializer: S) -> Result - where S: Serializer, - { - serializer.collect_seq(self) - } - } -} - impl Serialize for [T] where T: Serialize, { - serialize_seq!(); + #[inline] + fn serialize(&self, serializer: S) -> Result + where S: Serializer, + { + serializer.collect_seq(self) + } +} + +macro_rules! seq_impl { + ($ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >) => { + impl Serialize for $ty + where + T: Serialize $(+ $tbound1 $(+ $tbound2)*)*, + $($typaram: $bound1 $(+ $bound2)*)* + { + #[inline] + fn serialize(&self, serializer: S) -> Result + where S: Serializer, + { + serializer.collect_seq(self) + } + } + } } #[cfg(any(feature = "std", feature = "collections"))] -impl Serialize for BinaryHeap -where - T: Serialize + Ord, -{ - serialize_seq!(); -} +seq_impl!(BinaryHeap); #[cfg(any(feature = "std", feature = "collections"))] -impl Serialize for BTreeSet -where - T: Serialize + Ord, -{ - serialize_seq!(); -} +seq_impl!(BTreeSet); #[cfg(feature = "std")] -impl Serialize for HashSet -where - T: Serialize + Eq + Hash, - H: BuildHasher, -{ - serialize_seq!(); -} +seq_impl!(HashSet); #[cfg(any(feature = "std", feature = "collections"))] -impl Serialize for LinkedList -where - T: Serialize, -{ - serialize_seq!(); -} +seq_impl!(LinkedList); #[cfg(any(feature = "std", feature = "collections"))] -impl Serialize for Vec -where - T: Serialize, -{ - serialize_seq!(); -} +seq_impl!(Vec); #[cfg(any(feature = "std", feature = "collections"))] -impl Serialize for VecDeque -where - T: Serialize, -{ - serialize_seq!(); -} +seq_impl!(VecDeque); //////////////////////////////////////////////////////////////////////////////// From 15faaf8bc331d861d29ad9814b7ebbcc6696d633 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 16:01:50 -0700 Subject: [PATCH 129/177] Condense the tuple impls --- serde/src/ser/impls.rs | 200 +++++------------------------------------ 1 file changed, 23 insertions(+), 177 deletions(-) diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 9105d386..4d1a97e4 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -233,22 +233,20 @@ impl Serialize for () { //////////////////////////////////////////////////////////////////////////////// macro_rules! tuple_impls { - ($( - $TupleVisitor:ident ($len:expr, $($T:ident),+) { - $($state:pat => $idx:tt,)+ - } - )+) => { + ($($len:expr => ($($n:tt $name:ident)+))+) => { $( - impl<$($T),+> Serialize for ($($T,)+) - where $($T: Serialize),+ + impl<$($name),+> Serialize for ($($name,)+) + where + $($name: Serialize,)+ { #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer, + where + S: Serializer, { let mut tuple = try!(serializer.serialize_tuple($len)); $( - try!(tuple.serialize_element(&self.$idx)); + try!(tuple.serialize_element(&self.$n)); )+ tuple.end() } @@ -258,174 +256,22 @@ macro_rules! tuple_impls { } tuple_impls! { - TupleVisitor1 (1, T0) { - 0 => 0, - } - TupleVisitor2 (2, T0, T1) { - 0 => 0, - 1 => 1, - } - TupleVisitor3 (3, T0, T1, T2) { - 0 => 0, - 1 => 1, - 2 => 2, - } - TupleVisitor4 (4, T0, T1, T2, T3) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - } - TupleVisitor5 (5, T0, T1, T2, T3, T4) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - } - TupleVisitor6 (6, T0, T1, T2, T3, T4, T5) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - 5 => 5, - } - TupleVisitor7 (7, T0, T1, T2, T3, T4, T5, T6) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - 5 => 5, - 6 => 6, - } - TupleVisitor8 (8, T0, T1, T2, T3, T4, T5, T6, T7) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - 5 => 5, - 6 => 6, - 7 => 7, - } - TupleVisitor9 (9, T0, T1, T2, T3, T4, T5, T6, T7, T8) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - 5 => 5, - 6 => 6, - 7 => 7, - 8 => 8, - } - TupleVisitor10 (10, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - 5 => 5, - 6 => 6, - 7 => 7, - 8 => 8, - 9 => 9, - } - TupleVisitor11 (11, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - 5 => 5, - 6 => 6, - 7 => 7, - 8 => 8, - 9 => 9, - 10 => 10, - } - TupleVisitor12 (12, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - 5 => 5, - 6 => 6, - 7 => 7, - 8 => 8, - 9 => 9, - 10 => 10, - 11 => 11, - } - TupleVisitor13 (13, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - 5 => 5, - 6 => 6, - 7 => 7, - 8 => 8, - 9 => 9, - 10 => 10, - 11 => 11, - 12 => 12, - } - TupleVisitor14 (14, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - 5 => 5, - 6 => 6, - 7 => 7, - 8 => 8, - 9 => 9, - 10 => 10, - 11 => 11, - 12 => 12, - 13 => 13, - } - TupleVisitor15 (15, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - 5 => 5, - 6 => 6, - 7 => 7, - 8 => 8, - 9 => 9, - 10 => 10, - 11 => 11, - 12 => 12, - 13 => 13, - 14 => 14, - } - TupleVisitor16 (16, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - 5 => 5, - 6 => 6, - 7 => 7, - 8 => 8, - 9 => 9, - 10 => 10, - 11 => 11, - 12 => 12, - 13 => 13, - 14 => 14, - 15 => 15, - } + 1 => (0 T0) + 2 => (0 T0 1 T1) + 3 => (0 T0 1 T1 2 T2) + 4 => (0 T0 1 T1 2 T2 3 T3) + 5 => (0 T0 1 T1 2 T2 3 T3 4 T4) + 6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5) + 7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6) + 8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7) + 9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8) + 10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9) + 11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10) + 12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11) + 13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12) + 14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13) + 15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14) + 16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15) } //////////////////////////////////////////////////////////////////////////////// From f28abe8fde465e3ca59bbffe2c323e465ddf6398 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 16:09:53 -0700 Subject: [PATCH 130/177] Map impls more like the seq impls --- serde/src/ser/impls.rs | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 4d1a97e4..46d0601e 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -165,11 +165,11 @@ where } macro_rules! seq_impl { - ($ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >) => { + ($ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident)* >) => { impl Serialize for $ty where T: Serialize $(+ $tbound1 $(+ $tbound2)*)*, - $($typaram: $bound1 $(+ $bound2)*)* + $($typaram: $bound,)* { #[inline] fn serialize(&self, serializer: S) -> Result @@ -276,35 +276,29 @@ tuple_impls! { //////////////////////////////////////////////////////////////////////////////// -macro_rules! serialize_map { - () => { - #[inline] - fn serialize(&self, serializer: S) -> Result - where S: Serializer, +macro_rules! map_impl { + ($ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)* >) => { + impl Serialize for $ty + where + K: Serialize $(+ $kbound1 $(+ $kbound2)*)*, + V: Serialize, + $($typaram: $bound,)* { - serializer.collect_map(self) + #[inline] + fn serialize(&self, serializer: S) -> Result + where S: Serializer, + { + serializer.collect_seq(self) + } } } } #[cfg(any(feature = "std", feature = "collections"))] -impl Serialize for BTreeMap -where - K: Serialize + Ord, - V: Serialize, -{ - serialize_map!(); -} +map_impl!(BTreeMap); #[cfg(feature = "std")] -impl Serialize for HashMap -where - K: Serialize + Eq + Hash, - V: Serialize, - H: BuildHasher, -{ - serialize_map!(); -} +map_impl!(HashMap); //////////////////////////////////////////////////////////////////////////////// From f45b83f0c1bf7cc4734be2cd41731976238601e9 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 16:26:30 -0700 Subject: [PATCH 131/177] Condense the deref impls --- serde/src/ser/impls.rs | 89 +++++++++--------------------------------- 1 file changed, 18 insertions(+), 71 deletions(-) diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 46d0601e..0fb48c11 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -302,87 +302,34 @@ map_impl!(HashMap); //////////////////////////////////////////////////////////////////////////////// -impl<'a, T: ?Sized> Serialize for &'a T -where - T: Serialize, -{ - #[inline] - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - (**self).serialize(serializer) - } +macro_rules! deref_impl { + ($($desc:tt)+) => { + impl $($desc)+ { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + (**self).serialize(serializer) + } + } + }; } -impl<'a, T: ?Sized> Serialize for &'a mut T -where - T: Serialize, -{ - #[inline] - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - (**self).serialize(serializer) - } -} +deref_impl!(<'a, T: ?Sized> Serialize for &'a T where T: Serialize); +deref_impl!(<'a, T: ?Sized> Serialize for &'a mut T where T: Serialize); #[cfg(any(feature = "std", feature = "alloc"))] -impl Serialize for Box -where - T: Serialize, -{ - #[inline] - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - (**self).serialize(serializer) - } -} +deref_impl!( Serialize for Box where T: Serialize); #[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] -impl Serialize for Rc -where - T: Serialize, -{ - #[inline] - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - (**self).serialize(serializer) - } -} +deref_impl!( Serialize for Rc where T: Serialize); #[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] -impl Serialize for Arc -where - T: Serialize, -{ - #[inline] - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - (**self).serialize(serializer) - } -} +deref_impl!( Serialize for Arc where T: Serialize); #[cfg(any(feature = "std", feature = "collections"))] -impl<'a, T: ?Sized> Serialize for Cow<'a, T> -where - T: Serialize + ToOwned, -{ - #[inline] - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - (**self).serialize(serializer) - } -} +deref_impl!(<'a, T: ?Sized> Serialize for Cow<'a, T> where T: Serialize + ToOwned); //////////////////////////////////////////////////////////////////////////////// From fb7964fde70c603d91005aa18f87905e5df894c0 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 16:36:24 -0700 Subject: [PATCH 132/177] Clean up serialize_display_bounded_length --- serde/src/ser/impls.rs | 46 ++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 0fb48c11..291c6670 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -369,34 +369,30 @@ impl Serialize for Duration { //////////////////////////////////////////////////////////////////////////////// -/// Seralize the `$value` that implements Display as a string, -/// when that string is statically known to never have more than -/// a constant `$MAX_LEN` bytes. +/// Serialize a value that implements `Display` as a string, when that string is +/// statically known to never have more than a constant `MAX_LEN` bytes. /// -/// Panics if the Display impl tries to write more than `$MAX_LEN` bytes. +/// Panics if the `Display` impl tries to write more than `MAX_LEN` bytes. #[cfg(feature = "std")] macro_rules! serialize_display_bounded_length { - ($value: expr, $MAX_LEN: expr, $serializer: expr) => { - { - let mut buffer: [u8; $MAX_LEN] = unsafe { mem::uninitialized() }; - let remaining_len; - { - let mut remaining = &mut buffer[..]; - write!(remaining, "{}", $value).unwrap(); - remaining_len = remaining.len() - } - let written_len = buffer.len() - remaining_len; - let written = &buffer[..written_len]; + ($value:expr, $max:expr, $serializer:expr) => {{ + let mut buffer: [u8; $max] = unsafe { mem::uninitialized() }; + let remaining_len = { + let mut remaining = &mut buffer[..]; + write!(remaining, "{}", $value).unwrap(); + remaining.len() + }; + let written_len = buffer.len() - remaining_len; + let written = &buffer[..written_len]; - // write! only provides fmt::Formatter to Display implementations, - // which has methods write_str and write_char but no method to write arbitrary bytes. - // Therefore, `written` is well-formed in UTF-8. - let written_str = unsafe { - str::from_utf8_unchecked(written) - }; - $serializer.serialize_str(written_str) - } - } + // write! only provides fmt::Formatter to Display implementations, which + // has methods write_str and write_char but no method to write arbitrary + // bytes. Therefore `written` must be valid UTF-8. + let written_str = unsafe { + str::from_utf8_unchecked(written) + }; + $serializer.serialize_str(written_str) + }} } #[cfg(feature = "std")] @@ -436,8 +432,6 @@ impl Serialize for net::Ipv6Addr { } } -//////////////////////////////////////////////////////////////////////////////// - #[cfg(feature = "std")] impl Serialize for net::SocketAddr { fn serialize(&self, serializer: S) -> Result From dbe7d04282aba75a05441bc8f30d77875a1df6db Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 16:38:04 -0700 Subject: [PATCH 133/177] Import Path and PathBuf directly --- serde/src/de/impls.rs | 10 +++++----- serde/src/lib.rs | 4 +++- serde/src/ser/impls.rs | 4 ++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 156169de..8731ae67 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -948,20 +948,20 @@ struct PathBufVisitor; #[cfg(feature = "std")] impl<'de> Visitor<'de> for PathBufVisitor { - type Value = path::PathBuf; + type Value = PathBuf; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("path string") } - fn visit_str(self, v: &str) -> Result + fn visit_str(self, v: &str) -> Result where E: Error, { Ok(From::from(v)) } - fn visit_string(self, v: String) -> Result + fn visit_string(self, v: String) -> Result where E: Error, { @@ -971,8 +971,8 @@ impl<'de> Visitor<'de> for PathBufVisitor { #[cfg(feature = "std")] -impl<'de> Deserialize<'de> for path::PathBuf { - fn deserialize(deserializer: D) -> Result +impl<'de> Deserialize<'de> for PathBuf { + fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { diff --git a/serde/src/lib.rs b/serde/src/lib.rs index de44550b..e83cfde9 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -162,7 +162,7 @@ mod lib { pub use collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque}; #[cfg(feature = "std")] - pub use std::{error, net, path}; + pub use std::{error, net}; #[cfg(feature = "std")] pub use std::collections::{HashMap, HashSet}; @@ -173,6 +173,8 @@ mod lib { #[cfg(feature = "std")] pub use std::io::Write; #[cfg(feature = "std")] + pub use std::path::{Path, PathBuf}; + #[cfg(feature = "std")] pub use std::time::Duration; #[cfg(feature = "unstable")] diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 291c6670..590fb951 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -472,7 +472,7 @@ impl Serialize for net::SocketAddrV6 { //////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "std")] -impl Serialize for path::Path { +impl Serialize for Path { fn serialize(&self, serializer: S) -> Result where S: Serializer, @@ -485,7 +485,7 @@ impl Serialize for path::Path { } #[cfg(feature = "std")] -impl Serialize for path::PathBuf { +impl Serialize for PathBuf { fn serialize(&self, serializer: S) -> Result where S: Serializer, From 8b6f77095a50c02c9308c05de464dd62334d71cb Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 16:43:03 -0700 Subject: [PATCH 134/177] Remove redundant cfg --- serde/src/ser/impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 590fb951..e6adc816 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -504,6 +504,7 @@ impl Serialize for OsStr { use std::os::unix::ffi::OsStrExt; serializer.serialize_newtype_variant("OsString", 0, "Unix", self.as_bytes()) } + #[cfg(windows)] fn serialize(&self, serializer: S) -> Result where @@ -516,7 +517,6 @@ impl Serialize for OsStr { } #[cfg(all(feature = "std", any(unix, windows)))] -#[cfg(feature = "std")] impl Serialize for OsString { fn serialize(&self, serializer: S) -> Result where From 0e7c027ff1e38e98eef51027c003607189119584 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 16:44:05 -0700 Subject: [PATCH 135/177] NonZero is just another deref --- serde/src/ser/impls.rs | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index e6adc816..d92b6266 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -331,6 +331,9 @@ deref_impl!( Serialize for Arc where T: Serialize); #[cfg(any(feature = "std", feature = "collections"))] deref_impl!(<'a, T: ?Sized> Serialize for Cow<'a, T> where T: Serialize + ToOwned); +#[cfg(feature = "unstable")] +deref_impl!( Serialize for NonZero where T: Serialize + Zeroable); + //////////////////////////////////////////////////////////////////////////////// impl Serialize for Result @@ -525,16 +528,3 @@ impl Serialize for OsString { self.as_os_str().serialize(serializer) } } - -#[cfg(feature = "unstable")] -impl Serialize for NonZero -where - T: Serialize + Zeroable, -{ - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - (**self).serialize(serializer) - } -} From dfea7ec93971894d5a18b98e00ff3664e4cd2aff Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 16:46:38 -0700 Subject: [PATCH 136/177] This is not a bottleneck --- serde/src/de/utf8.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/serde/src/de/utf8.rs b/serde/src/de/utf8.rs index be13f029..576fd03c 100644 --- a/serde/src/de/utf8.rs +++ b/serde/src/de/utf8.rs @@ -40,7 +40,6 @@ pub struct Encode { } impl Encode { - // FIXME: use this from_utf8_unchecked, since we know it can never fail pub fn as_str(&self) -> &str { str::from_utf8(&self.buf[self.pos..]).unwrap() } From dd092dce95b6c7fb0234f20b52d601ba880b5ce4 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 16:53:27 -0700 Subject: [PATCH 137/177] Allow using IgnoredAny as a visitor --- serde/src/de/ignored_any.rs | 194 ++++++++++++++++++------------------ 1 file changed, 99 insertions(+), 95 deletions(-) diff --git a/serde/src/de/ignored_any.rs b/serde/src/de/ignored_any.rs index dff76273..fb8aaf10 100644 --- a/serde/src/de/ignored_any.rs +++ b/serde/src/de/ignored_any.rs @@ -7,106 +7,110 @@ use de::{Deserialize, Deserializer, Visitor, SeqVisitor, MapVisitor, Error}; #[derive(Copy, Clone, Debug, Default)] pub struct IgnoredAny; +impl<'de> Visitor<'de> for IgnoredAny { + type Value = IgnoredAny; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("anything at all") + } + + #[inline] + fn visit_bool(self, x: bool) -> Result { + let _ = x; + Ok(IgnoredAny) + } + + #[inline] + fn visit_i64(self, x: i64) -> Result { + let _ = x; + Ok(IgnoredAny) + } + + #[inline] + fn visit_u64(self, x: u64) -> Result { + let _ = x; + Ok(IgnoredAny) + } + + #[inline] + fn visit_f64(self, x: f64) -> Result { + let _ = x; + Ok(IgnoredAny) + } + + #[inline] + fn visit_str(self, s: &str) -> Result + where + E: Error, + { + let _ = s; + Ok(IgnoredAny) + } + + #[inline] + fn visit_none(self) -> Result { + Ok(IgnoredAny) + } + + #[inline] + fn visit_some(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + IgnoredAny::deserialize(deserializer) + } + + #[inline] + fn visit_newtype_struct(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + IgnoredAny::deserialize(deserializer) + } + + #[inline] + fn visit_unit(self) -> Result { + Ok(IgnoredAny) + } + + #[inline] + fn visit_seq(self, mut visitor: V) -> Result + where + V: SeqVisitor<'de>, + { + while let Some(IgnoredAny) = try!(visitor.visit()) { + // Gobble + } + Ok(IgnoredAny) + } + + #[inline] + fn visit_map(self, mut visitor: V) -> Result + where + V: MapVisitor<'de>, + { + while let Some((IgnoredAny, IgnoredAny)) = try!(visitor.visit()) { + // Gobble + } + Ok(IgnoredAny) + } + + #[inline] + fn visit_bytes(self, bytes: &[u8]) -> Result + where + E: Error, + { + let _ = bytes; + Ok(IgnoredAny) + } +} + impl<'de> Deserialize<'de> for IgnoredAny { #[inline] fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { - struct IgnoredAnyVisitor; - - impl<'de> Visitor<'de> for IgnoredAnyVisitor { - type Value = IgnoredAny; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("anything at all") - } - - #[inline] - fn visit_bool(self, _: bool) -> Result { - Ok(IgnoredAny) - } - - #[inline] - fn visit_i64(self, _: i64) -> Result { - Ok(IgnoredAny) - } - - #[inline] - fn visit_u64(self, _: u64) -> Result { - Ok(IgnoredAny) - } - - #[inline] - fn visit_f64(self, _: f64) -> Result { - Ok(IgnoredAny) - } - - #[inline] - fn visit_str(self, _: &str) -> Result - where - E: Error, - { - Ok(IgnoredAny) - } - - #[inline] - fn visit_none(self) -> Result { - Ok(IgnoredAny) - } - - #[inline] - fn visit_some(self, deserializer: D) -> Result - where - D: Deserializer<'de>, - { - IgnoredAny::deserialize(deserializer) - } - - #[inline] - fn visit_newtype_struct(self, deserializer: D) -> Result - where - D: Deserializer<'de>, - { - IgnoredAny::deserialize(deserializer) - } - - #[inline] - fn visit_unit(self) -> Result { - Ok(IgnoredAny) - } - - #[inline] - fn visit_seq(self, mut visitor: V) -> Result - where - V: SeqVisitor<'de>, - { - while let Some(_) = try!(visitor.visit::()) { - // Gobble - } - Ok(IgnoredAny) - } - - #[inline] - fn visit_map(self, mut visitor: V) -> Result - where - V: MapVisitor<'de>, - { - while let Some((_, _)) = try!(visitor.visit::()) { - // Gobble - } - Ok(IgnoredAny) - } - - #[inline] - fn visit_bytes(self, _: &[u8]) -> Result - where - E: Error, - { - Ok(IgnoredAny) - } - } - - deserializer.deserialize_ignored_any(IgnoredAnyVisitor) + deserializer.deserialize_ignored_any(IgnoredAny) } } From a937a06d3e0ca1ae92eea7140f8c79a961e380de Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 17:22:51 -0700 Subject: [PATCH 138/177] Add an IgnoredAny example --- serde/src/de/ignored_any.rs | 95 ++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 2 deletions(-) diff --git a/serde/src/de/ignored_any.rs b/serde/src/de/ignored_any.rs index fb8aaf10..048c6a3a 100644 --- a/serde/src/de/ignored_any.rs +++ b/serde/src/de/ignored_any.rs @@ -2,8 +2,99 @@ use lib::*; use de::{Deserialize, Deserializer, Visitor, SeqVisitor, MapVisitor, Error}; -/// A target for deserializers that want to ignore data. Implements Deserialize -/// and silently eats data given to it. +/// An efficient way of discarding data from a deserializer. +/// +/// Think of this like `serde_json::Value` in that it can be deserialized from +/// any type, except that it does not store any information about the data that +/// gets deserialized. +/// +/// ```rust +/// use std::fmt; +/// use std::marker::PhantomData; +/// +/// use serde::de::{self, Deserialize, DeserializeSeed, Deserializer, Visitor, SeqVisitor, IgnoredAny}; +/// +/// /// A seed that can be used to deserialize only the `n`th element of a sequence +/// /// while efficiently discarding elements of any type before or after index `n`. +/// /// +/// /// For example to deserialize only the element at index 3: +/// /// +/// /// ```rust +/// /// NthElement::new(3).deserialize(deserializer) +/// /// ``` +/// pub struct NthElement { +/// n: usize, +/// marker: PhantomData, +/// } +/// +/// impl NthElement { +/// pub fn new(n: usize) -> Self { +/// NthElement { +/// n: n, +/// marker: PhantomData, +/// } +/// } +/// } +/// +/// impl<'de, T> Visitor<'de> for NthElement +/// where T: Deserialize<'de> +/// { +/// type Value = T; +/// +/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { +/// write!(formatter, "a sequence in which we care about element {}", self.n) +/// } +/// +/// fn visit_seq(self, mut seq: V) -> Result +/// where V: SeqVisitor<'de> +/// { +/// // Skip over the first `n` elements. +/// for i in 0..self.n { +/// // It is an error if the sequence ends before we get to element `n`. +/// if seq.visit::()?.is_none() { +/// return Err(de::Error::invalid_length(i, &self)); +/// } +/// } +/// +/// // Deserialize the one we care about. +/// let nth = match seq.visit()? { +/// Some(nth) => nth, +/// None => { +/// return Err(de::Error::invalid_length(self.n, &self)); +/// } +/// }; +/// +/// // Skip over any remaining elements in the sequence after `n`. +/// while let Some(IgnoredAny) = seq.visit()? { +/// // ignore +/// } +/// +/// Ok(nth) +/// } +/// } +/// +/// impl<'de, T> DeserializeSeed<'de> for NthElement +/// where T: Deserialize<'de> +/// { +/// type Value = T; +/// +/// fn deserialize(self, deserializer: D) -> Result +/// where D: Deserializer<'de> +/// { +/// deserializer.deserialize_seq(self) +/// } +/// } +/// +/// # fn example<'de, D>(deserializer: D) -> Result<(), D::Error> +/// # where D: Deserializer<'de> +/// # { +/// // Deserialize only the sequence element at index 3 from this deserializer. +/// // The element at index 3 is required to be a string. Elements before and +/// // after index 3 are allowed to be of any type. +/// let s: String = NthElement::new(3).deserialize(deserializer)?; +/// # Ok(()) +/// # } +/// ``` #[derive(Copy, Clone, Debug, Default)] pub struct IgnoredAny; From 3f920f645c4ba614775fff9e6d914ecd3a8184f7 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 17:34:42 -0700 Subject: [PATCH 139/177] License boilerplate --- serde/src/de/from_primitive.rs | 4 +--- serde/src/de/ignored_any.rs | 8 ++++++++ serde/src/de/impls.rs | 8 ++++++++ serde/src/de/mod.rs | 8 ++++++++ serde/src/de/utf8.rs | 8 ++++++++ serde/src/de/value.rs | 8 ++++++++ serde/src/export.rs | 8 ++++++++ serde/src/lib.rs | 8 ++++++++ serde/src/macros.rs | 8 ++++++++ serde/src/private/de.rs | 8 ++++++++ serde/src/private/macros.rs | 8 ++++++++ serde/src/private/mod.rs | 8 ++++++++ serde/src/private/ser.rs | 8 ++++++++ serde/src/ser/impls.rs | 8 ++++++++ serde/src/ser/impossible.rs | 8 ++++++++ serde/src/ser/mod.rs | 8 ++++++++ serde_codegen_internals/src/ast.rs | 8 ++++++++ serde_codegen_internals/src/attr.rs | 8 ++++++++ serde_codegen_internals/src/case.rs | 8 ++++++++ serde_codegen_internals/src/check.rs | 8 ++++++++ serde_codegen_internals/src/ctxt.rs | 8 ++++++++ serde_codegen_internals/src/lib.rs | 8 ++++++++ serde_derive/src/bound.rs | 8 ++++++++ serde_derive/src/de.rs | 8 ++++++++ serde_derive/src/fragment.rs | 8 ++++++++ serde_derive/src/lib.rs | 8 ++++++++ serde_derive/src/ser.rs | 8 ++++++++ serde_test/src/assert.rs | 8 ++++++++ serde_test/src/de.rs | 8 ++++++++ serde_test/src/error.rs | 8 ++++++++ serde_test/src/lib.rs | 8 ++++++++ serde_test/src/ser.rs | 8 ++++++++ serde_test/src/token.rs | 8 ++++++++ test_suite/tests/compile-fail/borrow/bad_lifetimes.rs | 8 ++++++++ .../tests/compile-fail/borrow/duplicate_lifetime.rs | 8 ++++++++ test_suite/tests/compile-fail/borrow/empty_lifetimes.rs | 8 ++++++++ test_suite/tests/compile-fail/borrow/no_lifetimes.rs | 8 ++++++++ test_suite/tests/compile-fail/borrow/wrong_lifetime.rs | 8 ++++++++ test_suite/tests/compile-fail/default-attribute/enum.rs | 8 ++++++++ .../default-attribute/nameless_struct_fields.rs | 8 ++++++++ .../compile-fail/duplicate-attribute/rename-and-ser.rs | 8 ++++++++ .../compile-fail/duplicate-attribute/rename-rename-de.rs | 8 ++++++++ .../duplicate-attribute/rename-ser-rename-ser.rs | 8 ++++++++ .../compile-fail/duplicate-attribute/rename-ser-rename.rs | 8 ++++++++ .../compile-fail/duplicate-attribute/rename-ser-ser.rs | 8 ++++++++ .../compile-fail/duplicate-attribute/two-rename-ser.rs | 8 ++++++++ .../duplicate-attribute/with-and-serialize-with.rs | 8 ++++++++ .../enum-representation/internal-tuple-variant.rs | 8 ++++++++ .../enum-representation/internally-tagged-struct.rs | 8 ++++++++ .../enum-representation/untagged-and-internal.rs | 8 ++++++++ .../compile-fail/enum-representation/untagged-struct.rs | 8 ++++++++ test_suite/tests/compile-fail/remote/bad_getter.rs | 8 ++++++++ test_suite/tests/compile-fail/remote/bad_remote.rs | 8 ++++++++ test_suite/tests/compile-fail/remote/enum_getter.rs | 8 ++++++++ test_suite/tests/compile-fail/remote/missing_field.rs | 8 ++++++++ test_suite/tests/compile-fail/remote/nonremote_getter.rs | 8 ++++++++ test_suite/tests/compile-fail/remote/unknown_field.rs | 8 ++++++++ test_suite/tests/compile-fail/remote/wrong_de.rs | 8 ++++++++ test_suite/tests/compile-fail/remote/wrong_getter.rs | 8 ++++++++ test_suite/tests/compile-fail/remote/wrong_ser.rs | 8 ++++++++ test_suite/tests/compile-fail/type-attribute/from.rs | 8 ++++++++ test_suite/tests/compile-fail/type-attribute/into.rs | 8 ++++++++ .../tests/compile-fail/unknown-attribute/container.rs | 8 ++++++++ test_suite/tests/compile-fail/unknown-attribute/field.rs | 8 ++++++++ .../tests/compile-fail/unknown-attribute/variant.rs | 8 ++++++++ test_suite/tests/compiletest.rs | 8 ++++++++ test_suite/tests/macros.rs | 8 ++++++++ test_suite/tests/run-pass/identity-op.rs | 8 ++++++++ test_suite/tests/test_annotations.rs | 8 ++++++++ test_suite/tests/test_borrow.rs | 8 ++++++++ test_suite/tests/test_de.rs | 8 ++++++++ test_suite/tests/test_gen.rs | 8 ++++++++ test_suite/tests/test_macros.rs | 8 ++++++++ test_suite/tests/test_remote.rs | 8 ++++++++ test_suite/tests/test_ser.rs | 8 ++++++++ test_suite/tests/test_value.rs | 8 ++++++++ 76 files changed, 601 insertions(+), 3 deletions(-) diff --git a/serde/src/de/from_primitive.rs b/serde/src/de/from_primitive.rs index 9ec25904..ae293952 100644 --- a/serde/src/de/from_primitive.rs +++ b/serde/src/de/from_primitive.rs @@ -1,6 +1,4 @@ -// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. +// Copyright 2017 Serde Developers // // Licensed under the Apache License, Version 2.0 or the MIT license diff --git a/serde/src/de/ignored_any.rs b/serde/src/de/ignored_any.rs index 048c6a3a..b8ff0c75 100644 --- a/serde/src/de/ignored_any.rs +++ b/serde/src/de/ignored_any.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use lib::*; use de::{Deserialize, Deserializer, Visitor, SeqVisitor, MapVisitor, Error}; diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 8731ae67..12d2b96d 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use lib::*; use de::{Deserialize, Deserializer, EnumVisitor, Error, SeqVisitor, Unexpected, VariantVisitor, diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 89d4a792..a9772922 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + //! Generic data structure deserialization framework. //! //! The two most important traits in this module are `Deserialize` and diff --git a/serde/src/de/utf8.rs b/serde/src/de/utf8.rs index 576fd03c..37221a1e 100644 --- a/serde/src/de/utf8.rs +++ b/serde/src/de/utf8.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use lib::*; const TAG_CONT: u8 = 0b1000_0000; diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 34802e02..7e859f30 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + //! This module supports deserializing from primitives with the `ValueDeserializer` trait. use lib::*; diff --git a/serde/src/export.rs b/serde/src/export.rs index cad039fd..bf017bbd 100644 --- a/serde/src/export.rs +++ b/serde/src/export.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + pub use lib::clone::Clone; pub use lib::convert::{From, Into}; pub use lib::default::Default; diff --git a/serde/src/lib.rs b/serde/src/lib.rs index e83cfde9..bad71266 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + //! # Serde //! //! Serde is a framework for ***ser***ializing and ***de***serializing Rust data diff --git a/serde/src/macros.rs b/serde/src/macros.rs index c2e43f1b..2ff7ec37 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + // Super explicit first paragraph because this shows up at the top level and // trips up people who are just looking for basic Serialize / Deserialize // documentation. diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 0f0d2c4f..844a9d7b 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use lib::*; use de::{Deserialize, Deserializer, Error, Visitor}; diff --git a/serde/src/private/macros.rs b/serde/src/private/macros.rs index a25de638..0253e6e0 100644 --- a/serde/src/private/macros.rs +++ b/serde/src/private/macros.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[doc(hidden)] #[macro_export] macro_rules! __private_serialize { diff --git a/serde/src/private/mod.rs b/serde/src/private/mod.rs index 7e0a82de..98307c97 100644 --- a/serde/src/private/mod.rs +++ b/serde/src/private/mod.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + mod macros; pub mod ser; diff --git a/serde/src/private/ser.rs b/serde/src/private/ser.rs index ccf77723..994875d4 100644 --- a/serde/src/private/ser.rs +++ b/serde/src/private/ser.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use lib::*; use ser::{self, Serialize, Serializer, SerializeMap, SerializeStruct, Impossible}; diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index d92b6266..a44da1ce 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use lib::*; use ser::{Serialize, SerializeSeq, SerializeTuple, Serializer}; diff --git a/serde/src/ser/impossible.rs b/serde/src/ser/impossible.rs index 36fa421f..592047f4 100644 --- a/serde/src/ser/impossible.rs +++ b/serde/src/ser/impossible.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + //! This module contains `Impossible` serializer and its implementations. use lib::*; diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index fd1c0f0d..0aa3c9a7 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + //! Generic data structure serialization framework. //! //! The two most important traits in this module are [`Serialize`] and diff --git a/serde_codegen_internals/src/ast.rs b/serde_codegen_internals/src/ast.rs index 462d061f..062281d9 100644 --- a/serde_codegen_internals/src/ast.rs +++ b/serde_codegen_internals/src/ast.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use syn; use attr; use check; diff --git a/serde_codegen_internals/src/attr.rs b/serde_codegen_internals/src/attr.rs index cb4ddd8a..5e3c0dc1 100644 --- a/serde_codegen_internals/src/attr.rs +++ b/serde_codegen_internals/src/attr.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use Ctxt; use syn; use syn::MetaItem::{List, NameValue, Word}; diff --git a/serde_codegen_internals/src/case.rs b/serde_codegen_internals/src/case.rs index d25d98df..3d3af39f 100644 --- a/serde_codegen_internals/src/case.rs +++ b/serde_codegen_internals/src/case.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use std::ascii::AsciiExt; use std::str::FromStr; diff --git a/serde_codegen_internals/src/check.rs b/serde_codegen_internals/src/check.rs index fd4d4e7d..4ac274e1 100644 --- a/serde_codegen_internals/src/check.rs +++ b/serde_codegen_internals/src/check.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use ast::{Body, Item}; use Ctxt; diff --git a/serde_codegen_internals/src/ctxt.rs b/serde_codegen_internals/src/ctxt.rs index a112c7e9..80aec476 100644 --- a/serde_codegen_internals/src/ctxt.rs +++ b/serde_codegen_internals/src/ctxt.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use std::fmt::Display; use std::cell::RefCell; diff --git a/serde_codegen_internals/src/lib.rs b/serde_codegen_internals/src/lib.rs index 6353330b..df018f0e 100644 --- a/serde_codegen_internals/src/lib.rs +++ b/serde_codegen_internals/src/lib.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + extern crate syn; #[macro_use] extern crate synom; diff --git a/serde_derive/src/bound.rs b/serde_derive/src/bound.rs index c980d3df..d539617b 100644 --- a/serde_derive/src/bound.rs +++ b/serde_derive/src/bound.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use std::collections::HashSet; use syn::{self, visit}; diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 7493e000..6d07458d 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use syn::{self, Ident}; use quote::{self, Tokens, ToTokens}; diff --git a/serde_derive/src/fragment.rs b/serde_derive/src/fragment.rs index f35578db..58cf0a2c 100644 --- a/serde_derive/src/fragment.rs +++ b/serde_derive/src/fragment.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use quote::{Tokens, ToTokens}; pub enum Fragment { diff --git a/serde_derive/src/lib.rs b/serde_derive/src/lib.rs index b543732c..a88a47a1 100644 --- a/serde_derive/src/lib.rs +++ b/serde_derive/src/lib.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #![doc(html_root_url = "https://docs.rs/serde_derive/0.9.13")] #![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))] diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index 45293cdb..43bd4c8a 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use syn::{self, Ident}; use quote::Tokens; diff --git a/serde_test/src/assert.rs b/serde_test/src/assert.rs index 6715c5b1..5f6e946c 100644 --- a/serde_test/src/assert.rs +++ b/serde_test/src/assert.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use serde::{Serialize, Deserialize}; use de::Deserializer; diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index 5727b889..c30f6e27 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use serde::de::{self, Deserialize, DeserializeSeed, EnumVisitor, IntoDeserializer, MapVisitor, SeqVisitor, VariantVisitor, Visitor}; use serde::de::value::{MapVisitorDeserializer, SeqVisitorDeserializer}; diff --git a/serde_test/src/error.rs b/serde_test/src/error.rs index 2cf5161f..034a019a 100644 --- a/serde_test/src/error.rs +++ b/serde_test/src/error.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use std::error; use std::fmt::{self, Display}; diff --git a/serde_test/src/lib.rs b/serde_test/src/lib.rs index ac86f444..346e0d70 100644 --- a/serde_test/src/lib.rs +++ b/serde_test/src/lib.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #![doc(html_root_url = "https://docs.rs/serde_test/0.9.13")] #[macro_use] diff --git a/serde_test/src/ser.rs b/serde_test/src/ser.rs index 4e733fcf..b7b80d3b 100644 --- a/serde_test/src/ser.rs +++ b/serde_test/src/ser.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use serde::{ser, Serialize}; use error::Error; diff --git a/serde_test/src/token.rs b/serde_test/src/token.rs index a9d01a33..c640e48f 100644 --- a/serde_test/src/token.rs +++ b/serde_test/src/token.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[derive(Copy, Clone, PartialEq, Debug)] pub enum Token { /// A serialized `bool`. diff --git a/test_suite/tests/compile-fail/borrow/bad_lifetimes.rs b/test_suite/tests/compile-fail/borrow/bad_lifetimes.rs index b4a5e4a3..a33968f3 100644 --- a/test_suite/tests/compile-fail/borrow/bad_lifetimes.rs +++ b/test_suite/tests/compile-fail/borrow/bad_lifetimes.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/borrow/duplicate_lifetime.rs b/test_suite/tests/compile-fail/borrow/duplicate_lifetime.rs index 542ddc2a..482a8411 100644 --- a/test_suite/tests/compile-fail/borrow/duplicate_lifetime.rs +++ b/test_suite/tests/compile-fail/borrow/duplicate_lifetime.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/borrow/empty_lifetimes.rs b/test_suite/tests/compile-fail/borrow/empty_lifetimes.rs index c1d43b57..0aec052b 100644 --- a/test_suite/tests/compile-fail/borrow/empty_lifetimes.rs +++ b/test_suite/tests/compile-fail/borrow/empty_lifetimes.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/borrow/no_lifetimes.rs b/test_suite/tests/compile-fail/borrow/no_lifetimes.rs index 47b3c0d4..ca0f0409 100644 --- a/test_suite/tests/compile-fail/borrow/no_lifetimes.rs +++ b/test_suite/tests/compile-fail/borrow/no_lifetimes.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/borrow/wrong_lifetime.rs b/test_suite/tests/compile-fail/borrow/wrong_lifetime.rs index 5cf8999f..707cd118 100644 --- a/test_suite/tests/compile-fail/borrow/wrong_lifetime.rs +++ b/test_suite/tests/compile-fail/borrow/wrong_lifetime.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/default-attribute/enum.rs b/test_suite/tests/compile-fail/default-attribute/enum.rs index 74c5d7ca..7b0649bb 100644 --- a/test_suite/tests/compile-fail/default-attribute/enum.rs +++ b/test_suite/tests/compile-fail/default-attribute/enum.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/default-attribute/nameless_struct_fields.rs b/test_suite/tests/compile-fail/default-attribute/nameless_struct_fields.rs index 2e8bccc6..83aec668 100644 --- a/test_suite/tests/compile-fail/default-attribute/nameless_struct_fields.rs +++ b/test_suite/tests/compile-fail/default-attribute/nameless_struct_fields.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/duplicate-attribute/rename-and-ser.rs b/test_suite/tests/compile-fail/duplicate-attribute/rename-and-ser.rs index c55a7140..cc94685c 100644 --- a/test_suite/tests/compile-fail/duplicate-attribute/rename-and-ser.rs +++ b/test_suite/tests/compile-fail/duplicate-attribute/rename-and-ser.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/duplicate-attribute/rename-rename-de.rs b/test_suite/tests/compile-fail/duplicate-attribute/rename-rename-de.rs index 92b02a8d..9b02357a 100644 --- a/test_suite/tests/compile-fail/duplicate-attribute/rename-rename-de.rs +++ b/test_suite/tests/compile-fail/duplicate-attribute/rename-rename-de.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/duplicate-attribute/rename-ser-rename-ser.rs b/test_suite/tests/compile-fail/duplicate-attribute/rename-ser-rename-ser.rs index 3f3ead14..b8434413 100644 --- a/test_suite/tests/compile-fail/duplicate-attribute/rename-ser-rename-ser.rs +++ b/test_suite/tests/compile-fail/duplicate-attribute/rename-ser-rename-ser.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/duplicate-attribute/rename-ser-rename.rs b/test_suite/tests/compile-fail/duplicate-attribute/rename-ser-rename.rs index 5f160c40..8aee5131 100644 --- a/test_suite/tests/compile-fail/duplicate-attribute/rename-ser-rename.rs +++ b/test_suite/tests/compile-fail/duplicate-attribute/rename-ser-rename.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/duplicate-attribute/rename-ser-ser.rs b/test_suite/tests/compile-fail/duplicate-attribute/rename-ser-ser.rs index 7792bf6a..25c50fa2 100644 --- a/test_suite/tests/compile-fail/duplicate-attribute/rename-ser-ser.rs +++ b/test_suite/tests/compile-fail/duplicate-attribute/rename-ser-ser.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/duplicate-attribute/two-rename-ser.rs b/test_suite/tests/compile-fail/duplicate-attribute/two-rename-ser.rs index 31d903ee..96a65732 100644 --- a/test_suite/tests/compile-fail/duplicate-attribute/two-rename-ser.rs +++ b/test_suite/tests/compile-fail/duplicate-attribute/two-rename-ser.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/duplicate-attribute/with-and-serialize-with.rs b/test_suite/tests/compile-fail/duplicate-attribute/with-and-serialize-with.rs index 9d6058f6..9ca98995 100644 --- a/test_suite/tests/compile-fail/duplicate-attribute/with-and-serialize-with.rs +++ b/test_suite/tests/compile-fail/duplicate-attribute/with-and-serialize-with.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/enum-representation/internal-tuple-variant.rs b/test_suite/tests/compile-fail/enum-representation/internal-tuple-variant.rs index c399ab07..6b02bfd0 100644 --- a/test_suite/tests/compile-fail/enum-representation/internal-tuple-variant.rs +++ b/test_suite/tests/compile-fail/enum-representation/internal-tuple-variant.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/enum-representation/internally-tagged-struct.rs b/test_suite/tests/compile-fail/enum-representation/internally-tagged-struct.rs index bd4fe2ea..31615ff6 100644 --- a/test_suite/tests/compile-fail/enum-representation/internally-tagged-struct.rs +++ b/test_suite/tests/compile-fail/enum-representation/internally-tagged-struct.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/enum-representation/untagged-and-internal.rs b/test_suite/tests/compile-fail/enum-representation/untagged-and-internal.rs index 71104ff6..4edbf004 100644 --- a/test_suite/tests/compile-fail/enum-representation/untagged-and-internal.rs +++ b/test_suite/tests/compile-fail/enum-representation/untagged-and-internal.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/enum-representation/untagged-struct.rs b/test_suite/tests/compile-fail/enum-representation/untagged-struct.rs index 0bf6dd13..3546748e 100644 --- a/test_suite/tests/compile-fail/enum-representation/untagged-struct.rs +++ b/test_suite/tests/compile-fail/enum-representation/untagged-struct.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/remote/bad_getter.rs b/test_suite/tests/compile-fail/remote/bad_getter.rs index 3495a10b..7b01c9cf 100644 --- a/test_suite/tests/compile-fail/remote/bad_getter.rs +++ b/test_suite/tests/compile-fail/remote/bad_getter.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/remote/bad_remote.rs b/test_suite/tests/compile-fail/remote/bad_remote.rs index 5ef17670..a81627db 100644 --- a/test_suite/tests/compile-fail/remote/bad_remote.rs +++ b/test_suite/tests/compile-fail/remote/bad_remote.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/remote/enum_getter.rs b/test_suite/tests/compile-fail/remote/enum_getter.rs index e012cbe1..016cfc03 100644 --- a/test_suite/tests/compile-fail/remote/enum_getter.rs +++ b/test_suite/tests/compile-fail/remote/enum_getter.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/remote/missing_field.rs b/test_suite/tests/compile-fail/remote/missing_field.rs index 3be802a6..d4ceca3c 100644 --- a/test_suite/tests/compile-fail/remote/missing_field.rs +++ b/test_suite/tests/compile-fail/remote/missing_field.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/remote/nonremote_getter.rs b/test_suite/tests/compile-fail/remote/nonremote_getter.rs index 11271e5a..ce7539be 100644 --- a/test_suite/tests/compile-fail/remote/nonremote_getter.rs +++ b/test_suite/tests/compile-fail/remote/nonremote_getter.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/remote/unknown_field.rs b/test_suite/tests/compile-fail/remote/unknown_field.rs index 8f2fa481..d1f2206c 100644 --- a/test_suite/tests/compile-fail/remote/unknown_field.rs +++ b/test_suite/tests/compile-fail/remote/unknown_field.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/remote/wrong_de.rs b/test_suite/tests/compile-fail/remote/wrong_de.rs index 58a05e19..10e97986 100644 --- a/test_suite/tests/compile-fail/remote/wrong_de.rs +++ b/test_suite/tests/compile-fail/remote/wrong_de.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/remote/wrong_getter.rs b/test_suite/tests/compile-fail/remote/wrong_getter.rs index f767263d..e939928a 100644 --- a/test_suite/tests/compile-fail/remote/wrong_getter.rs +++ b/test_suite/tests/compile-fail/remote/wrong_getter.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/remote/wrong_ser.rs b/test_suite/tests/compile-fail/remote/wrong_ser.rs index bd4ca1a2..ac3c7c24 100644 --- a/test_suite/tests/compile-fail/remote/wrong_ser.rs +++ b/test_suite/tests/compile-fail/remote/wrong_ser.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/type-attribute/from.rs b/test_suite/tests/compile-fail/type-attribute/from.rs index 408f33b5..72e0f1de 100644 --- a/test_suite/tests/compile-fail/type-attribute/from.rs +++ b/test_suite/tests/compile-fail/type-attribute/from.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/type-attribute/into.rs b/test_suite/tests/compile-fail/type-attribute/into.rs index 62a0982a..8f6de4d4 100644 --- a/test_suite/tests/compile-fail/type-attribute/into.rs +++ b/test_suite/tests/compile-fail/type-attribute/into.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/unknown-attribute/container.rs b/test_suite/tests/compile-fail/unknown-attribute/container.rs index 9bf97a19..c60c99c1 100644 --- a/test_suite/tests/compile-fail/unknown-attribute/container.rs +++ b/test_suite/tests/compile-fail/unknown-attribute/container.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/unknown-attribute/field.rs b/test_suite/tests/compile-fail/unknown-attribute/field.rs index 82915b21..66c3a0a8 100644 --- a/test_suite/tests/compile-fail/unknown-attribute/field.rs +++ b/test_suite/tests/compile-fail/unknown-attribute/field.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compile-fail/unknown-attribute/variant.rs b/test_suite/tests/compile-fail/unknown-attribute/variant.rs index de3ec976..0cfac627 100644 --- a/test_suite/tests/compile-fail/unknown-attribute/variant.rs +++ b/test_suite/tests/compile-fail/unknown-attribute/variant.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/compiletest.rs b/test_suite/tests/compiletest.rs index a4773093..f5fb664e 100644 --- a/test_suite/tests/compiletest.rs +++ b/test_suite/tests/compiletest.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #![cfg(feature = "unstable")] extern crate compiletest_rs as compiletest; diff --git a/test_suite/tests/macros.rs b/test_suite/tests/macros.rs index fdf61515..4f6ea66e 100644 --- a/test_suite/tests/macros.rs +++ b/test_suite/tests/macros.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + macro_rules! btreeset { () => { BTreeSet::new() diff --git a/test_suite/tests/run-pass/identity-op.rs b/test_suite/tests/run-pass/identity-op.rs index e1638025..2ec0cc19 100644 --- a/test_suite/tests/run-pass/identity-op.rs +++ b/test_suite/tests/run-pass/identity-op.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #![deny(identity_op)] #[macro_use] diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index 45e9b441..74376209 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/test_borrow.rs b/test_suite/tests/test_borrow.rs index 47c58844..9d0a65fc 100644 --- a/test_suite/tests/test_borrow.rs +++ b/test_suite/tests/test_borrow.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/test_de.rs b/test_suite/tests/test_de.rs index dc2662fb..4a0ebb10 100644 --- a/test_suite/tests/test_de.rs +++ b/test_suite/tests/test_de.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #![cfg_attr(feature = "unstable", feature(into_boxed_c_str))] #[macro_use] diff --git a/test_suite/tests/test_gen.rs b/test_suite/tests/test_gen.rs index b4cddfa5..2f3d6299 100644 --- a/test_suite/tests/test_gen.rs +++ b/test_suite/tests/test_gen.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developer +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + // These just test that serde_codegen is able to produce code that compiles // successfully when there are a variety of generics and non-(de)serializable // types involved. diff --git a/test_suite/tests/test_macros.rs b/test_suite/tests/test_macros.rs index e16a54d5..2f35fcf4 100644 --- a/test_suite/tests/test_macros.rs +++ b/test_suite/tests/test_macros.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/test_remote.rs b/test_suite/tests/test_remote.rs index 3e3217c8..30ccbb27 100644 --- a/test_suite/tests/test_remote.rs +++ b/test_suite/tests/test_remote.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/test_ser.rs b/test_suite/tests/test_ser.rs index 46a7c3fa..28472ce3 100644 --- a/test_suite/tests/test_ser.rs +++ b/test_suite/tests/test_ser.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; diff --git a/test_suite/tests/test_value.rs b/test_suite/tests/test_value.rs index 08b1c3c3..42df751c 100644 --- a/test_suite/tests/test_value.rs +++ b/test_suite/tests/test_value.rs @@ -1,3 +1,11 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + #[macro_use] extern crate serde_derive; From 37f8ea234fc41c06c1000757ee5b97d88a7c2553 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 17:43:10 -0700 Subject: [PATCH 140/177] Hyperlink the de module documentation --- serde/src/de/mod.rs | 52 ++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index a9772922..ae819be9 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -8,8 +8,8 @@ //! Generic data structure deserialization framework. //! -//! The two most important traits in this module are `Deserialize` and -//! `Deserializer`. +//! The two most important traits in this module are [`Deserialize`] and +//! [`Deserializer`]. //! //! - **A type that implements `Deserialize` is a data structure** that can be //! deserialized from any data format supported by Serde, and conversely @@ -18,32 +18,31 @@ //! //! # The Deserialize trait //! -//! Serde provides `Deserialize` implementations for many Rust primitive and +//! Serde provides [`Deserialize`] implementations for many Rust primitive and //! standard library types. The complete list is below. All of these can be //! deserialized using Serde out of the box. //! -//! Additionally, Serde provides a procedural macro called `serde_derive` to -//! automatically generate `Deserialize` implementations for structs and enums -//! in your program. See the [codegen section of the manual][codegen] for how to -//! use this. +//! Additionally, Serde provides a procedural macro called [`serde_derive`] to +//! automatically generate [`Deserialize`] implementations for structs and enums +//! in your program. See the [codegen section of the manual] for how to use +//! this. //! -//! In rare cases it may be necessary to implement `Deserialize` manually for -//! some type in your program. See the [Implementing -//! `Deserialize`][impl-deserialize] section of the manual for more about this. +//! In rare cases it may be necessary to implement [`Deserialize`] manually for +//! some type in your program. See the [Implementing `Deserialize`] section of +//! the manual for more about this. //! -//! Third-party crates may provide `Deserialize` implementations for types that -//! they expose. For example the `linked-hash-map` crate provides a -//! `LinkedHashMap` type that is deserializable by Serde because the crate -//! provides an implementation of `Deserialize` for it. +//! Third-party crates may provide [`Deserialize`] implementations for types +//! that they expose. For example the [`linked-hash-map`] crate provides a +//! [`LinkedHashMap`] type that is deserializable by Serde because the +//! crate provides an implementation of [`Deserialize`] for it. //! //! # The Deserializer trait //! -//! `Deserializer` implementations are provided by third-party crates, for -//! example [`serde_json`][serde_json], [`serde_yaml`][serde_yaml] and -//! [`bincode`][bincode]. +//! [`Deserializer`] implementations are provided by third-party crates, for +//! example [`serde_json`], [`serde_yaml`] and [`bincode`]. //! //! A partial list of well-maintained formats is given on the [Serde -//! website][data-formats]. +//! website][data formats]. //! //! # Implementations of Deserialize provided by Serde //! @@ -95,12 +94,17 @@ //! - SocketAddrV4 //! - SocketAddrV6 //! -//! [codegen]: https://serde.rs/codegen.html -//! [impl-deserialize]: https://serde.rs/impl-deserialize.html -//! [serde_json]: https://github.com/serde-rs/json -//! [serde_yaml]: https://github.com/dtolnay/serde-yaml -//! [bincode]: https://github.com/TyOverby/bincode -//! [data-formats]: https://serde.rs/#data-formats +//! [Implementing `Deserialize`]: https://serde.rs/impl-deserialize.html +//! [`Deserialize`]: ../trait.Deserialize.html +//! [`Deserializer`]: ../trait.Deserializer.html +//! [`LinkedHashMap`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html +//! [`bincode`]: https://github.com/TyOverby/bincode +//! [`linked-hash-map`]: https://crates.io/crates/linked-hash-map +//! [`serde_derive`]: https://crates.io/crates/serde_derive +//! [`serde_json`]: https://github.com/serde-rs/json +//! [`serde_yaml`]: https://github.com/dtolnay/serde-yaml +//! [codegen section of the manual]: https://serde.rs/codegen.html +//! [data formats]: https://serde.rs/#data-formats use lib::*; From 03462b6e39ce8e160ccf1b7ebed180867c387fb9 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 17:48:39 -0700 Subject: [PATCH 141/177] Update the list of deserializable types --- serde/src/de/mod.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index ae819be9..35e00531 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -48,12 +48,12 @@ //! //! This is a slightly different set of types than what is supported for //! serialization. Some types can be serialized by Serde but not deserialized. -//! One example is `&str`. +//! One example is `OsStr`. //! //! - **Primitive types**: //! - bool -//! - isize, i8, i16, i32, i64 -//! - usize, u8, u16, u32, u64 +//! - i8, i16, i32, i64, isize +//! - u8, u16, u32, u64, usize //! - f32, f64 //! - char //! - **Compound types**: @@ -81,10 +81,18 @@ //! - VecDeque\ //! - Vec\ //! - EnumSet\ (unstable) +//! - **Zero-copy types**: +//! - &str +//! - &[u8] +//! - **FFI types**: +//! - CString +//! - Box\ +//! - OsString //! - **Miscellaneous standard library types**: //! - Duration //! - Path //! - PathBuf +//! - Range\ //! - NonZero\ (unstable) //! - **Net types**: //! - IpAddr From 91a0f248a1259b26fef63ddf59e11fbb032bf7b6 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 22:58:47 -0700 Subject: [PATCH 142/177] More readable MapDeserializer bounds --- serde/src/de/value.rs | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 7e859f30..76b2ea84 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -11,6 +11,7 @@ use lib::*; use de::{self, IntoDeserializer, Expected, SeqVisitor}; +use self::private::{First, Second}; //////////////////////////////////////////////////////////////////////////////// @@ -641,12 +642,12 @@ pub struct MapDeserializer<'de, I, E> where I: Iterator, I::Item: private::Pair, - ::First: IntoDeserializer<'de, E>, - ::Second: IntoDeserializer<'de, E>, + First: IntoDeserializer<'de, E>, + Second: IntoDeserializer<'de, E>, E: de::Error, { iter: iter::Fuse, - value: Option<::Second>, + value: Option>, count: usize, lifetime: PhantomData<&'de ()>, error: PhantomData, @@ -656,10 +657,8 @@ impl<'de, I, E> MapDeserializer<'de, I, E> where I: Iterator, I::Item: private::Pair, - ::First: IntoDeserializer<'de, - E>, - ::Second: IntoDeserializer<'de, - E>, + First: IntoDeserializer<'de, E>, + Second: IntoDeserializer<'de, E>, E: de::Error, { /// Construct a new `MapDeserializer`. @@ -689,9 +688,7 @@ where } } - fn next_pair - (&mut self,) - -> Option<(::First, ::Second)> { + fn next_pair(&mut self) -> Option<(First, Second)> { match self.iter.next() { Some(kv) => { self.count += 1; @@ -705,8 +702,8 @@ where impl<'de, I, E> de::Deserializer<'de> for MapDeserializer<'de, I, E> where I: Iterator, I::Item: private::Pair, - ::First: IntoDeserializer<'de, E>, - ::Second: IntoDeserializer<'de, E>, + First: IntoDeserializer<'de, E>, + Second: IntoDeserializer<'de, E>, E: de::Error { type Error = E; @@ -746,8 +743,8 @@ impl<'de, I, E> de::Deserializer<'de> for MapDeserializer<'de, I, E> impl<'de, I, E> de::MapVisitor<'de> for MapDeserializer<'de, I, E> where I: Iterator, I::Item: private::Pair, - ::First: IntoDeserializer<'de, E>, - ::Second: IntoDeserializer<'de, E>, + First: IntoDeserializer<'de, E>, + Second: IntoDeserializer<'de, E>, E: de::Error { type Error = E; @@ -799,8 +796,8 @@ impl<'de, I, E> de::MapVisitor<'de> for MapDeserializer<'de, I, E> impl<'de, I, E> de::SeqVisitor<'de> for MapDeserializer<'de, I, E> where I: Iterator, I::Item: private::Pair, - ::First: IntoDeserializer<'de, E>, - ::Second: IntoDeserializer<'de, E>, + First: IntoDeserializer<'de, E>, + Second: IntoDeserializer<'de, E>, E: de::Error { type Error = E; @@ -828,8 +825,8 @@ impl<'de, I, E> de::SeqVisitor<'de> for MapDeserializer<'de, I, E> impl<'de, I, E> Clone for MapDeserializer<'de, I, E> where I: Iterator + Clone, I::Item: private::Pair, - ::First: IntoDeserializer<'de, E>, - ::Second: IntoDeserializer<'de, E> + Clone, + First: IntoDeserializer<'de, E>, + Second: IntoDeserializer<'de, E> + Clone, E: de::Error { fn clone(&self) -> Self { @@ -849,8 +846,8 @@ impl<'de, I, E> Clone for MapDeserializer<'de, I, E> impl<'de, I, E> Debug for MapDeserializer<'de, I, E> where I: Iterator + Debug, I::Item: private::Pair, - ::First: IntoDeserializer<'de, E>, - ::Second: IntoDeserializer<'de, E> + Debug, + First: IntoDeserializer<'de, E>, + Second: IntoDeserializer<'de, E> + Debug, E: de::Error { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { @@ -1098,4 +1095,7 @@ mod private { self } } + + pub type First = ::First; + pub type Second = ::Second; } From 4e2f08cc7ae0a02da59c3ca5eac076c6abba3e48 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 13 Apr 2017 23:04:53 -0700 Subject: [PATCH 143/177] Format some where clauses that rustfmt refused to touch --- serde/src/de/impls.rs | 63 +++++++++++++++++++----------- serde/src/de/value.rs | 87 +++++++++++++++++++++++++----------------- serde/src/macros.rs | 3 +- serde/src/ser/impls.rs | 17 ++++++--- 4 files changed, 105 insertions(+), 65 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 12d2b96d..222df624 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -78,7 +78,8 @@ macro_rules! visit_integer_method { ($src_ty:ident, $method:ident, $from_method:ident, $group:ident, $group_ty:ident) => { #[inline] fn $method(self, v: $src_ty) -> Result - where E: Error + where + E: Error, { match FromPrimitive::$from_method(v) { Some(v) => Ok(v), @@ -92,7 +93,8 @@ macro_rules! visit_float_method { ($src_ty:ident, $method:ident) => { #[inline] fn $method(self, v: $src_ty) -> Result - where E: Error + where + E: Error, { Ok(v as Self::Value) } @@ -104,7 +106,8 @@ macro_rules! impl_deserialize_num { impl<'de> Deserialize<'de> for $ty { #[inline] fn deserialize(deserializer: D) -> Result<$ty, D::Error> - where D: Deserializer<'de>, + where + D: Deserializer<'de>, { struct PrimitiveVisitor; @@ -510,8 +513,9 @@ macro_rules! seq_impl { } impl<'de, T $(, $typaram)*> Visitor<'de> for $visitor_ty - where T: Deserialize<'de>, - $($($boundparam: $bound1 $(+ $bound2)*),*)* + where + T: Deserialize<'de>, + $($($boundparam: $bound1 $(+ $bound2)*),*)* { type Value = $ty; @@ -521,7 +525,8 @@ macro_rules! seq_impl { #[inline] fn visit_seq(self, mut $visitor: V) -> Result - where V: SeqVisitor<'de>, + where + V: SeqVisitor<'de>, { let mut values = $with_capacity; @@ -534,11 +539,13 @@ macro_rules! seq_impl { } impl<'de, T $(, $typaram)*> Deserialize<'de> for $ty - where T: Deserialize<'de>, - $($($boundparam: $bound1 $(+ $bound2)*),*)* + where + T: Deserialize<'de>, + $($($boundparam: $bound1 $(+ $bound2)*),*)* { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de>, + where + D: Deserializer<'de>, { deserializer.deserialize_seq($visitor_ty::new()) } @@ -643,7 +650,8 @@ macro_rules! array_impls { ($($len:expr => ($($n:tt $name:ident)+))+) => { $( impl<'de, T> Visitor<'de> for ArrayVisitor<[T; $len]> - where T: Deserialize<'de> + where + T: Deserialize<'de>, { type Value = [T; $len]; @@ -653,7 +661,8 @@ macro_rules! array_impls { #[inline] fn visit_seq(self, mut visitor: V) -> Result<[T; $len], V::Error> - where V: SeqVisitor<'de>, + where + V: SeqVisitor<'de>, { $( let $name = match try!(visitor.visit()) { @@ -667,10 +676,12 @@ macro_rules! array_impls { } impl<'de, T> Deserialize<'de> for [T; $len] - where T: Deserialize<'de>, + where + T: Deserialize<'de>, { fn deserialize(deserializer: D) -> Result<[T; $len], D::Error> - where D: Deserializer<'de>, + where + D: Deserializer<'de>, { deserializer.deserialize_seq_fixed_size($len, ArrayVisitor::<[T; $len]>::new()) } @@ -739,7 +750,8 @@ macro_rules! tuple_impls { #[inline] #[allow(non_snake_case)] fn visit_seq(self, mut visitor: V) -> Result<($($name,)+), V::Error> - where V: SeqVisitor<'de>, + where + V: SeqVisitor<'de>, { $( let $name = match try!(visitor.visit()) { @@ -755,7 +767,8 @@ macro_rules! tuple_impls { impl<'de, $($name: Deserialize<'de>),+> Deserialize<'de> for ($($name,)+) { #[inline] fn deserialize(deserializer: D) -> Result<($($name,)+), D::Error> - where D: Deserializer<'de>, + where + D: Deserializer<'de>, { deserializer.deserialize_tuple($len, $visitor::new()) } @@ -806,9 +819,10 @@ macro_rules! map_impl { } impl<'de, K, V $(, $typaram)*> Visitor<'de> for $visitor_ty - where K: Deserialize<'de>, - V: Deserialize<'de>, - $($boundparam: $bound1 $(+ $bound2)*),* + where + K: Deserialize<'de>, + V: Deserialize<'de>, + $($boundparam: $bound1 $(+ $bound2)*),* { type Value = $ty; @@ -818,7 +832,8 @@ macro_rules! map_impl { #[inline] fn visit_map(self, mut $visitor: Visitor) -> Result - where Visitor: MapVisitor<'de>, + where + Visitor: MapVisitor<'de>, { let mut values = $with_capacity; @@ -831,12 +846,14 @@ macro_rules! map_impl { } impl<'de, K, V $(, $typaram)*> Deserialize<'de> for $ty - where K: Deserialize<'de>, - V: Deserialize<'de>, - $($boundparam: $bound1 $(+ $bound2)*),* + where + K: Deserialize<'de>, + V: Deserialize<'de>, + $($boundparam: $bound1 $(+ $bound2)*),* { fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de>, + where + D: Deserializer<'de>, { deserializer.deserialize_map($visitor_ty::new()) } diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 76b2ea84..2e611551 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -121,7 +121,8 @@ macro_rules! primitive_deserializer { } impl<'de, E> IntoDeserializer<'de, E> for $ty - where E: de::Error, + where + E: de::Error, { type Deserializer = $name; @@ -134,7 +135,8 @@ macro_rules! primitive_deserializer { } impl<'de, E> de::Deserializer<'de> for $name - where E: de::Error, + where + E: de::Error, { type Error = E; @@ -145,7 +147,8 @@ macro_rules! primitive_deserializer { } fn deserialize(self, visitor: V) -> Result - where V: de::Visitor<'de>, + where + V: de::Visitor<'de>, { visitor.$method(self.value $($cast)*) } @@ -700,16 +703,18 @@ where } impl<'de, I, E> de::Deserializer<'de> for MapDeserializer<'de, I, E> - where I: Iterator, - I::Item: private::Pair, - First: IntoDeserializer<'de, E>, - Second: IntoDeserializer<'de, E>, - E: de::Error +where + I: Iterator, + I::Item: private::Pair, + First: IntoDeserializer<'de, E>, + Second: IntoDeserializer<'de, E>, + E: de::Error, { type Error = E; fn deserialize(mut self, visitor: V_) -> Result - where V_: de::Visitor<'de> + where + V_: de::Visitor<'de>, { let value = try!(visitor.visit_map(&mut self)); try!(self.end()); @@ -717,7 +722,8 @@ impl<'de, I, E> de::Deserializer<'de> for MapDeserializer<'de, I, E> } fn deserialize_seq(mut self, visitor: V_) -> Result - where V_: de::Visitor<'de> + where + V_: de::Visitor<'de>, { let value = try!(visitor.visit_seq(&mut self)); try!(self.end()); @@ -728,7 +734,8 @@ impl<'de, I, E> de::Deserializer<'de> for MapDeserializer<'de, I, E> _len: usize, visitor: V_) -> Result - where V_: de::Visitor<'de> + where + V_: de::Visitor<'de>, { self.deserialize_seq(visitor) } @@ -741,16 +748,18 @@ impl<'de, I, E> de::Deserializer<'de> for MapDeserializer<'de, I, E> } impl<'de, I, E> de::MapVisitor<'de> for MapDeserializer<'de, I, E> - where I: Iterator, - I::Item: private::Pair, - First: IntoDeserializer<'de, E>, - Second: IntoDeserializer<'de, E>, - E: de::Error +where + I: Iterator, + I::Item: private::Pair, + First: IntoDeserializer<'de, E>, + Second: IntoDeserializer<'de, E>, + E: de::Error, { type Error = E; fn visit_key_seed(&mut self, seed: T) -> Result, Self::Error> - where T: de::DeserializeSeed<'de> + where + T: de::DeserializeSeed<'de>, { match self.next_pair() { Some((key, value)) => { @@ -762,7 +771,8 @@ impl<'de, I, E> de::MapVisitor<'de> for MapDeserializer<'de, I, E> } fn visit_value_seed(&mut self, seed: T) -> Result - where T: de::DeserializeSeed<'de> + where + T: de::DeserializeSeed<'de>, { let value = self.value.take(); // Panic because this indicates a bug in the program rather than an @@ -775,8 +785,9 @@ impl<'de, I, E> de::MapVisitor<'de> for MapDeserializer<'de, I, E> kseed: TK, vseed: TV) -> Result, Self::Error> - where TK: de::DeserializeSeed<'de>, - TV: de::DeserializeSeed<'de> + where + TK: de::DeserializeSeed<'de>, + TV: de::DeserializeSeed<'de>, { match self.next_pair() { Some((key, value)) => { @@ -794,16 +805,18 @@ impl<'de, I, E> de::MapVisitor<'de> for MapDeserializer<'de, I, E> } impl<'de, I, E> de::SeqVisitor<'de> for MapDeserializer<'de, I, E> - where I: Iterator, - I::Item: private::Pair, - First: IntoDeserializer<'de, E>, - Second: IntoDeserializer<'de, E>, - E: de::Error +where + I: Iterator, + I::Item: private::Pair, + First: IntoDeserializer<'de, E>, + Second: IntoDeserializer<'de, E>, + E: de::Error, { type Error = E; fn visit_seed(&mut self, seed: T) -> Result, Self::Error> - where T: de::DeserializeSeed<'de> + where + T: de::DeserializeSeed<'de>, { match self.next_pair() { Some((k, v)) => { @@ -823,11 +836,12 @@ impl<'de, I, E> de::SeqVisitor<'de> for MapDeserializer<'de, I, E> // // ::Second: Clone impl<'de, I, E> Clone for MapDeserializer<'de, I, E> - where I: Iterator + Clone, - I::Item: private::Pair, - First: IntoDeserializer<'de, E>, - Second: IntoDeserializer<'de, E> + Clone, - E: de::Error +where + I: Iterator + Clone, + I::Item: private::Pair, + First: IntoDeserializer<'de, E>, + Second: IntoDeserializer<'de, E> + Clone, + E: de::Error, { fn clone(&self) -> Self { MapDeserializer { @@ -844,11 +858,12 @@ impl<'de, I, E> Clone for MapDeserializer<'de, I, E> // // ::Second: Debug impl<'de, I, E> Debug for MapDeserializer<'de, I, E> - where I: Iterator + Debug, - I::Item: private::Pair, - First: IntoDeserializer<'de, E>, - Second: IntoDeserializer<'de, E> + Debug, - E: de::Error +where + I: Iterator + Debug, + I::Item: private::Pair, + First: IntoDeserializer<'de, E>, + Second: IntoDeserializer<'de, E> + Debug, + E: de::Error, { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.debug_struct("MapDeserializer") diff --git a/serde/src/macros.rs b/serde/src/macros.rs index 2ff7ec37..f75eebf9 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -141,7 +141,8 @@ macro_rules! forward_to_deserialize_method { ($func:ident<$l:tt, $v:ident>($($arg:ident : $ty:ty),*)) => { #[inline] fn $func<$v>(self, $($arg: $ty,)* visitor: $v) -> $crate::export::Result<$v::Value, Self::Error> - where $v: $crate::de::Visitor<$l> + where + $v: $crate::de::Visitor<$l>, { $( let _ = $arg; diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index a44da1ce..c10cbe52 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -137,10 +137,14 @@ impl Serialize for [T; 0] { macro_rules! array_impls { ($($len:tt)+) => { $( - impl Serialize for [T; $len] where T: Serialize { + impl Serialize for [T; $len] + where + T: Serialize, + { #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer, + where + S: Serializer, { let mut seq = try!(serializer.serialize_seq_fixed_size($len)); for e in self { @@ -166,7 +170,8 @@ where { #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer, + where + S: Serializer, { serializer.collect_seq(self) } @@ -181,7 +186,8 @@ macro_rules! seq_impl { { #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer, + where + S: Serializer, { serializer.collect_seq(self) } @@ -294,7 +300,8 @@ macro_rules! map_impl { { #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer, + where + S: Serializer, { serializer.collect_seq(self) } From 26d357e84604c55921786f75b04aaa753365e296 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 12:08:26 -0700 Subject: [PATCH 144/177] Map ser impls should serialize a map --- serde/src/ser/impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index c10cbe52..b127773e 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -303,7 +303,7 @@ macro_rules! map_impl { where S: Serializer, { - serializer.collect_seq(self) + serializer.collect_map(self) } } } From f2de0509f5cbabad34e20dded361a65347afc96c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 12:24:22 -0700 Subject: [PATCH 145/177] Whitelist the zero prefixed literals used in array_impls --- serde/src/lib.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/serde/src/lib.rs b/serde/src/lib.rs index bad71266..4b84c7ba 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -94,7 +94,10 @@ #![cfg_attr(feature = "collections", feature(collections))] // Whitelisted clippy lints. -#![cfg_attr(feature = "cargo-clippy", allow(linkedlist, type_complexity, doc_markdown))] +#![cfg_attr(feature = "cargo-clippy", allow(doc_markdown))] +#![cfg_attr(feature = "cargo-clippy", allow(linkedlist))] +#![cfg_attr(feature = "cargo-clippy", allow(type_complexity))] +#![cfg_attr(feature = "cargo-clippy", allow(zero_prefixed_literal))] // Blacklisted Rust lints. #![deny(missing_docs, unused_imports)] From 31cec0571223589b2bb4b9db327a30db8d3e7519 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 11:58:29 -0700 Subject: [PATCH 146/177] Access traits --- serde/src/de/ignored_any.rs | 26 ++-- serde/src/de/impls.rs | 122 +++++++++---------- serde/src/de/mod.rs | 235 ++++++++++++++++++------------------ serde/src/de/value.rs | 60 ++++----- serde/src/private/de.rs | 78 ++++++------ serde_derive/src/de.rs | 102 ++++++++-------- serde_test/src/de.rs | 34 +++--- 7 files changed, 329 insertions(+), 328 deletions(-) diff --git a/serde/src/de/ignored_any.rs b/serde/src/de/ignored_any.rs index b8ff0c75..a4f3abe2 100644 --- a/serde/src/de/ignored_any.rs +++ b/serde/src/de/ignored_any.rs @@ -8,7 +8,7 @@ use lib::*; -use de::{Deserialize, Deserializer, Visitor, SeqVisitor, MapVisitor, Error}; +use de::{Deserialize, Deserializer, Visitor, SeqAccess, MapAccess, Error}; /// An efficient way of discarding data from a deserializer. /// @@ -20,7 +20,7 @@ use de::{Deserialize, Deserializer, Visitor, SeqVisitor, MapVisitor, Error}; /// use std::fmt; /// use std::marker::PhantomData; /// -/// use serde::de::{self, Deserialize, DeserializeSeed, Deserializer, Visitor, SeqVisitor, IgnoredAny}; +/// use serde::de::{self, Deserialize, DeserializeSeed, Deserializer, Visitor, SeqAccess, IgnoredAny}; /// /// /// A seed that can be used to deserialize only the `n`th element of a sequence /// /// while efficiently discarding elements of any type before or after index `n`. @@ -53,19 +53,19 @@ use de::{Deserialize, Deserializer, Visitor, SeqVisitor, MapVisitor, Error}; /// write!(formatter, "a sequence in which we care about element {}", self.n) /// } /// -/// fn visit_seq(self, mut seq: V) -> Result -/// where V: SeqVisitor<'de> +/// fn visit_seq(self, mut seq: A) -> Result +/// where A: SeqAccess<'de> /// { /// // Skip over the first `n` elements. /// for i in 0..self.n { /// // It is an error if the sequence ends before we get to element `n`. -/// if seq.visit::()?.is_none() { +/// if seq.next_element::()?.is_none() { /// return Err(de::Error::invalid_length(i, &self)); /// } /// } /// /// // Deserialize the one we care about. -/// let nth = match seq.visit()? { +/// let nth = match seq.next_element()? { /// Some(nth) => nth, /// None => { /// return Err(de::Error::invalid_length(self.n, &self)); @@ -73,7 +73,7 @@ use de::{Deserialize, Deserializer, Visitor, SeqVisitor, MapVisitor, Error}; /// }; /// /// // Skip over any remaining elements in the sequence after `n`. -/// while let Some(IgnoredAny) = seq.visit()? { +/// while let Some(IgnoredAny) = seq.next_element()? { /// // ignore /// } /// @@ -173,22 +173,22 @@ impl<'de> Visitor<'de> for IgnoredAny { } #[inline] - fn visit_seq(self, mut visitor: V) -> Result + fn visit_seq(self, mut seq: A) -> Result where - V: SeqVisitor<'de>, + A: SeqAccess<'de>, { - while let Some(IgnoredAny) = try!(visitor.visit()) { + while let Some(IgnoredAny) = try!(seq.next_element()) { // Gobble } Ok(IgnoredAny) } #[inline] - fn visit_map(self, mut visitor: V) -> Result + fn visit_map(self, mut map: A) -> Result where - V: MapVisitor<'de>, + A: MapAccess<'de>, { - while let Some((IgnoredAny, IgnoredAny)) = try!(visitor.visit()) { + while let Some((IgnoredAny, IgnoredAny)) = try!(map.next_entry()) { // Gobble } Ok(IgnoredAny) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 222df624..b7ec32b1 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -8,11 +8,11 @@ use lib::*; -use de::{Deserialize, Deserializer, EnumVisitor, Error, SeqVisitor, Unexpected, VariantVisitor, +use de::{Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess, Visitor}; #[cfg(any(feature = "std", feature = "collections"))] -use de::MapVisitor; +use de::MapAccess; use de::from_primitive::FromPrimitive; @@ -340,14 +340,14 @@ impl<'de> Visitor<'de> for CStringVisitor { formatter.write_str("byte array") } - fn visit_seq(self, mut visitor: V) -> Result + fn visit_seq(self, mut seq: A) -> Result where - V: SeqVisitor<'de>, + A: SeqAccess<'de>, { - let len = cmp::min(visitor.size_hint().0, 4096); + let len = cmp::min(seq.size_hint().0, 4096); let mut values = Vec::with_capacity(len); - while let Some(value) = try!(visitor.visit()) { + while let Some(value) = try!(seq.next_element()) { values.push(value); } @@ -495,7 +495,7 @@ macro_rules! seq_impl { ( $ty:ident < T $(, $typaram:ident)* >, $visitor_ty:ident $( < $($boundparam:ident : $bound1:ident $(+ $bound2:ident)*),* > )*, - $visitor:ident, + $access:ident, $ctor:expr, $with_capacity:expr, $insert:expr @@ -524,13 +524,13 @@ macro_rules! seq_impl { } #[inline] - fn visit_seq(self, mut $visitor: V) -> Result + fn visit_seq(self, mut $access: A) -> Result where - V: SeqVisitor<'de>, + A: SeqAccess<'de>, { let mut values = $with_capacity; - while let Some(value) = try!($visitor.visit()) { + while let Some(value) = try!($access.next_element()) { $insert(&mut values, value); } @@ -628,9 +628,9 @@ impl<'de, T> Visitor<'de> for ArrayVisitor<[T; 0]> { } #[inline] - fn visit_seq(self, _: V) -> Result<[T; 0], V::Error> + fn visit_seq(self, _: A) -> Result<[T; 0], A::Error> where - V: SeqVisitor<'de>, + A: SeqAccess<'de>, { Ok([]) } @@ -660,12 +660,12 @@ macro_rules! array_impls { } #[inline] - fn visit_seq(self, mut visitor: V) -> Result<[T; $len], V::Error> + fn visit_seq(self, mut seq: A) -> Result<[T; $len], A::Error> where - V: SeqVisitor<'de>, + A: SeqAccess<'de>, { $( - let $name = match try!(visitor.visit()) { + let $name = match try!(seq.next_element()) { Some(val) => val, None => return Err(Error::invalid_length($n, &self)), }; @@ -749,12 +749,12 @@ macro_rules! tuple_impls { #[inline] #[allow(non_snake_case)] - fn visit_seq(self, mut visitor: V) -> Result<($($name,)+), V::Error> + fn visit_seq(self, mut seq: A) -> Result<($($name,)+), A::Error> where - V: SeqVisitor<'de>, + A: SeqAccess<'de>, { $( - let $name = match try!(visitor.visit()) { + let $name = match try!(seq.next_element()) { Some(value) => value, None => return Err(Error::invalid_length($n, &self)), }; @@ -802,7 +802,7 @@ macro_rules! map_impl { ( $ty:ident < K, V $(, $typaram:ident)* >, $visitor_ty:ident < $($boundparam:ident : $bound1:ident $(+ $bound2:ident)*),* >, - $visitor:ident, + $access:ident, $ctor:expr, $with_capacity:expr ) => { @@ -831,13 +831,13 @@ macro_rules! map_impl { } #[inline] - fn visit_map(self, mut $visitor: Visitor) -> Result + fn visit_map(self, mut $access: A) -> Result where - Visitor: MapVisitor<'de>, + A: MapAccess<'de>, { let mut values = $with_capacity; - while let Some((key, value)) = try!($visitor.visit()) { + while let Some((key, value)) = try!($access.next_entry()) { values.insert(key, value); } @@ -1086,29 +1086,29 @@ impl<'de> Visitor<'de> for OsStringVisitor { } #[cfg(unix)] - fn visit_enum(self, visitor: V) -> Result + fn visit_enum(self, data: A) -> Result where - V: EnumVisitor<'de>, + A: EnumAccess<'de>, { use std::os::unix::ffi::OsStringExt; - match try!(visitor.visit_variant()) { - (OsStringKind::Unix, variant) => variant.visit_newtype().map(OsString::from_vec), + match try!(data.variant()) { + (OsStringKind::Unix, variant) => variant.deserialize_newtype().map(OsString::from_vec), (OsStringKind::Windows, _) => Err(Error::custom("cannot deserialize Windows OS string on Unix",),), } } #[cfg(windows)] - fn visit_enum(self, visitor: V) -> Result + fn visit_enum(self, data: A) -> Result where - V: EnumVisitor<'de>, + A: EnumAccess<'de>, { use std::os::windows::ffi::OsStringExt; - match try!(visitor.visit_variant()) { + match try!(data.variant()) { (OsStringKind::Windows, variant) => { variant - .visit_newtype::>() + .deserialize_newtype::>() .map(|vec| OsString::from_wide(&vec)) } (OsStringKind::Unix, _) => Err(Error::custom("cannot deserialize Unix OS string on Windows",),), @@ -1285,17 +1285,17 @@ impl<'de> Deserialize<'de> for Duration { formatter.write_str("struct Duration") } - fn visit_seq(self, mut visitor: V) -> Result + fn visit_seq(self, mut seq: A) -> Result where - V: SeqVisitor<'de>, + A: SeqAccess<'de>, { - let secs: u64 = match try!(visitor.visit()) { + let secs: u64 = match try!(seq.next_element()) { Some(value) => value, None => { return Err(Error::invalid_length(0, &self)); } }; - let nanos: u32 = match try!(visitor.visit()) { + let nanos: u32 = match try!(seq.next_element()) { Some(value) => value, None => { return Err(Error::invalid_length(1, &self)); @@ -1304,35 +1304,35 @@ impl<'de> Deserialize<'de> for Duration { Ok(Duration::new(secs, nanos)) } - fn visit_map(self, mut visitor: V) -> Result + fn visit_map(self, mut map: A) -> Result where - V: MapVisitor<'de>, + A: MapAccess<'de>, { let mut secs: Option = None; let mut nanos: Option = None; - while let Some(key) = try!(visitor.visit_key::()) { + while let Some(key) = try!(map.next_key()) { match key { Field::Secs => { if secs.is_some() { - return Err(::duplicate_field("secs")); + return Err(::duplicate_field("secs")); } - secs = Some(try!(visitor.visit_value())); + secs = Some(try!(map.next_value())); } Field::Nanos => { if nanos.is_some() { - return Err(::duplicate_field("nanos")); + return Err(::duplicate_field("nanos")); } - nanos = Some(try!(visitor.visit_value())); + nanos = Some(try!(map.next_value())); } } } let secs = match secs { Some(secs) => secs, - None => return Err(::missing_field("secs")), + None => return Err(::missing_field("secs")), }; let nanos = match nanos { Some(nanos) => nanos, - None => return Err(::missing_field("nanos")), + None => return Err(::missing_field("nanos")), }; Ok(Duration::new(secs, nanos)) } @@ -1425,17 +1425,17 @@ where formatter.write_str("struct Range") } - fn visit_seq(self, mut visitor: V) -> Result, V::Error> + fn visit_seq(self, mut seq: A) -> Result, A::Error> where - V: SeqVisitor<'de>, + A: SeqAccess<'de>, { - let start: Idx = match try!(visitor.visit()) { + let start: Idx = match try!(seq.next_element()) { Some(value) => value, None => { return Err(Error::invalid_length(0, &self)); } }; - let end: Idx = match try!(visitor.visit()) { + let end: Idx = match try!(seq.next_element()) { Some(value) => value, None => { return Err(Error::invalid_length(1, &self)); @@ -1444,35 +1444,35 @@ where Ok(start..end) } - fn visit_map(self, mut visitor: V) -> Result, V::Error> + fn visit_map(self, mut map: A) -> Result, A::Error> where - V: MapVisitor<'de>, + A: MapAccess<'de>, { let mut start: Option = None; let mut end: Option = None; - while let Some(key) = try!(visitor.visit_key::()) { + while let Some(key) = try!(map.next_key()) { match key { Field::Start => { if start.is_some() { - return Err(::duplicate_field("start")); + return Err(::duplicate_field("start")); } - start = Some(try!(visitor.visit_value())); + start = Some(try!(map.next_value())); } Field::End => { if end.is_some() { - return Err(::duplicate_field("end")); + return Err(::duplicate_field("end")); } - end = Some(try!(visitor.visit_value())); + end = Some(try!(map.next_value())); } } } let start = match start { Some(start) => start, - None => return Err(::missing_field("start")), + None => return Err(::missing_field("start")), }; let end = match end { Some(end) => end, - None => return Err(::missing_field("end")), + None => return Err(::missing_field("end")), }; Ok(start..end) } @@ -1598,13 +1598,13 @@ where formatter.write_str("enum Result") } - fn visit_enum(self, visitor: V) -> Result, V::Error> + fn visit_enum(self, data: A) -> Result, A::Error> where - V: EnumVisitor<'de>, + A: EnumAccess<'de>, { - match try!(visitor.visit_variant()) { - (Field::Ok, variant) => variant.visit_newtype().map(Ok), - (Field::Err, variant) => variant.visit_newtype().map(Err), + match try!(data.variant()) { + (Field::Ok, variant) => variant.deserialize_newtype().map(Ok), + (Field::Err, variant) => variant.deserialize_newtype().map(Err), } } } diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 35e00531..86398eb3 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -585,7 +585,7 @@ where /// use std::fmt; /// use std::marker::PhantomData; /// -/// use serde::de::{Deserialize, DeserializeSeed, Deserializer, Visitor, SeqVisitor}; +/// use serde::de::{Deserialize, DeserializeSeed, Deserializer, Visitor, SeqAccess}; /// /// // A DeserializeSeed implementation that uses stateful deserialization to /// // append array elements onto the end of an existing vector. The preexisting @@ -618,12 +618,12 @@ where /// write!(formatter, "an array of integers") /// } /// -/// fn visit_seq(self, mut visitor: V) -> Result<(), V::Error> -/// where V: SeqVisitor<'de> +/// fn visit_seq(self, mut seq: A) -> Result<(), A::Error> +/// where A: SeqAccess<'de> /// { /// // Visit each element in the inner array and push it onto /// // the existing vector. -/// while let Some(elem) = visitor.visit()? { +/// while let Some(elem) = seq.next_element()? { /// self.0.push(elem); /// } /// Ok(()) @@ -648,14 +648,14 @@ where /// write!(formatter, "an array of arrays") /// } /// -/// fn visit_seq(self, mut visitor: V) -> Result, V::Error> -/// where V: SeqVisitor<'de> +/// fn visit_seq(self, mut seq: A) -> Result, A::Error> +/// where A: SeqAccess<'de> /// { /// // Create a single Vec to hold the flattened contents. /// let mut vec = Vec::new(); /// /// // Each iteration through this loop is one inner array. -/// while let Some(()) = visitor.visit_seed(ExtendVec(&mut vec))? { +/// while let Some(()) = seq.next_element_seed(ExtendVec(&mut vec))? { /// // Nothing to do; inner array has been appended into `vec`. /// } /// @@ -1260,29 +1260,29 @@ pub trait Visitor<'de>: Sized { } /// Deserialize `Value` as a sequence of elements. - fn visit_seq(self, visitor: V) -> Result + fn visit_seq(self, seq: A) -> Result where - V: SeqVisitor<'de>, + A: SeqAccess<'de>, { - let _ = visitor; + let _ = seq; Err(Error::invalid_type(Unexpected::Seq, &self)) } /// Deserialize `Value` as a key-value map. - fn visit_map(self, visitor: V) -> Result + fn visit_map(self, map: A) -> Result where - V: MapVisitor<'de>, + A: MapAccess<'de>, { - let _ = visitor; + let _ = map; Err(Error::invalid_type(Unexpected::Map, &self)) } /// Deserialize `Value` as an enum. - fn visit_enum(self, visitor: V) -> Result + fn visit_enum(self, data: A) -> Result where - V: EnumVisitor<'de>, + A: EnumAccess<'de>, { - let _ = visitor; + let _ = data; Err(Error::invalid_type(Unexpected::Enum, &self)) } @@ -1345,11 +1345,11 @@ pub trait Visitor<'de>: Sized { //////////////////////////////////////////////////////////////////////////////// -/// `SeqVisitor` visits each item in a sequence. +/// Provides a `Visitor` access to each element of a sequence in the input. /// /// This is a trait that a `Deserializer` passes to a `Visitor` implementation, /// which deserializes each item in a sequence. -pub trait SeqVisitor<'de> { +pub trait SeqAccess<'de> { /// The error type that can be returned if some error occurs during /// deserialization. type Error: Error; @@ -1357,9 +1357,9 @@ pub trait SeqVisitor<'de> { /// This returns `Ok(Some(value))` for the next value in the sequence, or /// `Ok(None)` if there are no more remaining items. /// - /// `Deserialize` implementations should typically use `SeqVisitor::visit` - /// instead. - fn visit_seed(&mut self, seed: T) -> Result, Self::Error> + /// `Deserialize` implementations should typically use + /// `SeqAcccess::next_element` instead. + fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> where T: DeserializeSeed<'de>; @@ -1367,13 +1367,13 @@ pub trait SeqVisitor<'de> { /// `Ok(None)` if there are no more remaining items. /// /// This method exists as a convenience for `Deserialize` implementations. - /// `SeqVisitor` implementations should not override the default behavior. + /// `SeqAccess` implementations should not override the default behavior. #[inline] - fn visit(&mut self) -> Result, Self::Error> + fn next_element(&mut self) -> Result, Self::Error> where T: Deserialize<'de>, { - self.visit_seed(PhantomData) + self.next_element_seed(PhantomData) } /// Return the lower and upper bound of items remaining in the sequence. @@ -1383,26 +1383,26 @@ pub trait SeqVisitor<'de> { } } -impl<'de, 'a, V> SeqVisitor<'de> for &'a mut V +impl<'de, 'a, V> SeqAccess<'de> for &'a mut V where - V: SeqVisitor<'de>, + V: SeqAccess<'de>, { type Error = V::Error; #[inline] - fn visit_seed(&mut self, seed: T) -> Result, V::Error> + fn next_element_seed(&mut self, seed: T) -> Result, V::Error> where T: DeserializeSeed<'de>, { - (**self).visit_seed(seed) + (**self).next_element_seed(seed) } #[inline] - fn visit(&mut self) -> Result, V::Error> + fn next_element(&mut self) -> Result, V::Error> where T: Deserialize<'de>, { - (**self).visit() + (**self).next_element() } #[inline] @@ -1413,10 +1413,10 @@ where //////////////////////////////////////////////////////////////////////////////// -/// `MapVisitor` visits each item in a sequence. +/// Provides a `Visitor` access to each entry of a map in the input. /// /// This is a trait that a `Deserializer` passes to a `Visitor` implementation. -pub trait MapVisitor<'de> { +pub trait MapAccess<'de> { /// The error type that can be returned if some error occurs during /// deserialization. type Error: Error; @@ -1425,29 +1425,29 @@ pub trait MapVisitor<'de> { /// if there are no more remaining entries. /// /// `Deserialize` implementations should typically use - /// `MapVisitor::visit_key` or `MapVisitor::visit` instead. - fn visit_key_seed(&mut self, seed: K) -> Result, Self::Error> + /// `MapAccess::next_key` or `MapAccess::next_entry` instead. + fn next_key_seed(&mut self, seed: K) -> Result, Self::Error> where K: DeserializeSeed<'de>; /// This returns a `Ok(value)` for the next value in the map. /// /// `Deserialize` implementations should typically use - /// `MapVisitor::visit_value` instead. - fn visit_value_seed(&mut self, seed: V) -> Result + /// `MapAccess::next_value` instead. + fn next_value_seed(&mut self, seed: V) -> Result where V: DeserializeSeed<'de>; /// This returns `Ok(Some((key, value)))` for the next (key-value) pair in /// the map, or `Ok(None)` if there are no more remaining items. /// - /// `MapVisitor` implementations should override the default behavior if a + /// `MapAccess` implementations should override the default behavior if a /// more efficient implementation is possible. /// - /// `Deserialize` implementations should typically use `MapVisitor::visit` - /// instead. + /// `Deserialize` implementations should typically use + /// `MapAccess::next_entry` instead. #[inline] - fn visit_seed( + fn next_entry_seed( &mut self, kseed: K, vseed: V, @@ -1456,9 +1456,9 @@ pub trait MapVisitor<'de> { K: DeserializeSeed<'de>, V: DeserializeSeed<'de>, { - match try!(self.visit_key_seed(kseed)) { + match try!(self.next_key_seed(kseed)) { Some(key) => { - let value = try!(self.visit_value_seed(vseed)); + let value = try!(self.next_value_seed(vseed)); Ok(Some((key, value))) } None => Ok(None), @@ -1469,39 +1469,39 @@ pub trait MapVisitor<'de> { /// if there are no more remaining entries. /// /// This method exists as a convenience for `Deserialize` implementations. - /// `MapVisitor` implementations should not override the default behavior. + /// `MapAccess` implementations should not override the default behavior. #[inline] - fn visit_key(&mut self) -> Result, Self::Error> + fn next_key(&mut self) -> Result, Self::Error> where K: Deserialize<'de>, { - self.visit_key_seed(PhantomData) + self.next_key_seed(PhantomData) } /// This returns a `Ok(value)` for the next value in the map. /// /// This method exists as a convenience for `Deserialize` implementations. - /// `MapVisitor` implementations should not override the default behavior. + /// `MapAccess` implementations should not override the default behavior. #[inline] - fn visit_value(&mut self) -> Result + fn next_value(&mut self) -> Result where V: Deserialize<'de>, { - self.visit_value_seed(PhantomData) + self.next_value_seed(PhantomData) } /// This returns `Ok(Some((key, value)))` for the next (key-value) pair in /// the map, or `Ok(None)` if there are no more remaining items. /// /// This method exists as a convenience for `Deserialize` implementations. - /// `MapVisitor` implementations should not override the default behavior. + /// `MapAccess` implementations should not override the default behavior. #[inline] - fn visit(&mut self) -> Result, Self::Error> + fn next_entry(&mut self) -> Result, Self::Error> where K: Deserialize<'de>, V: Deserialize<'de>, { - self.visit_seed(PhantomData, PhantomData) + self.next_entry_seed(PhantomData, PhantomData) } /// Return the lower and upper bound of items remaining in the sequence. @@ -1511,30 +1511,30 @@ pub trait MapVisitor<'de> { } } -impl<'de, 'a, V_> MapVisitor<'de> for &'a mut V_ +impl<'de, 'a, V_> MapAccess<'de> for &'a mut V_ where - V_: MapVisitor<'de>, + V_: MapAccess<'de>, { type Error = V_::Error; #[inline] - fn visit_key_seed(&mut self, seed: K) -> Result, Self::Error> + fn next_key_seed(&mut self, seed: K) -> Result, Self::Error> where K: DeserializeSeed<'de>, { - (**self).visit_key_seed(seed) + (**self).next_key_seed(seed) } #[inline] - fn visit_value_seed(&mut self, seed: V) -> Result + fn next_value_seed(&mut self, seed: V) -> Result where V: DeserializeSeed<'de>, { - (**self).visit_value_seed(seed) + (**self).next_value_seed(seed) } #[inline] - fn visit_seed( + fn next_entry_seed( &mut self, kseed: K, vseed: V, @@ -1543,32 +1543,32 @@ where K: DeserializeSeed<'de>, V: DeserializeSeed<'de>, { - (**self).visit_seed(kseed, vseed) + (**self).next_entry_seed(kseed, vseed) } #[inline] - fn visit(&mut self) -> Result, V_::Error> + fn next_entry(&mut self) -> Result, V_::Error> where K: Deserialize<'de>, V: Deserialize<'de>, { - (**self).visit() + (**self).next_entry() } #[inline] - fn visit_key(&mut self) -> Result, V_::Error> + fn next_key(&mut self) -> Result, V_::Error> where K: Deserialize<'de>, { - (**self).visit_key() + (**self).next_key() } #[inline] - fn visit_value(&mut self) -> Result + fn next_value(&mut self) -> Result where V: Deserialize<'de>, { - (**self).visit_value() + (**self).next_value() } #[inline] @@ -1579,44 +1579,45 @@ where //////////////////////////////////////////////////////////////////////////////// -/// `EnumVisitor` is a visitor that is created by the `Deserializer` and passed -/// to the `Deserialize` in order to identify which variant of an enum to -/// deserialize. -pub trait EnumVisitor<'de>: Sized { +/// Provides a `Visitor` access to the data of an enum in the input. +/// +/// `EnumAccess` is created by the `Deserializer` and passed to the +/// `Visitor` in order to identify which variant of an enum to deserialize. +pub trait EnumAccess<'de>: Sized { /// The error type that can be returned if some error occurs during /// deserialization. type Error: Error; /// The `Visitor` that will be used to deserialize the content of the enum /// variant. - type Variant: VariantVisitor<'de, Error = Self::Error>; + type Variant: VariantAccess<'de, Error = Self::Error>; - /// `visit_variant` is called to identify which variant to deserialize. + /// `variant` is called to identify which variant to deserialize. /// - /// `Deserialize` implementations should typically use - /// `EnumVisitor::visit_variant` instead. - fn visit_variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> + /// `Deserialize` implementations should typically use `EnumAccess::variant` + /// instead. + fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> where V: DeserializeSeed<'de>; - /// `visit_variant` is called to identify which variant to deserialize. + /// `variant` is called to identify which variant to deserialize. /// /// This method exists as a convenience for `Deserialize` implementations. - /// `EnumVisitor` implementations should not override the default behavior. + /// `EnumAccess` implementations should not override the default behavior. #[inline] - fn visit_variant(self) -> Result<(V, Self::Variant), Self::Error> + fn variant(self) -> Result<(V, Self::Variant), Self::Error> where V: Deserialize<'de>, { - self.visit_variant_seed(PhantomData) + self.variant_seed(PhantomData) } } -/// `VariantVisitor` is a visitor that is created by the `Deserializer` and +/// `VariantAccess` is a visitor that is created by the `Deserializer` and /// passed to the `Deserialize` to deserialize the content of a particular enum /// variant. -pub trait VariantVisitor<'de>: Sized { +pub trait VariantAccess<'de>: Sized { /// The error type that can be returned if some error occurs during - /// deserialization. Must match the error type of our `EnumVisitor`. + /// deserialization. Must match the error type of our `EnumAccess`. type Error: Error; /// Called when deserializing a variant with no values. @@ -1625,55 +1626,55 @@ pub trait VariantVisitor<'de>: Sized { /// `invalid_type` error should be constructed: /// /// ```rust - /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantVisitor, Unexpected}; + /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected}; /// # /// # struct X; /// # - /// # impl<'de> VariantVisitor<'de> for X { + /// # impl<'de> VariantAccess<'de> for X { /// # type Error = value::Error; /// # - /// fn visit_unit(self) -> Result<(), Self::Error> { + /// fn deserialize_unit(self) -> Result<(), Self::Error> { /// // What the data actually contained; suppose it is a tuple variant. /// let unexp = Unexpected::TupleVariant; /// Err(de::Error::invalid_type(unexp, &"unit variant")) /// } /// # - /// # fn visit_newtype_seed(self, _: T) -> Result + /// # fn deserialize_newtype_seed(self, _: T) -> Result /// # where T: DeserializeSeed<'de> /// # { unimplemented!() } /// # - /// # fn visit_tuple(self, _: usize, _: V) -> Result + /// # fn deserialize_tuple(self, _: usize, _: V) -> Result /// # where V: Visitor<'de> /// # { unimplemented!() } /// # - /// # fn visit_struct(self, _: &[&str], _: V) -> Result + /// # fn deserialize_struct(self, _: &[&str], _: V) -> Result /// # where V: Visitor<'de> /// # { unimplemented!() } /// # } /// ``` - fn visit_unit(self) -> Result<(), Self::Error>; + fn deserialize_unit(self) -> Result<(), Self::Error>; /// Called when deserializing a variant with a single value. /// /// `Deserialize` implementations should typically use - /// `VariantVisitor::visit_newtype` instead. + /// `VariantAccess::deserialize_newtype` instead. /// /// If the data contains a different type of variant, the following /// `invalid_type` error should be constructed: /// /// ```rust - /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantVisitor, Unexpected}; + /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected}; /// # /// # struct X; /// # - /// # impl<'de> VariantVisitor<'de> for X { + /// # impl<'de> VariantAccess<'de> for X { /// # type Error = value::Error; /// # - /// # fn visit_unit(self) -> Result<(), Self::Error> { + /// # fn deserialize_unit(self) -> Result<(), Self::Error> { /// # unimplemented!() /// # } /// # - /// fn visit_newtype_seed(self, _seed: T) -> Result + /// fn deserialize_newtype_seed(self, _seed: T) -> Result /// where T: DeserializeSeed<'de> /// { /// // What the data actually contained; suppose it is a unit variant. @@ -1681,30 +1682,30 @@ pub trait VariantVisitor<'de>: Sized { /// Err(de::Error::invalid_type(unexp, &"newtype variant")) /// } /// # - /// # fn visit_tuple(self, _: usize, _: V) -> Result + /// # fn deserialize_tuple(self, _: usize, _: V) -> Result /// # where V: Visitor<'de> /// # { unimplemented!() } /// # - /// # fn visit_struct(self, _: &[&str], _: V) -> Result + /// # fn deserialize_struct(self, _: &[&str], _: V) -> Result /// # where V: Visitor<'de> /// # { unimplemented!() } /// # } /// ``` - fn visit_newtype_seed(self, seed: T) -> Result + fn deserialize_newtype_seed(self, seed: T) -> Result where T: DeserializeSeed<'de>; /// Called when deserializing a variant with a single value. /// /// This method exists as a convenience for `Deserialize` implementations. - /// `VariantVisitor` implementations should not override the default + /// `VariantAccess` implementations should not override the default /// behavior. #[inline] - fn visit_newtype(self) -> Result + fn deserialize_newtype(self) -> Result where T: Deserialize<'de>, { - self.visit_newtype_seed(PhantomData) + self.deserialize_newtype_seed(PhantomData) } /// Called when deserializing a tuple-like variant. @@ -1715,24 +1716,24 @@ pub trait VariantVisitor<'de>: Sized { /// `invalid_type` error should be constructed: /// /// ```rust - /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantVisitor, Unexpected}; + /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected}; /// # /// # struct X; /// # - /// # impl<'de> VariantVisitor<'de> for X { + /// # impl<'de> VariantAccess<'de> for X { /// # type Error = value::Error; /// # - /// # fn visit_unit(self) -> Result<(), Self::Error> { + /// # fn deserialize_unit(self) -> Result<(), Self::Error> { /// # unimplemented!() /// # } /// # - /// # fn visit_newtype_seed(self, _: T) -> Result + /// # fn deserialize_newtype_seed(self, _: T) -> Result /// # where T: DeserializeSeed<'de> /// # { unimplemented!() } /// # - /// fn visit_tuple(self, - /// _len: usize, - /// _visitor: V) -> Result + /// fn deserialize_tuple(self, + /// _len: usize, + /// _visitor: V) -> Result /// where V: Visitor<'de> /// { /// // What the data actually contained; suppose it is a unit variant. @@ -1740,12 +1741,12 @@ pub trait VariantVisitor<'de>: Sized { /// Err(de::Error::invalid_type(unexp, &"tuple variant")) /// } /// # - /// # fn visit_struct(self, _: &[&str], _: V) -> Result + /// # fn deserialize_struct(self, _: &[&str], _: V) -> Result /// # where V: Visitor<'de> /// # { unimplemented!() } /// # } /// ``` - fn visit_tuple(self, len: usize, visitor: V) -> Result + fn deserialize_tuple(self, len: usize, visitor: V) -> Result where V: Visitor<'de>; @@ -1757,28 +1758,28 @@ pub trait VariantVisitor<'de>: Sized { /// `invalid_type` error should be constructed: /// /// ```rust - /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantVisitor, Unexpected}; + /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected}; /// # /// # struct X; /// # - /// # impl<'de> VariantVisitor<'de> for X { + /// # impl<'de> VariantAccess<'de> for X { /// # type Error = value::Error; /// # - /// # fn visit_unit(self) -> Result<(), Self::Error> { + /// # fn deserialize_unit(self) -> Result<(), Self::Error> { /// # unimplemented!() /// # } /// # - /// # fn visit_newtype_seed(self, _: T) -> Result + /// # fn deserialize_newtype_seed(self, _: T) -> Result /// # where T: DeserializeSeed<'de> /// # { unimplemented!() } /// # - /// # fn visit_tuple(self, _: usize, _: V) -> Result + /// # fn deserialize_tuple(self, _: usize, _: V) -> Result /// # where V: Visitor<'de> /// # { unimplemented!() } /// # - /// fn visit_struct(self, - /// _fields: &'static [&'static str], - /// _visitor: V) -> Result + /// fn deserialize_struct(self, + /// _fields: &'static [&'static str], + /// _visitor: V) -> Result /// where V: Visitor<'de> /// { /// // What the data actually contained; suppose it is a unit variant. @@ -1787,7 +1788,7 @@ pub trait VariantVisitor<'de>: Sized { /// } /// # } /// ``` - fn visit_struct( + fn deserialize_struct( self, fields: &'static [&'static str], visitor: V, diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 2e611551..0917d549 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -10,7 +10,7 @@ use lib::*; -use de::{self, IntoDeserializer, Expected, SeqVisitor}; +use de::{self, IntoDeserializer, Expected, SeqAccess}; use self::private::{First, Second}; //////////////////////////////////////////////////////////////////////////////// @@ -223,14 +223,14 @@ where } } -impl<'de, E> de::EnumVisitor<'de> for U32Deserializer +impl<'de, E> de::EnumAccess<'de> for U32Deserializer where E: de::Error, { type Error = E; type Variant = private::UnitOnly; - fn visit_variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> + fn variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> where T: de::DeserializeSeed<'de>, { @@ -293,14 +293,14 @@ where } } -impl<'de, 'a, E> de::EnumVisitor<'de> for StrDeserializer<'a, E> +impl<'de, 'a, E> de::EnumAccess<'de> for StrDeserializer<'a, E> where E: de::Error, { type Error = E; type Variant = private::UnitOnly; - fn visit_variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> + fn variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> where T: de::DeserializeSeed<'de>, { @@ -367,14 +367,14 @@ where } #[cfg(any(feature = "std", feature = "collections"))] -impl<'de, 'a, E> de::EnumVisitor<'de> for StringDeserializer +impl<'de, 'a, E> de::EnumAccess<'de> for StringDeserializer where E: de::Error, { type Error = E; type Variant = private::UnitOnly; - fn visit_variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> + fn variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> where T: de::DeserializeSeed<'de>, { @@ -444,14 +444,14 @@ where } #[cfg(any(feature = "std", feature = "collections"))] -impl<'de, 'a, E> de::EnumVisitor<'de> for CowStrDeserializer<'a, E> +impl<'de, 'a, E> de::EnumAccess<'de> for CowStrDeserializer<'a, E> where E: de::Error, { type Error = E; type Variant = private::UnitOnly; - fn visit_variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> + fn variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error> where T: de::DeserializeSeed<'de>, { @@ -524,7 +524,7 @@ where } } -impl<'de, I, T, E> de::SeqVisitor<'de> for SeqDeserializer +impl<'de, I, T, E> de::SeqAccess<'de> for SeqDeserializer where I: Iterator, T: IntoDeserializer<'de, E>, @@ -532,7 +532,7 @@ where { type Error = E; - fn visit_seed(&mut self, seed: V) -> Result, Self::Error> + fn next_element_seed(&mut self, seed: V) -> Result, Self::Error> where V: de::DeserializeSeed<'de>, { @@ -605,7 +605,7 @@ where //////////////////////////////////////////////////////////////////////////////// -/// A helper deserializer that deserializes a sequence using a `SeqVisitor`. +/// A helper deserializer that deserializes a sequence using a `SeqAccess`. #[derive(Clone, Debug)] pub struct SeqVisitorDeserializer { visitor: V_, @@ -620,7 +620,7 @@ impl SeqVisitorDeserializer { impl<'de, V_> de::Deserializer<'de> for SeqVisitorDeserializer where - V_: de::SeqVisitor<'de>, + V_: de::SeqAccess<'de>, { type Error = V_::Error; @@ -747,7 +747,7 @@ where } } -impl<'de, I, E> de::MapVisitor<'de> for MapDeserializer<'de, I, E> +impl<'de, I, E> de::MapAccess<'de> for MapDeserializer<'de, I, E> where I: Iterator, I::Item: private::Pair, @@ -757,7 +757,7 @@ where { type Error = E; - fn visit_key_seed(&mut self, seed: T) -> Result, Self::Error> + fn next_key_seed(&mut self, seed: T) -> Result, Self::Error> where T: de::DeserializeSeed<'de>, { @@ -770,18 +770,18 @@ where } } - fn visit_value_seed(&mut self, seed: T) -> Result + fn next_value_seed(&mut self, seed: T) -> Result where T: de::DeserializeSeed<'de>, { let value = self.value.take(); // Panic because this indicates a bug in the program rather than an // expected failure. - let value = value.expect("MapVisitor::visit_value called before visit_key"); + let value = value.expect("MapAccess::visit_value called before visit_key"); seed.deserialize(value.into_deserializer()) } - fn visit_seed(&mut self, + fn next_entry_seed(&mut self, kseed: TK, vseed: TV) -> Result, Self::Error> @@ -804,7 +804,7 @@ where } } -impl<'de, I, E> de::SeqVisitor<'de> for MapDeserializer<'de, I, E> +impl<'de, I, E> de::SeqAccess<'de> for MapDeserializer<'de, I, E> where I: Iterator, I::Item: private::Pair, @@ -814,7 +814,7 @@ where { type Error = E; - fn visit_seed(&mut self, seed: T) -> Result, Self::Error> + fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> where T: de::DeserializeSeed<'de>, { @@ -876,7 +876,7 @@ where } } -// Used in the `impl SeqVisitor for MapDeserializer` to visit the map as a +// Used in the `impl SeqAccess for MapDeserializer` to visit the map as a // sequence of pairs. struct PairDeserializer(A, B, PhantomData); @@ -933,7 +933,7 @@ where struct PairVisitor(Option, Option, PhantomData); -impl<'de, A, B, E> de::SeqVisitor<'de> for PairVisitor +impl<'de, A, B, E> de::SeqAccess<'de> for PairVisitor where A: IntoDeserializer<'de, E>, B: IntoDeserializer<'de, E>, @@ -941,7 +941,7 @@ where { type Error = E; - fn visit_seed(&mut self, seed: T) -> Result, Self::Error> + fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> where T: de::DeserializeSeed<'de>, { @@ -1010,7 +1010,7 @@ where //////////////////////////////////////////////////////////////////////////////// -/// A helper deserializer that deserializes a map using a `MapVisitor`. +/// A helper deserializer that deserializes a map using a `MapAccess`. #[derive(Clone, Debug)] pub struct MapVisitorDeserializer { visitor: V_, @@ -1025,7 +1025,7 @@ impl MapVisitorDeserializer { impl<'de, V_> de::Deserializer<'de> for MapVisitorDeserializer where - V_: de::MapVisitor<'de>, + V_: de::MapAccess<'de>, { type Error = V_::Error; @@ -1059,31 +1059,31 @@ mod private { (t, UnitOnly { marker: PhantomData }) } - impl<'de, E> de::VariantVisitor<'de> for UnitOnly + impl<'de, E> de::VariantAccess<'de> for UnitOnly where E: de::Error, { type Error = E; - fn visit_unit(self) -> Result<(), Self::Error> { + fn deserialize_unit(self) -> Result<(), Self::Error> { Ok(()) } - fn visit_newtype_seed(self, _seed: T) -> Result + fn deserialize_newtype_seed(self, _seed: T) -> Result where T: de::DeserializeSeed<'de>, { Err(de::Error::invalid_type(Unexpected::UnitVariant, &"newtype variant"),) } - fn visit_tuple(self, _len: usize, _visitor: V) -> Result + fn deserialize_tuple(self, _len: usize, _visitor: V) -> Result where V: de::Visitor<'de>, { Err(de::Error::invalid_type(Unexpected::UnitVariant, &"tuple variant"),) } - fn visit_struct( + fn deserialize_struct( self, _fields: &'static [&'static str], _visitor: V, diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 844a9d7b..d5c03061 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -201,8 +201,8 @@ mod content { use lib::*; - use de::{self, Deserialize, DeserializeSeed, Deserializer, Visitor, SeqVisitor, MapVisitor, - EnumVisitor, Unexpected}; + use de::{self, Deserialize, DeserializeSeed, Deserializer, Visitor, SeqAccess, MapAccess, + EnumAccess, Unexpected}; /// Used from generated code to buffer the contents of the Deserializer when /// deserializing untagged enums and internally tagged enums. @@ -426,10 +426,10 @@ mod content { fn visit_seq(self, mut visitor: V) -> Result where - V: SeqVisitor<'de>, + V: SeqAccess<'de>, { let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); - while let Some(e) = try!(visitor.visit()) { + while let Some(e) = try!(visitor.next_element()) { vec.push(e); } Ok(Content::Seq(vec)) @@ -437,10 +437,10 @@ mod content { fn visit_map(self, mut visitor: V) -> Result where - V: MapVisitor<'de>, + V: MapAccess<'de>, { let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); - while let Some(kv) = try!(visitor.visit()) { + while let Some(kv) = try!(visitor.next_entry()) { vec.push(kv); } Ok(Content::Map(vec)) @@ -448,7 +448,7 @@ mod content { fn visit_enum(self, _visitor: V) -> Result where - V: EnumVisitor<'de>, + V: EnumAccess<'de>, { Err(de::Error::custom("untagged and internally tagged enums do not support enum input",),) } @@ -682,7 +682,7 @@ mod content { fn visit_seq(self, visitor: V) -> Result where - V: SeqVisitor<'de>, + V: SeqAccess<'de>, { ContentVisitor .visit_seq(visitor) @@ -691,7 +691,7 @@ mod content { fn visit_map(self, visitor: V) -> Result where - V: MapVisitor<'de>, + V: MapAccess<'de>, { ContentVisitor .visit_map(visitor) @@ -700,7 +700,7 @@ mod content { fn visit_enum(self, visitor: V) -> Result where - V: EnumVisitor<'de>, + V: EnumAccess<'de>, { ContentVisitor .visit_enum(visitor) @@ -761,21 +761,21 @@ mod content { fn visit_map(self, mut visitor: V) -> Result where - V: MapVisitor<'de>, + V: MapAccess<'de>, { let mut tag = None; let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); while let Some(k) = - try!(visitor.visit_key_seed(TagOrContentVisitor::new(self.tag_name))) { + try!(visitor.next_key_seed(TagOrContentVisitor::new(self.tag_name))) { match k { TagOrContent::Tag => { if tag.is_some() { return Err(de::Error::duplicate_field(self.tag_name)); } - tag = Some(try!(visitor.visit_value())); + tag = Some(try!(visitor.next_value())); } TagOrContent::Content(k) => { - let v = try!(visitor.visit_value()); + let v = try!(visitor.next_value()); vec.push((k, v)); } } @@ -995,14 +995,14 @@ mod content { err: PhantomData, } - impl<'de, E> de::EnumVisitor<'de> for EnumDeserializer + impl<'de, E> de::EnumAccess<'de> for EnumDeserializer where E: de::Error, { type Error = E; type Variant = VariantDeserializer; - fn visit_variant_seed( + fn variant_seed( self, seed: V, ) -> Result<(V::Value, VariantDeserializer), Self::Error> @@ -1026,20 +1026,20 @@ mod content { err: PhantomData, } - impl<'de, E> de::VariantVisitor<'de> for VariantDeserializer + impl<'de, E> de::VariantAccess<'de> for VariantDeserializer where E: de::Error, { type Error = E; - fn visit_unit(self) -> Result<(), E> { + fn deserialize_unit(self) -> Result<(), E> { match self.value { Some(value) => de::Deserialize::deserialize(ContentDeserializer::new(value)), None => Ok(()), } } - fn visit_newtype_seed(self, seed: T) -> Result + fn deserialize_newtype_seed(self, seed: T) -> Result where T: de::DeserializeSeed<'de>, { @@ -1051,7 +1051,7 @@ mod content { } } - fn visit_tuple(self, _len: usize, visitor: V) -> Result + fn deserialize_tuple(self, _len: usize, visitor: V) -> Result where V: de::Visitor<'de>, { @@ -1064,7 +1064,7 @@ mod content { } } - fn visit_struct( + fn deserialize_struct( self, _fields: &'static [&'static str], visitor: V, @@ -1134,13 +1134,13 @@ mod content { } } - impl<'de, E> de::SeqVisitor<'de> for SeqDeserializer + impl<'de, E> de::SeqAccess<'de> for SeqDeserializer where E: de::Error, { type Error = E; - fn visit_seed(&mut self, seed: T) -> Result, Self::Error> + fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> where T: de::DeserializeSeed<'de>, { @@ -1180,13 +1180,13 @@ mod content { } } - impl<'de, E> de::MapVisitor<'de> for MapDeserializer + impl<'de, E> de::MapAccess<'de> for MapDeserializer where E: de::Error, { type Error = E; - fn visit_key_seed(&mut self, seed: T) -> Result, Self::Error> + fn next_key_seed(&mut self, seed: T) -> Result, Self::Error> where T: de::DeserializeSeed<'de>, { @@ -1199,7 +1199,7 @@ mod content { } } - fn visit_value_seed(&mut self, seed: T) -> Result + fn next_value_seed(&mut self, seed: T) -> Result where T: de::DeserializeSeed<'de>, { @@ -1391,14 +1391,14 @@ mod content { err: PhantomData, } - impl<'de, 'a, E> de::EnumVisitor<'de> for EnumRefDeserializer<'a, E> + impl<'de, 'a, E> de::EnumAccess<'de> for EnumRefDeserializer<'a, E> where E: de::Error, { type Error = E; type Variant = VariantRefDeserializer<'a, Self::Error>; - fn visit_variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> + fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> where V: de::DeserializeSeed<'de>, { @@ -1419,20 +1419,20 @@ mod content { err: PhantomData, } - impl<'de, 'a, E> de::VariantVisitor<'de> for VariantRefDeserializer<'a, E> + impl<'de, 'a, E> de::VariantAccess<'de> for VariantRefDeserializer<'a, E> where E: de::Error, { type Error = E; - fn visit_unit(self) -> Result<(), E> { + fn deserialize_unit(self) -> Result<(), E> { match self.value { Some(value) => de::Deserialize::deserialize(ContentRefDeserializer::new(value)), None => Ok(()), } } - fn visit_newtype_seed(self, seed: T) -> Result + fn deserialize_newtype_seed(self, seed: T) -> Result where T: de::DeserializeSeed<'de>, { @@ -1444,7 +1444,7 @@ mod content { } } - fn visit_tuple(self, _len: usize, visitor: V) -> Result + fn deserialize_tuple(self, _len: usize, visitor: V) -> Result where V: de::Visitor<'de>, { @@ -1457,7 +1457,7 @@ mod content { } } - fn visit_struct( + fn deserialize_struct( self, _fields: &'static [&'static str], visitor: V, @@ -1527,13 +1527,13 @@ mod content { } } - impl<'de, 'a, E> de::SeqVisitor<'de> for SeqRefDeserializer<'a, E> + impl<'de, 'a, E> de::SeqAccess<'de> for SeqRefDeserializer<'a, E> where E: de::Error, { type Error = E; - fn visit_seed(&mut self, seed: T) -> Result, Self::Error> + fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> where T: de::DeserializeSeed<'de>, { @@ -1573,13 +1573,13 @@ mod content { } } - impl<'de, 'a, E> de::MapVisitor<'de> for MapRefDeserializer<'a, E> + impl<'de, 'a, E> de::MapAccess<'de> for MapRefDeserializer<'a, E> where E: de::Error, { type Error = E; - fn visit_key_seed(&mut self, seed: T) -> Result, Self::Error> + fn next_key_seed(&mut self, seed: T) -> Result, Self::Error> where T: de::DeserializeSeed<'de>, { @@ -1593,7 +1593,7 @@ mod content { } } - fn visit_value_seed(&mut self, seed: T) -> Result + fn next_value_seed(&mut self, seed: T) -> Result where T: de::DeserializeSeed<'de>, { @@ -1678,7 +1678,7 @@ mod content { fn visit_map(self, _: V) -> Result<(), V::Error> where - V: MapVisitor<'de>, + V: MapAccess<'de>, { Ok(()) } diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 6d07458d..994b9a9b 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -292,7 +292,7 @@ fn deserialize_tuple( let dispatch = if let Some(deserializer) = deserializer { quote!(_serde::Deserializer::deserialize_tuple(#deserializer, #nfields, #visitor_expr)) } else if is_enum { - quote!(_serde::de::VariantVisitor::visit_tuple(__visitor, #nfields, #visitor_expr)) + quote!(_serde::de::VariantAccess::deserialize_tuple(__variant, #nfields, #visitor_expr)) } else if nfields == 1 { let type_name = item_attrs.name().deserialize_name(); quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr)) @@ -307,7 +307,7 @@ fn deserialize_tuple( let visitor_var = if all_skipped { quote!(_) } else { - quote!(mut __visitor) + quote!(mut __seq) }; quote_block! { @@ -326,8 +326,8 @@ fn deserialize_tuple( #visit_newtype_struct #[inline] - fn visit_seq<__V>(self, #visitor_var: __V) -> _serde::export::Result - where __V: _serde::de::SeqVisitor<'de> + fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result + where __A: _serde::de::SeqAccess<'de> { #visit_seq } @@ -364,7 +364,7 @@ fn deserialize_seq( let visit = match field.attrs.deserialize_with() { None => { let field_ty = &field.ty; - quote!(try!(_serde::de::SeqVisitor::visit::<#field_ty>(&mut __visitor))) + quote!(try!(_serde::de::SeqAccess::next_element::<#field_ty>(&mut __seq))) } Some(path) => { let (wrapper, wrapper_ty) = wrap_deserialize_with( @@ -372,7 +372,7 @@ fn deserialize_seq( quote!({ #wrapper _serde::export::Option::map( - try!(_serde::de::SeqVisitor::visit::<#wrapper_ty>(&mut __visitor)), + try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)), |__wrap| __wrap.value) }) } @@ -501,7 +501,7 @@ fn deserialize_struct( } } else if is_enum { quote! { - _serde::de::VariantVisitor::visit_struct(__visitor, FIELDS, #visitor_expr) + _serde::de::VariantAccess::deserialize_struct(__variant, FIELDS, #visitor_expr) } } else { let type_name = item_attrs.name().deserialize_name(); @@ -516,7 +516,7 @@ fn deserialize_struct( let visitor_var = if all_skipped { quote!(_) } else { - quote!(mut __visitor) + quote!(mut __seq) }; let visit_seq = if is_untagged { @@ -525,8 +525,8 @@ fn deserialize_struct( } else { Some(quote! { #[inline] - fn visit_seq<__V>(self, #visitor_var: __V) -> _serde::export::Result - where __V: _serde::de::SeqVisitor<'de> + fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result + where __A: _serde::de::SeqAccess<'de> { #visit_seq } @@ -551,8 +551,8 @@ fn deserialize_struct( #visit_seq #[inline] - fn visit_map<__V>(self, mut __visitor: __V) -> _serde::export::Result - where __V: _serde::de::MapVisitor<'de> + fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result + where __A: _serde::de::MapAccess<'de> { #visit_map } @@ -624,7 +624,7 @@ fn deserialize_externally_tagged_enum( Match(deserialize_externally_tagged_variant(params, variant, item_attrs),); quote! { - (__Field::#variant_name, __visitor) => #block + (__Field::#variant_name, __variant) => #block } }, ); @@ -637,15 +637,15 @@ fn deserialize_externally_tagged_enum( // all variants have `#[serde(skip_deserializing)]`. quote! { // FIXME: Once we drop support for Rust 1.15: - // let _serde::export::Err(__err) = _serde::de::EnumVisitor::visit_variant::<__Field>(__visitor); + // let _serde::export::Err(__err) = _serde::de::EnumAccess::variant::<__Field>(__data); // _serde::export::Err(__err) _serde::export::Result::map( - _serde::de::EnumVisitor::visit_variant::<__Field>(__visitor), + _serde::de::EnumAccess::variant::<__Field>(__data), |(__impossible, _)| match __impossible {}) } } else { quote! { - match try!(_serde::de::EnumVisitor::visit_variant(__visitor)) { + match try!(_serde::de::EnumAccess::variant(__data)) { #(#variant_arms)* } } @@ -666,8 +666,8 @@ fn deserialize_externally_tagged_enum( _serde::export::Formatter::write_str(formatter, #expecting) } - fn visit_enum<__V>(self, __visitor: __V) -> _serde::export::Result - where __V: _serde::de::EnumVisitor<'de> + fn visit_enum<__A>(self, __data: __A) -> _serde::export::Result + where __A: _serde::de::EnumAccess<'de> { #match_variant } @@ -807,7 +807,7 @@ fn deserialize_adjacently_tagged_enum( } let mut missing_content = quote! { - _serde::export::Err(<__V::Error as _serde::de::Error>::missing_field(#content)) + _serde::export::Err(<__A::Error as _serde::de::Error>::missing_field(#content)) }; if variants.iter().any(is_unit) { let fallthrough = if variants.iter().all(is_unit) { @@ -842,12 +842,12 @@ fn deserialize_adjacently_tagged_enum( let visit_third_key = quote! { // Visit the third key in the map, hopefully there isn't one. - match try!(_serde::de::MapVisitor::visit_key_seed(&mut __visitor, #tag_or_content)) { + match try!(_serde::de::MapAccess::next_key_seed(&mut __map, #tag_or_content)) { _serde::export::Some(_serde::private::de::TagOrContentField::Tag) => { - _serde::export::Err(<__V::Error as _serde::de::Error>::duplicate_field(#tag)) + _serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#tag)) } _serde::export::Some(_serde::private::de::TagOrContentField::Content) => { - _serde::export::Err(<__V::Error as _serde::de::Error>::duplicate_field(#content)) + _serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#content)) } _serde::export::None => _serde::export::Ok(__ret), } @@ -888,24 +888,24 @@ fn deserialize_adjacently_tagged_enum( _serde::export::Formatter::write_str(formatter, #expecting) } - fn visit_map<__V>(self, mut __visitor: __V) -> _serde::export::Result - where __V: _serde::de::MapVisitor<'de> + fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result + where __A: _serde::de::MapAccess<'de> { // Visit the first key. - match try!(_serde::de::MapVisitor::visit_key_seed(&mut __visitor, #tag_or_content)) { + match try!(_serde::de::MapAccess::next_key_seed(&mut __map, #tag_or_content)) { // First key is the tag. _serde::export::Some(_serde::private::de::TagOrContentField::Tag) => { // Parse the tag. - let __field = try!(_serde::de::MapVisitor::visit_value(&mut __visitor)); + let __field = try!(_serde::de::MapAccess::next_value(&mut __map)); // Visit the second key. - match try!(_serde::de::MapVisitor::visit_key_seed(&mut __visitor, #tag_or_content)) { + match try!(_serde::de::MapAccess::next_key_seed(&mut __map, #tag_or_content)) { // Second key is a duplicate of the tag. _serde::export::Some(_serde::private::de::TagOrContentField::Tag) => { - _serde::export::Err(<__V::Error as _serde::de::Error>::duplicate_field(#tag)) + _serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#tag)) } // Second key is the content. _serde::export::Some(_serde::private::de::TagOrContentField::Content) => { - let __ret = try!(_serde::de::MapVisitor::visit_value_seed(&mut __visitor, + let __ret = try!(_serde::de::MapAccess::next_value_seed(&mut __map, __Seed { field: __field, marker: _serde::export::PhantomData, @@ -921,14 +921,14 @@ fn deserialize_adjacently_tagged_enum( // First key is the content. _serde::export::Some(_serde::private::de::TagOrContentField::Content) => { // Buffer up the content. - let __content = try!(_serde::de::MapVisitor::visit_value::<_serde::private::de::Content>(&mut __visitor)); + let __content = try!(_serde::de::MapAccess::next_value::<_serde::private::de::Content>(&mut __map)); // Visit the second key. - match try!(_serde::de::MapVisitor::visit_key_seed(&mut __visitor, #tag_or_content)) { + match try!(_serde::de::MapAccess::next_key_seed(&mut __map, #tag_or_content)) { // Second key is the tag. _serde::export::Some(_serde::private::de::TagOrContentField::Tag) => { - let __deserializer = _serde::private::de::ContentDeserializer::<__V::Error>::new(__content); + let __deserializer = _serde::private::de::ContentDeserializer::<__A::Error>::new(__content); // Parse the tag. - let __ret = try!(match try!(_serde::de::MapVisitor::visit_value(&mut __visitor)) { + let __ret = try!(match try!(_serde::de::MapAccess::next_value(&mut __map)) { // Deserialize the buffered content now that we know the variant. #(#variant_arms)* }); @@ -937,29 +937,29 @@ fn deserialize_adjacently_tagged_enum( } // Second key is a duplicate of the content. _serde::export::Some(_serde::private::de::TagOrContentField::Content) => { - _serde::export::Err(<__V::Error as _serde::de::Error>::duplicate_field(#content)) + _serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#content)) } // There is no second key. _serde::export::None => { - _serde::export::Err(<__V::Error as _serde::de::Error>::missing_field(#tag)) + _serde::export::Err(<__A::Error as _serde::de::Error>::missing_field(#tag)) } } } // There is no first key. _serde::export::None => { - _serde::export::Err(<__V::Error as _serde::de::Error>::missing_field(#tag)) + _serde::export::Err(<__A::Error as _serde::de::Error>::missing_field(#tag)) } } } - fn visit_seq<__V>(self, mut __visitor: __V) -> _serde::export::Result - where __V: _serde::de::SeqVisitor<'de> + fn visit_seq<__A>(self, mut __seq: __A) -> _serde::export::Result + where __A: _serde::de::SeqAccess<'de> { // Visit the first element - the tag. - match try!(_serde::de::SeqVisitor::visit(&mut __visitor)) { + match try!(_serde::de::SeqAccess::next_element(&mut __seq)) { _serde::export::Some(__field) => { // Visit the second element - the content. - match try!(_serde::de::SeqVisitor::visit_seed(&mut __visitor, + match try!(_serde::de::SeqAccess::next_element_seed(&mut __seq, __Seed { field: __field, marker: _serde::export::PhantomData, @@ -1041,7 +1041,7 @@ fn deserialize_externally_tagged_variant( Style::Unit => { let this = ¶ms.this; quote_block! { - try!(_serde::de::VariantVisitor::visit_unit(__visitor)); + try!(_serde::de::VariantAccess::deserialize_unit(__variant)); _serde::export::Ok(#this::#variant_ident) } } @@ -1156,7 +1156,7 @@ fn deserialize_externally_tagged_newtype_variant( let field_ty = &field.ty; quote_expr! { _serde::export::Result::map( - _serde::de::VariantVisitor::visit_newtype::<#field_ty>(__visitor), + _serde::de::VariantAccess::deserialize_newtype::<#field_ty>(__variant), #this::#variant_ident) } } @@ -1165,7 +1165,7 @@ fn deserialize_externally_tagged_newtype_variant( quote_block! { #wrapper _serde::export::Result::map( - _serde::de::VariantVisitor::visit_newtype::<#wrapper_ty>(__visitor), + _serde::de::VariantAccess::deserialize_newtype::<#wrapper_ty>(__variant), |__wrapper| #this::#variant_ident(__wrapper.value)) } } @@ -1380,7 +1380,7 @@ fn deserialize_map( None => { let field_ty = &field.ty; quote! { - try!(_serde::de::MapVisitor::visit_value::<#field_ty>(&mut __visitor)) + try!(_serde::de::MapAccess::next_value::<#field_ty>(&mut __map)) } } Some(path) => { @@ -1388,14 +1388,14 @@ fn deserialize_map( params, field.ty, path); quote!({ #wrapper - try!(_serde::de::MapVisitor::visit_value::<#wrapper_ty>(&mut __visitor)).value + try!(_serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map)).value }) } }; quote! { __Field::#name => { if _serde::export::Option::is_some(&#name) { - return _serde::export::Err(<__V::Error as _serde::de::Error>::duplicate_field(#deser_name)); + return _serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#deser_name)); } #name = _serde::export::Some(#visit); } @@ -1407,7 +1407,7 @@ fn deserialize_map( None } else { Some(quote! { - _ => { let _ = try!(_serde::de::MapVisitor::visit_value::<_serde::de::IgnoredAny>(&mut __visitor)); } + _ => { let _ = try!(_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)); } }) }; @@ -1417,14 +1417,14 @@ fn deserialize_map( let match_keys = if item_attrs.deny_unknown_fields() && all_skipped { quote! { // FIXME: Once we drop support for Rust 1.15: - // let _serde::export::None::<__Field> = try!(_serde::de::MapVisitor::visit_key(&mut __visitor)); + // let _serde::export::None::<__Field> = try!(_serde::de::MapAccess::next_key(&mut __map)); _serde::export::Option::map( - try!(_serde::de::MapVisitor::visit_key::<__Field>(&mut __visitor)), + try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)), |__impossible| match __impossible {}); } } else { quote! { - while let _serde::export::Some(__key) = try!(_serde::de::MapVisitor::visit_key::<__Field>(&mut __visitor)) { + while let _serde::export::Some(__key) = try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)) { match __key { #(#value_arms)* #ignored_arm @@ -1577,7 +1577,7 @@ fn expr_is_missing(field: &Field, item_attrs: &attr::Item) -> Fragment { } Some(_) => { quote_expr! { - return _serde::export::Err(<__V::Error as _serde::de::Error>::missing_field(#name)) + return _serde::export::Err(<__A::Error as _serde::de::Error>::missing_field(#name)) } } } diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index c30f6e27..b6ce5725 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -6,8 +6,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use serde::de::{self, Deserialize, DeserializeSeed, EnumVisitor, IntoDeserializer, MapVisitor, - SeqVisitor, VariantVisitor, Visitor}; +use serde::de::{self, Deserialize, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, + SeqAccess, VariantAccess, Visitor}; use serde::de::value::{MapVisitorDeserializer, SeqVisitorDeserializer}; use error::Error; @@ -390,10 +390,10 @@ struct DeserializerSeqVisitor<'a, 'de: 'a> { end: Token, } -impl<'de, 'a> SeqVisitor<'de> for DeserializerSeqVisitor<'a, 'de> { +impl<'de, 'a> SeqAccess<'de> for DeserializerSeqVisitor<'a, 'de> { type Error = Error; - fn visit_seed(&mut self, seed: T) -> Result, Error> + fn next_element_seed(&mut self, seed: T) -> Result, Error> where T: DeserializeSeed<'de>, { @@ -418,10 +418,10 @@ struct DeserializerMapVisitor<'a, 'de: 'a> { end: Token, } -impl<'de, 'a> MapVisitor<'de> for DeserializerMapVisitor<'a, 'de> { +impl<'de, 'a> MapAccess<'de> for DeserializerMapVisitor<'a, 'de> { type Error = Error; - fn visit_key_seed(&mut self, seed: K) -> Result, Error> + fn next_key_seed(&mut self, seed: K) -> Result, Error> where K: DeserializeSeed<'de>, { @@ -432,7 +432,7 @@ impl<'de, 'a> MapVisitor<'de> for DeserializerMapVisitor<'a, 'de> { seed.deserialize(&mut *self.de).map(Some) } - fn visit_value_seed(&mut self, seed: V) -> Result + fn next_value_seed(&mut self, seed: V) -> Result where V: DeserializeSeed<'de>, { @@ -451,11 +451,11 @@ struct DeserializerEnumVisitor<'a, 'de: 'a> { de: &'a mut Deserializer<'de>, } -impl<'de, 'a> EnumVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { +impl<'de, 'a> EnumAccess<'de> for DeserializerEnumVisitor<'a, 'de> { type Error = Error; type Variant = Self; - fn visit_variant_seed(self, seed: V) -> Result<(V::Value, Self), Error> + fn variant_seed(self, seed: V) -> Result<(V::Value, Self), Error> where V: DeserializeSeed<'de>, { @@ -477,10 +477,10 @@ impl<'de, 'a> EnumVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { } } -impl<'de, 'a> VariantVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { +impl<'de, 'a> VariantAccess<'de> for DeserializerEnumVisitor<'a, 'de> { type Error = Error; - fn visit_unit(self) -> Result<(), Error> { + fn deserialize_unit(self) -> Result<(), Error> { match self.de.tokens.first() { Some(&Token::UnitVariant(_, _)) => { self.de.next_token(); @@ -491,7 +491,7 @@ impl<'de, 'a> VariantVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { } } - fn visit_newtype_seed(self, seed: T) -> Result + fn deserialize_newtype_seed(self, seed: T) -> Result where T: DeserializeSeed<'de>, { @@ -505,7 +505,7 @@ impl<'de, 'a> VariantVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { } } - fn visit_tuple(self, len: usize, visitor: V) -> Result + fn deserialize_tuple(self, len: usize, visitor: V) -> Result where V: Visitor<'de>, { @@ -534,7 +534,7 @@ impl<'de, 'a> VariantVisitor<'de> for DeserializerEnumVisitor<'a, 'de> { } } - fn visit_struct(self, fields: &'static [&'static str], visitor: V) -> Result + fn deserialize_struct(self, fields: &'static [&'static str], visitor: V) -> Result where V: Visitor<'de>, { @@ -589,10 +589,10 @@ impl<'a, 'de> EnumMapVisitor<'a, 'de> { } } -impl<'de, 'a> MapVisitor<'de> for EnumMapVisitor<'a, 'de> { +impl<'de, 'a> MapAccess<'de> for EnumMapVisitor<'a, 'de> { type Error = Error; - fn visit_key_seed(&mut self, seed: K) -> Result, Error> + fn next_key_seed(&mut self, seed: K) -> Result, Error> where K: DeserializeSeed<'de>, { @@ -608,7 +608,7 @@ impl<'de, 'a> MapVisitor<'de> for EnumMapVisitor<'a, 'de> { } } - fn visit_value_seed(&mut self, seed: V) -> Result + fn next_value_seed(&mut self, seed: V) -> Result where V: DeserializeSeed<'de>, { From e77e7c4bba26a0daee7064c4c0fc54d767266c6f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 12:50:35 -0700 Subject: [PATCH 147/177] Rename Deserializer::deserialize to deserialize_any --- serde/src/de/impls.rs | 4 +- serde/src/de/mod.rs | 16 +++---- serde/src/de/value.rs | 44 ++++++++++---------- serde/src/macros.rs | 92 ++++++++++++++++++++--------------------- serde/src/private/de.rs | 42 +++++++++---------- serde_derive/src/de.rs | 8 ++-- serde_test/src/de.rs | 26 ++++++------ 7 files changed, 116 insertions(+), 116 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index b7ec32b1..3999f3e3 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -1070,7 +1070,7 @@ impl<'de> Deserialize<'de> for OsStringKind { } } - deserializer.deserialize(KindVisitor) + deserializer.deserialize_identifier(KindVisitor) } } @@ -1581,7 +1581,7 @@ where } } - deserializer.deserialize(FieldVisitor) + deserializer.deserialize_identifier(FieldVisitor) } } diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 86398eb3..dc67021b 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -763,22 +763,22 @@ where /// to look at the serialized data and tell what it represents. For example /// the JSON deserializer may see an opening curly brace (`{`) and know that /// it is seeing a map. If the data format supports -/// `Deserializer::deserialize`, it will drive the Visitor using whatever +/// `Deserializer::deserialize_any`, it will drive the Visitor using whatever /// type it sees in the input. JSON uses this approach when deserializing /// `serde_json::Value` which is an enum that can represent any JSON /// document. Without knowing what is in a JSON document, we can deserialize -/// it to `serde_json::Value` by going through `Deserializer::deserialize`. +/// it to `serde_json::Value` by going through `Deserializer::deserialize_any`. /// /// 2. The various `deserialize_*` methods. Non-self-describing formats like /// Bincode need to be told what is in the input in order to deserialize it. /// The `deserialize_*` methods are hints to the deserializer for how to /// interpret the next piece of input. Non-self-describing formats are not /// able to deserialize something like `serde_json::Value` which relies on -/// `Deserializer::deserialize`. +/// `Deserializer::deserialize_any`. /// /// When implementing `Deserialize`, you should avoid relying on -/// `Deserializer::deserialize` unless you need to be told by the Deserializer -/// what type is in the input. Know that relying on `Deserializer::deserialize` +/// `Deserializer::deserialize_any` unless you need to be told by the Deserializer +/// what type is in the input. Know that relying on `Deserializer::deserialize_any` /// means your data type will be able to deserialize from self-describing /// formats only, ruling out Bincode and many others. pub trait Deserializer<'de>: Sized { @@ -790,12 +790,12 @@ pub trait Deserializer<'de>: Sized { /// on what data type is in the input. /// /// When implementing `Deserialize`, you should avoid relying on - /// `Deserializer::deserialize` unless you need to be told by the + /// `Deserializer::deserialize_any` unless you need to be told by the /// Deserializer what type is in the input. Know that relying on - /// `Deserializer::deserialize` means your data type will be able to + /// `Deserializer::deserialize_any` means your data type will be able to /// deserialize from self-describing formats only, ruling out Bincode and /// many others. - fn deserialize(self, visitor: V) -> Result + fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de>; diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 0917d549..a521c9a6 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -88,13 +88,13 @@ where { type Error = E; - forward_to_deserialize! { + forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct struct identifier tuple enum ignored_any byte_buf } - fn deserialize(self, visitor: V) -> Result + fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { @@ -140,13 +140,13 @@ macro_rules! primitive_deserializer { { type Error = E; - forward_to_deserialize! { + forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct struct identifier tuple enum ignored_any byte_buf } - fn deserialize(self, visitor: V) -> Result + fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { @@ -197,13 +197,13 @@ where { type Error = E; - forward_to_deserialize! { + forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct struct identifier tuple ignored_any byte_buf } - fn deserialize(self, visitor: V) -> Result + fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { @@ -267,7 +267,7 @@ where { type Error = E; - fn deserialize(self, visitor: V) -> Result + fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { @@ -286,7 +286,7 @@ where visitor.visit_enum(self) } - forward_to_deserialize! { + forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct struct identifier tuple ignored_any byte_buf @@ -340,7 +340,7 @@ where { type Error = E; - fn deserialize(self, visitor: V) -> Result + fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { @@ -359,7 +359,7 @@ where visitor.visit_enum(self) } - forward_to_deserialize! { + forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct struct identifier tuple ignored_any byte_buf @@ -414,7 +414,7 @@ where { type Error = E; - fn deserialize(self, visitor: V) -> Result + fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { @@ -436,7 +436,7 @@ where visitor.visit_enum(self) } - forward_to_deserialize! { + forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct struct identifier tuple ignored_any byte_buf @@ -508,7 +508,7 @@ where { type Error = E; - fn deserialize(mut self, visitor: V) -> Result + fn deserialize_any(mut self, visitor: V) -> Result where V: de::Visitor<'de>, { @@ -517,7 +517,7 @@ where Ok(v) } - forward_to_deserialize! { + forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct struct identifier tuple enum ignored_any byte_buf @@ -624,14 +624,14 @@ where { type Error = V_::Error; - fn deserialize(self, visitor: V) -> Result + fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { visitor.visit_seq(self.visitor) } - forward_to_deserialize! { + forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct struct identifier tuple enum ignored_any byte_buf @@ -712,7 +712,7 @@ where { type Error = E; - fn deserialize(mut self, visitor: V_) -> Result + fn deserialize_any(mut self, visitor: V_) -> Result where V_: de::Visitor<'de>, { @@ -740,7 +740,7 @@ where self.deserialize_seq(visitor) } - forward_to_deserialize! { + forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option bytes map unit_struct newtype_struct tuple_struct struct identifier tuple enum ignored_any byte_buf @@ -888,13 +888,13 @@ where { type Error = E; - forward_to_deserialize! { + forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option bytes map unit_struct newtype_struct tuple_struct struct identifier tuple enum ignored_any byte_buf } - fn deserialize(self, visitor: V) -> Result + fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { @@ -1029,14 +1029,14 @@ where { type Error = V_::Error; - fn deserialize(self, visitor: V) -> Result + fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { visitor.visit_map(self.visitor) } - forward_to_deserialize! { + forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct struct identifier tuple enum ignored_any byte_buf diff --git a/serde/src/macros.rs b/serde/src/macros.rs index f75eebf9..6b7ea6e2 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -30,7 +30,7 @@ /// # impl<'de> Deserializer<'de> for MyDeserializer { /// # type Error = value::Error; /// # -/// # fn deserialize(self, _: V) -> Result +/// # fn deserialize_any(self, _: V) -> Result /// # where V: Visitor<'de> /// # { /// # unimplemented!() @@ -40,10 +40,10 @@ /// fn deserialize_bool(self, visitor: V) -> Result /// where V: Visitor<'de> /// { -/// self.deserialize(visitor) +/// self.deserialize_any(visitor) /// } /// # -/// # forward_to_deserialize! { +/// # forward_to_deserialize_any! { /// # u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option /// # seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct /// # tuple_struct struct identifier tuple enum ignored_any @@ -53,9 +53,9 @@ /// # fn main() {} /// ``` /// -/// The `forward_to_deserialize!` macro implements these simple forwarding -/// methods so that they forward directly to [`Deserializer::deserialize`]. You -/// can choose which methods to forward. +/// The `forward_to_deserialize_any!` macro implements these simple forwarding +/// methods so that they forward directly to [`Deserializer::deserialize_any`]. +/// You can choose which methods to forward. /// /// ```rust /// # #[macro_use] @@ -68,7 +68,7 @@ /// impl<'de> Deserializer<'de> for MyDeserializer { /// # type Error = value::Error; /// # -/// fn deserialize(self, visitor: V) -> Result +/// fn deserialize_any(self, visitor: V) -> Result /// where V: Visitor<'de> /// { /// /* ... */ @@ -76,7 +76,7 @@ /// # unimplemented!() /// } /// -/// forward_to_deserialize! { +/// forward_to_deserialize_any! { /// bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option /// seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct /// tuple_struct struct identifier tuple enum ignored_any @@ -104,13 +104,13 @@ /// # impl<'q, V> Deserializer<'q> for MyDeserializer { /// # type Error = value::Error; /// # -/// # fn deserialize(self, visitor: W) -> Result +/// # fn deserialize_any(self, visitor: W) -> Result /// # where W: Visitor<'q> /// # { /// # unimplemented!() /// # } /// # -/// forward_to_deserialize! { +/// forward_to_deserialize_any! { /// > /// bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option /// seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct @@ -123,21 +123,21 @@ /// /// [`Deserializer`]: trait.Deserializer.html /// [`Visitor`]: de/trait.Visitor.html -/// [`Deserializer::deserialize`]: trait.Deserializer.html#tymethod.deserialize +/// [`Deserializer::deserialize_any`]: trait.Deserializer.html#tymethod.deserialize_any #[macro_export] -macro_rules! forward_to_deserialize { +macro_rules! forward_to_deserialize_any { (<$visitor:ident: Visitor<$lifetime:tt>> $($func:ident)*) => { - $(forward_to_deserialize_helper!{$func<$lifetime, $visitor>})* + $(forward_to_deserialize_any_helper!{$func<$lifetime, $visitor>})* }; // This case must be after the previous one. ($($func:ident)*) => { - $(forward_to_deserialize_helper!{$func<'de, V>})* + $(forward_to_deserialize_any_helper!{$func<'de, V>})* }; } #[doc(hidden)] #[macro_export] -macro_rules! forward_to_deserialize_method { +macro_rules! forward_to_deserialize_any_method { ($func:ident<$l:tt, $v:ident>($($arg:ident : $ty:ty),*)) => { #[inline] fn $func<$v>(self, $($arg: $ty,)* visitor: $v) -> $crate::export::Result<$v::Value, Self::Error> @@ -147,99 +147,99 @@ macro_rules! forward_to_deserialize_method { $( let _ = $arg; )* - self.deserialize(visitor) + self.deserialize_any(visitor) } }; } #[doc(hidden)] #[macro_export] -macro_rules! forward_to_deserialize_helper { +macro_rules! forward_to_deserialize_any_helper { (bool<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_bool<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_bool<$l, $v>()} }; (u8<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_u8<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_u8<$l, $v>()} }; (u16<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_u16<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_u16<$l, $v>()} }; (u32<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_u32<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_u32<$l, $v>()} }; (u64<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_u64<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_u64<$l, $v>()} }; (i8<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_i8<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_i8<$l, $v>()} }; (i16<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_i16<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_i16<$l, $v>()} }; (i32<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_i32<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_i32<$l, $v>()} }; (i64<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_i64<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_i64<$l, $v>()} }; (f32<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_f32<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_f32<$l, $v>()} }; (f64<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_f64<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_f64<$l, $v>()} }; (char<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_char<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_char<$l, $v>()} }; (str<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_str<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_str<$l, $v>()} }; (string<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_string<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_string<$l, $v>()} }; (unit<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_unit<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_unit<$l, $v>()} }; (option<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_option<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_option<$l, $v>()} }; (seq<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_seq<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_seq<$l, $v>()} }; (seq_fixed_size<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_seq_fixed_size<$l, $v>(len: usize)} + forward_to_deserialize_any_method!{deserialize_seq_fixed_size<$l, $v>(len: usize)} }; (bytes<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_bytes<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_bytes<$l, $v>()} }; (byte_buf<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_byte_buf<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_byte_buf<$l, $v>()} }; (map<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_map<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_map<$l, $v>()} }; (unit_struct<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_unit_struct<$l, $v>(name: &'static str)} + forward_to_deserialize_any_method!{deserialize_unit_struct<$l, $v>(name: &'static str)} }; (newtype_struct<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_newtype_struct<$l, $v>(name: &'static str)} + forward_to_deserialize_any_method!{deserialize_newtype_struct<$l, $v>(name: &'static str)} }; (tuple_struct<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_tuple_struct<$l, $v>(name: &'static str, len: usize)} + forward_to_deserialize_any_method!{deserialize_tuple_struct<$l, $v>(name: &'static str, len: usize)} }; (struct<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_struct<$l, $v>(name: &'static str, fields: &'static [&'static str])} + forward_to_deserialize_any_method!{deserialize_struct<$l, $v>(name: &'static str, fields: &'static [&'static str])} }; (identifier<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_identifier<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_identifier<$l, $v>()} }; (tuple<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_tuple<$l, $v>(len: usize)} + forward_to_deserialize_any_method!{deserialize_tuple<$l, $v>(len: usize)} }; (enum<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_enum<$l, $v>(name: &'static str, variants: &'static [&'static str])} + forward_to_deserialize_any_method!{deserialize_enum<$l, $v>(name: &'static str, variants: &'static [&'static str])} }; (ignored_any<$l:tt, $v:ident>) => { - forward_to_deserialize_method!{deserialize_ignored_any<$l, $v>()} + forward_to_deserialize_any_method!{deserialize_ignored_any<$l, $v>()} }; } diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index d5c03061..7ad86def 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -33,7 +33,7 @@ where { type Error = E; - fn deserialize(self, _visitor: V) -> Result + fn deserialize_any(self, _visitor: V) -> Result where V: Visitor<'de>, { @@ -47,7 +47,7 @@ where visitor.visit_none() } - forward_to_deserialize! { + forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct tuple_struct struct identifier tuple enum ignored_any @@ -271,7 +271,7 @@ mod content { { // Untagged and internally tagged enums are only supported in // self-describing formats. - deserializer.deserialize(ContentVisitor) + deserializer.deserialize_any(ContentVisitor) } } @@ -481,7 +481,7 @@ mod content { { // Internally tagged enums are only supported in self-describing // formats. - deserializer.deserialize(self) + deserializer.deserialize_any(self) } } @@ -745,7 +745,7 @@ mod content { { // Internally tagged enums are only supported in self-describing // formats. - deserializer.deserialize(self) + deserializer.deserialize_any(self) } } @@ -854,7 +854,7 @@ mod content { { type Error = E; - fn deserialize(self, visitor: V) -> Result + fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de>, { @@ -969,7 +969,7 @@ mod content { ) } - forward_to_deserialize! { + forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq seq_fixed_size bytes byte_buf map unit_struct tuple_struct struct identifier tuple ignored_any @@ -1057,7 +1057,7 @@ mod content { { match self.value { Some(Content::Seq(v)) => { - de::Deserializer::deserialize(SeqDeserializer::new(v), visitor) + de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor) } Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"tuple variant"),), None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"tuple variant"),), @@ -1074,7 +1074,7 @@ mod content { { match self.value { Some(Content::Map(v)) => { - de::Deserializer::deserialize(MapDeserializer::new(v), visitor) + de::Deserializer::deserialize_any(MapDeserializer::new(v), visitor) } Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant"),), _ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant"),), @@ -1109,7 +1109,7 @@ mod content { type Error = E; #[inline] - fn deserialize(mut self, visitor: V) -> Result + fn deserialize_any(mut self, visitor: V) -> Result where V: de::Visitor<'de>, { @@ -1127,7 +1127,7 @@ mod content { } } - forward_to_deserialize! { + forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct tuple_struct struct identifier tuple enum ignored_any @@ -1221,14 +1221,14 @@ mod content { type Error = E; #[inline] - fn deserialize(self, visitor: V) -> Result + fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { visitor.visit_map(self) } - forward_to_deserialize! { + forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct tuple_struct struct identifier tuple enum ignored_any @@ -1250,7 +1250,7 @@ mod content { { type Error = E; - fn deserialize(self, visitor: V) -> Result + fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de>, { @@ -1365,7 +1365,7 @@ mod content { ) } - forward_to_deserialize! { + forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq seq_fixed_size bytes byte_buf map unit_struct tuple_struct struct identifier tuple ignored_any @@ -1450,7 +1450,7 @@ mod content { { match self.value { Some(&Content::Seq(ref v)) => { - de::Deserializer::deserialize(SeqRefDeserializer::new(v), visitor) + de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor) } Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"tuple variant"),), None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"tuple variant"),), @@ -1467,7 +1467,7 @@ mod content { { match self.value { Some(&Content::Map(ref v)) => { - de::Deserializer::deserialize(MapRefDeserializer::new(v), visitor) + de::Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor) } Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant"),), _ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant"),), @@ -1502,7 +1502,7 @@ mod content { type Error = E; #[inline] - fn deserialize(mut self, visitor: V) -> Result + fn deserialize_any(mut self, visitor: V) -> Result where V: de::Visitor<'de>, { @@ -1520,7 +1520,7 @@ mod content { } } - forward_to_deserialize! { + forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct tuple_struct struct identifier tuple enum ignored_any @@ -1615,14 +1615,14 @@ mod content { type Error = E; #[inline] - fn deserialize(self, visitor: V) -> Result + fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { visitor.visit_map(self) } - forward_to_deserialize! { + forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct tuple_struct struct identifier tuple enum ignored_any diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 994b9a9b..6eb3846b 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -497,7 +497,7 @@ fn deserialize_struct( }; let dispatch = if let Some(deserializer) = deserializer { quote! { - _serde::Deserializer::deserialize(#deserializer, #visitor_expr) + _serde::Deserializer::deserialize_any(#deserializer, #visitor_expr) } } else if is_enum { quote! { @@ -729,7 +729,7 @@ fn deserialize_internally_tagged_enum( #variants_stmt - let __tagged = try!(_serde::Deserializer::deserialize( + let __tagged = try!(_serde::Deserializer::deserialize_any( __deserializer, _serde::private::de::TaggedContentVisitor::<__Field>::new(#tag))); @@ -1083,7 +1083,7 @@ fn deserialize_internally_tagged_variant( let type_name = params.type_name(); let variant_name = variant.ident.as_ref(); quote_block! { - try!(_serde::Deserializer::deserialize(#deserializer, _serde::private::de::InternallyTaggedUnitVisitor::new(#type_name, #variant_name))); + try!(_serde::Deserializer::deserialize_any(#deserializer, _serde::private::de::InternallyTaggedUnitVisitor::new(#type_name, #variant_name))); _serde::export::Ok(#this::#variant_ident) } } @@ -1109,7 +1109,7 @@ fn deserialize_untagged_variant( let variant_name = variant.ident.as_ref(); quote_expr! { _serde::export::Result::map( - _serde::Deserializer::deserialize( + _serde::Deserializer::deserialize_any( #deserializer, _serde::private::de::UntaggedUnitVisitor::new(#type_name, #variant_name) ), diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index b6ce5725..cef4bcae 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -97,12 +97,12 @@ impl<'de> Deserializer<'de> { impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { type Error = Error; - forward_to_deserialize! { + forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq bytes byte_buf map identifier ignored_any } - fn deserialize(self, visitor: V) -> Result + fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de>, { @@ -192,7 +192,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { self.next_token(); visitor.visit_some(self) } - Some(_) => self.deserialize(visitor), + Some(_) => self.deserialize_any(visitor), None => Err(Error::EndOfTokens), } } @@ -239,7 +239,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { Err(Error::InvalidName(n)) } } - Some(_) => self.deserialize(visitor), + Some(_) => self.deserialize_any(visitor), None => Err(Error::EndOfTokens), } } @@ -257,7 +257,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { Err(Error::InvalidName(n)) } } - Some(_) => self.deserialize(visitor), + Some(_) => self.deserialize_any(visitor), None => Err(Error::EndOfTokens), } } @@ -271,7 +271,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { self.next_token(); self.visit_seq(Some(len), Token::SeqEnd, visitor) } - Some(_) => self.deserialize(visitor), + Some(_) => self.deserialize_any(visitor), None => Err(Error::EndOfTokens), } } @@ -302,7 +302,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { self.next_token(); self.visit_seq(Some(len), Token::TupleStructEnd, visitor) } - Some(_) => self.deserialize(visitor), + Some(_) => self.deserialize_any(visitor), None => Err(Error::EndOfTokens), } } @@ -349,7 +349,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { Err(Error::InvalidName(n)) } } - Some(_) => self.deserialize(visitor), + Some(_) => self.deserialize_any(visitor), None => Err(Error::EndOfTokens), } } @@ -376,7 +376,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { self.next_token(); self.visit_map(Some(fields.len()), Token::MapEnd, visitor) } - Some(_) => self.deserialize(visitor), + Some(_) => self.deserialize_any(visitor), None => Err(Error::EndOfTokens), } } @@ -529,7 +529,7 @@ impl<'de, 'a> VariantAccess<'de> for DeserializerEnumVisitor<'a, 'de> { Err(Error::UnexpectedToken(token)) } } - Some(_) => de::Deserializer::deserialize(self.de, visitor), + Some(_) => de::Deserializer::deserialize_any(self.de, visitor), None => Err(Error::EndOfTokens), } } @@ -559,7 +559,7 @@ impl<'de, 'a> VariantAccess<'de> for DeserializerEnumVisitor<'a, 'de> { Err(Error::UnexpectedToken(token)) } } - Some(_) => de::Deserializer::deserialize(self.de, visitor), + Some(_) => de::Deserializer::deserialize_any(self.de, visitor), None => Err(Error::EndOfTokens), } } @@ -649,14 +649,14 @@ struct BytesDeserializer { impl<'de> de::Deserializer<'de> for BytesDeserializer { type Error = Error; - fn deserialize(self, visitor: V) -> Result + fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { visitor.visit_bytes(self.value) } - forward_to_deserialize! { + forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct struct identifier tuple enum ignored_any byte_buf From 0c5db90de86a43195965540a6276bf880e7c57e9 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 13:27:42 -0700 Subject: [PATCH 148/177] Simplify size_hint to Option --- serde/src/de/impls.rs | 31 ++++++++++++++------------- serde/src/de/mod.rs | 16 +++++++------- serde/src/de/value.rs | 28 ++++++++++++------------- serde/src/private/de.rs | 46 +++++++++++++++++++++++++++++++---------- serde_test/src/de.rs | 10 ++++----- 5 files changed, 78 insertions(+), 53 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 3999f3e3..c955498b 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -16,6 +16,9 @@ use de::MapAccess; use de::from_primitive::FromPrimitive; +#[cfg(any(feature = "std", feature = "collections"))] +use private::de::size_hint; + //////////////////////////////////////////////////////////////////////////////// struct UnitVisitor; @@ -344,7 +347,7 @@ impl<'de> Visitor<'de> for CStringVisitor { where A: SeqAccess<'de>, { - let len = cmp::min(seq.size_hint().0, 4096); + let len = size_hint::cautious(seq.size_hint()); let mut values = Vec::with_capacity(len); while let Some(value) = try!(seq.next_element()) { @@ -557,16 +560,16 @@ macro_rules! seq_impl { seq_impl!( BinaryHeap, BinaryHeapVisitor, - visitor, + seq, BinaryHeap::new(), - BinaryHeap::with_capacity(cmp::min(visitor.size_hint().0, 4096)), + BinaryHeap::with_capacity(size_hint::cautious(seq.size_hint())), BinaryHeap::push); #[cfg(any(feature = "std", feature = "collections"))] seq_impl!( BTreeSet, BTreeSetVisitor, - visitor, + seq, BTreeSet::new(), BTreeSet::new(), BTreeSet::insert); @@ -575,7 +578,7 @@ seq_impl!( seq_impl!( LinkedList, LinkedListVisitor, - visitor, + seq, LinkedList::new(), LinkedList::new(), LinkedList::push_back); @@ -585,27 +588,27 @@ seq_impl!( HashSet, HashSetVisitor, - visitor, + seq, HashSet::with_hasher(S::default()), - HashSet::with_capacity_and_hasher(cmp::min(visitor.size_hint().0, 4096), S::default()), + HashSet::with_capacity_and_hasher(size_hint::cautious(seq.size_hint()), S::default()), HashSet::insert); #[cfg(any(feature = "std", feature = "collections"))] seq_impl!( Vec, VecVisitor, - visitor, + seq, Vec::new(), - Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)), + Vec::with_capacity(size_hint::cautious(seq.size_hint())), Vec::push); #[cfg(any(feature = "std", feature = "collections"))] seq_impl!( VecDeque, VecDequeVisitor, - visitor, + seq, VecDeque::new(), - VecDeque::with_capacity(cmp::min(visitor.size_hint().0, 4096)), + VecDeque::with_capacity(size_hint::cautious(seq.size_hint())), VecDeque::push_back); //////////////////////////////////////////////////////////////////////////////// @@ -865,7 +868,7 @@ macro_rules! map_impl { map_impl!( BTreeMap, BTreeMapVisitor, - visitor, + map, BTreeMap::new(), BTreeMap::new()); @@ -874,9 +877,9 @@ map_impl!( HashMap, HashMapVisitor, - visitor, + map, HashMap::with_hasher(S::default()), - HashMap::with_capacity_and_hasher(cmp::min(visitor.size_hint().0, 4096), S::default())); + HashMap::with_capacity_and_hasher(size_hint::cautious(map.size_hint()), S::default())); //////////////////////////////////////////////////////////////////////////////// diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index dc67021b..af45dbb3 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -1376,10 +1376,10 @@ pub trait SeqAccess<'de> { self.next_element_seed(PhantomData) } - /// Return the lower and upper bound of items remaining in the sequence. + /// Returns the number of elements remaining in the sequence, if known. #[inline] - fn size_hint(&self) -> (usize, Option) { - (0, None) + fn size_hint(&self) -> Option { + None } } @@ -1406,7 +1406,7 @@ where } #[inline] - fn size_hint(&self) -> (usize, Option) { + fn size_hint(&self) -> Option { (**self).size_hint() } } @@ -1504,10 +1504,10 @@ pub trait MapAccess<'de> { self.next_entry_seed(PhantomData, PhantomData) } - /// Return the lower and upper bound of items remaining in the sequence. + /// Returns the number of entries remaining in the map, if known. #[inline] - fn size_hint(&self) -> (usize, Option) { - (0, None) + fn size_hint(&self) -> Option { + None } } @@ -1572,7 +1572,7 @@ where } #[inline] - fn size_hint(&self) -> (usize, Option) { + fn size_hint(&self) -> Option { (**self).size_hint() } } diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index a521c9a6..921a4ac5 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -11,6 +11,7 @@ use lib::*; use de::{self, IntoDeserializer, Expected, SeqAccess}; +use private::de::size_hint; use self::private::{First, Second}; //////////////////////////////////////////////////////////////////////////////// @@ -545,8 +546,8 @@ where } } - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() + fn size_hint(&self) -> Option { + size_hint::from_bounds(&self.iter) } } @@ -799,8 +800,8 @@ where } } - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() + fn size_hint(&self) -> Option { + size_hint::from_bounds(&self.iter) } } @@ -827,8 +828,8 @@ where } } - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() + fn size_hint(&self) -> Option { + size_hint::from_bounds(&self.iter) } } @@ -910,7 +911,7 @@ where if pair_visitor.1.is_none() { Ok(pair) } else { - let remaining = pair_visitor.size_hint().0; + let remaining = pair_visitor.size_hint().unwrap(); // First argument is the number of elements in the data, second // argument is the number of elements expected by the Deserialize. Err(de::Error::invalid_length(2, &ExpectedInSeq(2 - remaining))) @@ -954,15 +955,14 @@ where } } - fn size_hint(&self) -> (usize, Option) { - let len = if self.0.is_some() { - 2 + fn size_hint(&self) -> Option { + if self.0.is_some() { + Some(2) } else if self.1.is_some() { - 1 + Some(1) } else { - 0 - }; - (len, Some(len)) + Some(0) + } } } diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 7ad86def..957052a3 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -187,6 +187,29 @@ where deserializer.deserialize_str(CowBytesVisitor) } +pub mod size_hint { + use lib::*; + + pub fn from_bounds(iter: &I) -> Option + where I: Iterator + { + helper(iter.size_hint()) + } + + pub fn cautious(hint: Option) -> usize { + cmp::min(hint.unwrap_or(0), 4096) + } + + fn helper(bounds: (usize, Option)) -> Option { + match bounds { + (lower, Some(upper)) if lower == upper => { + Some(upper) + } + _ => None, + } + } +} + #[cfg(any(feature = "std", feature = "collections"))] mod content { // This module is private and nothing here should be used outside of @@ -203,6 +226,7 @@ mod content { use de::{self, Deserialize, DeserializeSeed, Deserializer, Visitor, SeqAccess, MapAccess, EnumAccess, Unexpected}; + use super::size_hint; /// Used from generated code to buffer the contents of the Deserializer when /// deserializing untagged enums and internally tagged enums. @@ -428,7 +452,7 @@ mod content { where V: SeqAccess<'de>, { - let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); + let mut vec = Vec::with_capacity(size_hint::cautious(visitor.size_hint())); while let Some(e) = try!(visitor.next_element()) { vec.push(e); } @@ -439,7 +463,7 @@ mod content { where V: MapAccess<'de>, { - let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); + let mut vec = Vec::with_capacity(size_hint::cautious(visitor.size_hint())); while let Some(kv) = try!(visitor.next_entry()) { vec.push(kv); } @@ -764,7 +788,7 @@ mod content { V: MapAccess<'de>, { let mut tag = None; - let mut vec = Vec::with_capacity(cmp::min(visitor.size_hint().0, 4096)); + let mut vec = Vec::with_capacity(size_hint::cautious(visitor.size_hint())); while let Some(k) = try!(visitor.next_key_seed(TagOrContentVisitor::new(self.tag_name))) { match k { @@ -1153,8 +1177,8 @@ mod content { } } - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() + fn size_hint(&self) -> Option { + size_hint::from_bounds(&self.iter) } } @@ -1209,8 +1233,8 @@ mod content { } } - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() + fn size_hint(&self) -> Option { + size_hint::from_bounds(&self.iter) } } @@ -1546,8 +1570,8 @@ mod content { } } - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() + fn size_hint(&self) -> Option { + size_hint::from_bounds(&self.iter) } } @@ -1603,8 +1627,8 @@ mod content { } } - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() + fn size_hint(&self) -> Option { + size_hint::from_bounds(&self.iter) } } diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index cef4bcae..c826ee86 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -404,9 +404,8 @@ impl<'de, 'a> SeqAccess<'de> for DeserializerSeqVisitor<'a, 'de> { seed.deserialize(&mut *self.de).map(Some) } - fn size_hint(&self) -> (usize, Option) { - let len = self.len.unwrap_or(0); - (len, self.len) + fn size_hint(&self) -> Option { + self.len } } @@ -439,9 +438,8 @@ impl<'de, 'a> MapAccess<'de> for DeserializerMapVisitor<'a, 'de> { seed.deserialize(&mut *self.de) } - fn size_hint(&self) -> (usize, Option) { - let len = self.len.unwrap_or(0); - (len, self.len) + fn size_hint(&self) -> Option { + self.len } } From fc927e0e25135b1076c07234e43ccd938d82c85f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 13:37:57 -0700 Subject: [PATCH 149/177] Review deserialize impls --- serde/src/de/impls.rs | 328 ++++++++++++++++-------------------------- 1 file changed, 123 insertions(+), 205 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index c955498b..b36d503f 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -402,8 +402,7 @@ impl<'de> Deserialize<'de> for Box { where D: Deserializer<'de>, { - let s = try!(CString::deserialize(deserializer)); - Ok(s.into_boxed_c_str()) + CString::deserialize(deserializer).map(CString::into_boxed_c_str) } } @@ -444,7 +443,7 @@ where where D: Deserializer<'de>, { - Ok(Some(try!(Deserialize::deserialize(deserializer)))) + T::deserialize(deserializer).map(Some) } } @@ -494,63 +493,56 @@ impl<'de, T> Deserialize<'de> for PhantomData { //////////////////////////////////////////////////////////////////////////////// +#[cfg(any(feature = "std", feature = "collections"))] macro_rules! seq_impl { ( - $ty:ident < T $(, $typaram:ident)* >, - $visitor_ty:ident $( < $($boundparam:ident : $bound1:ident $(+ $bound2:ident)*),* > )*, + $ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >, $access:ident, $ctor:expr, $with_capacity:expr, $insert:expr ) => { - struct $visitor_ty { - marker: PhantomData<$ty>, - } - - impl $visitor_ty { - fn new() -> Self { - $visitor_ty { - marker: PhantomData, - } - } - } - - impl<'de, T $(, $typaram)*> Visitor<'de> for $visitor_ty - where - T: Deserialize<'de>, - $($($boundparam: $bound1 $(+ $bound2)*),*)* - { - type Value = $ty; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a sequence") - } - - #[inline] - fn visit_seq(self, mut $access: A) -> Result - where - A: SeqAccess<'de>, - { - let mut values = $with_capacity; - - while let Some(value) = try!($access.next_element()) { - $insert(&mut values, value); - } - - Ok(values) - } - } - impl<'de, T $(, $typaram)*> Deserialize<'de> for $ty where - T: Deserialize<'de>, - $($($boundparam: $bound1 $(+ $bound2)*),*)* + T: Deserialize<'de> $(+ $tbound1 $(+ $tbound2)*)*, + $($typaram: $bound1 $(+ $bound2)*,)* { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { - deserializer.deserialize_seq($visitor_ty::new()) + struct SeqVisitor { + marker: PhantomData<$ty>, + } + + impl<'de, T $(, $typaram)*> Visitor<'de> for SeqVisitor + where + T: Deserialize<'de> $(+ $tbound1 $(+ $tbound2)*)*, + $($typaram: $bound1 $(+ $bound2)*,)* + { + type Value = $ty; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a sequence") + } + + #[inline] + fn visit_seq(self, mut $access: A) -> Result + where + A: SeqAccess<'de>, + { + let mut values = $with_capacity; + + while let Some(value) = try!($access.next_element()) { + $insert(&mut values, value); + } + + Ok(values) + } + } + + let visitor = SeqVisitor { marker: PhantomData }; + deserializer.deserialize_seq(visitor) } } } @@ -558,8 +550,7 @@ macro_rules! seq_impl { #[cfg(any(feature = "std", feature = "collections"))] seq_impl!( - BinaryHeap, - BinaryHeapVisitor, + BinaryHeap, seq, BinaryHeap::new(), BinaryHeap::with_capacity(size_hint::cautious(seq.size_hint())), @@ -567,8 +558,7 @@ seq_impl!( #[cfg(any(feature = "std", feature = "collections"))] seq_impl!( - BTreeSet, - BTreeSetVisitor, + BTreeSet, seq, BTreeSet::new(), BTreeSet::new(), @@ -577,7 +567,6 @@ seq_impl!( #[cfg(any(feature = "std", feature = "collections"))] seq_impl!( LinkedList, - LinkedListVisitor, seq, LinkedList::new(), LinkedList::new(), @@ -585,9 +574,7 @@ seq_impl!( #[cfg(feature = "std")] seq_impl!( - HashSet, - HashSetVisitor, + HashSet, seq, HashSet::with_hasher(S::default()), HashSet::with_capacity_and_hasher(size_hint::cautious(seq.size_hint()), S::default()), @@ -596,7 +583,6 @@ seq_impl!( #[cfg(any(feature = "std", feature = "collections"))] seq_impl!( Vec, - VecVisitor, seq, Vec::new(), Vec::with_capacity(size_hint::cautious(seq.size_hint())), @@ -605,7 +591,6 @@ seq_impl!( #[cfg(any(feature = "std", feature = "collections"))] seq_impl!( VecDeque, - VecDequeVisitor, seq, VecDeque::new(), VecDeque::with_capacity(size_hint::cautious(seq.size_hint())), @@ -731,7 +716,7 @@ array_impls! { //////////////////////////////////////////////////////////////////////////////// macro_rules! tuple_impls { - ($($len:expr => $visitor:ident => ($($n:tt $name:ident)+))+) => { + ($($len:tt $visitor:ident => ($($n:tt $name:ident)+))+) => { $( struct $visitor<$($name,)+> { marker: PhantomData<($($name,)+)>, @@ -781,84 +766,77 @@ macro_rules! tuple_impls { } tuple_impls! { - 1 => TupleVisitor1 => (0 T0) - 2 => TupleVisitor2 => (0 T0 1 T1) - 3 => TupleVisitor3 => (0 T0 1 T1 2 T2) - 4 => TupleVisitor4 => (0 T0 1 T1 2 T2 3 T3) - 5 => TupleVisitor5 => (0 T0 1 T1 2 T2 3 T3 4 T4) - 6 => TupleVisitor6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5) - 7 => TupleVisitor7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6) - 8 => TupleVisitor8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7) - 9 => TupleVisitor9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8) - 10 => TupleVisitor10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9) - 11 => TupleVisitor11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10) - 12 => TupleVisitor12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11) - 13 => TupleVisitor13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12) - 14 => TupleVisitor14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13) - 15 => TupleVisitor15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14) - 16 => TupleVisitor16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15) + 1 TupleVisitor1 => (0 T0) + 2 TupleVisitor2 => (0 T0 1 T1) + 3 TupleVisitor3 => (0 T0 1 T1 2 T2) + 4 TupleVisitor4 => (0 T0 1 T1 2 T2 3 T3) + 5 TupleVisitor5 => (0 T0 1 T1 2 T2 3 T3 4 T4) + 6 TupleVisitor6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5) + 7 TupleVisitor7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6) + 8 TupleVisitor8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7) + 9 TupleVisitor9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8) + 10 TupleVisitor10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9) + 11 TupleVisitor11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10) + 12 TupleVisitor12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11) + 13 TupleVisitor13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12) + 14 TupleVisitor14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13) + 15 TupleVisitor15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14) + 16 TupleVisitor16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15) } //////////////////////////////////////////////////////////////////////////////// +#[cfg(any(feature = "std", feature = "collections"))] macro_rules! map_impl { ( - $ty:ident < K, V $(, $typaram:ident)* >, - $visitor_ty:ident < $($boundparam:ident : $bound1:ident $(+ $bound2:ident)*),* >, + $ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >, $access:ident, $ctor:expr, $with_capacity:expr ) => { - struct $visitor_ty { - marker: PhantomData<$ty>, - } - - impl $visitor_ty { - fn new() -> Self { - $visitor_ty { - marker: PhantomData, - } - } - } - - impl<'de, K, V $(, $typaram)*> Visitor<'de> for $visitor_ty - where - K: Deserialize<'de>, - V: Deserialize<'de>, - $($boundparam: $bound1 $(+ $bound2)*),* - { - type Value = $ty; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a map") - } - - #[inline] - fn visit_map(self, mut $access: A) -> Result - where - A: MapAccess<'de>, - { - let mut values = $with_capacity; - - while let Some((key, value)) = try!($access.next_entry()) { - values.insert(key, value); - } - - Ok(values) - } - } - impl<'de, K, V $(, $typaram)*> Deserialize<'de> for $ty where - K: Deserialize<'de>, + K: Deserialize<'de> $(+ $kbound1 $(+ $kbound2)*)*, V: Deserialize<'de>, - $($boundparam: $bound1 $(+ $bound2)*),* + $($typaram: $bound1 $(+ $bound2)*),* { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { - deserializer.deserialize_map($visitor_ty::new()) + struct MapVisitor { + marker: PhantomData<$ty>, + } + + impl<'de, K, V $(, $typaram)*> Visitor<'de> for MapVisitor + where + K: Deserialize<'de> $(+ $kbound1 $(+ $kbound2)*)*, + V: Deserialize<'de>, + $($typaram: $bound1 $(+ $bound2)*),* + { + type Value = $ty; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a map") + } + + #[inline] + fn visit_map(self, mut $access: A) -> Result + where + A: MapAccess<'de>, + { + let mut values = $with_capacity; + + while let Some((key, value)) = try!($access.next_entry()) { + values.insert(key, value); + } + + Ok(values) + } + } + + let visitor = MapVisitor { marker: PhantomData }; + deserializer.deserialize_map(visitor) } } } @@ -866,17 +844,14 @@ macro_rules! map_impl { #[cfg(any(feature = "std", feature = "collections"))] map_impl!( - BTreeMap, - BTreeMapVisitor, + BTreeMap, map, BTreeMap::new(), BTreeMap::new()); #[cfg(feature = "std")] map_impl!( - HashMap, - HashMapVisitor, + HashMap, map, HashMap::with_hasher(S::default()), HashMap::with_capacity_and_hasher(size_hint::cautious(map.size_hint()), S::default())); @@ -884,90 +859,37 @@ map_impl!( //////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "std")] -impl<'de> Deserialize<'de> for net::IpAddr { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let s = try!(String::deserialize(deserializer)); - match s.parse() { - Ok(s) => Ok(s), - Err(err) => Err(D::Error::custom(err)), +macro_rules! parse_impl { + ($ty:ty) => { + impl<'de> Deserialize<'de> for $ty { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s = try!(String::deserialize(deserializer)); + s.parse().map_err(Error::custom) + } } } } #[cfg(feature = "std")] -impl<'de> Deserialize<'de> for net::Ipv4Addr { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let s = try!(String::deserialize(deserializer)); - match s.parse() { - Ok(s) => Ok(s), - Err(err) => Err(D::Error::custom(err)), - } - } -} +parse_impl!(net::IpAddr); #[cfg(feature = "std")] -impl<'de> Deserialize<'de> for net::Ipv6Addr { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let s = try!(String::deserialize(deserializer)); - match s.parse() { - Ok(s) => Ok(s), - Err(err) => Err(D::Error::custom(err)), - } - } -} - -//////////////////////////////////////////////////////////////////////////////// +parse_impl!(net::Ipv4Addr); #[cfg(feature = "std")] -impl<'de> Deserialize<'de> for net::SocketAddr { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let s = try!(String::deserialize(deserializer)); - match s.parse() { - Ok(s) => Ok(s), - Err(err) => Err(D::Error::custom(err)), - } - } -} +parse_impl!(net::Ipv6Addr); #[cfg(feature = "std")] -impl<'de> Deserialize<'de> for net::SocketAddrV4 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let s = try!(String::deserialize(deserializer)); - match s.parse() { - Ok(s) => Ok(s), - Err(err) => Err(D::Error::custom(err)), - } - } -} +parse_impl!(net::SocketAddr); #[cfg(feature = "std")] -impl<'de> Deserialize<'de> for net::SocketAddrV6 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let s = try!(String::deserialize(deserializer)); - match s.parse() { - Ok(s) => Ok(s), - Err(err) => Err(D::Error::custom(err)), - } - } -} +parse_impl!(net::SocketAddrV4); + +#[cfg(feature = "std")] +parse_impl!(net::SocketAddrV6); //////////////////////////////////////////////////////////////////////////////// @@ -1140,8 +1062,7 @@ where where D: Deserializer<'de>, { - let val = try!(Deserialize::deserialize(deserializer)); - Ok(Box::new(val)) + T::deserialize(deserializer).map(Box::new) } } @@ -1154,8 +1075,7 @@ where where D: Deserializer<'de>, { - let v: Vec = try!(Deserialize::deserialize(deserializer)); - Ok(v.into_boxed_slice()) + Vec::::deserialize(deserializer).map(Vec::into_boxed_slice) } } @@ -1165,8 +1085,7 @@ impl<'de> Deserialize<'de> for Box { where D: Deserializer<'de>, { - let s = try!(String::deserialize(deserializer)); - Ok(s.into_boxed_str()) + String::deserialize(deserializer).map(String::into_boxed_str) } } @@ -1179,8 +1098,7 @@ where where D: Deserializer<'de>, { - let val = try!(Deserialize::deserialize(deserializer)); - Ok(Arc::new(val)) + T::deserialize(deserializer).map(Arc::new) } } @@ -1193,8 +1111,7 @@ where where D: Deserializer<'de>, { - let val = try!(Deserialize::deserialize(deserializer)); - Ok(Rc::new(val)) + T::deserialize(deserializer).map(Rc::new) } } @@ -1209,8 +1126,7 @@ where where D: Deserializer<'de>, { - let val = try!(Deserialize::deserialize(deserializer)); - Ok(Cow::Owned(val)) + T::Owned::deserialize(deserializer).map(Cow::Owned) } } @@ -1505,6 +1421,8 @@ where if value == Zero::zero() { return Err(Error::custom("expected a non-zero value")); } + // Waiting for a safe way to construct NonZero: + // https://github.com/rust-lang/rust/issues/27730#issuecomment-269726075 unsafe { Ok(NonZero::new(value)) } } } From 9cda4563c07ee2a2cf1f98a1b86be9968be05600 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 14:10:53 -0700 Subject: [PATCH 150/177] Clean up extraneous vertical space --- serde/src/de/impls.rs | 5 ----- serde/src/private/de.rs | 1 - 2 files changed, 6 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index b36d503f..2b8cbb66 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -919,7 +919,6 @@ impl<'de> Visitor<'de> for PathBufVisitor { } } - #[cfg(feature = "std")] impl<'de> Deserialize<'de> for PathBuf { fn deserialize(deserializer: D) -> Result @@ -1402,9 +1401,6 @@ where } } -//////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////// #[cfg(feature = "unstable")] @@ -1429,7 +1425,6 @@ where //////////////////////////////////////////////////////////////////////////////// - impl<'de, T, E> Deserialize<'de> for Result where T: Deserialize<'de>, diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 957052a3..963585f0 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -1259,7 +1259,6 @@ mod content { } } - /// Not public API. pub struct ContentRefDeserializer<'a, E> { content: &'a Content, From c70c364754ae9ab120f2e899a5ade777e91e06d8 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 14:24:47 -0700 Subject: [PATCH 151/177] Example of IntoDeserializer --- serde/src/de/mod.rs | 31 +++++++++++++++++++++++++++++-- serde/src/de/value.rs | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index af45dbb3..5f9895d5 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -1799,9 +1799,36 @@ pub trait VariantAccess<'de>: Sized { //////////////////////////////////////////////////////////////////////////////// -/// This trait converts primitive types into a deserializer. +/// Converts an existing value into a `Deserializer` from which other values can +/// be deserialized. +/// +/// ```rust +/// #[macro_use] +/// extern crate serde_derive; +/// +/// extern crate serde; +/// +/// use std::str::FromStr; +/// use serde::de::{value, Deserialize, IntoDeserializer}; +/// +/// #[derive(Deserialize)] +/// enum Setting { +/// On, +/// Off, +/// } +/// +/// impl FromStr for Setting { +/// type Err = value::Error; +/// +/// fn from_str(s: &str) -> Result { +/// Self::deserialize(s.into_deserializer()) +/// } +/// } +/// # +/// # fn main() {} +/// ``` pub trait IntoDeserializer<'de, E: Error = value::Error> { - /// The actual deserializer type. + /// The type of the deserializer being converted into. type Deserializer: Deserializer<'de, Error = E>; /// Convert this value into a deserializer. diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 921a4ac5..16603b9f 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -6,7 +6,34 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! This module supports deserializing from primitives with the `ValueDeserializer` trait. +//! Building blocks for deserializing basic values using the `IntoDeserializer` +//! trait. +//! +//! ```rust +//! #[macro_use] +//! extern crate serde_derive; +//! +//! extern crate serde; +//! +//! use std::str::FromStr; +//! use serde::de::{value, Deserialize, IntoDeserializer}; +//! +//! #[derive(Deserialize)] +//! enum Setting { +//! On, +//! Off, +//! } +//! +//! impl FromStr for Setting { +//! type Err = value::Error; +//! +//! fn from_str(s: &str) -> Result { +//! Self::deserialize(s.into_deserializer()) +//! } +//! } +//! # +//! # fn main() {} +//! ``` use lib::*; @@ -16,7 +43,8 @@ use self::private::{First, Second}; //////////////////////////////////////////////////////////////////////////////// -/// This represents all the possible errors that can occur using the `ValueDeserializer`. +/// A minimal representation of all possible errors that can occur using the +/// `IntoDeserializer` trait. #[derive(Clone, Debug, PartialEq)] pub struct Error { err: ErrorImpl, From ea5af417fbe6c76662bfadd750fea0f16ac29246 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 14:30:28 -0700 Subject: [PATCH 152/177] Use access terminology for value deserializers --- serde/src/de/value.rs | 44 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 16603b9f..51a6e670 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -634,30 +634,30 @@ where //////////////////////////////////////////////////////////////////////////////// -/// A helper deserializer that deserializes a sequence using a `SeqAccess`. +/// A deserializer holding a `SeqAccess`. #[derive(Clone, Debug)] -pub struct SeqVisitorDeserializer { - visitor: V_, +pub struct SeqAccessDeserializer { + seq: A, } -impl SeqVisitorDeserializer { - /// Construct a new `SeqVisitorDeserializer`. - pub fn new(visitor: V_) -> Self { - SeqVisitorDeserializer { visitor: visitor } +impl SeqAccessDeserializer { + /// Construct a new `SeqAccessDeserializer`. + pub fn new(seq: A) -> Self { + SeqAccessDeserializer { seq: seq } } } -impl<'de, V_> de::Deserializer<'de> for SeqVisitorDeserializer +impl<'de, A> de::Deserializer<'de> for SeqAccessDeserializer where - V_: de::SeqAccess<'de>, + A: de::SeqAccess<'de>, { - type Error = V_::Error; + type Error = A::Error; fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { - visitor.visit_seq(self.visitor) + visitor.visit_seq(self.seq) } forward_to_deserialize_any! { @@ -1038,30 +1038,30 @@ where //////////////////////////////////////////////////////////////////////////////// -/// A helper deserializer that deserializes a map using a `MapAccess`. +/// A deserializer holding a `MapAccess`. #[derive(Clone, Debug)] -pub struct MapVisitorDeserializer { - visitor: V_, +pub struct MapAccessDeserializer { + map: A, } -impl MapVisitorDeserializer { - /// Construct a new `MapVisitorDeserializer`. - pub fn new(visitor: V_) -> Self { - MapVisitorDeserializer { visitor: visitor } +impl MapAccessDeserializer { + /// Construct a new `MapAccessDeserializer`. + pub fn new(map: A) -> Self { + MapAccessDeserializer { map: map } } } -impl<'de, V_> de::Deserializer<'de> for MapVisitorDeserializer +impl<'de, A> de::Deserializer<'de> for MapAccessDeserializer where - V_: de::MapAccess<'de>, + A: de::MapAccess<'de>, { - type Error = V_::Error; + type Error = A::Error; fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { - visitor.visit_map(self.visitor) + visitor.visit_map(self.map) } forward_to_deserialize_any! { From bc4205a1d0fd9bf41b07f865dc59c9bad718ac69 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 14:31:29 -0700 Subject: [PATCH 153/177] Use V as the Visitor parameter --- serde/src/de/value.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 51a6e670..e260d831 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -693,7 +693,7 @@ where Second: IntoDeserializer<'de, E>, E: de::Error, { - /// Construct a new `MapDeserializer`. + /// Construct a new `MapDeserializer`. pub fn new(iter: I) -> Self { MapDeserializer { iter: iter.fuse(), @@ -741,30 +741,30 @@ where { type Error = E; - fn deserialize_any(mut self, visitor: V_) -> Result + fn deserialize_any(mut self, visitor: V) -> Result where - V_: de::Visitor<'de>, + V: de::Visitor<'de>, { let value = try!(visitor.visit_map(&mut self)); try!(self.end()); Ok(value) } - fn deserialize_seq(mut self, visitor: V_) -> Result + fn deserialize_seq(mut self, visitor: V) -> Result where - V_: de::Visitor<'de>, + V: de::Visitor<'de>, { let value = try!(visitor.visit_seq(&mut self)); try!(self.end()); Ok(value) } - fn deserialize_seq_fixed_size(self, - _len: usize, - visitor: V_) - -> Result + fn deserialize_seq_fixed_size(self, + _len: usize, + visitor: V) + -> Result where - V_: de::Visitor<'de>, + V: de::Visitor<'de>, { self.deserialize_seq(visitor) } From e722cf87913b2814f8ee09a37c74faa792de1a95 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 14:33:00 -0700 Subject: [PATCH 154/177] Fix some function signatures that rustfmt missed --- serde/src/de/value.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index e260d831..20ff3907 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -759,10 +759,11 @@ where Ok(value) } - fn deserialize_seq_fixed_size(self, - _len: usize, - visitor: V) - -> Result + fn deserialize_seq_fixed_size( + self, + _len: usize, + visitor: V, + ) -> Result where V: de::Visitor<'de>, { @@ -810,10 +811,11 @@ where seed.deserialize(value.into_deserializer()) } - fn next_entry_seed(&mut self, - kseed: TK, - vseed: TV) - -> Result, Self::Error> + fn next_entry_seed( + &mut self, + kseed: TK, + vseed: TV, + ) -> Result, Self::Error> where TK: de::DeserializeSeed<'de>, TV: de::DeserializeSeed<'de>, From d10fa2bd8667bf64d0cf8e894f2961a3c59b6368 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 14:38:58 -0700 Subject: [PATCH 155/177] Keep underscored names out of the documentation --- serde/src/de/value.rs | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 20ff3907..06e50414 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -65,10 +65,11 @@ impl de::Error for Error { } #[cfg(not(any(feature = "std", feature = "collections")))] - fn custom(_msg: T) -> Self + fn custom(msg: T) -> Self where T: Display, { + let _ = msg; Error { err: () } } } @@ -241,13 +242,15 @@ where fn deserialize_enum( self, - _name: &str, - _variants: &'static [&'static str], + name: &str, + variants: &'static [&'static str], visitor: V, ) -> Result where V: de::Visitor<'de>, { + let _ = name; + let _ = variants; visitor.visit_enum(self) } } @@ -305,13 +308,15 @@ where fn deserialize_enum( self, - _name: &str, - _variants: &'static [&'static str], + name: &str, + variants: &'static [&'static str], visitor: V, ) -> Result where V: de::Visitor<'de>, { + let _ = name; + let _ = variants; visitor.visit_enum(self) } @@ -378,13 +383,15 @@ where fn deserialize_enum( self, - _name: &str, - _variants: &'static [&'static str], + name: &str, + variants: &'static [&'static str], visitor: V, ) -> Result where V: de::Visitor<'de>, { + let _ = name; + let _ = variants; visitor.visit_enum(self) } @@ -455,13 +462,15 @@ where fn deserialize_enum( self, - _name: &str, - _variants: &'static [&'static str], + name: &str, + variants: &'static [&'static str], visitor: V, ) -> Result where V: de::Visitor<'de>, { + let _ = name; + let _ = variants; visitor.visit_enum(self) } @@ -761,12 +770,13 @@ where fn deserialize_seq_fixed_size( self, - _len: usize, + len: usize, visitor: V, ) -> Result where V: de::Visitor<'de>, { + let _ = len; self.deserialize_seq(visitor) } From 6a3747202382ec63246ce140d636aab76def75e4 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 14:40:37 -0700 Subject: [PATCH 156/177] Implement ser::Error for the value error --- serde/src/de/value.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 06e50414..c52b86c9 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -39,6 +39,7 @@ use lib::*; use de::{self, IntoDeserializer, Expected, SeqAccess}; use private::de::size_hint; +use ser; use self::private::{First, Second}; //////////////////////////////////////////////////////////////////////////////// @@ -74,6 +75,15 @@ impl de::Error for Error { } } +impl ser::Error for Error { + fn custom(msg: T) -> Self + where + T: Display, + { + de::Error::custom(msg) + } +} + impl Display for Error { #[cfg(any(feature = "std", feature = "collections"))] fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { From 6829c10a109cbaae6406b8a0c64225d1044a05f5 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 14:49:45 -0700 Subject: [PATCH 157/177] Helper deserializer means nothing --- serde/src/de/value.rs | 45 ++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index c52b86c9..77b97d99 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -116,7 +116,7 @@ where } } -/// A helper deserializer that deserializes a `()`. +/// A deserializer holding a `()`. #[derive(Clone, Debug)] pub struct UnitDeserializer { marker: PhantomData, @@ -152,8 +152,9 @@ where //////////////////////////////////////////////////////////////////////////////// macro_rules! primitive_deserializer { - ($ty:ty, $name:ident, $method:ident $($cast:tt)*) => { - /// A helper deserializer that deserializes a number. + ($ty:ty, $doc:tt, $name:ident, $method:ident $($cast:tt)*) => { + #[doc = "A deserializer holding"] + #[doc = $doc] #[derive(Clone, Debug)] pub struct $name { value: $ty, @@ -196,21 +197,21 @@ macro_rules! primitive_deserializer { } } -primitive_deserializer!(bool, BoolDeserializer, visit_bool); -primitive_deserializer!(i8, I8Deserializer, visit_i8); -primitive_deserializer!(i16, I16Deserializer, visit_i16); -primitive_deserializer!(i32, I32Deserializer, visit_i32); -primitive_deserializer!(i64, I64Deserializer, visit_i64); -primitive_deserializer!(isize, IsizeDeserializer, visit_i64 as i64); -primitive_deserializer!(u8, U8Deserializer, visit_u8); -primitive_deserializer!(u16, U16Deserializer, visit_u16); -primitive_deserializer!(u64, U64Deserializer, visit_u64); -primitive_deserializer!(usize, UsizeDeserializer, visit_u64 as u64); -primitive_deserializer!(f32, F32Deserializer, visit_f32); -primitive_deserializer!(f64, F64Deserializer, visit_f64); -primitive_deserializer!(char, CharDeserializer, visit_char); +primitive_deserializer!(bool, "a `bool`.", BoolDeserializer, visit_bool); +primitive_deserializer!(i8, "an `i8`.", I8Deserializer, visit_i8); +primitive_deserializer!(i16, "an `i16`.", I16Deserializer, visit_i16); +primitive_deserializer!(i32, "an `i32`.", I32Deserializer, visit_i32); +primitive_deserializer!(i64, "an `i64`.", I64Deserializer, visit_i64); +primitive_deserializer!(isize, "an `isize`.", IsizeDeserializer, visit_i64 as i64); +primitive_deserializer!(u8, "a `u8`.", U8Deserializer, visit_u8); +primitive_deserializer!(u16, "a `u16`.", U16Deserializer, visit_u16); +primitive_deserializer!(u64, "a `u64`.", U64Deserializer, visit_u64); +primitive_deserializer!(usize, "a `usize`.", UsizeDeserializer, visit_u64 as u64); +primitive_deserializer!(f32, "an `f32`.", F32Deserializer, visit_f32); +primitive_deserializer!(f64, "an `f64`.", F64Deserializer, visit_f64); +primitive_deserializer!(char, "a `char`.", CharDeserializer, visit_char); -/// A helper deserializer that deserializes a number. +/// A deserializer holding a `u32`. #[derive(Clone, Debug)] pub struct U32Deserializer { value: u32, @@ -282,7 +283,7 @@ where //////////////////////////////////////////////////////////////////////////////// -/// A helper deserializer that deserializes a `&str`. +/// A deserializer holding a `&str`. #[derive(Clone, Debug)] pub struct StrDeserializer<'a, E> { value: &'a str, @@ -354,7 +355,7 @@ where //////////////////////////////////////////////////////////////////////////////// -/// A helper deserializer that deserializes a `String`. +/// A deserializer holding a `String`. #[cfg(any(feature = "std", feature = "collections"))] #[derive(Clone, Debug)] pub struct StringDeserializer { @@ -430,7 +431,7 @@ where //////////////////////////////////////////////////////////////////////////////// -/// A helper deserializer that deserializes a `String`. +/// A deserializer holding a `Cow`. #[cfg(any(feature = "std", feature = "collections"))] #[derive(Clone, Debug)] pub struct CowStrDeserializer<'a, E> { @@ -509,7 +510,7 @@ where //////////////////////////////////////////////////////////////////////////////// -/// A helper deserializer that deserializes a sequence. +/// A deserializer that iterates over a sequence. #[derive(Clone, Debug)] pub struct SeqDeserializer { iter: iter::Fuse, @@ -688,7 +689,7 @@ where //////////////////////////////////////////////////////////////////////////////// -/// A helper deserializer that deserializes a map. +/// A deserializer that iterates over a map. pub struct MapDeserializer<'de, I, E> where I: Iterator, From 67d56ae42765379cb6b0301885c33d9917f9feb4 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 15:00:16 -0700 Subject: [PATCH 158/177] Remove unneeded impl bounds --- serde/src/de/value.rs | 44 +++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 77b97d99..29c8bcdb 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -521,9 +521,8 @@ pub struct SeqDeserializer { impl SeqDeserializer where I: Iterator, - E: de::Error, { - /// Construct a new `SeqDeserializer`. + /// Construct a new `SeqDeserializer`. pub fn new(iter: I) -> Self { SeqDeserializer { iter: iter.fuse(), @@ -531,7 +530,13 @@ where marker: PhantomData, } } +} +impl SeqDeserializer +where + I: Iterator, + E: de::Error, +{ /// Check for remaining elements after passing a `SeqDeserializer` to /// `Visitor::visit_seq`. pub fn end(mut self) -> Result<(), E> { @@ -694,9 +699,6 @@ pub struct MapDeserializer<'de, I, E> where I: Iterator, I::Item: private::Pair, - First: IntoDeserializer<'de, E>, - Second: IntoDeserializer<'de, E>, - E: de::Error, { iter: iter::Fuse, value: Option>, @@ -709,9 +711,6 @@ impl<'de, I, E> MapDeserializer<'de, I, E> where I: Iterator, I::Item: private::Pair, - First: IntoDeserializer<'de, E>, - Second: IntoDeserializer<'de, E>, - E: de::Error, { /// Construct a new `MapDeserializer`. pub fn new(iter: I) -> Self { @@ -723,7 +722,14 @@ where error: PhantomData, } } +} +impl<'de, I, E> MapDeserializer<'de, I, E> +where + I: Iterator, + I::Item: private::Pair, + E: de::Error, +{ /// Check for remaining elements after passing a `MapDeserializer` to /// `Visitor::visit_map`. pub fn end(mut self) -> Result<(), E> { @@ -739,7 +745,13 @@ where Err(de::Error::invalid_length(self.count + remaining, &ExpectedInMap(self.count)),) } } +} +impl<'de, I, E> MapDeserializer<'de, I, E> +where + I: Iterator, + I::Item: private::Pair, +{ fn next_pair(&mut self) -> Option<(First, Second)> { match self.iter.next() { Some(kv) => { @@ -884,16 +896,12 @@ where } } -// Cannot #[derive(Clone)] because of the bound: -// -// ::Second: Clone +// Cannot #[derive(Clone)] because of the bound `Second: Clone`. impl<'de, I, E> Clone for MapDeserializer<'de, I, E> where I: Iterator + Clone, I::Item: private::Pair, - First: IntoDeserializer<'de, E>, - Second: IntoDeserializer<'de, E> + Clone, - E: de::Error, + Second: Clone, { fn clone(&self) -> Self { MapDeserializer { @@ -906,16 +914,12 @@ where } } -// Cannot #[derive(Debug)] because of the bound: -// -// ::Second: Debug +// Cannot #[derive(Debug)] because of the bound `Second: Debug`. impl<'de, I, E> Debug for MapDeserializer<'de, I, E> where I: Iterator + Debug, I::Item: private::Pair, - First: IntoDeserializer<'de, E>, - Second: IntoDeserializer<'de, E> + Debug, - E: de::Error, + Second: Debug, { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.debug_struct("MapDeserializer") From b0dc7ea6da10d5d089c52b73f59beefd2566e60b Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 15:03:43 -0700 Subject: [PATCH 159/177] Nicer type parameter for the access forwarding impls --- serde/src/de/mod.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 5f9895d5..74fb629e 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -1383,14 +1383,14 @@ pub trait SeqAccess<'de> { } } -impl<'de, 'a, V> SeqAccess<'de> for &'a mut V +impl<'de, 'a, A> SeqAccess<'de> for &'a mut A where - V: SeqAccess<'de>, + A: SeqAccess<'de>, { - type Error = V::Error; + type Error = A::Error; #[inline] - fn next_element_seed(&mut self, seed: T) -> Result, V::Error> + fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> where T: DeserializeSeed<'de>, { @@ -1398,7 +1398,7 @@ where } #[inline] - fn next_element(&mut self) -> Result, V::Error> + fn next_element(&mut self) -> Result, Self::Error> where T: Deserialize<'de>, { @@ -1511,11 +1511,11 @@ pub trait MapAccess<'de> { } } -impl<'de, 'a, V_> MapAccess<'de> for &'a mut V_ +impl<'de, 'a, A> MapAccess<'de> for &'a mut A where - V_: MapAccess<'de>, + A: MapAccess<'de>, { - type Error = V_::Error; + type Error = A::Error; #[inline] fn next_key_seed(&mut self, seed: K) -> Result, Self::Error> @@ -1547,7 +1547,7 @@ where } #[inline] - fn next_entry(&mut self) -> Result, V_::Error> + fn next_entry(&mut self) -> Result, Self::Error> where K: Deserialize<'de>, V: Deserialize<'de>, @@ -1556,7 +1556,7 @@ where } #[inline] - fn next_key(&mut self) -> Result, V_::Error> + fn next_key(&mut self) -> Result, Self::Error> where K: Deserialize<'de>, { @@ -1564,7 +1564,7 @@ where } #[inline] - fn next_value(&mut self) -> Result + fn next_value(&mut self) -> Result where V: Deserialize<'de>, { From 337c6e91d88c636631a78aea6d5b4ba28dd8b880 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 15:07:19 -0700 Subject: [PATCH 160/177] Access terminology in serde_test --- serde_test/src/de.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index c826ee86..818b6294 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -8,7 +8,7 @@ use serde::de::{self, Deserialize, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, VariantAccess, Visitor}; -use serde::de::value::{MapVisitorDeserializer, SeqVisitorDeserializer}; +use serde::de::value::{MapAccessDeserializer, SeqAccessDeserializer}; use error::Error; use token::Token; @@ -618,7 +618,7 @@ impl<'de, 'a> MapAccess<'de> for EnumMapVisitor<'a, 'de> { len: None, end: Token::TupleVariantEnd, }; - try!(seed.deserialize(SeqVisitorDeserializer::new(visitor))) + try!(seed.deserialize(SeqAccessDeserializer::new(visitor))) }; try!(self.de.expect_token(Token::TupleVariantEnd)); Ok(value) @@ -630,7 +630,7 @@ impl<'de, 'a> MapAccess<'de> for EnumMapVisitor<'a, 'de> { len: None, end: Token::StructVariantEnd, }; - try!(seed.deserialize(MapVisitorDeserializer::new(visitor))) + try!(seed.deserialize(MapAccessDeserializer::new(visitor))) }; try!(self.de.expect_token(Token::StructVariantEnd)); Ok(value) From 5b118fdef425e3602a86f2ddead678540a191d84 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 15:24:21 -0700 Subject: [PATCH 161/177] Reorder methods to match the serializer trait --- serde/src/de/impls.rs | 8 +- serde/src/de/mod.rs | 162 ++++++++++++++++++++-------------------- serde/src/de/value.rs | 66 ++++++++-------- serde/src/macros.rs | 70 ++++++++--------- serde/src/private/de.rs | 42 +++++------ serde_test/src/de.rs | 10 +-- 6 files changed, 181 insertions(+), 177 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 2b8cbb66..ad481bdf 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -130,32 +130,36 @@ macro_rules! impl_deserialize_num { } } }; + (integer $ty:ident) => { visit_integer_method!(i8, visit_i8, from_i8, Signed, i64); visit_integer_method!(i16, visit_i16, from_i16, Signed, i64); visit_integer_method!(i32, visit_i32, from_i32, Signed, i64); visit_integer_method!(i64, visit_i64, from_i64, Signed, i64); + visit_integer_method!(u8, visit_u8, from_u8, Unsigned, u64); visit_integer_method!(u16, visit_u16, from_u16, Unsigned, u64); visit_integer_method!(u32, visit_u32, from_u32, Unsigned, u64); visit_integer_method!(u64, visit_u64, from_u64, Unsigned, u64); }; + (float $ty:ident) => { visit_float_method!(f32, visit_f32); visit_float_method!(f64, visit_f64); }; } -impl_deserialize_num!(isize, deserialize_i64, integer); impl_deserialize_num!(i8, deserialize_i8, integer); impl_deserialize_num!(i16, deserialize_i16, integer); impl_deserialize_num!(i32, deserialize_i32, integer); impl_deserialize_num!(i64, deserialize_i64, integer); -impl_deserialize_num!(usize, deserialize_u64, integer); +impl_deserialize_num!(isize, deserialize_i64, integer); + impl_deserialize_num!(u8, deserialize_u8, integer); impl_deserialize_num!(u16, deserialize_u16, integer); impl_deserialize_num!(u32, deserialize_u32, integer); impl_deserialize_num!(u64, deserialize_u64, integer); +impl_deserialize_num!(usize, deserialize_u64, integer); impl_deserialize_num!(f32, deserialize_f32, integer, float); impl_deserialize_num!(f64, deserialize_f64, integer, float); diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 74fb629e..a8275ef6 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -804,26 +804,6 @@ pub trait Deserializer<'de>: Sized { where V: Visitor<'de>; - /// Hint that the `Deserialize` type is expecting a `u8` value. - fn deserialize_u8(self, visitor: V) -> Result - where - V: Visitor<'de>; - - /// Hint that the `Deserialize` type is expecting a `u16` value. - fn deserialize_u16(self, visitor: V) -> Result - where - V: Visitor<'de>; - - /// Hint that the `Deserialize` type is expecting a `u32` value. - fn deserialize_u32(self, visitor: V) -> Result - where - V: Visitor<'de>; - - /// Hint that the `Deserialize` type is expecting a `u64` value. - fn deserialize_u64(self, visitor: V) -> Result - where - V: Visitor<'de>; - /// Hint that the `Deserialize` type is expecting an `i8` value. fn deserialize_i8(self, visitor: V) -> Result where @@ -844,6 +824,26 @@ pub trait Deserializer<'de>: Sized { where V: Visitor<'de>; + /// Hint that the `Deserialize` type is expecting a `u8` value. + fn deserialize_u8(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a `u16` value. + fn deserialize_u16(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a `u32` value. + fn deserialize_u32(self, visitor: V) -> Result + where + V: Visitor<'de>; + + /// Hint that the `Deserialize` type is expecting a `u64` value. + fn deserialize_u64(self, visitor: V) -> Result + where + V: Visitor<'de>; + /// Hint that the `Deserialize` type is expecting a `f32` value. fn deserialize_f32(self, visitor: V) -> Result where @@ -1225,67 +1225,6 @@ pub trait Visitor<'de>: Sized { self.visit_str(&v) } - /// Deserialize a `()` into a `Value`. - fn visit_unit(self) -> Result - where - E: Error, - { - Err(Error::invalid_type(Unexpected::Unit, &self)) - } - - /// Deserialize an absent optional `Value`. - fn visit_none(self) -> Result - where - E: Error, - { - Err(Error::invalid_type(Unexpected::Option, &self)) - } - - /// Deserialize a present optional `Value`. - fn visit_some(self, deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let _ = deserializer; - Err(Error::invalid_type(Unexpected::Option, &self)) - } - - /// Deserialize `Value` as a newtype struct. - fn visit_newtype_struct(self, deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let _ = deserializer; - Err(Error::invalid_type(Unexpected::NewtypeStruct, &self)) - } - - /// Deserialize `Value` as a sequence of elements. - fn visit_seq(self, seq: A) -> Result - where - A: SeqAccess<'de>, - { - let _ = seq; - Err(Error::invalid_type(Unexpected::Seq, &self)) - } - - /// Deserialize `Value` as a key-value map. - fn visit_map(self, map: A) -> Result - where - A: MapAccess<'de>, - { - let _ = map; - Err(Error::invalid_type(Unexpected::Map, &self)) - } - - /// Deserialize `Value` as an enum. - fn visit_enum(self, data: A) -> Result - where - A: EnumAccess<'de>, - { - let _ = data; - Err(Error::invalid_type(Unexpected::Enum, &self)) - } - /// Deserialize a `&[u8]` into a `Value`. /// /// This method allows the `Deserializer` to avoid a copy by retaining @@ -1341,6 +1280,67 @@ pub trait Visitor<'de>: Sized { { self.visit_bytes(&v) } + + /// Deserialize an absent optional `Value`. + fn visit_none(self) -> Result + where + E: Error, + { + Err(Error::invalid_type(Unexpected::Option, &self)) + } + + /// Deserialize a present optional `Value`. + fn visit_some(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let _ = deserializer; + Err(Error::invalid_type(Unexpected::Option, &self)) + } + + /// Deserialize a `()` into a `Value`. + fn visit_unit(self) -> Result + where + E: Error, + { + Err(Error::invalid_type(Unexpected::Unit, &self)) + } + + /// Deserialize `Value` as a newtype struct. + fn visit_newtype_struct(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let _ = deserializer; + Err(Error::invalid_type(Unexpected::NewtypeStruct, &self)) + } + + /// Deserialize `Value` as a sequence of elements. + fn visit_seq(self, seq: A) -> Result + where + A: SeqAccess<'de>, + { + let _ = seq; + Err(Error::invalid_type(Unexpected::Seq, &self)) + } + + /// Deserialize `Value` as a key-value map. + fn visit_map(self, map: A) -> Result + where + A: MapAccess<'de>, + { + let _ = map; + Err(Error::invalid_type(Unexpected::Map, &self)) + } + + /// Deserialize `Value` as an enum. + fn visit_enum(self, data: A) -> Result + where + A: EnumAccess<'de>, + { + let _ = data; + Err(Error::invalid_type(Unexpected::Enum, &self)) + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 29c8bcdb..8cf9e028 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -129,9 +129,9 @@ where type Error = E; forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq - seq_fixed_size bytes map unit_struct newtype_struct tuple_struct struct - identifier tuple enum ignored_any byte_buf + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf unit unit_struct newtype_struct seq seq_fixed_size tuple + tuple_struct map struct identifier enum ignored_any } fn deserialize_any(self, visitor: V) -> Result @@ -182,9 +182,9 @@ macro_rules! primitive_deserializer { type Error = E; forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit - option seq seq_fixed_size bytes map unit_struct newtype_struct - tuple_struct struct identifier tuple enum ignored_any byte_buf + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf option unit unit_struct newtype_struct seq seq_fixed_size + tuple tuple_struct map struct identifier enum ignored_any } fn deserialize_any(self, visitor: V) -> Result @@ -239,9 +239,9 @@ where type Error = E; forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct - struct identifier tuple ignored_any byte_buf + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf option unit unit_struct newtype_struct seq seq_fixed_size + tuple tuple_struct map struct identifier ignored_any } fn deserialize_any(self, visitor: V) -> Result @@ -332,9 +332,9 @@ where } forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct - struct identifier tuple ignored_any byte_buf + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf option unit unit_struct newtype_struct seq seq_fixed_size + tuple tuple_struct map struct identifier ignored_any } } @@ -407,9 +407,9 @@ where } forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct - struct identifier tuple ignored_any byte_buf + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf option unit unit_struct newtype_struct seq seq_fixed_size + tuple tuple_struct map struct identifier ignored_any } } @@ -486,9 +486,9 @@ where } forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct - struct identifier tuple ignored_any byte_buf + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf option unit unit_struct newtype_struct seq seq_fixed_size + tuple tuple_struct map struct identifier ignored_any } } @@ -572,9 +572,9 @@ where } forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct - struct identifier tuple enum ignored_any byte_buf + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf option unit unit_struct newtype_struct seq seq_fixed_size + tuple tuple_struct map struct identifier enum ignored_any } } @@ -686,9 +686,9 @@ where } forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct - struct identifier tuple enum ignored_any byte_buf + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf option unit unit_struct newtype_struct seq seq_fixed_size + tuple tuple_struct map struct identifier enum ignored_any } } @@ -804,9 +804,9 @@ where } forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - bytes map unit_struct newtype_struct tuple_struct struct identifier - tuple enum ignored_any byte_buf + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf option unit unit_struct newtype_struct tuple tuple_struct + map struct identifier enum ignored_any } } @@ -945,9 +945,9 @@ where type Error = E; forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - bytes map unit_struct newtype_struct tuple_struct struct identifier - tuple enum ignored_any byte_buf + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf option unit unit_struct newtype_struct tuple tuple_struct + map struct identifier enum ignored_any } fn deserialize_any(self, visitor: V) -> Result @@ -1092,9 +1092,9 @@ where } forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct - struct identifier tuple enum ignored_any byte_buf + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf option unit unit_struct newtype_struct seq seq_fixed_size + tuple tuple_struct map struct identifier enum ignored_any } } diff --git a/serde/src/macros.rs b/serde/src/macros.rs index 6b7ea6e2..b3d5d402 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -77,9 +77,9 @@ /// } /// /// forward_to_deserialize_any! { -/// bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option -/// seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct -/// tuple_struct struct identifier tuple enum ignored_any +/// bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes +/// byte_buf option unit unit_struct newtype_struct seq seq_fixed_size +/// tuple tuple_struct map struct identifier enum ignored_any /// } /// } /// # @@ -112,9 +112,9 @@ /// # /// forward_to_deserialize_any! { /// > -/// bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option -/// seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct -/// tuple_struct struct identifier tuple enum ignored_any +/// bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes +/// byte_buf option unit unit_struct newtype_struct seq seq_fixed_size +/// tuple tuple_struct map struct identifier enum ignored_any /// } /// # } /// # @@ -158,18 +158,6 @@ macro_rules! forward_to_deserialize_any_helper { (bool<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_bool<$l, $v>()} }; - (u8<$l:tt, $v:ident>) => { - forward_to_deserialize_any_method!{deserialize_u8<$l, $v>()} - }; - (u16<$l:tt, $v:ident>) => { - forward_to_deserialize_any_method!{deserialize_u16<$l, $v>()} - }; - (u32<$l:tt, $v:ident>) => { - forward_to_deserialize_any_method!{deserialize_u32<$l, $v>()} - }; - (u64<$l:tt, $v:ident>) => { - forward_to_deserialize_any_method!{deserialize_u64<$l, $v>()} - }; (i8<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_i8<$l, $v>()} }; @@ -182,6 +170,18 @@ macro_rules! forward_to_deserialize_any_helper { (i64<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_i64<$l, $v>()} }; + (u8<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_u8<$l, $v>()} + }; + (u16<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_u16<$l, $v>()} + }; + (u32<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_u32<$l, $v>()} + }; + (u64<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_u64<$l, $v>()} + }; (f32<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_f32<$l, $v>()} }; @@ -197,26 +197,17 @@ macro_rules! forward_to_deserialize_any_helper { (string<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_string<$l, $v>()} }; - (unit<$l:tt, $v:ident>) => { - forward_to_deserialize_any_method!{deserialize_unit<$l, $v>()} - }; - (option<$l:tt, $v:ident>) => { - forward_to_deserialize_any_method!{deserialize_option<$l, $v>()} - }; - (seq<$l:tt, $v:ident>) => { - forward_to_deserialize_any_method!{deserialize_seq<$l, $v>()} - }; - (seq_fixed_size<$l:tt, $v:ident>) => { - forward_to_deserialize_any_method!{deserialize_seq_fixed_size<$l, $v>(len: usize)} - }; (bytes<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_bytes<$l, $v>()} }; (byte_buf<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_byte_buf<$l, $v>()} }; - (map<$l:tt, $v:ident>) => { - forward_to_deserialize_any_method!{deserialize_map<$l, $v>()} + (option<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_option<$l, $v>()} + }; + (unit<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_unit<$l, $v>()} }; (unit_struct<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_unit_struct<$l, $v>(name: &'static str)} @@ -224,18 +215,27 @@ macro_rules! forward_to_deserialize_any_helper { (newtype_struct<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_newtype_struct<$l, $v>(name: &'static str)} }; + (seq<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_seq<$l, $v>()} + }; + (seq_fixed_size<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_seq_fixed_size<$l, $v>(len: usize)} + }; + (tuple<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_tuple<$l, $v>(len: usize)} + }; (tuple_struct<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_tuple_struct<$l, $v>(name: &'static str, len: usize)} }; + (map<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_map<$l, $v>()} + }; (struct<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_struct<$l, $v>(name: &'static str, fields: &'static [&'static str])} }; (identifier<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_identifier<$l, $v>()} }; - (tuple<$l:tt, $v:ident>) => { - forward_to_deserialize_any_method!{deserialize_tuple<$l, $v>(len: usize)} - }; (enum<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_enum<$l, $v>(name: &'static str, variants: &'static [&'static str])} }; diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 963585f0..33aecb4e 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -48,9 +48,9 @@ where } forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq - seq_fixed_size bytes byte_buf map unit_struct newtype_struct - tuple_struct struct identifier tuple enum ignored_any + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf unit unit_struct newtype_struct seq seq_fixed_size tuple + tuple_struct map struct identifier enum ignored_any } } @@ -994,9 +994,9 @@ mod content { } forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq - seq_fixed_size bytes byte_buf map unit_struct tuple_struct struct - identifier tuple ignored_any + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf unit unit_struct seq seq_fixed_size tuple tuple_struct map + struct identifier ignored_any } } @@ -1152,9 +1152,9 @@ mod content { } forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct - tuple_struct struct identifier tuple enum ignored_any + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf option unit unit_struct newtype_struct seq seq_fixed_size + tuple tuple_struct map struct identifier enum ignored_any } } @@ -1253,9 +1253,9 @@ mod content { } forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct - tuple_struct struct identifier tuple enum ignored_any + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf option unit unit_struct newtype_struct seq seq_fixed_size + tuple tuple_struct map struct identifier enum ignored_any } } @@ -1389,9 +1389,9 @@ mod content { } forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq - seq_fixed_size bytes byte_buf map unit_struct tuple_struct struct - identifier tuple ignored_any + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf unit unit_struct seq seq_fixed_size tuple tuple_struct map + struct identifier ignored_any } } @@ -1544,9 +1544,9 @@ mod content { } forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct - tuple_struct struct identifier tuple enum ignored_any + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf option unit unit_struct newtype_struct seq seq_fixed_size + tuple tuple_struct map struct identifier enum ignored_any } } @@ -1646,9 +1646,9 @@ mod content { } forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct - tuple_struct struct identifier tuple enum ignored_any + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf option unit unit_struct newtype_struct seq seq_fixed_size + tuple tuple_struct map struct identifier enum ignored_any } } diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index 818b6294..a1f497c7 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -98,8 +98,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { type Error = Error; forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit - seq bytes byte_buf map identifier ignored_any + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf unit seq map identifier ignored_any } fn deserialize_any(self, visitor: V) -> Result @@ -655,8 +655,8 @@ impl<'de> de::Deserializer<'de> for BytesDeserializer { } forward_to_deserialize_any! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct - struct identifier tuple enum ignored_any byte_buf + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf option unit unit_struct newtype_struct seq seq_fixed_size + tuple tuple_struct map struct identifier enum ignored_any } } From 6d55501dab17ab025dd570e19d0861ca60005268 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 15:42:27 -0700 Subject: [PATCH 162/177] Replace "codegen" with "derive" --- Cargo.toml | 2 +- serde_derive/Cargo.toml | 2 +- serde_derive/src/de.rs | 2 +- serde_derive/src/lib.rs | 2 +- serde_derive/src/ser.rs | 2 +- .../Cargo.toml | 6 +++--- .../LICENSE-APACHE | 0 .../LICENSE-MIT | 0 .../README.md | 0 .../src/ast.rs | 0 .../src/attr.rs | 0 .../src/case.rs | 0 .../src/check.rs | 0 .../src/ctxt.rs | 0 .../src/lib.rs | 0 15 files changed, 8 insertions(+), 8 deletions(-) rename {serde_codegen_internals => serde_derive_internals}/Cargo.toml (74%) rename {serde_codegen_internals => serde_derive_internals}/LICENSE-APACHE (100%) rename {serde_codegen_internals => serde_derive_internals}/LICENSE-MIT (100%) rename {serde_codegen_internals => serde_derive_internals}/README.md (100%) rename {serde_codegen_internals => serde_derive_internals}/src/ast.rs (100%) rename {serde_codegen_internals => serde_derive_internals}/src/attr.rs (100%) rename {serde_codegen_internals => serde_derive_internals}/src/case.rs (100%) rename {serde_codegen_internals => serde_derive_internals}/src/check.rs (100%) rename {serde_codegen_internals => serde_derive_internals}/src/ctxt.rs (100%) rename {serde_codegen_internals => serde_derive_internals}/src/lib.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index 601a709e..29db37d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,8 @@ [workspace] members = [ "serde", - "serde_codegen_internals", "serde_derive", + "serde_derive_internals", "serde_test", "test_suite", "test_suite/no_std", diff --git a/serde_derive/Cargo.toml b/serde_derive/Cargo.toml index c9e42766..9f8d99d2 100644 --- a/serde_derive/Cargo.toml +++ b/serde_derive/Cargo.toml @@ -21,5 +21,5 @@ proc-macro = true [dependencies] quote = "0.3.8" -serde_codegen_internals = { version = "=0.14.2", default-features = false, path = "../serde_codegen_internals" } +serde_derive_internals = { version = "=0.14.2", default-features = false, path = "../serde_derive_internals" } syn = { version = "0.11", features = ["visit"] } diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 6eb3846b..f6b6566b 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -1090,7 +1090,7 @@ fn deserialize_internally_tagged_variant( Style::Newtype | Style::Struct => { deserialize_untagged_variant(params, variant, item_attrs, deserializer) } - Style::Tuple => unreachable!("checked in serde_codegen_internals"), + Style::Tuple => unreachable!("checked in serde_derive_internals"), } } diff --git a/serde_derive/src/lib.rs b/serde_derive/src/lib.rs index a88a47a1..55cea20e 100644 --- a/serde_derive/src/lib.rs +++ b/serde_derive/src/lib.rs @@ -18,7 +18,7 @@ extern crate syn; #[macro_use] extern crate quote; -extern crate serde_codegen_internals as internals; +extern crate serde_derive_internals as internals; extern crate proc_macro; use proc_macro::TokenStream; diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index 43bd4c8a..d55da219 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -490,7 +490,7 @@ fn serialize_internally_tagged_variant( &type_name, ) } - Style::Tuple => unreachable!("checked in serde_codegen_internals"), + Style::Tuple => unreachable!("checked in serde_derive_internals"), } } diff --git a/serde_codegen_internals/Cargo.toml b/serde_derive_internals/Cargo.toml similarity index 74% rename from serde_codegen_internals/Cargo.toml rename to serde_derive_internals/Cargo.toml index f572d487..85d6cb91 100644 --- a/serde_codegen_internals/Cargo.toml +++ b/serde_derive_internals/Cargo.toml @@ -1,12 +1,12 @@ [package] -name = "serde_codegen_internals" +name = "serde_derive_internals" version = "0.14.2" authors = ["Erick Tryzelaar "] license = "MIT/Apache-2.0" -description = "AST representation used by Serde codegen. Unstable." +description = "AST representation used by Serde derive macros. Unstable." homepage = "https://serde.rs" repository = "https://github.com/serde-rs/serde" -documentation = "https://docs.serde.rs/serde_codegen_internals/" +documentation = "https://docs.serde.rs/serde_derive_internals/" keywords = ["serde", "serialization"] readme = "README.md" include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] diff --git a/serde_codegen_internals/LICENSE-APACHE b/serde_derive_internals/LICENSE-APACHE similarity index 100% rename from serde_codegen_internals/LICENSE-APACHE rename to serde_derive_internals/LICENSE-APACHE diff --git a/serde_codegen_internals/LICENSE-MIT b/serde_derive_internals/LICENSE-MIT similarity index 100% rename from serde_codegen_internals/LICENSE-MIT rename to serde_derive_internals/LICENSE-MIT diff --git a/serde_codegen_internals/README.md b/serde_derive_internals/README.md similarity index 100% rename from serde_codegen_internals/README.md rename to serde_derive_internals/README.md diff --git a/serde_codegen_internals/src/ast.rs b/serde_derive_internals/src/ast.rs similarity index 100% rename from serde_codegen_internals/src/ast.rs rename to serde_derive_internals/src/ast.rs diff --git a/serde_codegen_internals/src/attr.rs b/serde_derive_internals/src/attr.rs similarity index 100% rename from serde_codegen_internals/src/attr.rs rename to serde_derive_internals/src/attr.rs diff --git a/serde_codegen_internals/src/case.rs b/serde_derive_internals/src/case.rs similarity index 100% rename from serde_codegen_internals/src/case.rs rename to serde_derive_internals/src/case.rs diff --git a/serde_codegen_internals/src/check.rs b/serde_derive_internals/src/check.rs similarity index 100% rename from serde_codegen_internals/src/check.rs rename to serde_derive_internals/src/check.rs diff --git a/serde_codegen_internals/src/ctxt.rs b/serde_derive_internals/src/ctxt.rs similarity index 100% rename from serde_codegen_internals/src/ctxt.rs rename to serde_derive_internals/src/ctxt.rs diff --git a/serde_codegen_internals/src/lib.rs b/serde_derive_internals/src/lib.rs similarity index 100% rename from serde_codegen_internals/src/lib.rs rename to serde_derive_internals/src/lib.rs From f9535a4d671c07211e7fd4c984b08546c1bb1944 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 15:52:56 -0700 Subject: [PATCH 163/177] Remove "item" terminology in favor of "container" The docs have been using "container" for a long time. --- serde_derive/src/bound.rs | 22 ++-- serde_derive/src/de.rs | 178 ++++++++++++++-------------- serde_derive/src/ser.rs | 102 ++++++++-------- serde_derive_internals/src/ast.rs | 12 +- serde_derive_internals/src/attr.rs | 8 +- serde_derive_internals/src/check.rs | 4 +- 6 files changed, 163 insertions(+), 163 deletions(-) diff --git a/serde_derive/src/bound.rs b/serde_derive/src/bound.rs index d539617b..f77bede5 100644 --- a/serde_derive/src/bound.rs +++ b/serde_derive/src/bound.rs @@ -10,7 +10,7 @@ use std::collections::HashSet; use syn::{self, visit}; -use internals::ast::Item; +use internals::ast::Container; use internals::attr; macro_rules! path { @@ -53,14 +53,14 @@ pub fn with_where_predicates( } pub fn with_where_predicates_from_fields( - item: &Item, + cont: &Container, generics: &syn::Generics, from_field: F, ) -> syn::Generics where F: Fn(&attr::Field) -> Option<&[syn::WherePredicate]>, { - let predicates = item.body + let predicates = cont.body .all_fields() .flat_map(|field| from_field(&field.attrs)) .flat_map(|predicates| predicates.to_vec()); @@ -82,7 +82,7 @@ where // c: C, // } pub fn with_bound( - item: &Item, + cont: &Container, generics: &syn::Generics, filter: F, bound: &syn::Path, @@ -124,7 +124,7 @@ where .map(|ty_param| ty_param.ident.clone()) .collect(); - let relevant_tys = item.body + let relevant_tys = cont.body .all_fields() .filter(|&field| filter(&field.attrs)) .map(|field| &field.ty); @@ -169,7 +169,7 @@ where generics } -pub fn with_self_bound(item: &Item, generics: &syn::Generics, bound: &syn::Path) -> syn::Generics { +pub fn with_self_bound(cont: &Container, generics: &syn::Generics, bound: &syn::Path) -> syn::Generics { let mut generics = generics.clone(); generics .where_clause @@ -179,7 +179,7 @@ pub fn with_self_bound(item: &Item, generics: &syn::Generics, bound: &syn::Path) syn::WhereBoundPredicate { bound_lifetimes: Vec::new(), // the type that is being bounded e.g. MyStruct<'a, T> - bounded_ty: type_of_item(item), + bounded_ty: type_of_item(cont), // the bound e.g. Default bounds: vec![ syn::TyParamBound::Trait( @@ -222,22 +222,22 @@ pub fn with_lifetime_bound(generics: &syn::Generics, lifetime: &str) -> syn::Gen generics } -fn type_of_item(item: &Item) -> syn::Ty { +fn type_of_item(cont: &Container) -> syn::Ty { syn::Ty::Path( None, syn::Path { global: false, segments: vec![ syn::PathSegment { - ident: item.ident.clone(), + ident: cont.ident.clone(), parameters: syn::PathParameters::AngleBracketed( syn::AngleBracketedParameterData { - lifetimes: item.generics + lifetimes: cont.generics .lifetimes .iter() .map(|def| def.lifetime.clone()) .collect(), - types: item.generics + types: cont.generics .ty_params .iter() .map(|param| syn::Ty::Path(None, param.ident.clone().into())) diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index f6b6566b..e9526494 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -11,23 +11,23 @@ use quote::{self, Tokens, ToTokens}; use bound; use fragment::{Fragment, Expr, Stmts, Match}; -use internals::ast::{Body, Field, Item, Style, Variant}; +use internals::ast::{Body, Container, Field, Style, Variant}; use internals::{self, attr}; use std::collections::BTreeSet; -pub fn expand_derive_deserialize(item: &syn::DeriveInput) -> Result { +pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result { let ctxt = internals::Ctxt::new(); - let item = Item::from_ast(&ctxt, item); + let cont = Container::from_ast(&ctxt, input); try!(ctxt.check()); - let ident = &item.ident; - let params = Parameters::new(&item); + let ident = &cont.ident; + let params = Parameters::new(&cont); let dummy_const = Ident::new(format!("_IMPL_DESERIALIZE_FOR_{}", ident)); - let body = Stmts(deserialize_body(&item, ¶ms)); + let body = Stmts(deserialize_body(&cont, ¶ms)); - let impl_item = if let Some(remote) = item.attrs.remote() { - let (impl_generics, ty_generics, where_clause) = item.generics.split_for_impl(); + let impl_block = if let Some(remote) = cont.attrs.remote() { + let (impl_generics, ty_generics, where_clause) = cont.generics.split_for_impl(); let de_lifetime = params.de_lifetime_def(); quote! { impl #impl_generics #ident #ty_generics #where_clause { @@ -57,7 +57,7 @@ pub fn expand_derive_deserialize(item: &syn::DeriveInput) -> Result Self { - let local = item.ident.clone(); - let this = match item.attrs.remote() { + fn new(cont: &Container) -> Self { + let local = cont.ident.clone(); + let this = match cont.attrs.remote() { Some(remote) => remote.clone(), - None => item.ident.clone().into(), + None => cont.ident.clone().into(), }; - let generics = build_generics(item); - let borrowed = borrowed_lifetimes(item); - let has_getter = item.body.has_getter(); + let generics = build_generics(cont); + let borrowed = borrowed_lifetimes(cont); + let has_getter = cont.body.has_getter(); Parameters { local: local, @@ -122,31 +122,31 @@ impl Parameters { // All the generics in the input, plus a bound `T: Deserialize` for each generic // field type that will be deserialized by us, plus a bound `T: Default` for // each generic field type that will be set to a default value. -fn build_generics(item: &Item) -> syn::Generics { - let generics = bound::without_defaults(item.generics); +fn build_generics(cont: &Container) -> syn::Generics { + let generics = bound::without_defaults(cont.generics); - let generics = bound::with_where_predicates_from_fields(item, &generics, attr::Field::de_bound); + let generics = bound::with_where_predicates_from_fields(cont, &generics, attr::Field::de_bound); - match item.attrs.de_bound() { + match cont.attrs.de_bound() { Some(predicates) => bound::with_where_predicates(&generics, predicates), None => { - let generics = match *item.attrs.default() { + let generics = match *cont.attrs.default() { attr::Default::Default => { - bound::with_self_bound(item, &generics, &path!(_serde::export::Default)) + bound::with_self_bound(cont, &generics, &path!(_serde::export::Default)) } attr::Default::None | attr::Default::Path(_) => generics, }; let generics = bound::with_bound( - item, + cont, &generics, needs_deserialize_bound, &path!(_serde::Deserialize<'de>), ); bound::with_bound( - item, + cont, &generics, requires_default, &path!(_serde::export::Default), @@ -169,40 +169,40 @@ fn requires_default(attrs: &attr::Field) -> bool { attrs.default() == &attr::Default::Default } -// The union of lifetimes borrowed by each field of the item. +// The union of lifetimes borrowed by each field of the container. // // These turn into bounds on the `'de` lifetime of the Deserialize impl. If // lifetimes `'a` and `'b` are borrowed but `'c` is not, the impl is: // // impl<'de: 'a + 'b, 'a, 'b, 'c> Deserialize<'de> for S<'a, 'b, 'c> -fn borrowed_lifetimes(item: &Item) -> BTreeSet { +fn borrowed_lifetimes(cont: &Container) -> BTreeSet { let mut lifetimes = BTreeSet::new(); - for field in item.body.all_fields() { + for field in cont.body.all_fields() { lifetimes.extend(field.attrs.borrowed_lifetimes().iter().cloned()); } lifetimes } -fn deserialize_body(item: &Item, params: &Parameters) -> Fragment { - if let Some(from_type) = item.attrs.from_type() { +fn deserialize_body(cont: &Container, params: &Parameters) -> Fragment { + if let Some(from_type) = cont.attrs.from_type() { deserialize_from(from_type) } else { - match item.body { - Body::Enum(ref variants) => deserialize_item_enum(params, variants, &item.attrs), + match cont.body { + Body::Enum(ref variants) => deserialize_enum(params, variants, &cont.attrs), Body::Struct(Style::Struct, ref fields) => { if fields.iter().any(|field| field.ident.is_none()) { panic!("struct has unnamed fields"); } - deserialize_struct(None, params, fields, &item.attrs, None) + deserialize_struct(None, params, fields, &cont.attrs, None) } Body::Struct(Style::Tuple, ref fields) | Body::Struct(Style::Newtype, ref fields) => { if fields.iter().any(|field| field.ident.is_some()) { panic!("tuple struct has named fields"); } - deserialize_tuple(None, params, fields, &item.attrs, None) + deserialize_tuple(None, params, fields, &cont.attrs, None) } - Body::Struct(Style::Unit, _) => deserialize_unit_struct(params, &item.attrs), + Body::Struct(Style::Unit, _) => deserialize_unit_struct(params, &cont.attrs), } } } @@ -215,9 +215,9 @@ fn deserialize_from(from_type: &syn::Ty) -> Fragment { } } -fn deserialize_unit_struct(params: &Parameters, item_attrs: &attr::Item) -> Fragment { +fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fragment { let this = ¶ms.this; - let type_name = item_attrs.name().deserialize_name(); + let type_name = cattrs.name().deserialize_name(); let expecting = format!("unit struct {}", params.type_name()); @@ -247,7 +247,7 @@ fn deserialize_tuple( variant_ident: Option<&syn::Ident>, params: &Parameters, fields: &[Field], - item_attrs: &attr::Item, + cattrs: &attr::Container, deserializer: Option, ) -> Fragment { let this = ¶ms.this; @@ -281,7 +281,7 @@ fn deserialize_tuple( None }; - let visit_seq = Stmts(deserialize_seq(&type_path, params, fields, false, item_attrs),); + let visit_seq = Stmts(deserialize_seq(&type_path, params, fields, false, cattrs),); let visitor_expr = quote! { __Visitor { @@ -294,10 +294,10 @@ fn deserialize_tuple( } else if is_enum { quote!(_serde::de::VariantAccess::deserialize_tuple(__variant, #nfields, #visitor_expr)) } else if nfields == 1 { - let type_name = item_attrs.name().deserialize_name(); + let type_name = cattrs.name().deserialize_name(); quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr)) } else { - let type_name = item_attrs.name().deserialize_name(); + let type_name = cattrs.name().deserialize_name(); quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #nfields, #visitor_expr)) }; @@ -342,7 +342,7 @@ fn deserialize_seq( params: &Parameters, fields: &[Field], is_struct: bool, - item_attrs: &attr::Item, + cattrs: &attr::Container, ) -> Fragment { let vars = (0..fields.len()).map(field_i as fn(_) -> _); @@ -356,7 +356,7 @@ fn deserialize_seq( let let_values = vars.clone().zip(fields) .map(|(var, field)| { if field.attrs.skip_deserializing() { - let default = Expr(expr_is_missing(&field, item_attrs)); + let default = Expr(expr_is_missing(&field, cattrs)); quote! { let #var = #default; } @@ -453,7 +453,7 @@ fn deserialize_struct( variant_ident: Option<&syn::Ident>, params: &Parameters, fields: &[Field], - item_attrs: &attr::Item, + cattrs: &attr::Container, deserializer: Option, ) -> Fragment { let is_enum = variant_ident.is_some(); @@ -481,10 +481,10 @@ fn deserialize_struct( None => format!("struct {}", params.type_name()), }; - let visit_seq = Stmts(deserialize_seq(&type_path, params, fields, true, item_attrs),); + let visit_seq = Stmts(deserialize_seq(&type_path, params, fields, true, cattrs),); let (field_visitor, fields_stmt, visit_map) = - deserialize_struct_visitor(type_path, params, fields, item_attrs); + deserialize_struct_visitor(type_path, params, fields, cattrs); let field_visitor = Stmts(field_visitor); let fields_stmt = Stmts(fields_stmt); let visit_map = Stmts(visit_map); @@ -504,7 +504,7 @@ fn deserialize_struct( _serde::de::VariantAccess::deserialize_struct(__variant, FIELDS, #visitor_expr) } } else { - let type_name = item_attrs.name().deserialize_name(); + let type_name = cattrs.name().deserialize_name(); quote! { _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr) } @@ -564,33 +564,33 @@ fn deserialize_struct( } } -fn deserialize_item_enum( +fn deserialize_enum( params: &Parameters, variants: &[Variant], - item_attrs: &attr::Item, + cattrs: &attr::Container, ) -> Fragment { - match *item_attrs.tag() { - attr::EnumTag::External => deserialize_externally_tagged_enum(params, variants, item_attrs), + match *cattrs.tag() { + attr::EnumTag::External => deserialize_externally_tagged_enum(params, variants, cattrs), attr::EnumTag::Internal { ref tag } => { - deserialize_internally_tagged_enum(params, variants, item_attrs, tag) + deserialize_internally_tagged_enum(params, variants, cattrs, tag) } attr::EnumTag::Adjacent { ref tag, ref content, - } => deserialize_adjacently_tagged_enum(params, variants, item_attrs, tag, content), - attr::EnumTag::None => deserialize_untagged_enum(params, variants, item_attrs), + } => deserialize_adjacently_tagged_enum(params, variants, cattrs, tag, content), + attr::EnumTag::None => deserialize_untagged_enum(params, variants, cattrs), } } fn deserialize_externally_tagged_enum( params: &Parameters, variants: &[Variant], - item_attrs: &attr::Item, + cattrs: &attr::Container, ) -> Fragment { let this = ¶ms.this; let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,); - let type_name = item_attrs.name().deserialize_name(); + let type_name = cattrs.name().deserialize_name(); let expecting = format!("enum {}", params.type_name()); @@ -608,7 +608,7 @@ fn deserialize_externally_tagged_enum( } }; - let variant_visitor = Stmts(deserialize_field_visitor(variant_names_idents, item_attrs, true),); + let variant_visitor = Stmts(deserialize_field_visitor(variant_names_idents, cattrs, true),); // Match arms to extract a variant from a string let variant_arms = @@ -621,7 +621,7 @@ fn deserialize_externally_tagged_enum( let variant_name = field_i(i); let block = - Match(deserialize_externally_tagged_variant(params, variant, item_attrs),); + Match(deserialize_externally_tagged_variant(params, variant, cattrs),); quote! { (__Field::#variant_name, __variant) => #block @@ -686,7 +686,7 @@ fn deserialize_externally_tagged_enum( fn deserialize_internally_tagged_enum( params: &Parameters, variants: &[Variant], - item_attrs: &attr::Item, + cattrs: &attr::Container, tag: &str, ) -> Fragment { let variant_names_idents: Vec<_> = variants @@ -703,7 +703,7 @@ fn deserialize_internally_tagged_enum( } }; - let variant_visitor = Stmts(deserialize_field_visitor(variant_names_idents, item_attrs, true),); + let variant_visitor = Stmts(deserialize_field_visitor(variant_names_idents, cattrs, true),); // Match arms to extract a variant from a string let variant_arms = variants.iter() @@ -715,7 +715,7 @@ fn deserialize_internally_tagged_enum( let block = Match(deserialize_internally_tagged_variant( params, variant, - item_attrs, + cattrs, quote!(_serde::private::de::ContentDeserializer::<__D::Error>::new(__tagged.content)), )); @@ -742,7 +742,7 @@ fn deserialize_internally_tagged_enum( fn deserialize_adjacently_tagged_enum( params: &Parameters, variants: &[Variant], - item_attrs: &attr::Item, + cattrs: &attr::Container, tag: &str, content: &str, ) -> Fragment { @@ -763,7 +763,7 @@ fn deserialize_adjacently_tagged_enum( } }; - let variant_visitor = Stmts(deserialize_field_visitor(variant_names_idents, item_attrs, true),); + let variant_visitor = Stmts(deserialize_field_visitor(variant_names_idents, cattrs, true),); let ref variant_arms: Vec<_> = variants .iter() @@ -777,7 +777,7 @@ fn deserialize_adjacently_tagged_enum( deserialize_untagged_variant( params, variant, - item_attrs, + cattrs, quote!(__deserializer), ), ); @@ -790,7 +790,7 @@ fn deserialize_adjacently_tagged_enum( .collect(); let expecting = format!("adjacently tagged enum {}", params.type_name()); - let type_name = item_attrs.name().deserialize_name(); + let type_name = cattrs.name().deserialize_name(); let tag_or_content = quote! { _serde::private::de::TagOrContentFieldVisitor { @@ -992,7 +992,7 @@ fn deserialize_adjacently_tagged_enum( fn deserialize_untagged_enum( params: &Parameters, variants: &[Variant], - item_attrs: &attr::Item, + cattrs: &attr::Container, ) -> Fragment { let attempts = variants .iter() @@ -1002,7 +1002,7 @@ fn deserialize_untagged_enum( Expr(deserialize_untagged_variant( params, variant, - item_attrs, + cattrs, quote!(_serde::private::de::ContentRefDeserializer::<__D::Error>::new(&__content)), )) }, @@ -1033,7 +1033,7 @@ fn deserialize_untagged_enum( fn deserialize_externally_tagged_variant( params: &Parameters, variant: &Variant, - item_attrs: &attr::Item, + cattrs: &attr::Container, ) -> Fragment { let variant_ident = &variant.ident; @@ -1053,7 +1053,7 @@ fn deserialize_externally_tagged_variant( Some(variant_ident), params, &variant.fields, - item_attrs, + cattrs, None, ) } @@ -1062,7 +1062,7 @@ fn deserialize_externally_tagged_variant( Some(variant_ident), params, &variant.fields, - item_attrs, + cattrs, None, ) } @@ -1072,7 +1072,7 @@ fn deserialize_externally_tagged_variant( fn deserialize_internally_tagged_variant( params: &Parameters, variant: &Variant, - item_attrs: &attr::Item, + cattrs: &attr::Container, deserializer: Tokens, ) -> Fragment { let variant_ident = &variant.ident; @@ -1088,7 +1088,7 @@ fn deserialize_internally_tagged_variant( } } Style::Newtype | Style::Struct => { - deserialize_untagged_variant(params, variant, item_attrs, deserializer) + deserialize_untagged_variant(params, variant, cattrs, deserializer) } Style::Tuple => unreachable!("checked in serde_derive_internals"), } @@ -1097,7 +1097,7 @@ fn deserialize_internally_tagged_variant( fn deserialize_untagged_variant( params: &Parameters, variant: &Variant, - item_attrs: &attr::Item, + cattrs: &attr::Container, deserializer: Tokens, ) -> Fragment { let variant_ident = &variant.ident; @@ -1129,7 +1129,7 @@ fn deserialize_untagged_variant( Some(variant_ident), params, &variant.fields, - item_attrs, + cattrs, Some(deserializer), ) } @@ -1138,7 +1138,7 @@ fn deserialize_untagged_variant( Some(variant_ident), params, &variant.fields, - item_attrs, + cattrs, Some(deserializer), ) } @@ -1202,14 +1202,14 @@ fn deserialize_untagged_newtype_variant( fn deserialize_field_visitor( fields: Vec<(String, Ident)>, - item_attrs: &attr::Item, + cattrs: &attr::Container, is_variant: bool, ) -> Fragment { let field_strs = fields.iter().map(|&(ref name, _)| name); let field_bytes = fields.iter().map(|&(ref name, _)| quote::ByteStr(name)); let field_idents: &Vec<_> = &fields.iter().map(|&(_, ref ident)| ident).collect(); - let ignore_variant = if is_variant || item_attrs.deny_unknown_fields() { + let ignore_variant = if is_variant || cattrs.deny_unknown_fields() { None } else { Some(quote!(__ignore,)) @@ -1242,7 +1242,7 @@ fn deserialize_field_visitor( quote! { _serde::export::Err(_serde::de::Error::unknown_variant(__value, VARIANTS)) } - } else if item_attrs.deny_unknown_fields() { + } else if cattrs.deny_unknown_fields() { quote! { _serde::export::Err(_serde::de::Error::unknown_field(__value, FIELDS)) } @@ -1252,7 +1252,7 @@ fn deserialize_field_visitor( } }; - let bytes_to_str = if is_variant || item_attrs.deny_unknown_fields() { + let bytes_to_str = if is_variant || cattrs.deny_unknown_fields() { Some( quote! { let __value = &_serde::export::from_utf8_lossy(__value); @@ -1321,7 +1321,7 @@ fn deserialize_struct_visitor( struct_path: Tokens, params: &Parameters, fields: &[Field], - item_attrs: &attr::Item, + cattrs: &attr::Container, ) -> (Fragment, Fragment, Fragment) { let field_names_idents: Vec<_> = fields .iter() @@ -1337,9 +1337,9 @@ fn deserialize_struct_visitor( } }; - let field_visitor = deserialize_field_visitor(field_names_idents, item_attrs, false); + let field_visitor = deserialize_field_visitor(field_names_idents, cattrs, false); - let visit_map = deserialize_map(struct_path, params, fields, item_attrs); + let visit_map = deserialize_map(struct_path, params, fields, cattrs); (field_visitor, fields_stmt, visit_map) } @@ -1348,7 +1348,7 @@ fn deserialize_map( struct_path: Tokens, params: &Parameters, fields: &[Field], - item_attrs: &attr::Item, + cattrs: &attr::Container, ) -> Fragment { // Create the field names for the fields. let fields_names: Vec<_> = fields @@ -1403,7 +1403,7 @@ fn deserialize_map( }); // Visit ignored values to consume them - let ignored_arm = if item_attrs.deny_unknown_fields() { + let ignored_arm = if cattrs.deny_unknown_fields() { None } else { Some(quote! { @@ -1414,7 +1414,7 @@ fn deserialize_map( let all_skipped = fields .iter() .all(|field| field.attrs.skip_deserializing()); - let match_keys = if item_attrs.deny_unknown_fields() && all_skipped { + let match_keys = if cattrs.deny_unknown_fields() && all_skipped { quote! { // FIXME: Once we drop support for Rust 1.15: // let _serde::export::None::<__Field> = try!(_serde::de::MapAccess::next_key(&mut __map)); @@ -1438,7 +1438,7 @@ fn deserialize_map( .filter(|&&(field, _)| !field.attrs.skip_deserializing()) .map( |&(field, ref name)| { - let missing_expr = Match(expr_is_missing(&field, item_attrs)); + let missing_expr = Match(expr_is_missing(&field, cattrs)); quote! { let #name = match #name { @@ -1458,7 +1458,7 @@ fn deserialize_map( .clone() .expect("struct contains unnamed fields"); if field.attrs.skip_deserializing() { - let value = Expr(expr_is_missing(&field, item_attrs)); + let value = Expr(expr_is_missing(&field, cattrs)); quote!(#ident: #value) } else { quote!(#ident: #name) @@ -1466,7 +1466,7 @@ fn deserialize_map( }, ); - let let_default = match *item_attrs.default() { + let let_default = match *cattrs.default() { attr::Default::Default => { Some( quote!( @@ -1548,7 +1548,7 @@ fn wrap_deserialize_with( (wrapper, wrapper_ty) } -fn expr_is_missing(field: &Field, item_attrs: &attr::Item) -> Fragment { +fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment { match *field.attrs.default() { attr::Default::Default => { return quote_expr!(_serde::export::Default::default()); @@ -1559,7 +1559,7 @@ fn expr_is_missing(field: &Field, item_attrs: &attr::Item) -> Fragment { attr::Default::None => { /* below */ } } - match *item_attrs.default() { + match *cattrs.default() { attr::Default::Default | attr::Default::Path(_) => { let ident = &field.ident; diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index d55da219..f7193f18 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -11,23 +11,23 @@ use quote::Tokens; use bound; use fragment::{Fragment, Stmts, Match}; -use internals::ast::{Body, Field, Item, Style, Variant}; +use internals::ast::{Body, Container, Field, Style, Variant}; use internals::{self, attr}; use std::u32; -pub fn expand_derive_serialize(item: &syn::DeriveInput) -> Result { +pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result { let ctxt = internals::Ctxt::new(); - let item = Item::from_ast(&ctxt, item); + let cont = Container::from_ast(&ctxt, input); try!(ctxt.check()); - let ident = &item.ident; - let params = Parameters::new(&item); + let ident = &cont.ident; + let params = Parameters::new(&cont); let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl(); let dummy_const = Ident::new(format!("_IMPL_SERIALIZE_FOR_{}", ident)); - let body = Stmts(serialize_body(&item, ¶ms)); + let body = Stmts(serialize_body(&cont, ¶ms)); - let impl_item = if let Some(remote) = item.attrs.remote() { + let impl_block = if let Some(remote) = cont.attrs.remote() { quote! { impl #impl_generics #ident #ty_generics #where_clause { fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error> @@ -55,7 +55,7 @@ pub fn expand_derive_serialize(item: &syn::DeriveInput) -> Result Self { - let is_remote = item.attrs.remote().is_some(); + fn new(cont: &Container) -> Self { + let is_remote = cont.attrs.remote().is_some(); let self_var = if is_remote { Ident::new("__self") } else { Ident::new("self") }; - let this = match item.attrs.remote() { + let this = match cont.attrs.remote() { Some(remote) => remote.clone(), - None => item.ident.clone().into(), + None => cont.ident.clone().into(), }; - let generics = build_generics(item); + let generics = build_generics(cont); Parameters { self_var: self_var, @@ -111,17 +111,17 @@ impl Parameters { // All the generics in the input, plus a bound `T: Serialize` for each generic // field type that will be serialized by us. -fn build_generics(item: &Item) -> syn::Generics { - let generics = bound::without_defaults(item.generics); +fn build_generics(cont: &Container) -> syn::Generics { + let generics = bound::without_defaults(cont.generics); let generics = - bound::with_where_predicates_from_fields(item, &generics, attr::Field::ser_bound); + bound::with_where_predicates_from_fields(cont, &generics, attr::Field::ser_bound); - match item.attrs.ser_bound() { + match cont.attrs.ser_bound() { Some(predicates) => bound::with_where_predicates(&generics, predicates), None => { bound::with_bound( - item, + cont, &generics, needs_serialize_bound, &path!(_serde::Serialize), @@ -138,28 +138,28 @@ fn needs_serialize_bound(attrs: &attr::Field) -> bool { !attrs.skip_serializing() && attrs.serialize_with().is_none() && attrs.ser_bound().is_none() } -fn serialize_body(item: &Item, params: &Parameters) -> Fragment { - if let Some(into_type) = item.attrs.into_type() { +fn serialize_body(cont: &Container, params: &Parameters) -> Fragment { + if let Some(into_type) = cont.attrs.into_type() { serialize_into(params, into_type) } else { - match item.body { - Body::Enum(ref variants) => serialize_item_enum(params, variants, &item.attrs), + match cont.body { + Body::Enum(ref variants) => serialize_enum(params, variants, &cont.attrs), Body::Struct(Style::Struct, ref fields) => { if fields.iter().any(|field| field.ident.is_none()) { panic!("struct has unnamed fields"); } - serialize_struct(params, fields, &item.attrs) + serialize_struct(params, fields, &cont.attrs) } Body::Struct(Style::Tuple, ref fields) => { if fields.iter().any(|field| field.ident.is_some()) { panic!("tuple struct has named fields"); } - serialize_tuple_struct(params, fields, &item.attrs) + serialize_tuple_struct(params, fields, &cont.attrs) } Body::Struct(Style::Newtype, ref fields) => { - serialize_newtype_struct(params, &fields[0], &item.attrs) + serialize_newtype_struct(params, &fields[0], &cont.attrs) } - Body::Struct(Style::Unit, _) => serialize_unit_struct(&item.attrs), + Body::Struct(Style::Unit, _) => serialize_unit_struct(&cont.attrs), } } } @@ -173,8 +173,8 @@ fn serialize_into(params: &Parameters, into_type: &syn::Ty) -> Fragment { } } -fn serialize_unit_struct(item_attrs: &attr::Item) -> Fragment { - let type_name = item_attrs.name().serialize_name(); +fn serialize_unit_struct(cattrs: &attr::Container) -> Fragment { + let type_name = cattrs.name().serialize_name(); quote_expr! { _serde::Serializer::serialize_unit_struct(__serializer, #type_name) @@ -184,9 +184,9 @@ fn serialize_unit_struct(item_attrs: &attr::Item) -> Fragment { fn serialize_newtype_struct( params: &Parameters, field: &Field, - item_attrs: &attr::Item, + cattrs: &attr::Container, ) -> Fragment { - let type_name = item_attrs.name().serialize_name(); + let type_name = cattrs.name().serialize_name(); let mut field_expr = get_field(params, field, 0); if let Some(path) = field.attrs.serialize_with() { @@ -201,7 +201,7 @@ fn serialize_newtype_struct( fn serialize_tuple_struct( params: &Parameters, fields: &[Field], - item_attrs: &attr::Item, + cattrs: &attr::Container, ) -> Fragment { let serialize_stmts = serialize_tuple_struct_visitor( fields, @@ -210,7 +210,7 @@ fn serialize_tuple_struct( quote!(_serde::ser::SerializeTupleStruct::serialize_field), ); - let type_name = item_attrs.name().serialize_name(); + let type_name = cattrs.name().serialize_name(); let len = serialize_stmts.len(); let let_mut = mut_if(len > 0); @@ -221,7 +221,7 @@ fn serialize_tuple_struct( } } -fn serialize_struct(params: &Parameters, fields: &[Field], item_attrs: &attr::Item) -> Fragment { +fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Container) -> Fragment { assert!(fields.len() as u64 <= u32::MAX as u64); let serialize_fields = serialize_struct_visitor( @@ -231,7 +231,7 @@ fn serialize_struct(params: &Parameters, fields: &[Field], item_attrs: &attr::It quote!(_serde::ser::SerializeStruct::serialize_field), ); - let type_name = item_attrs.name().serialize_name(); + let type_name = cattrs.name().serialize_name(); let mut serialized_fields = fields .iter() @@ -260,10 +260,10 @@ fn serialize_struct(params: &Parameters, fields: &[Field], item_attrs: &attr::It } } -fn serialize_item_enum( +fn serialize_enum( params: &Parameters, variants: &[Variant], - item_attrs: &attr::Item, + cattrs: &attr::Container, ) -> Fragment { assert!(variants.len() as u64 <= u32::MAX as u64); @@ -274,7 +274,7 @@ fn serialize_item_enum( .enumerate() .map( |(variant_index, variant)| { - serialize_variant(params, variant, variant_index as u32, item_attrs) + serialize_variant(params, variant, variant_index as u32, cattrs) }, ) .collect(); @@ -290,7 +290,7 @@ fn serialize_variant( params: &Parameters, variant: &Variant, variant_index: u32, - item_attrs: &attr::Item, + cattrs: &attr::Container, ) -> Tokens { let this = ¶ms.this; let variant_ident = variant.ident.clone(); @@ -356,18 +356,18 @@ fn serialize_variant( }; let body = Match( - match *item_attrs.tag() { + match *cattrs.tag() { attr::EnumTag::External => { - serialize_externally_tagged_variant(params, variant, variant_index, item_attrs) + serialize_externally_tagged_variant(params, variant, variant_index, cattrs) } attr::EnumTag::Internal { ref tag } => { - serialize_internally_tagged_variant(params, variant, item_attrs, tag) + serialize_internally_tagged_variant(params, variant, cattrs, tag) } attr::EnumTag::Adjacent { ref tag, ref content, - } => serialize_adjacently_tagged_variant(params, variant, item_attrs, tag, content), - attr::EnumTag::None => serialize_untagged_variant(params, variant, item_attrs), + } => serialize_adjacently_tagged_variant(params, variant, cattrs, tag, content), + attr::EnumTag::None => serialize_untagged_variant(params, variant, cattrs), }, ); @@ -381,9 +381,9 @@ fn serialize_externally_tagged_variant( params: &Parameters, variant: &Variant, variant_index: u32, - item_attrs: &attr::Item, + cattrs: &attr::Container, ) -> Fragment { - let type_name = item_attrs.name().serialize_name(); + let type_name = cattrs.name().serialize_name(); let variant_name = variant.attrs.name().serialize_name(); match variant.style { @@ -442,10 +442,10 @@ fn serialize_externally_tagged_variant( fn serialize_internally_tagged_variant( params: &Parameters, variant: &Variant, - item_attrs: &attr::Item, + cattrs: &attr::Container, tag: &str, ) -> Fragment { - let type_name = item_attrs.name().serialize_name(); + let type_name = cattrs.name().serialize_name(); let variant_name = variant.attrs.name().serialize_name(); let enum_ident_str = params.type_name(); @@ -497,12 +497,12 @@ fn serialize_internally_tagged_variant( fn serialize_adjacently_tagged_variant( params: &Parameters, variant: &Variant, - item_attrs: &attr::Item, + cattrs: &attr::Container, tag: &str, content: &str, ) -> Fragment { let this = ¶ms.this; - let type_name = item_attrs.name().serialize_name(); + let type_name = cattrs.name().serialize_name(); let variant_name = variant.attrs.name().serialize_name(); let inner = Stmts( @@ -601,7 +601,7 @@ fn serialize_adjacently_tagged_variant( fn serialize_untagged_variant( params: &Parameters, variant: &Variant, - item_attrs: &attr::Item, + cattrs: &attr::Container, ) -> Fragment { match variant.style { Style::Unit => { @@ -622,7 +622,7 @@ fn serialize_untagged_variant( } Style::Tuple => serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields), Style::Struct => { - let type_name = item_attrs.name().serialize_name(); + let type_name = cattrs.name().serialize_name(); serialize_struct_variant(StructVariant::Untagged, params, &variant.fields, &type_name) } } diff --git a/serde_derive_internals/src/ast.rs b/serde_derive_internals/src/ast.rs index 062281d9..c34b0e3f 100644 --- a/serde_derive_internals/src/ast.rs +++ b/serde_derive_internals/src/ast.rs @@ -11,9 +11,9 @@ use attr; use check; use Ctxt; -pub struct Item<'a> { +pub struct Container<'a> { pub ident: syn::Ident, - pub attrs: attr::Item, + pub attrs: attr::Container, pub body: Body<'a>, pub generics: &'a syn::Generics, } @@ -43,9 +43,9 @@ pub enum Style { Unit, } -impl<'a> Item<'a> { - pub fn from_ast(cx: &Ctxt, item: &'a syn::MacroInput) -> Item<'a> { - let attrs = attr::Item::from_ast(cx, item); +impl<'a> Container<'a> { + pub fn from_ast(cx: &Ctxt, item: &'a syn::MacroInput) -> Container<'a> { + let attrs = attr::Container::from_ast(cx, item); let mut body = match item.body { syn::Body::Enum(ref variants) => Body::Enum(enum_from_ast(cx, variants)), @@ -71,7 +71,7 @@ impl<'a> Item<'a> { } } - let item = Item { + let item = Container { ident: item.ident.clone(), attrs: attrs, body: body, diff --git a/serde_derive_internals/src/attr.rs b/serde_derive_internals/src/attr.rs index 5e3c0dc1..4f08e1b5 100644 --- a/serde_derive_internals/src/attr.rs +++ b/serde_derive_internals/src/attr.rs @@ -15,7 +15,7 @@ use std::collections::BTreeSet; use std::str::FromStr; // This module handles parsing of `#[serde(...)]` attributes. The entrypoints -// are `attr::Item::from_ast`, `attr::Variant::from_ast`, and +// are `attr::Container::from_ast`, `attr::Variant::from_ast`, and // `attr::Field::from_ast`. Each returns an instance of the corresponding // struct. Note that none of them return a Result. Unrecognized, malformed, or // duplicated attributes result in a span_err but otherwise are ignored. The @@ -100,7 +100,7 @@ impl Name { /// Represents container (e.g. struct) attribute information #[derive(Debug)] -pub struct Item { +pub struct Container { name: Name, deny_unknown_fields: bool, default: Default, @@ -145,7 +145,7 @@ pub enum EnumTag { None, } -impl Item { +impl Container { /// Extract out the `#[serde(...)]` attributes from an item. pub fn from_ast(cx: &Ctxt, item: &syn::MacroInput) -> Self { let mut ser_name = Attr::none(cx, "rename"); @@ -365,7 +365,7 @@ impl Item { } }; - Item { + Container { name: Name { serialize: ser_name.get().unwrap_or_else(|| item.ident.to_string()), deserialize: de_name.get().unwrap_or_else(|| item.ident.to_string()), diff --git a/serde_derive_internals/src/check.rs b/serde_derive_internals/src/check.rs index 4ac274e1..941b2d4a 100644 --- a/serde_derive_internals/src/check.rs +++ b/serde_derive_internals/src/check.rs @@ -6,12 +6,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast::{Body, Item}; +use ast::{Body, Container}; use Ctxt; /// Cross-cutting checks that require looking at more than a single attrs /// object. Simpler checks should happen when parsing and building the attrs. -pub fn check(cx: &Ctxt, item: &Item) { +pub fn check(cx: &Ctxt, item: &Container) { match item.body { Body::Enum(_) => { if item.body.has_getter() { From a35bde49c6409b05136f5f2383ac836c1ffb665d Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 16:14:03 -0700 Subject: [PATCH 164/177] Factor out logic to decide the tag style --- serde_derive_internals/src/attr.rs | 102 ++++++++++++++++------------- 1 file changed, 55 insertions(+), 47 deletions(-) diff --git a/serde_derive_internals/src/attr.rs b/serde_derive_internals/src/attr.rs index 4f08e1b5..1af148d0 100644 --- a/serde_derive_internals/src/attr.rs +++ b/serde_derive_internals/src/attr.rs @@ -319,52 +319,6 @@ impl Container { } } - let tag = match (untagged.get(), internal_tag.get(), content.get()) { - (false, None, None) => EnumTag::External, - (true, None, None) => EnumTag::None, - (false, Some(tag), None) => { - // Check that there are no tuple variants. - if let syn::Body::Enum(ref variants) = item.body { - for variant in variants { - match variant.data { - syn::VariantData::Struct(_) | - syn::VariantData::Unit => {} - syn::VariantData::Tuple(ref fields) => { - if fields.len() != 1 { - cx.error("#[serde(tag = \"...\")] cannot be used with tuple \ - variants"); - break; - } - } - } - } - } - EnumTag::Internal { tag: tag } - } - (true, Some(_), None) => { - cx.error("enum cannot be both untagged and internally tagged"); - EnumTag::External // doesn't matter, will error - } - (false, None, Some(_)) => { - cx.error("#[serde(tag = \"...\", content = \"...\")] must be used together"); - EnumTag::External - } - (true, None, Some(_)) => { - cx.error("untagged enum cannot have #[serde(content = \"...\")]"); - EnumTag::External - } - (false, Some(tag), Some(content)) => { - EnumTag::Adjacent { - tag: tag, - content: content, - } - } - (true, Some(_), Some(_)) => { - cx.error("untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]"); - EnumTag::External - } - }; - Container { name: Name { serialize: ser_name.get().unwrap_or_else(|| item.ident.to_string()), @@ -375,7 +329,7 @@ impl Container { rename_all: rename_all.get().unwrap_or(RenameRule::None), ser_bound: ser_bound.get(), de_bound: de_bound.get(), - tag: tag, + tag: decide_tag(cx, item, untagged, internal_tag, content), from_type: from_type.get(), into_type: into_type.get(), remote: remote.get(), @@ -423,6 +377,60 @@ impl Container { } } +fn decide_tag( + cx: &Ctxt, + item: &syn::MacroInput, + untagged: BoolAttr, + internal_tag: Attr, + content: Attr, +) -> EnumTag { + match (untagged.get(), internal_tag.get(), content.get()) { + (false, None, None) => EnumTag::External, + (true, None, None) => EnumTag::None, + (false, Some(tag), None) => { + // Check that there are no tuple variants. + if let syn::Body::Enum(ref variants) = item.body { + for variant in variants { + match variant.data { + syn::VariantData::Struct(_) | + syn::VariantData::Unit => {} + syn::VariantData::Tuple(ref fields) => { + if fields.len() != 1 { + cx.error("#[serde(tag = \"...\")] cannot be used with tuple \ + variants"); + break; + } + } + } + } + } + EnumTag::Internal { tag: tag } + } + (true, Some(_), None) => { + cx.error("enum cannot be both untagged and internally tagged"); + EnumTag::External // doesn't matter, will error + } + (false, None, Some(_)) => { + cx.error("#[serde(tag = \"...\", content = \"...\")] must be used together"); + EnumTag::External + } + (true, None, Some(_)) => { + cx.error("untagged enum cannot have #[serde(content = \"...\")]"); + EnumTag::External + } + (false, Some(tag), Some(content)) => { + EnumTag::Adjacent { + tag: tag, + content: content, + } + } + (true, Some(_), Some(_)) => { + cx.error("untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]"); + EnumTag::External + } + } +} + /// Represents variant attribute information #[derive(Debug)] pub struct Variant { From 30e8c84d0102957f77eab058033f5a81eb073815 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 20:54:53 -0700 Subject: [PATCH 165/177] Allow borrowing from str's IntoDeserializer --- serde/src/de/value.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 8cf9e028..ec311be8 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -290,7 +290,7 @@ pub struct StrDeserializer<'a, E> { marker: PhantomData, } -impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a str +impl<'a, E> IntoDeserializer<'a, E> for &'a str where E: de::Error, { @@ -304,7 +304,7 @@ where } } -impl<'de, 'a, E> de::Deserializer<'de> for StrDeserializer<'a, E> +impl<'de, E> de::Deserializer<'de> for StrDeserializer<'de, E> where E: de::Error, { @@ -314,7 +314,7 @@ where where V: de::Visitor<'de>, { - visitor.visit_str(self.value) + visitor.visit_borrowed_str(self.value) } fn deserialize_enum( @@ -338,7 +338,7 @@ where } } -impl<'de, 'a, E> de::EnumAccess<'de> for StrDeserializer<'a, E> +impl<'de, E> de::EnumAccess<'de> for StrDeserializer<'de, E> where E: de::Error, { From cdfd4455288930ff5cc43033b9d8795758f49563 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 16:09:00 -0700 Subject: [PATCH 166/177] Generate deserialize impls for identifiers --- serde/src/private/de.rs | 109 ++++++- serde_derive/src/de.rs | 303 ++++++++++++------ serde_derive/src/ser.rs | 17 +- serde_derive_internals/src/ast.rs | 1 + serde_derive_internals/src/attr.rs | 73 +++++ serde_derive_internals/src/check.rs | 75 ++++- .../tests/compile-fail/identifier/both.rs | 19 ++ .../compile-fail/identifier/field_struct.rs | 16 + .../compile-fail/identifier/field_tuple.rs | 19 ++ .../identifier/newtype_not_last.rs | 20 ++ .../compile-fail/identifier/not_identifier.rs | 19 ++ .../tests/compile-fail/identifier/not_unit.rs | 20 ++ .../compile-fail/identifier/other_not_last.rs | 21 ++ .../compile-fail/identifier/serialize.rs | 19 ++ .../compile-fail/identifier/variant_struct.rs | 16 + .../compile-fail/identifier/variant_tuple.rs | 19 ++ test_suite/tests/test_identifier.rs | 82 +++++ 17 files changed, 745 insertions(+), 103 deletions(-) create mode 100644 test_suite/tests/compile-fail/identifier/both.rs create mode 100644 test_suite/tests/compile-fail/identifier/field_struct.rs create mode 100644 test_suite/tests/compile-fail/identifier/field_tuple.rs create mode 100644 test_suite/tests/compile-fail/identifier/newtype_not_last.rs create mode 100644 test_suite/tests/compile-fail/identifier/not_identifier.rs create mode 100644 test_suite/tests/compile-fail/identifier/not_unit.rs create mode 100644 test_suite/tests/compile-fail/identifier/other_not_last.rs create mode 100644 test_suite/tests/compile-fail/identifier/serialize.rs create mode 100644 test_suite/tests/compile-fail/identifier/variant_struct.rs create mode 100644 test_suite/tests/compile-fail/identifier/variant_tuple.rs create mode 100644 test_suite/tests/test_identifier.rs diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 33aecb4e..61bbf566 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -8,7 +8,7 @@ use lib::*; -use de::{Deserialize, Deserializer, Error, Visitor}; +use de::{Deserialize, Deserializer, IntoDeserializer, Error, Visitor}; #[cfg(any(feature = "std", feature = "collections"))] use de::Unexpected; @@ -1740,3 +1740,110 @@ mod content { } } } + +//////////////////////////////////////////////////////////////////////////////// + +// Like `IntoDeserializer` but also implemented for `&[u8]`. This is used for +// the newtype fallthrough case of `field_identifier`. +// +// #[derive(Deserialize)] +// #[serde(field_identifier)] +// enum F { +// A, +// B, +// Other(String), // deserialized using IdentifierDeserializer +// } +pub trait IdentifierDeserializer<'de, E: Error> { + type Deserializer: Deserializer<'de, Error = E>; + + fn from(self) -> Self::Deserializer; +} + +impl<'de, E> IdentifierDeserializer<'de, E> for u32 +where + E: Error, +{ + type Deserializer = >::Deserializer; + + fn from(self) -> Self::Deserializer { + self.into_deserializer() + } +} + +pub struct StrDeserializer<'a, E> { + value: &'a str, + marker: PhantomData, +} + +impl<'a, E> IdentifierDeserializer<'a, E> for &'a str +where + E: Error, +{ + type Deserializer = StrDeserializer<'a, E>; + + fn from(self) -> Self::Deserializer { + StrDeserializer { + value: self, + marker: PhantomData, + } + } +} + +impl<'de, 'a, E> Deserializer<'de> for StrDeserializer<'a, E> +where + E: Error, +{ + type Error = E; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_str(self.value) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf option unit unit_struct newtype_struct seq seq_fixed_size + tuple tuple_struct map struct identifier enum ignored_any + } +} + +pub struct BytesDeserializer<'a, E> { + value: &'a [u8], + marker: PhantomData, +} + +impl<'a, E> IdentifierDeserializer<'a, E> for &'a [u8] +where + E: Error, +{ + type Deserializer = BytesDeserializer<'a, E>; + + fn from(self) -> Self::Deserializer { + BytesDeserializer { + value: self, + marker: PhantomData, + } + } +} + +impl<'de, 'a, E> Deserializer<'de> for BytesDeserializer<'a, E> +where + E: Error, +{ + type Error = E; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_bytes(self.value) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes + byte_buf option unit unit_struct newtype_struct seq seq_fixed_size + tuple tuple_struct map struct identifier enum ignored_any + } +} diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index e9526494..79304878 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -186,7 +186,7 @@ fn borrowed_lifetimes(cont: &Container) -> BTreeSet { fn deserialize_body(cont: &Container, params: &Parameters) -> Fragment { if let Some(from_type) = cont.attrs.from_type() { deserialize_from(from_type) - } else { + } else if let attr::Identifier::No = cont.attrs.identifier() { match cont.body { Body::Enum(ref variants) => deserialize_enum(params, variants, &cont.attrs), Body::Struct(Style::Struct, ref fields) => { @@ -204,6 +204,13 @@ fn deserialize_body(cont: &Container, params: &Parameters) -> Fragment { } Body::Struct(Style::Unit, _) => deserialize_unit_struct(params, &cont.attrs), } + } else { + match cont.body { + Body::Enum(ref variants) => { + deserialize_custom_identifier(params, variants, &cont.attrs) + } + Body::Struct(_, _) => unreachable!("checked in serde_derive_internals"), + } } } @@ -608,7 +615,7 @@ fn deserialize_externally_tagged_enum( } }; - let variant_visitor = Stmts(deserialize_field_visitor(variant_names_idents, cattrs, true),); + let variant_visitor = Stmts(deserialize_generated_identifier(variant_names_idents, cattrs, true),); // Match arms to extract a variant from a string let variant_arms = @@ -703,7 +710,7 @@ fn deserialize_internally_tagged_enum( } }; - let variant_visitor = Stmts(deserialize_field_visitor(variant_names_idents, cattrs, true),); + let variant_visitor = Stmts(deserialize_generated_identifier(variant_names_idents, cattrs, true),); // Match arms to extract a variant from a string let variant_arms = variants.iter() @@ -763,7 +770,7 @@ fn deserialize_adjacently_tagged_enum( } }; - let variant_visitor = Stmts(deserialize_field_visitor(variant_names_idents, cattrs, true),); + let variant_visitor = Stmts(deserialize_generated_identifier(variant_names_idents, cattrs, true),); let ref variant_arms: Vec<_> = variants .iter() @@ -1200,67 +1207,23 @@ fn deserialize_untagged_newtype_variant( } } -fn deserialize_field_visitor( +fn deserialize_generated_identifier( fields: Vec<(String, Ident)>, cattrs: &attr::Container, is_variant: bool, ) -> Fragment { - let field_strs = fields.iter().map(|&(ref name, _)| name); - let field_bytes = fields.iter().map(|&(ref name, _)| quote::ByteStr(name)); + let this = quote!(__Field); let field_idents: &Vec<_> = &fields.iter().map(|&(_, ref ident)| ident).collect(); - let ignore_variant = if is_variant || cattrs.deny_unknown_fields() { - None + let (ignore_variant, fallthrough) = if is_variant || cattrs.deny_unknown_fields() { + (None, None) } else { - Some(quote!(__ignore,)) + let ignore_variant = quote!(__ignore,); + let fallthrough = quote!(_serde::export::Ok(__Field::__ignore)); + (Some(ignore_variant), Some(fallthrough)) }; - let visit_index = if is_variant { - let variant_indices = 0u32..; - let fallthrough_msg = format!("variant index 0 <= i < {}", fields.len()); - Some( - quote! { - fn visit_u32<__E>(self, __value: u32) -> _serde::export::Result<__Field, __E> - where __E: _serde::de::Error - { - match __value { - #( - #variant_indices => _serde::export::Ok(__Field::#field_idents), - )* - _ => _serde::export::Err(_serde::de::Error::invalid_value( - _serde::de::Unexpected::Unsigned(__value as u64), - &#fallthrough_msg)) - } - } - }, - ) - } else { - None - }; - - let fallthrough_arm = if is_variant { - quote! { - _serde::export::Err(_serde::de::Error::unknown_variant(__value, VARIANTS)) - } - } else if cattrs.deny_unknown_fields() { - quote! { - _serde::export::Err(_serde::de::Error::unknown_field(__value, FIELDS)) - } - } else { - quote! { - _serde::export::Ok(__Field::__ignore) - } - }; - - let bytes_to_str = if is_variant || cattrs.deny_unknown_fields() { - Some( - quote! { - let __value = &_serde::export::from_utf8_lossy(__value); - }, - ) - } else { - None - }; + let visitor_impl = Stmts(deserialize_identifier(this, &fields, is_variant, fallthrough)); quote_block! { #[allow(non_camel_case_types)] @@ -1269,54 +1232,204 @@ fn deserialize_field_visitor( #ignore_variant } + struct __FieldVisitor; + + impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { + type Value = __Field; + + #visitor_impl + } + impl<'de> _serde::Deserialize<'de> for __Field { #[inline] - fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<__Field, __D::Error> + fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result where __D: _serde::Deserializer<'de> { - struct __FieldVisitor; - - impl<'de> _serde::de::Visitor<'de> for __FieldVisitor { - type Value = __Field; - - fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result { - _serde::export::Formatter::write_str(formatter, "field name") - } - - #visit_index - - fn visit_str<__E>(self, __value: &str) -> _serde::export::Result<__Field, __E> - where __E: _serde::de::Error - { - match __value { - #( - #field_strs => _serde::export::Ok(__Field::#field_idents), - )* - _ => #fallthrough_arm - } - } - - fn visit_bytes<__E>(self, __value: &[u8]) -> _serde::export::Result<__Field, __E> - where __E: _serde::de::Error - { - match __value { - #( - #field_bytes => _serde::export::Ok(__Field::#field_idents), - )* - _ => { - #bytes_to_str - #fallthrough_arm - } - } - } - } - _serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor) } } } } +fn deserialize_custom_identifier( + params: &Parameters, + variants: &[Variant], + cattrs: &attr::Container, +) -> Fragment { + let is_variant = match cattrs.identifier() { + attr::Identifier::Variant => true, + attr::Identifier::Field => false, + attr::Identifier::No => unreachable!(), + }; + + let this = ¶ms.this; + let this = quote!(#this); + + let (ordinary, fallthrough) = if let Some(last) = variants.last() { + let last_ident = &last.ident; + if last.attrs.other() { + let ordinary = &variants[..variants.len() - 1]; + let fallthrough = quote!(_serde::export::Ok(#this::#last_ident)); + (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 fallthrough = quote! { + _serde::export::Result::map( + _serde::Deserialize::deserialize(#deserializer), + #this::#last_ident) + }; + (ordinary, Some(fallthrough)) + } else { + (variants, None) + } + } else { + (variants, None) + }; + + let names_idents: Vec<_> = ordinary + .iter() + .map(|variant| (variant.attrs.name().deserialize_name(), variant.ident.clone())) + .collect(); + + let names = names_idents.iter().map(|&(ref name, _)| name); + + let names_const = if fallthrough.is_some() { + None + } else if is_variant { + let variants = quote! { + const VARIANTS: &'static [&'static str] = &[ #(#names),* ]; + }; + Some(variants) + } else { + let fields = quote! { + const FIELDS: &'static [&'static str] = &[ #(#names),* ]; + }; + Some(fields) + }; + + let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params); + let visitor_impl = Stmts(deserialize_identifier(this.clone(), &names_idents, is_variant, fallthrough)); + + quote_block! { + #names_const + + struct __FieldVisitor #de_impl_generics #where_clause { + marker: _serde::export::PhantomData<#this #ty_generics>, + lifetime: _serde::export::PhantomData<&'de ()>, + } + + impl #de_impl_generics _serde::de::Visitor<'de> for __FieldVisitor #de_ty_generics #where_clause { + type Value = #this #ty_generics; + + #visitor_impl + } + + let __visitor = __FieldVisitor { + marker: _serde::export::PhantomData::<#this #ty_generics>, + lifetime: _serde::export::PhantomData, + }; + _serde::Deserializer::deserialize_identifier(__deserializer, __visitor) + } +} + +fn deserialize_identifier( + this: Tokens, + fields: &[(String, Ident)], + is_variant: bool, + fallthrough: Option, +) -> Fragment { + let field_strs = fields.iter().map(|&(ref name, _)| name); + let field_bytes = fields.iter().map(|&(ref name, _)| quote::ByteStr(name)); + + let constructors: &Vec<_> = &fields + .iter() + .map(|&(_, ref ident)| quote!(#this::#ident)) + .collect(); + + let expecting = if is_variant { + "variant identifier" + } else { + "field identifier" + }; + + let visit_index = if is_variant { + let variant_indices = 0u32..; + let fallthrough_msg = format!("variant index 0 <= i < {}", fields.len()); + let visit_index = quote! { + fn visit_u32<__E>(self, __value: u32) -> _serde::export::Result + where __E: _serde::de::Error + { + match __value { + #( + #variant_indices => _serde::export::Ok(#constructors), + )* + _ => _serde::export::Err(_serde::de::Error::invalid_value( + _serde::de::Unexpected::Unsigned(__value as u64), + &#fallthrough_msg)) + } + } + }; + Some(visit_index) + } else { + None + }; + + let bytes_to_str = if fallthrough.is_some() { + None + } else { + let conversion = quote! { + let __value = &_serde::export::from_utf8_lossy(__value); + }; + Some(conversion) + }; + + let fallthrough_arm = if let Some(fallthrough) = fallthrough { + fallthrough + } else if is_variant { + quote! { + _serde::export::Err(_serde::de::Error::unknown_variant(__value, VARIANTS)) + } + } else { + quote! { + _serde::export::Err(_serde::de::Error::unknown_field(__value, FIELDS)) + } + }; + + quote_block! { + fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result { + _serde::export::Formatter::write_str(formatter, #expecting) + } + + #visit_index + + fn visit_str<__E>(self, __value: &str) -> _serde::export::Result + where __E: _serde::de::Error + { + match __value { + #( + #field_strs => _serde::export::Ok(#constructors), + )* + _ => #fallthrough_arm + } + } + + fn visit_bytes<__E>(self, __value: &[u8]) -> _serde::export::Result + where __E: _serde::de::Error + { + match __value { + #( + #field_bytes => _serde::export::Ok(#constructors), + )* + _ => { + #bytes_to_str + #fallthrough_arm + } + } + } + } +} + fn deserialize_struct_visitor( struct_path: Tokens, params: &Parameters, @@ -1337,7 +1450,7 @@ fn deserialize_struct_visitor( } }; - let field_visitor = deserialize_field_visitor(field_names_idents, cattrs, false); + let field_visitor = deserialize_generated_identifier(field_names_idents, cattrs, false); let visit_map = deserialize_map(struct_path, params, fields, cattrs); diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index f7193f18..087702a3 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -12,13 +12,14 @@ use quote::Tokens; use bound; use fragment::{Fragment, Stmts, Match}; use internals::ast::{Body, Container, Field, Style, Variant}; -use internals::{self, attr}; +use internals::{attr, Ctxt}; use std::u32; pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result { - let ctxt = internals::Ctxt::new(); + let ctxt = Ctxt::new(); let cont = Container::from_ast(&ctxt, input); + precondition(&ctxt, &cont); try!(ctxt.check()); let ident = &cont.ident; @@ -61,6 +62,18 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result {} + attr::Identifier::Field => { + cx.error("field identifiers cannot be serialized"); + } + attr::Identifier::Variant => { + cx.error("variant identifiers cannot be serialized"); + } + } +} + struct Parameters { /// Variable holding the value being serialized. Either `self` for local /// types or `__self` for remote types. diff --git a/serde_derive_internals/src/ast.rs b/serde_derive_internals/src/ast.rs index c34b0e3f..7882334c 100644 --- a/serde_derive_internals/src/ast.rs +++ b/serde_derive_internals/src/ast.rs @@ -36,6 +36,7 @@ pub struct Field<'a> { pub ty: &'a syn::Ty, } +#[derive(Copy, Clone)] pub enum Style { Struct, Tuple, diff --git a/serde_derive_internals/src/attr.rs b/serde_derive_internals/src/attr.rs index 1af148d0..fd43527b 100644 --- a/serde_derive_internals/src/attr.rs +++ b/serde_derive_internals/src/attr.rs @@ -111,6 +111,7 @@ pub struct Container { from_type: Option, into_type: Option, remote: Option, + identifier: Identifier, } /// Styles of representing an enum. @@ -145,6 +146,23 @@ pub enum EnumTag { None, } +/// Whether this enum represents the fields of a struct or the variants of an +/// enum. +#[derive(Copy, Clone, Debug)] +pub enum Identifier { + /// It does not. + No, + + /// This enum represents the fields of a struct. All of the variants must be + /// unit variants, except possibly one which is annotated with + /// `#[serde(other)]` and is a newtype variant. + Field, + + /// This enum represents the variants of an enum. All of the variants must + /// be unit variants. + Variant, +} + impl Container { /// Extract out the `#[serde(...)]` attributes from an item. pub fn from_ast(cx: &Ctxt, item: &syn::MacroInput) -> Self { @@ -161,6 +179,8 @@ impl Container { let mut from_type = Attr::none(cx, "from"); let mut into_type = Attr::none(cx, "into"); let mut remote = Attr::none(cx, "remote"); + let mut field_identifier = BoolAttr::none(cx, "field_identifier"); + let mut variant_identifier = BoolAttr::none(cx, "variant_identifier"); for meta_items in item.attrs.iter().filter_map(get_serde_meta_items) { for meta_item in meta_items { @@ -307,6 +327,16 @@ impl Container { } } + // Parse `#[serde(field_identifier)]` + MetaItem(Word(ref name)) if name == "field_identifier" => { + field_identifier.set_true(); + } + + // Parse `#[serde(variant_identifier)]` + MetaItem(Word(ref name)) if name == "variant_identifier" => { + variant_identifier.set_true(); + } + MetaItem(ref meta_item) => { cx.error(format!("unknown serde container attribute `{}`", meta_item.name())); @@ -333,6 +363,7 @@ impl Container { from_type: from_type.get(), into_type: into_type.get(), remote: remote.get(), + identifier: decide_identifier(cx, item, field_identifier, variant_identifier), } } @@ -375,6 +406,10 @@ impl Container { pub fn remote(&self) -> Option<&syn::Path> { self.remote.as_ref() } + + pub fn identifier(&self) -> Identifier { + self.identifier + } } fn decide_tag( @@ -431,6 +466,31 @@ fn decide_tag( } } +fn decide_identifier( + cx: &Ctxt, + item: &syn::MacroInput, + field_identifier: BoolAttr, + variant_identifier: BoolAttr, +) -> Identifier { + match (&item.body, field_identifier.get(), variant_identifier.get()) { + (_, false, false) => Identifier::No, + (_, true, true) => { + cx.error("`field_identifier` and `variant_identifier` cannot both be set"); + Identifier::No + } + (&syn::Body::Struct(_), true, false) => { + cx.error("`field_identifier` can only be used on an enum"); + Identifier::No + } + (&syn::Body::Struct(_), false, true) => { + cx.error("`variant_identifier` can only be used on an enum"); + Identifier::No + } + (&syn::Body::Enum(_), true, false) => Identifier::Field, + (&syn::Body::Enum(_), false, true) => Identifier::Variant, + } +} + /// Represents variant attribute information #[derive(Debug)] pub struct Variant { @@ -440,6 +500,7 @@ pub struct Variant { rename_all: RenameRule, skip_deserializing: bool, skip_serializing: bool, + other: bool, } impl Variant { @@ -449,6 +510,7 @@ impl Variant { let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing"); let mut skip_serializing = BoolAttr::none(cx, "skip_serializing"); let mut rename_all = Attr::none(cx, "rename_all"); + let mut other = BoolAttr::none(cx, "other"); for meta_items in variant.attrs.iter().filter_map(get_serde_meta_items) { for meta_item in meta_items { @@ -487,11 +549,17 @@ impl Variant { MetaItem(Word(ref name)) if name == "skip_deserializing" => { skip_deserializing.set_true(); } + // Parse `#[serde(skip_serializing)]` MetaItem(Word(ref name)) if name == "skip_serializing" => { skip_serializing.set_true(); } + // Parse `#[serde(other)]` + MetaItem(Word(ref name)) if name == "other" => { + other.set_true(); + } + MetaItem(ref meta_item) => { cx.error(format!("unknown serde variant attribute `{}`", meta_item.name())); } @@ -517,6 +585,7 @@ impl Variant { rename_all: rename_all.get().unwrap_or(RenameRule::None), skip_deserializing: skip_deserializing.get(), skip_serializing: skip_serializing.get(), + other: other.get(), } } @@ -544,6 +613,10 @@ impl Variant { pub fn skip_serializing(&self) -> bool { self.skip_serializing } + + pub fn other(&self) -> bool { + self.other + } } /// Represents field attribute information diff --git a/serde_derive_internals/src/check.rs b/serde_derive_internals/src/check.rs index 941b2d4a..5a58fbaa 100644 --- a/serde_derive_internals/src/check.rs +++ b/serde_derive_internals/src/check.rs @@ -6,23 +6,88 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast::{Body, Container}; +use ast::{Body, Container, Style}; +use attr::Identifier; use Ctxt; /// Cross-cutting checks that require looking at more than a single attrs /// object. Simpler checks should happen when parsing and building the attrs. -pub fn check(cx: &Ctxt, item: &Container) { - match item.body { +pub fn check(cx: &Ctxt, cont: &Container) { + check_getter(cx, cont); + check_identifier(cx, cont); +} + +/// Getters are only allowed inside structs (not enums) with the `remote` +/// attribute. +fn check_getter(cx: &Ctxt, cont: &Container) { + match cont.body { Body::Enum(_) => { - if item.body.has_getter() { + if cont.body.has_getter() { cx.error("#[serde(getter = \"...\")] is not allowed in an enum"); } } Body::Struct(_, _) => { - if item.body.has_getter() && item.attrs.remote().is_none() { + if cont.body.has_getter() && cont.attrs.remote().is_none() { cx.error("#[serde(getter = \"...\")] can only be used in structs \ that have #[serde(remote = \"...\")]"); } } } } + +/// The `other` attribute must be used at most once and it must be the last +/// variant of an enum that has the `field_identifier` attribute. +/// +/// Inside a `variant_identifier` all variants must be unit variants. Inside a +/// `field_identifier` all but possibly one variant must be unit variants. The +/// last variant may be a newtype variant which is an implicit "other" case. +fn check_identifier(cx: &Ctxt, cont: &Container) { + let variants = match cont.body { + Body::Enum(ref variants) => variants, + Body::Struct(_, _) => { + return; + } + }; + + for (i, variant) in variants.iter().enumerate() { + match (variant.style, cont.attrs.identifier(), variant.attrs.other()) { + // The `other` attribute may only be used in a field_identifier. + (_, Identifier::Variant, true) | (_, Identifier::No, true) => { + cx.error("#[serde(other)] may only be used inside a field_identifier"); + } + + // Variant with `other` attribute must be the last one. + (Style::Unit, Identifier::Field, true) => { + if i < variants.len() - 1 { + cx.error("#[serde(other)] must be the last variant"); + } + } + + // Variant with `other` attribute must be a unit variant. + (_, Identifier::Field, true) => { + cx.error("#[serde(other)] must be on a unit variant"); + } + + // Any sort of variant is allowed if this is not an identifier. + (_, Identifier::No, false) => {} + + // Unit variant without `other` attribute is always fine. + (Style::Unit, _, false) => {} + + // The last field is allowed to be a newtype catch-all. + (Style::Newtype, Identifier::Field, false) => { + if i < variants.len() - 1 { + cx.error(format!("`{}` must be the last variant", variant.ident)); + } + } + + (_, Identifier::Field, false) => { + cx.error("field_identifier may only contain unit variants"); + } + + (_, Identifier::Variant, false) => { + cx.error("variant_identifier may only contain unit variants"); + } + } + } +} diff --git a/test_suite/tests/compile-fail/identifier/both.rs b/test_suite/tests/compile-fail/identifier/both.rs new file mode 100644 index 00000000..13a8d917 --- /dev/null +++ b/test_suite/tests/compile-fail/identifier/both.rs @@ -0,0 +1,19 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[macro_use] +extern crate serde_derive; + +#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked +#[serde(field_identifier, variant_identifier)] //~^ HELP: `field_identifier` and `variant_identifier` cannot both be set +enum F { + A, + B, +} + +fn main() {} diff --git a/test_suite/tests/compile-fail/identifier/field_struct.rs b/test_suite/tests/compile-fail/identifier/field_struct.rs new file mode 100644 index 00000000..79b380d9 --- /dev/null +++ b/test_suite/tests/compile-fail/identifier/field_struct.rs @@ -0,0 +1,16 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[macro_use] +extern crate serde_derive; + +#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked +#[serde(field_identifier)] +struct S; //~^^ HELP: `field_identifier` can only be used on an enum + +fn main() {} diff --git a/test_suite/tests/compile-fail/identifier/field_tuple.rs b/test_suite/tests/compile-fail/identifier/field_tuple.rs new file mode 100644 index 00000000..7b26885d --- /dev/null +++ b/test_suite/tests/compile-fail/identifier/field_tuple.rs @@ -0,0 +1,19 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[macro_use] +extern crate serde_derive; + +#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked +#[serde(field_identifier)] +enum F { + A, + B(u8, u8), //~^^^^ HELP: field_identifier may only contain unit variants +} + +fn main() {} diff --git a/test_suite/tests/compile-fail/identifier/newtype_not_last.rs b/test_suite/tests/compile-fail/identifier/newtype_not_last.rs new file mode 100644 index 00000000..f601be3e --- /dev/null +++ b/test_suite/tests/compile-fail/identifier/newtype_not_last.rs @@ -0,0 +1,20 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[macro_use] +extern crate serde_derive; + +#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked +#[serde(field_identifier)] +enum F { + A, + Other(String), //~^^^^ HELP: `Other` must be the last variant + B, +} + +fn main() {} diff --git a/test_suite/tests/compile-fail/identifier/not_identifier.rs b/test_suite/tests/compile-fail/identifier/not_identifier.rs new file mode 100644 index 00000000..3dd6d65f --- /dev/null +++ b/test_suite/tests/compile-fail/identifier/not_identifier.rs @@ -0,0 +1,19 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[macro_use] +extern crate serde_derive; + +#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked +enum F { + A, + #[serde(other)] //~^^^ HELP: #[serde(other)] may only be used inside a field_identifier + B, +} + +fn main() {} diff --git a/test_suite/tests/compile-fail/identifier/not_unit.rs b/test_suite/tests/compile-fail/identifier/not_unit.rs new file mode 100644 index 00000000..dfc65df2 --- /dev/null +++ b/test_suite/tests/compile-fail/identifier/not_unit.rs @@ -0,0 +1,20 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[macro_use] +extern crate serde_derive; + +#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked +#[serde(field_identifier)] +enum F { + A, + #[serde(other)] //~^^^^ HELP: #[serde(other)] must be on a unit variant + Other(u8, u8), +} + +fn main() {} diff --git a/test_suite/tests/compile-fail/identifier/other_not_last.rs b/test_suite/tests/compile-fail/identifier/other_not_last.rs new file mode 100644 index 00000000..481f4764 --- /dev/null +++ b/test_suite/tests/compile-fail/identifier/other_not_last.rs @@ -0,0 +1,21 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[macro_use] +extern crate serde_derive; + +#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked +#[serde(field_identifier)] +enum F { + A, + #[serde(other)] //~^^^^ HELP: #[serde(other)] must be the last variant + Other, + B, +} + +fn main() {} diff --git a/test_suite/tests/compile-fail/identifier/serialize.rs b/test_suite/tests/compile-fail/identifier/serialize.rs new file mode 100644 index 00000000..1c928b3f --- /dev/null +++ b/test_suite/tests/compile-fail/identifier/serialize.rs @@ -0,0 +1,19 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[macro_use] +extern crate serde_derive; + +#[derive(Serialize)] //~ ERROR: proc-macro derive panicked +#[serde(field_identifier)] //~^ HELP: field identifiers cannot be serialized +enum F { + A, + B, +} + +fn main() {} diff --git a/test_suite/tests/compile-fail/identifier/variant_struct.rs b/test_suite/tests/compile-fail/identifier/variant_struct.rs new file mode 100644 index 00000000..aeb37f9a --- /dev/null +++ b/test_suite/tests/compile-fail/identifier/variant_struct.rs @@ -0,0 +1,16 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[macro_use] +extern crate serde_derive; + +#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked +#[serde(variant_identifier)] +struct S; //~^^ HELP: `variant_identifier` can only be used on an enum + +fn main() {} diff --git a/test_suite/tests/compile-fail/identifier/variant_tuple.rs b/test_suite/tests/compile-fail/identifier/variant_tuple.rs new file mode 100644 index 00000000..9ea2ee2e --- /dev/null +++ b/test_suite/tests/compile-fail/identifier/variant_tuple.rs @@ -0,0 +1,19 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[macro_use] +extern crate serde_derive; + +#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked +#[serde(variant_identifier)] +enum F { + A, + B(u8, u8), //~^^^^ HELP: variant_identifier may only contain unit variants +} + +fn main() {} diff --git a/test_suite/tests/test_identifier.rs b/test_suite/tests/test_identifier.rs new file mode 100644 index 00000000..76f1cffa --- /dev/null +++ b/test_suite/tests/test_identifier.rs @@ -0,0 +1,82 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[macro_use] +extern crate serde_derive; + +extern crate serde; + +extern crate serde_test; +use serde_test::{Token, assert_de_tokens}; + +#[test] +fn test_variant_identifier() { + #[derive(Deserialize, Debug, PartialEq)] + #[serde(variant_identifier)] + enum V { + Aaa, + Bbb, + } + + assert_de_tokens(&V::Aaa, &[Token::U32(0)]); + assert_de_tokens(&V::Aaa, &[Token::Str("Aaa")]); + assert_de_tokens(&V::Aaa, &[Token::Bytes(b"Aaa")]); +} + +#[test] +fn test_field_identifier() { + #[derive(Deserialize, Debug, PartialEq)] + #[serde(field_identifier, rename_all = "snake_case")] + enum F { + Aaa, + Bbb, + } + + assert_de_tokens(&F::Aaa, &[Token::Str("aaa")]); + assert_de_tokens(&F::Aaa, &[Token::Bytes(b"aaa")]); +} + +#[test] +fn test_unit_fallthrough() { + #[derive(Deserialize, Debug, PartialEq)] + #[serde(field_identifier, rename_all = "snake_case")] + enum F { + Aaa, + Bbb, + #[serde(other)] + Other, + } + + assert_de_tokens(&F::Other, &[Token::Str("x")]); +} + +#[test] +fn test_newtype_fallthrough() { + #[derive(Deserialize, Debug, PartialEq)] + #[serde(field_identifier, rename_all = "snake_case")] + enum F { + Aaa, + Bbb, + Other(String), + } + + assert_de_tokens(&F::Other("x".to_owned()), &[Token::Str("x")]); +} + +#[test] +fn test_newtype_fallthrough_generic() { + #[derive(Deserialize, Debug, PartialEq)] + #[serde(field_identifier, rename_all = "snake_case")] + enum F { + Aaa, + Bbb, + Other(T), + } + + assert_de_tokens(&F::Other("x".to_owned()), &[Token::Str("x")]); +} From 54bbf81dfc96b0699b88076b4289de319ff71ec7 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 21:59:56 -0700 Subject: [PATCH 167/177] Put deserialize_struct and deserialize_enum adjacent --- serde/src/de/mod.rs | 12 ++++++------ serde/src/de/value.rs | 14 +++++++------- serde/src/macros.rs | 10 +++++----- serde/src/private/de.rs | 14 +++++++------- serde_test/src/de.rs | 2 +- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index a8275ef6..ef8582c8 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -985,12 +985,6 @@ pub trait Deserializer<'de>: Sized { where V: Visitor<'de>; - /// Hint that the `Deserialize` type is expecting the name of a struct - /// field or the discriminant of an enum variant. - fn deserialize_identifier(self, visitor: V) -> Result - where - V: Visitor<'de>; - /// Hint that the `Deserialize` type is expecting an enum value with a /// particular name and possible variants. fn deserialize_enum( @@ -1002,6 +996,12 @@ pub trait Deserializer<'de>: Sized { where V: Visitor<'de>; + /// Hint that the `Deserialize` type is expecting the name of a struct + /// field or the discriminant of an enum variant. + fn deserialize_identifier(self, visitor: V) -> Result + where + V: Visitor<'de>; + /// Hint that the `Deserialize` type needs to deserialize a value whose type /// doesn't matter because it is ignored. /// diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index ec311be8..ffedb3ef 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -131,7 +131,7 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes byte_buf unit unit_struct newtype_struct seq seq_fixed_size tuple - tuple_struct map struct identifier enum ignored_any + tuple_struct map struct enum identifier ignored_any } fn deserialize_any(self, visitor: V) -> Result @@ -184,7 +184,7 @@ macro_rules! primitive_deserializer { forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct identifier enum ignored_any + tuple tuple_struct map struct enum identifier ignored_any } fn deserialize_any(self, visitor: V) -> Result @@ -574,7 +574,7 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct identifier enum ignored_any + tuple tuple_struct map struct enum identifier ignored_any } } @@ -688,7 +688,7 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct identifier enum ignored_any + tuple tuple_struct map struct enum identifier ignored_any } } @@ -806,7 +806,7 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes byte_buf option unit unit_struct newtype_struct tuple tuple_struct - map struct identifier enum ignored_any + map struct enum identifier ignored_any } } @@ -947,7 +947,7 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes byte_buf option unit unit_struct newtype_struct tuple tuple_struct - map struct identifier enum ignored_any + map struct enum identifier ignored_any } fn deserialize_any(self, visitor: V) -> Result @@ -1094,7 +1094,7 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct identifier enum ignored_any + tuple tuple_struct map struct enum identifier ignored_any } } diff --git a/serde/src/macros.rs b/serde/src/macros.rs index b3d5d402..0d654583 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -79,7 +79,7 @@ /// forward_to_deserialize_any! { /// bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes /// byte_buf option unit unit_struct newtype_struct seq seq_fixed_size -/// tuple tuple_struct map struct identifier enum ignored_any +/// tuple tuple_struct map struct enum identifier ignored_any /// } /// } /// # @@ -114,7 +114,7 @@ /// > /// bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes /// byte_buf option unit unit_struct newtype_struct seq seq_fixed_size -/// tuple tuple_struct map struct identifier enum ignored_any +/// tuple tuple_struct map struct enum identifier ignored_any /// } /// # } /// # @@ -233,12 +233,12 @@ macro_rules! forward_to_deserialize_any_helper { (struct<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_struct<$l, $v>(name: &'static str, fields: &'static [&'static str])} }; - (identifier<$l:tt, $v:ident>) => { - forward_to_deserialize_any_method!{deserialize_identifier<$l, $v>()} - }; (enum<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_enum<$l, $v>(name: &'static str, variants: &'static [&'static str])} }; + (identifier<$l:tt, $v:ident>) => { + forward_to_deserialize_any_method!{deserialize_identifier<$l, $v>()} + }; (ignored_any<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_ignored_any<$l, $v>()} }; diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 61bbf566..52d2c143 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -50,7 +50,7 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes byte_buf unit unit_struct newtype_struct seq seq_fixed_size tuple - tuple_struct map struct identifier enum ignored_any + tuple_struct map struct enum identifier ignored_any } } @@ -1154,7 +1154,7 @@ mod content { forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct identifier enum ignored_any + tuple tuple_struct map struct enum identifier ignored_any } } @@ -1255,7 +1255,7 @@ mod content { forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct identifier enum ignored_any + tuple tuple_struct map struct enum identifier ignored_any } } @@ -1546,7 +1546,7 @@ mod content { forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct identifier enum ignored_any + tuple tuple_struct map struct enum identifier ignored_any } } @@ -1648,7 +1648,7 @@ mod content { forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct identifier enum ignored_any + tuple tuple_struct map struct enum identifier ignored_any } } @@ -1805,7 +1805,7 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct identifier enum ignored_any + tuple tuple_struct map struct enum identifier ignored_any } } @@ -1844,6 +1844,6 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct identifier enum ignored_any + tuple tuple_struct map struct enum identifier ignored_any } } diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index a1f497c7..7139dbac 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -657,6 +657,6 @@ impl<'de> de::Deserializer<'de> for BytesDeserializer { forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct identifier enum ignored_any + tuple tuple_struct map struct enum identifier ignored_any } } From 13463e25c2712607a24552eeb0fa53d5037f329a Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 22:09:46 -0700 Subject: [PATCH 168/177] Add a lowercase case convention --- serde_derive_internals/src/case.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/serde_derive_internals/src/case.rs b/serde_derive_internals/src/case.rs index 3d3af39f..e51f2e3e 100644 --- a/serde_derive_internals/src/case.rs +++ b/serde_derive_internals/src/case.rs @@ -15,6 +15,8 @@ use self::RenameRule::*; pub enum RenameRule { /// Don't apply a default rename rule. None, + /// Rename direct children to "lowercase" style. + LowerCase, /// Rename direct children to "PascalCase" style, as typically used for enum variants. PascalCase, /// Rename direct children to "camelCase" style. @@ -31,6 +33,7 @@ impl RenameRule { pub fn apply_to_variant(&self, variant: &str) -> String { match *self { None | PascalCase => variant.to_owned(), + LowerCase => variant.to_ascii_lowercase(), CamelCase => variant[..1].to_ascii_lowercase() + &variant[1..], SnakeCase => { let mut snake = String::new(); @@ -49,7 +52,7 @@ impl RenameRule { pub fn apply_to_field(&self, field: &str) -> String { match *self { - None | SnakeCase => field.to_owned(), + None | LowerCase | SnakeCase => field.to_owned(), PascalCase => { let mut pascal = String::new(); let mut capitalize = true; @@ -80,6 +83,7 @@ impl FromStr for RenameRule { fn from_str(rename_all_str: &str) -> Result { match rename_all_str { + "lowercase" => Ok(LowerCase), "PascalCase" => Ok(PascalCase), "camelCase" => Ok(CamelCase), "snake_case" => Ok(SnakeCase), @@ -92,12 +96,13 @@ impl FromStr for RenameRule { #[test] fn rename_variants() { - for &(original, camel, snake, screaming, kebab) in - &[("Outcome", "outcome", "outcome", "OUTCOME", "outcome"), - ("VeryTasty", "veryTasty", "very_tasty", "VERY_TASTY", "very-tasty"), - ("A", "a", "a", "A", "a"), - ("Z42", "z42", "z42", "Z42", "z42")] { + for &(original, lower, camel, snake, screaming, kebab) in + &[("Outcome", "outcome", "outcome", "outcome", "OUTCOME", "outcome"), + ("VeryTasty", "verytasty", "veryTasty", "very_tasty", "VERY_TASTY", "very-tasty"), + ("A", "a", "a", "a", "A", "a"), + ("Z42", "z42", "z42", "z42", "Z42", "z42")] { assert_eq!(None.apply_to_variant(original), original); + assert_eq!(LowerCase.apply_to_variant(original), lower); assert_eq!(PascalCase.apply_to_variant(original), original); assert_eq!(CamelCase.apply_to_variant(original), camel); assert_eq!(SnakeCase.apply_to_variant(original), snake); From 691e304fffa25366c038a1d61bc81f9a1a8ac3a7 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 22:13:55 -0700 Subject: [PATCH 169/177] Mention the shorthand for identifiers --- serde/src/de/impls.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index ad481bdf..37381ca0 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -935,6 +935,10 @@ impl<'de> Deserialize<'de> for PathBuf { //////////////////////////////////////////////////////////////////////////////// +// If this were outside of the serde crate, it would just use: +// +// #[derive(Deserialize)] +// #[serde(variant_identifier)] #[cfg(all(feature = "std", any(unix, windows)))] enum OsStringKind { Unix, @@ -1149,6 +1153,10 @@ impl<'de> Deserialize<'de> for Duration { where D: Deserializer<'de>, { + // If this were outside of the serde crate, it would just use: + // + // #[derive(Deserialize)] + // #[serde(field_identifier, rename_all = "lowercase")] enum Field { Secs, Nanos, @@ -1284,6 +1292,10 @@ where where D: Deserializer<'de>, { + // If this were outside of the serde crate, it would just use: + // + // #[derive(Deserialize)] + // #[serde(field_identifier, rename_all = "lowercase")] enum Field { Start, End, @@ -1438,6 +1450,10 @@ where where D: Deserializer<'de>, { + // If this were outside of the serde crate, it would just use: + // + // #[derive(Deserialize)] + // #[serde(variant_identifier)] enum Field { Ok, Err, From 4354aab93ac869703476be05d2d07113fbab1661 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 14 Apr 2017 22:29:46 -0700 Subject: [PATCH 170/177] Document the default behavior of Visitor methods --- serde/src/de/mod.rs | 114 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 89 insertions(+), 25 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index ef8582c8..ab361854 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -1072,7 +1072,9 @@ pub trait Visitor<'de>: Sized { /// ``` fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result; - /// Deserialize a `bool` into a `Value`. + /// The input contains a boolean. + /// + /// The default implementation fails with a type error. fn visit_bool(self, v: bool) -> Result where E: Error, @@ -1080,7 +1082,11 @@ pub trait Visitor<'de>: Sized { Err(Error::invalid_type(Unexpected::Bool(v), &self)) } - /// Deserialize an `i8` into a `Value`. + /// The input contains an `i8`. + /// + /// The default implementation forwards to [`visit_i64`]. + /// + /// [`visit_i64`]: #method.visit_i64 fn visit_i8(self, v: i8) -> Result where E: Error, @@ -1088,7 +1094,11 @@ pub trait Visitor<'de>: Sized { self.visit_i64(v as i64) } - /// Deserialize an `i16` into a `Value`. + /// The input contains an `i16`. + /// + /// The default implementation forwards to [`visit_i64`]. + /// + /// [`visit_i64`]: #method.visit_i64 fn visit_i16(self, v: i16) -> Result where E: Error, @@ -1096,7 +1106,11 @@ pub trait Visitor<'de>: Sized { self.visit_i64(v as i64) } - /// Deserialize an `i32` into a `Value`. + /// The input contains an `i32`. + /// + /// The default implementation forwards to [`visit_i64`]. + /// + /// [`visit_i64`]: #method.visit_i64 fn visit_i32(self, v: i32) -> Result where E: Error, @@ -1104,7 +1118,9 @@ pub trait Visitor<'de>: Sized { self.visit_i64(v as i64) } - /// Deserialize an `i64` into a `Value`. + /// The input contains an `i32`. + /// + /// The default implementation fails with a type error. fn visit_i64(self, v: i64) -> Result where E: Error, @@ -1112,7 +1128,11 @@ pub trait Visitor<'de>: Sized { Err(Error::invalid_type(Unexpected::Signed(v), &self)) } - /// Deserialize a `u8` into a `Value`. + /// The input contains a `u8`. + /// + /// The default implementation forwards to [`visit_u64`]. + /// + /// [`visit_u64`]: #method.visit_u64 fn visit_u8(self, v: u8) -> Result where E: Error, @@ -1120,7 +1140,11 @@ pub trait Visitor<'de>: Sized { self.visit_u64(v as u64) } - /// Deserialize a `u16` into a `Value`. + /// The input contains a `u16`. + /// + /// The default implementation forwards to [`visit_u64`]. + /// + /// [`visit_u64`]: #method.visit_u64 fn visit_u16(self, v: u16) -> Result where E: Error, @@ -1128,7 +1152,11 @@ pub trait Visitor<'de>: Sized { self.visit_u64(v as u64) } - /// Deserialize a `u32` into a `Value`. + /// The input contains a `u32`. + /// + /// The default implementation forwards to [`visit_u64`]. + /// + /// [`visit_u64`]: #method.visit_u64 fn visit_u32(self, v: u32) -> Result where E: Error, @@ -1136,7 +1164,9 @@ pub trait Visitor<'de>: Sized { self.visit_u64(v as u64) } - /// Deserialize a `u64` into a `Value`. + /// The input contains a `u64`. + /// + /// The default implementation fails with a type error. fn visit_u64(self, v: u64) -> Result where E: Error, @@ -1144,7 +1174,11 @@ pub trait Visitor<'de>: Sized { Err(Error::invalid_type(Unexpected::Unsigned(v), &self)) } - /// Deserialize a `f32` into a `Value`. + /// The input contains an `f32`. + /// + /// The default implementation forwards to [`visit_f64`]. + /// + /// [`visit_f64`]: #method.visit_f64 fn visit_f32(self, v: f32) -> Result where E: Error, @@ -1152,7 +1186,9 @@ pub trait Visitor<'de>: Sized { self.visit_f64(v as f64) } - /// Deserialize a `f64` into a `Value`. + /// The input contains an `f64`. + /// + /// The default implementation fails with a type error. fn visit_f64(self, v: f64) -> Result where E: Error, @@ -1160,7 +1196,12 @@ pub trait Visitor<'de>: Sized { Err(Error::invalid_type(Unexpected::Float(v), &self)) } - /// Deserialize a `char` into a `Value`. + /// The input contains a `char`. + /// + /// The default implementation forwards to [`visit_str`] as a one-character + /// string. + /// + /// [`visit_str`]: #method.visit_str #[inline] fn visit_char(self, v: char) -> Result where @@ -1169,7 +1210,8 @@ pub trait Visitor<'de>: Sized { self.visit_str(utf8::encode(v).as_str()) } - /// Deserialize a `&str` into a `Value`. + /// The input contains a string. The lifetime of the string is ephemeral and + /// it may be destroyed after this method returns. /// /// This method allows the `Deserializer` to avoid a copy by retaining /// ownership of any buffered data. `Deserialize` implementations that do @@ -1186,7 +1228,8 @@ pub trait Visitor<'de>: Sized { Err(Error::invalid_type(Unexpected::Str(v), &self)) } - /// Deserialize a `&str` that is borrowed from the input data. + /// The input contains a string that lives at least as long as the + /// `Deserializer`. /// /// This enables zero-copy deserialization of strings in some formats. For /// example JSON input containing the JSON string `"borrowed"` can be @@ -1202,7 +1245,8 @@ pub trait Visitor<'de>: Sized { self.visit_str(v) } - /// Deserialize a `String` into a `Value`. + /// The input contains a string and ownership of the string is being given + /// to the `Visitor`. /// /// This method allows the `Visitor` to avoid a copy by taking ownership of /// a string created by the `Deserializer`. `Deserialize` implementations @@ -1225,7 +1269,8 @@ pub trait Visitor<'de>: Sized { self.visit_str(&v) } - /// Deserialize a `&[u8]` into a `Value`. + /// The input contains a byte array. The lifetime of the byte array is + /// ephemeral and it may be destroyed after this method returns. /// /// This method allows the `Deserializer` to avoid a copy by retaining /// ownership of any buffered data. `Deserialize` implementations that do @@ -1243,7 +1288,8 @@ pub trait Visitor<'de>: Sized { Err(Error::invalid_type(Unexpected::Bytes(v), &self)) } - /// Deserialize a `&[u8]` that is borrowed from the input data. + /// The input contains a byte array that lives at least as long as the + /// `Deserializer`. /// /// This enables zero-copy deserialization of bytes in some formats. For /// example Bincode data containing bytes can be deserialized with zero @@ -1258,7 +1304,8 @@ pub trait Visitor<'de>: Sized { self.visit_bytes(v) } - /// Deserialize a `Vec` into a `Value`. + /// The input contains a byte array and ownership of the byte array is being + /// given to the `Visitor`. /// /// This method allows the `Visitor` to avoid a copy by taking ownership of /// a byte buffer created by the `Deserializer`. `Deserialize` @@ -1281,7 +1328,9 @@ pub trait Visitor<'de>: Sized { self.visit_bytes(&v) } - /// Deserialize an absent optional `Value`. + /// The input contains an optional that is absent. + /// + /// The default implementation fails with a type error. fn visit_none(self) -> Result where E: Error, @@ -1289,7 +1338,9 @@ pub trait Visitor<'de>: Sized { Err(Error::invalid_type(Unexpected::Option, &self)) } - /// Deserialize a present optional `Value`. + /// The input contains an optional that is present. + /// + /// The default implementation fails with a type error. fn visit_some(self, deserializer: D) -> Result where D: Deserializer<'de>, @@ -1298,7 +1349,9 @@ pub trait Visitor<'de>: Sized { Err(Error::invalid_type(Unexpected::Option, &self)) } - /// Deserialize a `()` into a `Value`. + /// The input contains a unit `()`. + /// + /// The default implementation fails with a type error. fn visit_unit(self) -> Result where E: Error, @@ -1306,7 +1359,12 @@ pub trait Visitor<'de>: Sized { Err(Error::invalid_type(Unexpected::Unit, &self)) } - /// Deserialize `Value` as a newtype struct. + /// The input contains a newtype struct. + /// + /// The content of the newtype struct may be read from the given + /// `Deserializer`. + /// + /// The default implementation fails with a type error. fn visit_newtype_struct(self, deserializer: D) -> Result where D: Deserializer<'de>, @@ -1315,7 +1373,9 @@ pub trait Visitor<'de>: Sized { Err(Error::invalid_type(Unexpected::NewtypeStruct, &self)) } - /// Deserialize `Value` as a sequence of elements. + /// The input contains a sequence of elements. + /// + /// The default implementation fails with a type error. fn visit_seq(self, seq: A) -> Result where A: SeqAccess<'de>, @@ -1324,7 +1384,9 @@ pub trait Visitor<'de>: Sized { Err(Error::invalid_type(Unexpected::Seq, &self)) } - /// Deserialize `Value` as a key-value map. + /// The input contains a key-value map. + /// + /// The default implementation fails with a type error. fn visit_map(self, map: A) -> Result where A: MapAccess<'de>, @@ -1333,7 +1395,9 @@ pub trait Visitor<'de>: Sized { Err(Error::invalid_type(Unexpected::Map, &self)) } - /// Deserialize `Value` as an enum. + /// The input contains an enum. + /// + /// The default implementation fails with a type error. fn visit_enum(self, data: A) -> Result where A: EnumAccess<'de>, From c13a37d4db1cbfcb47f4e62fb5c5f41a716a844f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 15 Apr 2017 12:35:04 -0700 Subject: [PATCH 171/177] Rename VariantAccess methods to not conflict with Deserializer --- serde/src/de/impls.rs | 12 +++++------ serde/src/de/mod.rs | 46 ++++++++++++++++++++--------------------- serde/src/de/value.rs | 8 +++---- serde/src/private/de.rs | 16 +++++++------- serde_derive/src/de.rs | 10 ++++----- serde_test/src/de.rs | 8 +++---- 6 files changed, 49 insertions(+), 51 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 37381ca0..6e4c6502 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -1025,7 +1025,7 @@ impl<'de> Visitor<'de> for OsStringVisitor { use std::os::unix::ffi::OsStringExt; match try!(data.variant()) { - (OsStringKind::Unix, variant) => variant.deserialize_newtype().map(OsString::from_vec), + (OsStringKind::Unix, v) => v.newtype_variant().map(OsString::from_vec), (OsStringKind::Windows, _) => Err(Error::custom("cannot deserialize Windows OS string on Unix",),), } } @@ -1038,10 +1038,8 @@ impl<'de> Visitor<'de> for OsStringVisitor { use std::os::windows::ffi::OsStringExt; match try!(data.variant()) { - (OsStringKind::Windows, variant) => { - variant - .deserialize_newtype::>() - .map(|vec| OsString::from_wide(&vec)) + (OsStringKind::Windows, v) => { + v.newtype_variant::>().map(|vec| OsString::from_wide(&vec)) } (OsStringKind::Unix, _) => Err(Error::custom("cannot deserialize Unix OS string on Windows",),), } @@ -1539,8 +1537,8 @@ where A: EnumAccess<'de>, { match try!(data.variant()) { - (Field::Ok, variant) => variant.deserialize_newtype().map(Ok), - (Field::Err, variant) => variant.deserialize_newtype().map(Err), + (Field::Ok, v) => v.newtype_variant().map(Ok), + (Field::Err, v) => v.newtype_variant().map(Err), } } } diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index ab361854..79ecd9b0 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -1697,31 +1697,31 @@ pub trait VariantAccess<'de>: Sized { /// # impl<'de> VariantAccess<'de> for X { /// # type Error = value::Error; /// # - /// fn deserialize_unit(self) -> Result<(), Self::Error> { + /// fn unit_variant(self) -> Result<(), Self::Error> { /// // What the data actually contained; suppose it is a tuple variant. /// let unexp = Unexpected::TupleVariant; /// Err(de::Error::invalid_type(unexp, &"unit variant")) /// } /// # - /// # fn deserialize_newtype_seed(self, _: T) -> Result + /// # fn newtype_variant_seed(self, _: T) -> Result /// # where T: DeserializeSeed<'de> /// # { unimplemented!() } /// # - /// # fn deserialize_tuple(self, _: usize, _: V) -> Result + /// # fn tuple_variant(self, _: usize, _: V) -> Result /// # where V: Visitor<'de> /// # { unimplemented!() } /// # - /// # fn deserialize_struct(self, _: &[&str], _: V) -> Result + /// # fn struct_variant(self, _: &[&str], _: V) -> Result /// # where V: Visitor<'de> /// # { unimplemented!() } /// # } /// ``` - fn deserialize_unit(self) -> Result<(), Self::Error>; + fn unit_variant(self) -> Result<(), Self::Error>; /// Called when deserializing a variant with a single value. /// /// `Deserialize` implementations should typically use - /// `VariantAccess::deserialize_newtype` instead. + /// `VariantAccess::newtype_variant` instead. /// /// If the data contains a different type of variant, the following /// `invalid_type` error should be constructed: @@ -1734,11 +1734,11 @@ pub trait VariantAccess<'de>: Sized { /// # impl<'de> VariantAccess<'de> for X { /// # type Error = value::Error; /// # - /// # fn deserialize_unit(self) -> Result<(), Self::Error> { + /// # fn unit_variant(self) -> Result<(), Self::Error> { /// # unimplemented!() /// # } /// # - /// fn deserialize_newtype_seed(self, _seed: T) -> Result + /// fn newtype_variant_seed(self, _seed: T) -> Result /// where T: DeserializeSeed<'de> /// { /// // What the data actually contained; suppose it is a unit variant. @@ -1746,16 +1746,16 @@ pub trait VariantAccess<'de>: Sized { /// Err(de::Error::invalid_type(unexp, &"newtype variant")) /// } /// # - /// # fn deserialize_tuple(self, _: usize, _: V) -> Result + /// # fn tuple_variant(self, _: usize, _: V) -> Result /// # where V: Visitor<'de> /// # { unimplemented!() } /// # - /// # fn deserialize_struct(self, _: &[&str], _: V) -> Result + /// # fn struct_variant(self, _: &[&str], _: V) -> Result /// # where V: Visitor<'de> /// # { unimplemented!() } /// # } /// ``` - fn deserialize_newtype_seed(self, seed: T) -> Result + fn newtype_variant_seed(self, seed: T) -> Result where T: DeserializeSeed<'de>; @@ -1765,11 +1765,11 @@ pub trait VariantAccess<'de>: Sized { /// `VariantAccess` implementations should not override the default /// behavior. #[inline] - fn deserialize_newtype(self) -> Result + fn newtype_variant(self) -> Result where T: Deserialize<'de>, { - self.deserialize_newtype_seed(PhantomData) + self.newtype_variant_seed(PhantomData) } /// Called when deserializing a tuple-like variant. @@ -1787,15 +1787,15 @@ pub trait VariantAccess<'de>: Sized { /// # impl<'de> VariantAccess<'de> for X { /// # type Error = value::Error; /// # - /// # fn deserialize_unit(self) -> Result<(), Self::Error> { + /// # fn unit_variant(self) -> Result<(), Self::Error> { /// # unimplemented!() /// # } /// # - /// # fn deserialize_newtype_seed(self, _: T) -> Result + /// # fn newtype_variant_seed(self, _: T) -> Result /// # where T: DeserializeSeed<'de> /// # { unimplemented!() } /// # - /// fn deserialize_tuple(self, + /// fn tuple_variant(self, /// _len: usize, /// _visitor: V) -> Result /// where V: Visitor<'de> @@ -1805,12 +1805,12 @@ pub trait VariantAccess<'de>: Sized { /// Err(de::Error::invalid_type(unexp, &"tuple variant")) /// } /// # - /// # fn deserialize_struct(self, _: &[&str], _: V) -> Result + /// # fn struct_variant(self, _: &[&str], _: V) -> Result /// # where V: Visitor<'de> /// # { unimplemented!() } /// # } /// ``` - fn deserialize_tuple(self, len: usize, visitor: V) -> Result + fn tuple_variant(self, len: usize, visitor: V) -> Result where V: Visitor<'de>; @@ -1829,19 +1829,19 @@ pub trait VariantAccess<'de>: Sized { /// # impl<'de> VariantAccess<'de> for X { /// # type Error = value::Error; /// # - /// # fn deserialize_unit(self) -> Result<(), Self::Error> { + /// # fn unit_variant(self) -> Result<(), Self::Error> { /// # unimplemented!() /// # } /// # - /// # fn deserialize_newtype_seed(self, _: T) -> Result + /// # fn newtype_variant_seed(self, _: T) -> Result /// # where T: DeserializeSeed<'de> /// # { unimplemented!() } /// # - /// # fn deserialize_tuple(self, _: usize, _: V) -> Result + /// # fn tuple_variant(self, _: usize, _: V) -> Result /// # where V: Visitor<'de> /// # { unimplemented!() } /// # - /// fn deserialize_struct(self, + /// fn struct_variant(self, /// _fields: &'static [&'static str], /// _visitor: V) -> Result /// where V: Visitor<'de> @@ -1852,7 +1852,7 @@ pub trait VariantAccess<'de>: Sized { /// } /// # } /// ``` - fn deserialize_struct( + fn struct_variant( self, fields: &'static [&'static str], visitor: V, diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index ffedb3ef..97c55881 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -1120,25 +1120,25 @@ mod private { { type Error = E; - fn deserialize_unit(self) -> Result<(), Self::Error> { + fn unit_variant(self) -> Result<(), Self::Error> { Ok(()) } - fn deserialize_newtype_seed(self, _seed: T) -> Result + fn newtype_variant_seed(self, _seed: T) -> Result where T: de::DeserializeSeed<'de>, { Err(de::Error::invalid_type(Unexpected::UnitVariant, &"newtype variant"),) } - fn deserialize_tuple(self, _len: usize, _visitor: V) -> Result + fn tuple_variant(self, _len: usize, _visitor: V) -> Result where V: de::Visitor<'de>, { Err(de::Error::invalid_type(Unexpected::UnitVariant, &"tuple variant"),) } - fn deserialize_struct( + fn struct_variant( self, _fields: &'static [&'static str], _visitor: V, diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 52d2c143..75111321 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -1056,14 +1056,14 @@ mod content { { type Error = E; - fn deserialize_unit(self) -> Result<(), E> { + fn unit_variant(self) -> Result<(), E> { match self.value { Some(value) => de::Deserialize::deserialize(ContentDeserializer::new(value)), None => Ok(()), } } - fn deserialize_newtype_seed(self, seed: T) -> Result + fn newtype_variant_seed(self, seed: T) -> Result where T: de::DeserializeSeed<'de>, { @@ -1075,7 +1075,7 @@ mod content { } } - fn deserialize_tuple(self, _len: usize, visitor: V) -> Result + fn tuple_variant(self, _len: usize, visitor: V) -> Result where V: de::Visitor<'de>, { @@ -1088,7 +1088,7 @@ mod content { } } - fn deserialize_struct( + fn struct_variant( self, _fields: &'static [&'static str], visitor: V, @@ -1448,14 +1448,14 @@ mod content { { type Error = E; - fn deserialize_unit(self) -> Result<(), E> { + fn unit_variant(self) -> Result<(), E> { match self.value { Some(value) => de::Deserialize::deserialize(ContentRefDeserializer::new(value)), None => Ok(()), } } - fn deserialize_newtype_seed(self, seed: T) -> Result + fn newtype_variant_seed(self, seed: T) -> Result where T: de::DeserializeSeed<'de>, { @@ -1467,7 +1467,7 @@ mod content { } } - fn deserialize_tuple(self, _len: usize, visitor: V) -> Result + fn tuple_variant(self, _len: usize, visitor: V) -> Result where V: de::Visitor<'de>, { @@ -1480,7 +1480,7 @@ mod content { } } - fn deserialize_struct( + fn struct_variant( self, _fields: &'static [&'static str], visitor: V, diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 79304878..c0b32f36 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -299,7 +299,7 @@ fn deserialize_tuple( let dispatch = if let Some(deserializer) = deserializer { quote!(_serde::Deserializer::deserialize_tuple(#deserializer, #nfields, #visitor_expr)) } else if is_enum { - quote!(_serde::de::VariantAccess::deserialize_tuple(__variant, #nfields, #visitor_expr)) + 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)) @@ -508,7 +508,7 @@ fn deserialize_struct( } } else if is_enum { quote! { - _serde::de::VariantAccess::deserialize_struct(__variant, FIELDS, #visitor_expr) + _serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr) } } else { let type_name = cattrs.name().deserialize_name(); @@ -1048,7 +1048,7 @@ fn deserialize_externally_tagged_variant( Style::Unit => { let this = ¶ms.this; quote_block! { - try!(_serde::de::VariantAccess::deserialize_unit(__variant)); + try!(_serde::de::VariantAccess::unit_variant(__variant)); _serde::export::Ok(#this::#variant_ident) } } @@ -1163,7 +1163,7 @@ fn deserialize_externally_tagged_newtype_variant( let field_ty = &field.ty; quote_expr! { _serde::export::Result::map( - _serde::de::VariantAccess::deserialize_newtype::<#field_ty>(__variant), + _serde::de::VariantAccess::newtype_variant::<#field_ty>(__variant), #this::#variant_ident) } } @@ -1172,7 +1172,7 @@ fn deserialize_externally_tagged_newtype_variant( quote_block! { #wrapper _serde::export::Result::map( - _serde::de::VariantAccess::deserialize_newtype::<#wrapper_ty>(__variant), + _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant), |__wrapper| #this::#variant_ident(__wrapper.value)) } } diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index 7139dbac..9b5fc85a 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -478,7 +478,7 @@ impl<'de, 'a> EnumAccess<'de> for DeserializerEnumVisitor<'a, 'de> { impl<'de, 'a> VariantAccess<'de> for DeserializerEnumVisitor<'a, 'de> { type Error = Error; - fn deserialize_unit(self) -> Result<(), Error> { + fn unit_variant(self) -> Result<(), Error> { match self.de.tokens.first() { Some(&Token::UnitVariant(_, _)) => { self.de.next_token(); @@ -489,7 +489,7 @@ impl<'de, 'a> VariantAccess<'de> for DeserializerEnumVisitor<'a, 'de> { } } - fn deserialize_newtype_seed(self, seed: T) -> Result + fn newtype_variant_seed(self, seed: T) -> Result where T: DeserializeSeed<'de>, { @@ -503,7 +503,7 @@ impl<'de, 'a> VariantAccess<'de> for DeserializerEnumVisitor<'a, 'de> { } } - fn deserialize_tuple(self, len: usize, visitor: V) -> Result + fn tuple_variant(self, len: usize, visitor: V) -> Result where V: Visitor<'de>, { @@ -532,7 +532,7 @@ impl<'de, 'a> VariantAccess<'de> for DeserializerEnumVisitor<'a, 'de> { } } - fn deserialize_struct(self, fields: &'static [&'static str], visitor: V) -> Result + fn struct_variant(self, fields: &'static [&'static str], visitor: V) -> Result where V: Visitor<'de>, { From e0c040a3a25b2c3028a6eb7e440df73c86cccc0c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 15 Apr 2017 12:36:43 -0700 Subject: [PATCH 172/177] Document MapAccess misuse --- serde/src/de/mod.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 79ecd9b0..245aa6ea 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -1498,6 +1498,11 @@ pub trait MapAccess<'de> { /// /// `Deserialize` implementations should typically use /// `MapAccess::next_value` instead. + /// + /// # Panics + /// + /// Calling `next_value_seed` before `next_key_seed` is incorrect and is + /// allowed to panic or return bogus results. fn next_value_seed(&mut self, seed: V) -> Result where V: DeserializeSeed<'de>; @@ -1546,6 +1551,11 @@ pub trait MapAccess<'de> { /// /// This method exists as a convenience for `Deserialize` implementations. /// `MapAccess` implementations should not override the default behavior. + /// + /// # Panics + /// + /// Calling `next_value` before `next_key` is incorrect and is allowed to + /// panic or return bogus results. #[inline] fn next_value(&mut self) -> Result where From 3eef7c87c9c8a6eb8514573f70ad4499781e017f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 16 Apr 2017 20:33:15 -0700 Subject: [PATCH 173/177] Fix xml link spacing --- serde/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serde/src/lib.rs b/serde/src/lib.rs index 4b84c7ba..52335228 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -70,7 +70,7 @@ //! [Hjson]: https://github.com/laktak/hjson-rust //! [BSON]: https://github.com/zonyitoo/bson-rs //! [URL]: https://github.com/nox/serde_urlencoded -//! [XML]:https://github.com/RReverser/serde-xml-rs +//! [XML]: https://github.com/RReverser/serde-xml-rs //! [Envy]: https://github.com/softprops/envy //! [Redis]: https://github.com/OneSignal/serde-redis //! [Cargo]: http://doc.crates.io/manifest.html From 739ad64c7cc79afc9acbe81f745671d9bfd0ff47 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 16 Apr 2017 20:44:27 -0700 Subject: [PATCH 174/177] Organize top links --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 358f9b22..c2f35e9c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,9 @@ -# Serde   [![Build Status](https://api.travis-ci.org/serde-rs/serde.svg?branch=master)](https://travis-ci.org/serde-rs/serde) [![Latest Version](https://img.shields.io/crates/v/serde.svg)](https://crates.io/crates/serde) +# Serde   [![Build Status]][travis] [![Latest Version]][crates.io] + +[Build Status]: https://api.travis-ci.org/serde-rs/serde.svg?branch=master +[travis]: https://travis-ci.org/serde-rs/serde +[Latest Version]: https://img.shields.io/crates/v/serde.svg +[crates.io]: https://crates.io/crates/serde **Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.** From 86deb8db795d98a5625cb4d8a4df8074dd5b56e5 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 17 Apr 2017 12:07:49 -0700 Subject: [PATCH 175/177] Remove seq_fixed_size in favor of tuple --- serde/src/de/impls.rs | 4 +- serde/src/de/mod.rs | 91 +++++++------- serde/src/de/value.rs | 48 ++++---- serde/src/macros.rs | 17 ++- serde/src/private/de.rs | 36 +++--- serde/src/private/macros.rs | 3 - serde/src/private/ser.rs | 33 +---- serde/src/ser/impls.rs | 6 +- serde/src/ser/impossible.rs | 3 +- serde/src/ser/mod.rs | 225 +++++++++++++++++++---------------- serde_test/src/de.rs | 27 +---- serde_test/src/ser.rs | 5 - serde_test/src/token.rs | 6 - test_suite/tests/test_de.rs | 20 ++-- test_suite/tests/test_ser.rs | 12 +- 15 files changed, 238 insertions(+), 298 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 6e4c6502..d7e6b7f8 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -634,7 +634,7 @@ impl<'de, T> Deserialize<'de> for [T; 0] { where D: Deserializer<'de>, { - deserializer.deserialize_seq_fixed_size(0, ArrayVisitor::<[T; 0]>::new()) + deserializer.deserialize_tuple(0, ArrayVisitor::<[T; 0]>::new()) } } @@ -675,7 +675,7 @@ macro_rules! array_impls { where D: Deserializer<'de>, { - deserializer.deserialize_seq_fixed_size($len, ArrayVisitor::<[T; $len]>::new()) + deserializer.deserialize_tuple($len, ArrayVisitor::<[T; $len]>::new()) } } )+ diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 245aa6ea..3c9afa6f 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -704,7 +704,7 @@ where /// Serde. /// /// The role of this trait is to define the deserialization half of the Serde -/// data model, which is a way to categorize every Rust data type into one of 28 +/// data model, which is a way to categorize every Rust data type into one of 27 /// possible types. Each method of the `Serializer` trait corresponds to one of /// the types of the data model. /// @@ -714,47 +714,54 @@ where /// /// The types that make up the Serde data model are: /// -/// - 12 primitive types: +/// - **12 primitive types** /// - bool /// - i8, i16, i32, i64 /// - u8, u16, u32, u64 /// - f32, f64 /// - char -/// - string -/// - byte array - [u8] -/// - option -/// - either none or some value -/// - unit -/// - unit is the type of () in Rust -/// - unit_struct -/// - for example `struct Unit` or `PhantomData` -/// - unit_variant -/// - the `E::A` and `E::B` in `enum E { A, B }` -/// - newtype_struct -/// - for example `struct Millimeters(u8)` -/// - newtype_variant -/// - the `E::N` in `enum E { N(u8) }` -/// - seq -/// - a variably sized sequence of values, for example `Vec` or -/// `HashSet` -/// - seq_fixed_size -/// - a statically sized sequence of values for which the size will be known -/// at deserialization time without looking at the serialized data, for -/// example `[u64; 10]` -/// - tuple -/// - for example `(u8,)` or `(String, u64, Vec)` -/// - tuple_struct -/// - for example `struct Rgb(u8, u8, u8)` -/// - tuple_variant -/// - the `E::T` in `enum E { T(u8, u8) }` -/// - map -/// - for example `BTreeMap` -/// - struct -/// - a key-value pairing in which the keys will be known at deserialization -/// time without looking at the serialized data, for example `struct S { r: -/// u8, g: u8, b: u8 }` -/// - struct_variant -/// - the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }` +/// - **string** +/// - UTF-8 bytes with a length and no null terminator. +/// - When serializing, all strings are handled equally. When deserializing, +/// there are three flavors of strings: transient, owned, and borrowed. +/// - **byte array** - [u8] +/// - Similar to strings, during deserialization byte arrays can be transient, +/// owned, or borrowed. +/// - **option** +/// - Either none or some value. +/// - **unit** +/// - The type of `()` in Rust. It represents an anonymous value containing no +/// data. +/// - **unit_struct** +/// - For example `struct Unit` or `PhantomData`. It represents a named value +/// containing no data. +/// - **unit_variant** +/// - For example the `E::A` and `E::B` in `enum E { A, B }`. +/// - **newtype_struct** +/// - For example `struct Millimeters(u8)`. +/// - **newtype_variant** +/// - For example the `E::N` in `enum E { N(u8) }`. +/// - **seq** +/// - A variably sized heterogeneous sequence of values, for example `Vec` or +/// `HashSet`. When serializing, the length may or may not be known before +/// iterating through all the data. When deserializing, the length is determined +/// by looking at the serialized data. +/// - **tuple** +/// - A statically sized heterogeneous sequence of values for which the length +/// will be known at deserialization time without looking at the serialized +/// data, for example `(u8,)` or `(String, u64, Vec)` or `[u64; 10]`. +/// - **tuple_struct** +/// - A named tuple, for example `struct Rgb(u8, u8, u8)`. +/// - **tuple_variant** +/// - For example the `E::T` in `enum E { T(u8, u8) }`. +/// - **map** +/// - A heterogeneous key-value pairing, for example `BTreeMap`. +/// - **struct** +/// - A heterogeneous key-value pairing in which the keys are strings and will be +/// known at deserialization time without looking at the serialized data, for +/// example `struct S { r: u8, g: u8, b: u8 }`. +/// - **struct_variant** +/// - For example the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`. /// /// The `Deserializer` trait supports two entry point styles which enables /// different kinds of deserialization. @@ -944,16 +951,6 @@ pub trait Deserializer<'de>: Sized { /// Hint that the `Deserialize` type is expecting a sequence of values and /// knows how many values there are without looking at the serialized data. - fn deserialize_seq_fixed_size( - self, - len: usize, - visitor: V, - ) -> Result - where - V: Visitor<'de>; - - /// Hint that the `Deserialize` type is expecting a tuple value with a - /// particular number of elements. fn deserialize_tuple(self, len: usize, visitor: V) -> Result where V: Visitor<'de>; diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 97c55881..d8b0b434 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -130,8 +130,8 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf unit unit_struct newtype_struct seq seq_fixed_size tuple - tuple_struct map struct enum identifier ignored_any + byte_buf unit unit_struct newtype_struct seq tuple tuple_struct map + struct enum identifier ignored_any } fn deserialize_any(self, visitor: V) -> Result @@ -183,8 +183,8 @@ macro_rules! primitive_deserializer { forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct enum identifier ignored_any + byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any } fn deserialize_any(self, visitor: V) -> Result @@ -240,8 +240,8 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct identifier ignored_any + byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct + map struct identifier ignored_any } fn deserialize_any(self, visitor: V) -> Result @@ -333,8 +333,8 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct identifier ignored_any + byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct + map struct identifier ignored_any } } @@ -408,8 +408,8 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct identifier ignored_any + byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct + map struct identifier ignored_any } } @@ -487,8 +487,8 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct identifier ignored_any + byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct + map struct identifier ignored_any } } @@ -573,8 +573,8 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct enum identifier ignored_any + byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct + map struct enum identifier ignored_any } } @@ -687,8 +687,8 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct enum identifier ignored_any + byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct + map struct enum identifier ignored_any } } @@ -791,7 +791,7 @@ where Ok(value) } - fn deserialize_seq_fixed_size( + fn deserialize_tuple( self, len: usize, visitor: V, @@ -805,8 +805,8 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct tuple tuple_struct - map struct enum identifier ignored_any + byte_buf option unit unit_struct newtype_struct tuple_struct map struct + enum identifier ignored_any } } @@ -946,8 +946,8 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct tuple tuple_struct - map struct enum identifier ignored_any + byte_buf option unit unit_struct newtype_struct tuple_struct map struct + enum identifier ignored_any } fn deserialize_any(self, visitor: V) -> Result @@ -973,7 +973,7 @@ where } } - fn deserialize_seq_fixed_size(self, len: usize, visitor: V) -> Result + fn deserialize_tuple(self, len: usize, visitor: V) -> Result where V: de::Visitor<'de>, { @@ -1093,8 +1093,8 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct enum identifier ignored_any + byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct + map struct enum identifier ignored_any } } diff --git a/serde/src/macros.rs b/serde/src/macros.rs index 0d654583..2a3d0872 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -44,9 +44,9 @@ /// } /// # /// # forward_to_deserialize_any! { -/// # u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option -/// # seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct -/// # tuple_struct struct identifier tuple enum ignored_any +/// # i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes +/// # byte_buf option unit unit_struct newtype_struct seq tuple +/// # tuple_struct map struct enum identifier ignored_any /// # } /// # } /// # @@ -78,8 +78,8 @@ /// /// forward_to_deserialize_any! { /// bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes -/// byte_buf option unit unit_struct newtype_struct seq seq_fixed_size -/// tuple tuple_struct map struct enum identifier ignored_any +/// byte_buf option unit unit_struct newtype_struct seq tuple +/// tuple_struct map struct enum identifier ignored_any /// } /// } /// # @@ -113,8 +113,8 @@ /// forward_to_deserialize_any! { /// > /// bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes -/// byte_buf option unit unit_struct newtype_struct seq seq_fixed_size -/// tuple tuple_struct map struct enum identifier ignored_any +/// byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct +/// map struct enum identifier ignored_any /// } /// # } /// # @@ -218,9 +218,6 @@ macro_rules! forward_to_deserialize_any_helper { (seq<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_seq<$l, $v>()} }; - (seq_fixed_size<$l:tt, $v:ident>) => { - forward_to_deserialize_any_method!{deserialize_seq_fixed_size<$l, $v>(len: usize)} - }; (tuple<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_tuple<$l, $v>(len: usize)} }; diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 75111321..6666ada2 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -49,8 +49,8 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf unit unit_struct newtype_struct seq seq_fixed_size tuple - tuple_struct map struct enum identifier ignored_any + byte_buf unit unit_struct newtype_struct seq tuple tuple_struct map + struct enum identifier ignored_any } } @@ -995,8 +995,8 @@ mod content { forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf unit unit_struct seq seq_fixed_size tuple tuple_struct map - struct identifier ignored_any + byte_buf unit unit_struct seq tuple tuple_struct map struct + identifier ignored_any } } @@ -1153,8 +1153,8 @@ mod content { forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct enum identifier ignored_any + byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any } } @@ -1254,8 +1254,8 @@ mod content { forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct enum identifier ignored_any + byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any } } @@ -1390,8 +1390,8 @@ mod content { forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf unit unit_struct seq seq_fixed_size tuple tuple_struct map - struct identifier ignored_any + byte_buf unit unit_struct seq tuple tuple_struct map struct + identifier ignored_any } } @@ -1545,8 +1545,8 @@ mod content { forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct enum identifier ignored_any + byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any } } @@ -1647,8 +1647,8 @@ mod content { forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct enum identifier ignored_any + byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any } } @@ -1804,8 +1804,8 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct enum identifier ignored_any + byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct + map struct enum identifier ignored_any } } @@ -1843,7 +1843,7 @@ where forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct enum identifier ignored_any + byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct + map struct enum identifier ignored_any } } diff --git a/serde/src/private/macros.rs b/serde/src/private/macros.rs index 0253e6e0..04676138 100644 --- a/serde/src/private/macros.rs +++ b/serde/src/private/macros.rs @@ -121,9 +121,6 @@ macro_rules! __serialize_unimplemented_helper { type SerializeSeq = $crate::ser::Impossible; __serialize_unimplemented_method!(serialize_seq(Option) -> SerializeSeq); }; - (seq_fixed_size) => { - __serialize_unimplemented_method!(serialize_seq_fixed_size(usize) -> SerializeSeq); - }; (tuple) => { type SerializeTuple = $crate::ser::Impossible; __serialize_unimplemented_method!(serialize_tuple(usize) -> SerializeTuple); diff --git a/serde/src/private/ser.rs b/serde/src/private/ser.rs index 994875d4..8cb26d95 100644 --- a/serde/src/private/ser.rs +++ b/serde/src/private/ser.rs @@ -245,10 +245,6 @@ where Err(self.bad_type(Unsupported::Sequence)) } - fn serialize_seq_fixed_size(self, _: usize) -> Result { - Err(self.bad_type(Unsupported::Sequence)) - } - fn serialize_tuple(self, _: usize) -> Result { Err(self.bad_type(Unsupported::Tuple)) } @@ -484,7 +480,6 @@ mod content { NewtypeVariant(&'static str, u32, &'static str, Box), Seq(Vec), - SeqFixedSize(Vec), Tuple(Vec), TupleStruct(&'static str, Vec), TupleVariant(&'static str, u32, &'static str, Vec), @@ -523,14 +518,6 @@ mod content { serializer.serialize_newtype_variant(n, i, v, &**c) } Content::Seq(ref elements) => elements.serialize(serializer), - Content::SeqFixedSize(ref elements) => { - use ser::SerializeSeq; - let mut seq = try!(serializer.serialize_seq_fixed_size(elements.len())); - for e in elements { - try!(seq.serialize_element(e)); - } - seq.end() - } Content::Tuple(ref elements) => { use ser::SerializeTuple; let mut tuple = try!(serializer.serialize_tuple(elements.len())); @@ -726,23 +713,12 @@ mod content { fn serialize_seq(self, len: Option) -> Result { Ok( SerializeSeq { - fixed_size: false, elements: Vec::with_capacity(len.unwrap_or(0)), error: PhantomData, }, ) } - fn serialize_seq_fixed_size(self, size: usize) -> Result { - Ok( - SerializeSeq { - fixed_size: true, - elements: Vec::with_capacity(size), - error: PhantomData, - }, - ) - } - fn serialize_tuple(self, len: usize) -> Result { Ok( SerializeTuple { @@ -828,7 +804,6 @@ mod content { } struct SerializeSeq { - fixed_size: bool, elements: Vec, error: PhantomData, } @@ -850,13 +825,7 @@ mod content { } fn end(self) -> Result { - Ok( - if self.fixed_size { - Content::SeqFixedSize(self.elements) - } else { - Content::Seq(self.elements) - }, - ) + Ok(Content::Seq(self.elements)) } } diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index b127773e..dad456f1 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -8,7 +8,7 @@ use lib::*; -use ser::{Serialize, SerializeSeq, SerializeTuple, Serializer}; +use ser::{Serialize, SerializeTuple, Serializer}; #[cfg(feature = "std")] use ser::Error; @@ -130,7 +130,7 @@ impl Serialize for [T; 0] { where S: Serializer, { - try!(serializer.serialize_seq_fixed_size(0)).end() + try!(serializer.serialize_tuple(0)).end() } } @@ -146,7 +146,7 @@ macro_rules! array_impls { where S: Serializer, { - let mut seq = try!(serializer.serialize_seq_fixed_size($len)); + let mut seq = try!(serializer.serialize_tuple($len)); for e in self { try!(seq.serialize_element(e)); } diff --git a/serde/src/ser/impossible.rs b/serde/src/ser/impossible.rs index 592047f4..f72748f6 100644 --- a/serde/src/ser/impossible.rs +++ b/serde/src/ser/impossible.rs @@ -53,8 +53,7 @@ use ser::{self, Serialize, SerializeSeq, SerializeTuple, SerializeTupleStruct, /// # __serialize_unimplemented! { /// # bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str bytes none some /// # unit unit_struct unit_variant newtype_struct newtype_variant -/// # seq_fixed_size tuple tuple_struct tuple_variant map struct -/// # struct_variant +/// # tuple tuple_struct tuple_variant map struct struct_variant /// # } /// } /// # diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 0aa3c9a7..67b60fcc 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -239,7 +239,7 @@ pub trait Serialize { /// A **data format** that can serialize any data structure supported by Serde. /// /// The role of this trait is to define the serialization half of the Serde data -/// model, which is a way to categorize every Rust data structure into one of 28 +/// model, which is a way to categorize every Rust data structure into one of 27 /// possible types. Each method of the `Serializer` trait corresponds to one of /// the types of the data model. /// @@ -248,47 +248,54 @@ pub trait Serialize { /// /// The types that make up the Serde data model are: /// -/// - 12 primitive types: +/// - **12 primitive types** /// - bool /// - i8, i16, i32, i64 /// - u8, u16, u32, u64 /// - f32, f64 /// - char -/// - string -/// - byte array - [u8] -/// - option -/// - either none or some value -/// - unit -/// - unit is the type of () in Rust -/// - unit_struct -/// - for example `struct Unit` or `PhantomData` -/// - unit_variant -/// - the `E::A` and `E::B` in `enum E { A, B }` -/// - newtype_struct -/// - for example `struct Millimeters(u8)` -/// - newtype_variant -/// - the `E::N` in `enum E { N(u8) }` -/// - seq -/// - a variably sized sequence of values, for example `Vec` or -/// `HashSet` -/// - seq_fixed_size -/// - a statically sized sequence of values for which the size will be known -/// at deserialization time without looking at the serialized data, for -/// example `[u64; 10]` -/// - tuple -/// - for example `(u8,)` or `(String, u64, Vec)` -/// - tuple_struct -/// - for example `struct Rgb(u8, u8, u8)` -/// - tuple_variant -/// - the `E::T` in `enum E { T(u8, u8) }` -/// - map -/// - for example `BTreeMap` -/// - struct -/// - a key-value pairing in which the keys will be known at deserialization -/// time without looking at the serialized data, for example `struct S { r: -/// u8, g: u8, b: u8 }` -/// - struct_variant -/// - the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }` +/// - **string** +/// - UTF-8 bytes with a length and no null terminator. +/// - When serializing, all strings are handled equally. When deserializing, +/// there are three flavors of strings: transient, owned, and borrowed. +/// - **byte array** - [u8] +/// - Similar to strings, during deserialization byte arrays can be transient, +/// owned, or borrowed. +/// - **option** +/// - Either none or some value. +/// - **unit** +/// - The type of `()` in Rust. It represents an anonymous value containing no +/// data. +/// - **unit_struct** +/// - For example `struct Unit` or `PhantomData`. It represents a named value +/// containing no data. +/// - **unit_variant** +/// - For example the `E::A` and `E::B` in `enum E { A, B }`. +/// - **newtype_struct** +/// - For example `struct Millimeters(u8)`. +/// - **newtype_variant** +/// - For example the `E::N` in `enum E { N(u8) }`. +/// - **seq** +/// - A variably sized heterogeneous sequence of values, for example `Vec` or +/// `HashSet`. When serializing, the length may or may not be known before +/// iterating through all the data. When deserializing, the length is determined +/// by looking at the serialized data. +/// - **tuple** +/// - A statically sized heterogeneous sequence of values for which the length +/// will be known at deserialization time without looking at the serialized +/// data, for example `(u8,)` or `(String, u64, Vec)` or `[u64; 10]`. +/// - **tuple_struct** +/// - A named tuple, for example `struct Rgb(u8, u8, u8)`. +/// - **tuple_variant** +/// - For example the `E::T` in `enum E { T(u8, u8) }`. +/// - **map** +/// - A heterogeneous key-value pairing, for example `BTreeMap`. +/// - **struct** +/// - A heterogeneous key-value pairing in which the keys are strings and will be +/// known at deserialization time without looking at the serialized data, for +/// example `struct S { r: u8, g: u8, b: u8 }`. +/// - **struct_variant** +/// - For example the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`. /// /// Many Serde serializers produce text or binary data as output, for example /// JSON or Bincode. This is not a requirement of the `Serializer` trait, and @@ -310,11 +317,10 @@ pub trait Serializer: Sized { /// The error type when some error occurs during serialization. type Error: Error; - /// Type returned from [`serialize_seq`] and [`serialize_seq_fixed_size`] - /// for serializing the content of the sequence. + /// Type returned from [`serialize_seq`] for serializing the content of the + /// sequence. /// /// [`serialize_seq`]: #tymethod.serialize_seq - /// [`serialize_seq_fixed_size`]: #tymethod.serialize_seq_fixed_size type SerializeSeq: SerializeSeq; /// Type returned from [`serialize_tuple`] for serializing the content of @@ -702,8 +708,7 @@ pub trait Serializer: Sized { /// # __serialize_unimplemented! { /// # bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str none some /// # unit unit_struct unit_variant newtype_struct newtype_variant - /// # seq seq_fixed_size tuple tuple_struct tuple_variant map struct - /// # struct_variant + /// # seq tuple tuple_struct tuple_variant map struct struct_variant /// # } /// # } /// # @@ -966,29 +971,6 @@ pub trait Serializer: Sized { /// then a call to `end`. /// /// ```rust - /// use serde::ser::{Serialize, Serializer, SerializeSeq}; - /// - /// const VRAM_SIZE: usize = 386; - /// struct Vram([u16; VRAM_SIZE]); - /// - /// impl Serialize for Vram { - /// fn serialize(&self, serializer: S) -> Result - /// where S: Serializer - /// { - /// let mut seq = serializer.serialize_seq_fixed_size(VRAM_SIZE)?; - /// for element in &self.0[..] { - /// seq.serialize_element(element)?; - /// } - /// seq.end() - /// } - /// } - /// ``` - fn serialize_seq_fixed_size(self, size: usize) -> Result; - - /// Begin to serialize a tuple. This call must be followed by zero or more - /// calls to `serialize_element`, then a call to `end`. - /// - /// ```rust /// use serde::ser::{Serialize, Serializer, SerializeTuple}; /// /// # mod fool { @@ -1015,6 +997,25 @@ pub trait Serializer: Sized { /// } /// } /// ``` + /// + /// ```rust + /// use serde::ser::{Serialize, Serializer, SerializeTuple}; + /// + /// const VRAM_SIZE: usize = 386; + /// struct Vram([u16; VRAM_SIZE]); + /// + /// impl Serialize for Vram { + /// fn serialize(&self, serializer: S) -> Result + /// where S: Serializer + /// { + /// let mut seq = serializer.serialize_tuple(VRAM_SIZE)?; + /// for element in &self.0[..] { + /// seq.serialize_element(element)?; + /// } + /// seq.end() + /// } + /// } + /// ``` fn serialize_tuple(self, len: usize) -> Result; /// Begin to serialize a tuple struct like `struct Rgb(u8, u8, u8)`. This @@ -1359,34 +1360,26 @@ pub trait Serializer: Sized { T: Display; } -/// Returned from `Serializer::serialize_seq` and -/// `Serializer::serialize_seq_fixed_size`. +/// Returned from `Serializer::serialize_seq`. /// /// ```rust /// # use std::marker::PhantomData; /// # -/// # macro_rules! unimplemented_vec { -/// # ($name:ident) => { -/// # struct $name(PhantomData); +/// # struct Vec(PhantomData); /// # -/// # impl $name { -/// # fn len(&self) -> usize { -/// # unimplemented!() -/// # } -/// # } -/// # -/// # impl<'a, T> IntoIterator for &'a $name { -/// # type Item = &'a T; -/// # type IntoIter = Box>; -/// # fn into_iter(self) -> Self::IntoIter { -/// # unimplemented!() -/// # } -/// # } +/// # impl Vec { +/// # fn len(&self) -> usize { +/// # unimplemented!() /// # } /// # } /// # -/// # unimplemented_vec!(Vec); -/// # unimplemented_vec!(Array); +/// # impl<'a, T> IntoIterator for &'a Vec { +/// # type Item = &'a T; +/// # type IntoIter = Box>; +/// # fn into_iter(self) -> Self::IntoIter { +/// # unimplemented!() +/// # } +/// # } /// # /// use serde::ser::{Serialize, Serializer, SerializeSeq}; /// @@ -1403,26 +1396,6 @@ pub trait Serializer: Sized { /// seq.end() /// } /// } -/// -/// # mod fool { -/// # trait Serialize {} -/// impl Serialize for [T; 16] -/// # {} -/// # } -/// # -/// # impl Serialize for Array -/// where T: Serialize -/// { -/// fn serialize(&self, serializer: S) -> Result -/// where S: Serializer -/// { -/// let mut seq = serializer.serialize_seq_fixed_size(16)?; -/// for element in self { -/// seq.serialize_element(element)?; -/// } -/// seq.end() -/// } -/// } /// ``` pub trait SerializeSeq { /// Must match the `Ok` type of our `Serializer`. @@ -1469,6 +1442,48 @@ pub trait SerializeSeq { /// } /// } /// ``` +/// +/// ```rust +/// # use std::marker::PhantomData; +/// # +/// # struct Array(PhantomData); +/// # +/// # impl Array { +/// # fn len(&self) -> usize { +/// # unimplemented!() +/// # } +/// # } +/// # +/// # impl<'a, T> IntoIterator for &'a Array { +/// # type Item = &'a T; +/// # type IntoIter = Box>; +/// # fn into_iter(self) -> Self::IntoIter { +/// # unimplemented!() +/// # } +/// # } +/// # +/// use serde::ser::{Serialize, Serializer, SerializeTuple}; +/// +/// # mod fool { +/// # trait Serialize {} +/// impl Serialize for [T; 16] +/// # {} +/// # } +/// # +/// # impl Serialize for Array +/// where T: Serialize +/// { +/// fn serialize(&self, serializer: S) -> Result +/// where S: Serializer +/// { +/// let mut seq = serializer.serialize_tuple(16)?; +/// for element in self { +/// seq.serialize_element(element)?; +/// } +/// seq.end() +/// } +/// } +/// ``` pub trait SerializeTuple { /// Must match the `Ok` type of our `Serializer`. type Ok; diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index 9b5fc85a..bb201073 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -132,7 +132,6 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { Token::UnitStruct(_name) => visitor.visit_unit(), Token::NewtypeStruct(_name) => visitor.visit_newtype_struct(self), Token::Seq(len) => self.visit_seq(len, Token::SeqEnd, visitor), - Token::SeqFixedSize(len) => self.visit_seq(Some(len), Token::SeqEnd, visitor), Token::Tuple(len) => self.visit_seq(Some(len), Token::TupleEnd, visitor), Token::TupleStruct(_, len) => self.visit_seq(Some(len), Token::TupleStructEnd, visitor), Token::Map(len) => self.visit_map(len, Token::MapEnd, visitor), @@ -262,20 +261,6 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } } - fn deserialize_seq_fixed_size(self, len: usize, visitor: V) -> Result - where - V: Visitor<'de>, - { - match self.tokens.first() { - Some(&Token::SeqFixedSize(_)) => { - self.next_token(); - self.visit_seq(Some(len), Token::SeqEnd, visitor) - } - Some(_) => self.deserialize_any(visitor), - None => Err(Error::EndOfTokens), - } - } - fn deserialize_tuple(self, len: usize, visitor: V) -> Result where V: Visitor<'de>, @@ -290,10 +275,6 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { self.next_token(); self.visit_seq(Some(len), Token::SeqEnd, visitor) } - Some(&Token::SeqFixedSize(_)) => { - self.next_token(); - self.visit_seq(Some(len), Token::SeqEnd, visitor) - } Some(&Token::Tuple(_)) => { self.next_token(); self.visit_seq(Some(len), Token::TupleEnd, visitor) @@ -333,10 +314,6 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { self.next_token(); self.visit_seq(Some(len), Token::SeqEnd, visitor) } - Some(&Token::SeqFixedSize(_)) => { - self.next_token(); - self.visit_seq(Some(len), Token::SeqEnd, visitor) - } Some(&Token::Tuple(_)) => { self.next_token(); self.visit_seq(Some(len), Token::TupleEnd, visitor) @@ -656,7 +633,7 @@ impl<'de> de::Deserializer<'de> for BytesDeserializer { forward_to_deserialize_any! { bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq seq_fixed_size - tuple tuple_struct map struct enum identifier ignored_any + byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct + map struct enum identifier ignored_any } } diff --git a/serde_test/src/ser.rs b/serde_test/src/ser.rs index b7b80d3b..5c90fee4 100644 --- a/serde_test/src/ser.rs +++ b/serde_test/src/ser.rs @@ -212,11 +212,6 @@ impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> { Ok(self) } - fn serialize_seq_fixed_size(self, len: usize) -> Result { - assert_next_token!(self, SeqFixedSize(len)); - Ok(self) - } - fn serialize_tuple(self, len: usize) -> Result { assert_next_token!(self, Tuple(len)); Ok(self) diff --git a/serde_test/src/token.rs b/serde_test/src/token.rs index c640e48f..07bbc0b9 100644 --- a/serde_test/src/token.rs +++ b/serde_test/src/token.rs @@ -103,12 +103,6 @@ pub enum Token { /// header is a list of elements, followed by `SeqEnd`. Seq(Option), - /// The header to an array of the given length. - /// - /// These are serialized via `serialize_seq_fized_size`, which requires a length. After this - /// header is a list of elements, followed by `SeqEnd`. - SeqFixedSize(usize), - /// An indicator of the end of a sequence. SeqEnd, diff --git a/test_suite/tests/test_de.rs b/test_suite/tests/test_de.rs index 4a0ebb10..e76fc6a9 100644 --- a/test_suite/tests/test_de.rs +++ b/test_suite/tests/test_de.rs @@ -360,8 +360,8 @@ declare_tests! { Token::SeqEnd, ], [0; 0] => &[ - Token::SeqFixedSize(0), - Token::SeqEnd, + Token::Tuple(0), + Token::TupleEnd, ], ([0; 0], [1], [2, 3]) => &[ Token::Seq(Some(3)), @@ -379,19 +379,19 @@ declare_tests! { Token::SeqEnd, ], ([0; 0], [1], [2, 3]) => &[ - Token::SeqFixedSize(3), - Token::SeqFixedSize(0), - Token::SeqEnd, + Token::Tuple(3), + Token::Tuple(0), + Token::TupleEnd, - Token::SeqFixedSize(1), + Token::Tuple(1), Token::I32(1), - Token::SeqEnd, + Token::TupleEnd, - Token::SeqFixedSize(2), + Token::Tuple(2), Token::I32(2), Token::I32(3), - Token::SeqEnd, - Token::SeqEnd, + Token::TupleEnd, + Token::TupleEnd, ], [0; 0] => &[ Token::TupleStruct("Anything", 0), diff --git a/test_suite/tests/test_ser.rs b/test_suite/tests/test_ser.rs index 28472ce3..2de5db14 100644 --- a/test_suite/tests/test_ser.rs +++ b/test_suite/tests/test_ser.rs @@ -138,15 +138,15 @@ declare_tests! { } test_array { [0; 0] => &[ - Token::SeqFixedSize(0), - Token::SeqEnd, + Token::Tuple(0), + Token::TupleEnd, ], [1, 2, 3] => &[ - Token::SeqFixedSize(3), + Token::Tuple(3), Token::I32(1), Token::I32(2), Token::I32(3), - Token::SeqEnd, + Token::TupleEnd, ], } test_vec { @@ -301,11 +301,11 @@ declare_tests! { } test_boxed_slice { Box::new([0, 1, 2]) => &[ - Token::SeqFixedSize(3), + Token::Tuple(3), Token::I32(0), Token::I32(1), Token::I32(2), - Token::SeqEnd, + Token::TupleEnd, ], } test_duration { From 6279b0d93025dd69183b56a0c69de87ffdafbaef Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 17 Apr 2017 14:19:32 -0700 Subject: [PATCH 176/177] Resolve merge conflicts --- serde/Cargo.toml | 8 +-- serde/src/de/impls.rs | 127 ++++++++++------------------------------ serde/src/lib.rs | 3 + serde/src/ser/impls.rs | 47 ++++++--------- serde_derive/Cargo.toml | 8 +-- serde_test/Cargo.toml | 8 +-- 6 files changed, 54 insertions(+), 147 deletions(-) diff --git a/serde/Cargo.toml b/serde/Cargo.toml index 81b5dd60..c1b4709f 100644 --- a/serde/Cargo.toml +++ b/serde/Cargo.toml @@ -1,12 +1,6 @@ [package] name = "serde" -<<<<<<< HEAD -version = "0.9.13" # remember to update html_root_url -||||||| merged common ancestors -version = "0.9.13" -======= -version = "0.9.14" ->>>>>>> origin/master +version = "0.9.14" # remember to update html_root_url authors = ["Erick Tryzelaar "] license = "MIT/Apache-2.0" description = "A generic serialization/deserialization framework" diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 4e8c7f0f..b1aedff4 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -12,82 +12,7 @@ use de::{Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, Va Visitor}; #[cfg(any(feature = "std", feature = "collections"))] -<<<<<<< HEAD use de::MapAccess; -||||||| merged common ancestors -use core::cmp; -use core::fmt; -#[cfg(feature = "std")] -use core::hash::{Hash, BuildHasher}; -use core::marker::PhantomData; -#[cfg(feature = "std")] -use std::net; -#[cfg(feature = "std")] -use std::path; -use core::str; -#[cfg(feature = "std")] -use std::ffi::{CString, OsString}; -#[cfg(all(feature = "std", feature="unstable"))] -use std::ffi::CStr; - -#[cfg(feature = "std")] -use std::rc::Rc; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::rc::Rc; - -#[cfg(feature = "std")] -use std::sync::Arc; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::arc::Arc; - -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::boxed::Box; - -#[cfg(feature = "std")] -use std::time::Duration; - -#[cfg(feature = "std")] -use std; -======= -use core::cmp; -use core::fmt; -#[cfg(feature = "std")] -use core::hash::{Hash, BuildHasher}; -use core::marker::PhantomData; -#[cfg(feature = "std")] -use std::net; -#[cfg(feature = "std")] -use std::path; -use core::str; -#[cfg(feature = "std")] -use std::ffi::{CString, OsString}; -#[cfg(all(feature = "std", feature="unstable"))] -use std::ffi::CStr; - -#[cfg(feature = "std")] -use std::rc::Rc; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::rc::Rc; - -#[cfg(feature = "std")] -use std::sync::Arc; -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::arc::Arc; - -#[cfg(all(feature = "alloc", not(feature = "std")))] -use alloc::boxed::Box; - -use core::cell::{Cell, RefCell}; - -#[cfg(feature = "std")] -use std::sync::{Mutex, RwLock}; - -#[cfg(feature = "std")] -use std::time::Duration; - -#[cfg(feature = "std")] -use std; ->>>>>>> origin/master use de::from_primitive::FromPrimitive; @@ -1210,51 +1135,59 @@ where } } -<<<<<<< HEAD //////////////////////////////////////////////////////////////////////////////// -||||||| merged common ancestors -/////////////////////////////////////////////////////////////////////////////// -======= -impl Deserialize for Cell { + +impl<'de, T> Deserialize<'de> for Cell +where + T: Deserialize<'de> + Copy, +{ fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer + where + D: Deserializer<'de>, { - let val = try!(Deserialize::deserialize(deserializer)); - Ok(Cell::new(val)) + T::deserialize(deserializer).map(Cell::new) } } -impl Deserialize for RefCell { +impl<'de, T> Deserialize<'de> for RefCell +where + T: Deserialize<'de> +{ fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer + where + D: Deserializer<'de>, { - let val = try!(Deserialize::deserialize(deserializer)); - Ok(RefCell::new(val)) + T::deserialize(deserializer).map(RefCell::new) } } #[cfg(feature = "std")] -impl Deserialize for Mutex { +impl<'de, T> Deserialize<'de> for Mutex +where + T: Deserialize<'de>, +{ fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer + where + D: Deserializer<'de>, { - let val = try!(Deserialize::deserialize(deserializer)); - Ok(Mutex::new(val)) + T::deserialize(deserializer).map(Mutex::new) } } #[cfg(feature = "std")] -impl Deserialize for RwLock { +impl<'de, T> Deserialize<'de> for RwLock +where + T: Deserialize<'de>, +{ fn deserialize(deserializer: D) -> Result, D::Error> - where D: Deserializer + where + D: Deserializer<'de>, { - let val = try!(Deserialize::deserialize(deserializer)); - Ok(RwLock::new(val)) + T::deserialize(deserializer).map(RwLock::new) } } -/////////////////////////////////////////////////////////////////////////////// ->>>>>>> origin/master +//////////////////////////////////////////////////////////////////////////////// // This is a cleaned-up version of the impl generated by: // diff --git a/serde/src/lib.rs b/serde/src/lib.rs index 52335228..c97339d4 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -129,6 +129,7 @@ mod lib { pub use self::core::{u8, u16, u32, u64, usize}; pub use self::core::{f32, f64}; + pub use self::core::cell::{Cell, RefCell}; pub use self::core::clone::{self, Clone}; pub use self::core::convert::{self, From, Into}; pub use self::core::default::{self, Default}; @@ -187,6 +188,8 @@ mod lib { pub use std::path::{Path, PathBuf}; #[cfg(feature = "std")] pub use std::time::Duration; + #[cfg(feature = "std")] + pub use std::sync::{Mutex, RwLock}; #[cfg(feature = "unstable")] pub use core::nonzero::{NonZero, Zeroable}; diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 10415680..4adfd24a 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -13,18 +13,7 @@ use ser::{Serialize, SerializeTuple, Serializer}; #[cfg(feature = "std")] use ser::Error; -<<<<<<< HEAD //////////////////////////////////////////////////////////////////////////////// -||||||| merged common ancestors -use core::marker::PhantomData; -======= -use core::cell::{Cell, RefCell}; - -#[cfg(feature = "std")] -use std::sync::{Mutex, RwLock}; - -use core::marker::PhantomData; ->>>>>>> origin/master macro_rules! primitive_impl { ($ty:ident, $method:ident $($cast:tt)*) => { @@ -360,28 +349,27 @@ deref_impl!(<'a, T: ?Sized> Serialize for Cow<'a, T> where T: Serialize + ToOwne #[cfg(feature = "unstable")] deref_impl!( Serialize for NonZero where T: Serialize + Zeroable); -<<<<<<< HEAD //////////////////////////////////////////////////////////////////////////////// -||||||| merged common ancestors -/////////////////////////////////////////////////////////////////////////////// -======= + impl Serialize for Cell - where T: Serialize + Copy +where + T: Serialize + Copy, { - #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { self.get().serialize(serializer) } } impl Serialize for RefCell - where T: Serialize +where + T: Serialize, { - #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { self.borrow().serialize(serializer) } @@ -389,11 +377,12 @@ impl Serialize for RefCell #[cfg(feature = "std")] impl Serialize for Mutex - where T: Serialize +where + T: Serialize, { - #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { match self.lock() { Ok(locked) => locked.serialize(serializer), @@ -404,11 +393,12 @@ impl Serialize for Mutex #[cfg(feature = "std")] impl Serialize for RwLock - where T: Serialize +where + T: Serialize, { - #[inline] fn serialize(&self, serializer: S) -> Result - where S: Serializer + where + S: Serializer, { match self.read() { Ok(locked) => locked.serialize(serializer), @@ -417,8 +407,7 @@ impl Serialize for RwLock } } -/////////////////////////////////////////////////////////////////////////////// ->>>>>>> origin/master +//////////////////////////////////////////////////////////////////////////////// impl Serialize for Result where diff --git a/serde_derive/Cargo.toml b/serde_derive/Cargo.toml index 086fbce8..8c8d147f 100644 --- a/serde_derive/Cargo.toml +++ b/serde_derive/Cargo.toml @@ -1,12 +1,6 @@ [package] name = "serde_derive" -<<<<<<< HEAD -version = "0.9.13" # remember to update html_root_url -||||||| merged common ancestors -version = "0.9.13" -======= -version = "0.9.14" ->>>>>>> origin/master +version = "0.9.14" # remember to update html_root_url authors = ["Erick Tryzelaar "] license = "MIT/Apache-2.0" description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" diff --git a/serde_test/Cargo.toml b/serde_test/Cargo.toml index 4feeca64..7f1c2602 100644 --- a/serde_test/Cargo.toml +++ b/serde_test/Cargo.toml @@ -1,12 +1,6 @@ [package] name = "serde_test" -<<<<<<< HEAD -version = "0.9.13" # remember to update html_root_url -||||||| merged common ancestors -version = "0.9.13" -======= -version = "0.9.14" ->>>>>>> origin/master +version = "0.9.14" # remember to update html_root_url authors = ["Erick Tryzelaar "] license = "MIT/Apache-2.0" description = "Token De/Serializer for testing De/Serialize implementations" From b8a6e68322ebd868a5635c96cfc550d9cb6fe220 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 17 Apr 2017 16:18:48 -0700 Subject: [PATCH 177/177] Revert "Allow borrowing from str's IntoDeserializer" This reverts commit 30e8c84d0102957f77eab058033f5a81eb073815. --- serde/src/de/value.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index d8b0b434..f3bf0558 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -290,7 +290,7 @@ pub struct StrDeserializer<'a, E> { marker: PhantomData, } -impl<'a, E> IntoDeserializer<'a, E> for &'a str +impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a str where E: de::Error, { @@ -304,7 +304,7 @@ where } } -impl<'de, E> de::Deserializer<'de> for StrDeserializer<'de, E> +impl<'de, 'a, E> de::Deserializer<'de> for StrDeserializer<'a, E> where E: de::Error, { @@ -314,7 +314,7 @@ where where V: de::Visitor<'de>, { - visitor.visit_borrowed_str(self.value) + visitor.visit_str(self.value) } fn deserialize_enum( @@ -338,7 +338,7 @@ where } } -impl<'de, E> de::EnumAccess<'de> for StrDeserializer<'de, E> +impl<'de, 'a, E> de::EnumAccess<'de> for StrDeserializer<'a, E> where E: de::Error, {