diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 1f0c8adc..6d394736 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -116,7 +116,6 @@ use lib::*; //////////////////////////////////////////////////////////////////////////////// -#[macro_use] pub mod value; mod from_primitive; diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index fcacb0c3..e2f24118 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -25,15 +25,13 @@ use lib::*; use self::private::{First, Second}; use __private::de::size_hint; -use de::{self, Expected, IntoDeserializer, SeqAccess}; +use de::{self, Deserializer, Expected, IntoDeserializer, SeqAccess, Visitor}; use ser; //////////////////////////////////////////////////////////////////////////////// -/// For structs that contain a PhantomData. We do not want the trait -/// bound `E: Clone` inferred by derive(Clone). -#[doc(hidden)] -#[macro_export] +// For structs that contain a PhantomData. We do not want the trait +// bound `E: Clone` inferred by derive(Clone). macro_rules! impl_copy_clone { ($ty:ident $(<$lifetime:tt>)*) => { impl<$($lifetime,)* E> Copy for $ty<$($lifetime,)* E> {} @@ -46,102 +44,6 @@ macro_rules! impl_copy_clone { }; } -/// Creates a deserializer any method of which forwards to the specified visitor method -#[doc(hidden)] -#[macro_export(local_inner_macros)] -macro_rules! forward_deserializer { - // Non-borrowed references - ( - $(#[$doc:meta])* - // Actually, * in lifetime should be ?, but that syntax is not supported - // on old Rust versions (<= 1.28) or in 2015 edition - ref $deserializer:ident $(<$lifetime:tt>)* ($ty:ty) => $visit:ident - ) => { - $(#[$doc])* - #[derive(Debug)] - pub struct $deserializer<$($lifetime,)* E> { - value: $ty, - marker: PhantomData, - } - - impl<$($lifetime,)* E> $deserializer<$($lifetime,)* E> { - /// Create a new deserializer from the given value. - pub fn new(value: $ty) -> Self { - $deserializer { - value: value, - marker: PhantomData, - } - } - } - - impl_copy_clone!($deserializer $(<$lifetime>)*); - - impl<'de, $($lifetime,)* E> $crate::de::Deserializer<'de> for $deserializer<$($lifetime,)* E> - where - E: $crate::de::Error, - { - type Error = E; - - fn deserialize_any(self, visitor: V) -> $crate::export::Result - where - V: $crate::de::Visitor<'de>, - { - visitor.$visit(self.value) - } - - forward_to_deserialize_any! { - bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str - string bytes byte_buf option unit unit_struct newtype_struct seq - tuple tuple_struct map struct enum identifier ignored_any - } - } - }; - // Borrowed references - ( - $(#[$doc:meta])* - borrowed $deserializer:ident($ty:ty) => $visit:ident - ) => { - $(#[$doc])* - #[derive(Debug)] - pub struct $deserializer<'de, E> { - value: $ty, - marker: PhantomData, - } - - impl<'de, E> $deserializer<'de, E> { - /// Create a new borrowed deserializer from the given value. - pub fn new(value: $ty) -> Self { - $deserializer { - value: value, - marker: PhantomData, - } - } - } - - impl_copy_clone!($deserializer<'de>); - - impl<'de, E> $crate::de::Deserializer<'de> for $deserializer<'de, E> - where - E: $crate::de::Error, - { - type Error = E; - - fn deserialize_any(self, visitor: V) -> $crate::export::Result - where - V: $crate::de::Visitor<'de>, - { - visitor.$visit(self.value) - } - - forward_to_deserialize_any! { - bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str - string bytes byte_buf option unit unit_struct newtype_struct seq - tuple tuple_struct map struct enum identifier ignored_any - } - } - }; -} - //////////////////////////////////////////////////////////////////////////////// /// A minimal representation of all possible errors that can occur using the @@ -763,19 +665,84 @@ where //////////////////////////////////////////////////////////////////////////////// -forward_deserializer!( - /// A deserializer holding a `&[u8]`. Always call [`Visitor::visit_bytes`] - /// - /// [`Visitor::visit_bytes`]: ../struct.Visitor.html#method.visit_bytes - ref BytesDeserializer<'a>(&'a [u8]) => visit_bytes -); -forward_deserializer!( - /// A deserializer holding a `&[u8]` with a lifetime tied to another - /// deserializer. Always call [`Visitor::visit_borrowed_bytes`] - /// - /// [`Visitor::visit_borrowed_bytes`]: ../struct.Visitor.html#method.visit_borrowed_bytes - borrowed BorrowedBytesDeserializer(&'de [u8]) => visit_borrowed_bytes -); +/// A deserializer holding a `&[u8]`. Always calls [`Visitor::visit_bytes`]. +#[derive(Debug)] +pub struct BytesDeserializer<'a, E> { + value: &'a [u8], + marker: PhantomData, +} + +impl<'a, E> BytesDeserializer<'a, E> { + /// Create a new deserializer from the given bytes. + pub fn new(value: &'a [u8]) -> Self { + BytesDeserializer { + value: value, + marker: PhantomData, + } + } +} + +impl_copy_clone!(BytesDeserializer<'a>); + +impl<'de, 'a, E> Deserializer<'de> for BytesDeserializer<'a, E> +where + E: de::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 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } +} + +/// A deserializer holding a `&[u8]` with a lifetime tied to another +/// deserializer. Always calls [`Visitor::visit_borrowed_bytes`]. +#[derive(Debug)] +pub struct BorrowedBytesDeserializer<'de, E> { + value: &'de [u8], + marker: PhantomData, +} + +impl<'de, E> BorrowedBytesDeserializer<'de, E> { + /// Create a new borrowed deserializer from the given borrowed bytes. + pub fn new(value: &'de [u8]) -> Self { + BorrowedBytesDeserializer { + value: value, + marker: PhantomData, + } + } +} + +impl_copy_clone!(BorrowedBytesDeserializer<'de>); + +impl<'de, E> Deserializer<'de> for BorrowedBytesDeserializer<'de, E> +where + E: de::Error, +{ + type Error = E; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_borrowed_bytes(self.value) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } +} //////////////////////////////////////////////////////////////////////////////// diff --git a/serde/src/lib.rs b/serde/src/lib.rs index bc7b9401..8cc8faea 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -258,7 +258,6 @@ mod macros; #[macro_use] mod integer128; -#[macro_use] pub mod de; pub mod ser; diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 24d2d691..fc37b9e5 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -1,7 +1,7 @@ use lib::*; +use de::value::{BorrowedBytesDeserializer, BytesDeserializer}; use de::{Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, Visitor}; -use de::value::{BytesDeserializer, BorrowedBytesDeserializer}; #[cfg(any(feature = "std", feature = "alloc"))] use de::{MapAccess, Unexpected}; @@ -2561,8 +2561,55 @@ where } } -forward_deserializer!(ref StrDeserializer<'a>(&'a str) => visit_str); -forward_deserializer!(borrowed BorrowedStrDeserializer(&'de str) => visit_borrowed_str); +pub struct StrDeserializer<'a, E> { + value: &'a str, + 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 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } +} + +pub struct BorrowedStrDeserializer<'de, E> { + value: &'de str, + marker: PhantomData, +} + +impl<'de, E> Deserializer<'de> for BorrowedStrDeserializer<'de, E> +where + E: Error, +{ + type Error = E; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_borrowed_str(self.value) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } +} impl<'a, E> IdentifierDeserializer<'a, E> for &'a str where @@ -2572,11 +2619,17 @@ where type BorrowedDeserializer = BorrowedStrDeserializer<'a, E>; fn from(self) -> Self::Deserializer { - StrDeserializer::new(self) + StrDeserializer { + value: self, + marker: PhantomData, + } } fn borrowed(self) -> Self::BorrowedDeserializer { - BorrowedStrDeserializer::new(self) + BorrowedStrDeserializer { + value: self, + marker: PhantomData, + } } } diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index c9a4bd34..9e9c4022 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -1893,15 +1893,12 @@ fn deserialize_generated_identifier( let fallthrough = quote!(_serde::__private::Ok(__Field::__other(__value))); ( Some(ignore_variant), - Some((fallthrough.clone(), fallthrough)) + Some((fallthrough.clone(), fallthrough)), ) } else if let Some(other_idx) = other_idx { let ignore_variant = fields[other_idx].1.clone(); let fallthrough = quote!(_serde::__private::Ok(__Field::#ignore_variant)); - ( - None, - Some((fallthrough.clone(), fallthrough)) - ) + (None, Some((fallthrough.clone(), fallthrough))) } else if is_variant || cattrs.deny_unknown_fields() { (None, None) } else { @@ -1909,7 +1906,7 @@ fn deserialize_generated_identifier( let fallthrough = quote!(_serde::__private::Ok(__Field::__ignore)); ( Some(ignore_variant), - Some((fallthrough.clone(), fallthrough)) + Some((fallthrough.clone(), fallthrough)), ) }; @@ -1973,25 +1970,21 @@ fn deserialize_custom_identifier( if last.attrs.other() { let ordinary = &variants[..variants.len() - 1]; let fallthrough = quote!(_serde::__private::Ok(#this::#last_ident)); - ( - ordinary, - Some((fallthrough.clone(), fallthrough)) - ) + (ordinary, Some((fallthrough.clone(), fallthrough))) } else if let Style::Newtype = last.style { let ordinary = &variants[..variants.len() - 1]; - let fallthrough = |method| quote! { - _serde::__private::Result::map( - _serde::Deserialize::deserialize( - _serde::__private::de::IdentifierDeserializer::#method(__value) - ), - #this::#last_ident) + let fallthrough = |method| { + quote! { + _serde::__private::Result::map( + _serde::Deserialize::deserialize( + _serde::__private::de::IdentifierDeserializer::#method(__value) + ), + #this::#last_ident) + } }; ( ordinary, - Some(( - fallthrough(quote!(from)), - fallthrough(quote!(borrowed)), - )) + Some((fallthrough(quote!(from)), fallthrough(quote!(borrowed)))), ) } else { (variants, None) @@ -2128,10 +2121,7 @@ fn deserialize_identifier( (None, None, None, None) }; - let ( - fallthrough_arm, - fallthrough_borrowed_arm, - ) = if let Some(fallthrough) = fallthrough.clone() { + let (fallthrough_arm, fallthrough_borrowed_arm) = if let Some(fallthrough) = fallthrough { fallthrough } else if is_variant { let fallthrough = quote! { diff --git a/test_suite/tests/test_borrow.rs b/test_suite/tests/test_borrow.rs index 15139cb9..fd8c9651 100644 --- a/test_suite/tests/test_borrow.rs +++ b/test_suite/tests/test_borrow.rs @@ -99,12 +99,7 @@ fn test_field_identifier() { Str(&'a str), } - assert_de_tokens( - &FieldStr::Str("value"), - &[ - Token::BorrowedStr("value"), - ], - ); + assert_de_tokens(&FieldStr::Str("value"), &[Token::BorrowedStr("value")]); #[derive(Deserialize, Debug, PartialEq)] #[serde(field_identifier)] @@ -115,9 +110,7 @@ fn test_field_identifier() { assert_de_tokens( &FieldBytes::Bytes(b"value"), - &[ - Token::BorrowedBytes(b"value"), - ], + &[Token::BorrowedBytes(b"value")], ); }