diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index d08bae3b..56ed7c57 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -44,6 +44,22 @@ use ser; //////////////////////////////////////////////////////////////////////////////// +// For structs that contain a PhantomData. We do not want the trait +// bound `E: Clone` inferred by derive(Clone). +macro_rules! impl_copy_clone { + ($ty:ident $(<$lifetime:tt>)*) => { + impl<$($lifetime,)* E> Copy for $ty<$($lifetime,)* E> {} + + impl<$($lifetime,)* E> Clone for $ty<$($lifetime,)* E> { + fn clone(&self) -> Self { + *self + } + } + }; +} + +//////////////////////////////////////////////////////////////////////////////// + /// A minimal representation of all possible errors that can occur using the /// `IntoDeserializer` trait. #[derive(Clone, Debug, PartialEq)] @@ -124,11 +140,13 @@ where } /// A deserializer holding a `()`. -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct UnitDeserializer { marker: PhantomData, } +impl_copy_clone!(UnitDeserializer); + impl<'de, E> de::Deserializer<'de> for UnitDeserializer where E: de::Error, @@ -162,12 +180,14 @@ macro_rules! primitive_deserializer { ($ty:ty, $doc:tt, $name:ident, $method:ident $($cast:tt)*) => { #[doc = "A deserializer holding"] #[doc = $doc] - #[derive(Clone, Debug)] + #[derive(Debug)] pub struct $name { value: $ty, marker: PhantomData } + impl_copy_clone!($name); + impl<'de, E> IntoDeserializer<'de, E> for $ty where E: de::Error, @@ -224,12 +244,14 @@ serde_if_integer128! { } /// A deserializer holding a `u32`. -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct U32Deserializer { value: u32, marker: PhantomData, } +impl_copy_clone!(U32Deserializer); + impl<'de, E> IntoDeserializer<'de, E> for u32 where E: de::Error, @@ -296,12 +318,14 @@ where //////////////////////////////////////////////////////////////////////////////// /// A deserializer holding a `&str`. -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct StrDeserializer<'a, E> { value: &'a str, marker: PhantomData, } +impl_copy_clone!(StrDeserializer<'de>); + impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a str where E: de::Error, @@ -369,12 +393,14 @@ where /// A deserializer holding a `&str` with a lifetime tied to another /// deserializer. -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct BorrowedStrDeserializer<'de, E> { value: &'de str, marker: PhantomData, } +impl_copy_clone!(BorrowedStrDeserializer<'de>); + impl<'de, E> BorrowedStrDeserializer<'de, E> { /// Create a new borrowed deserializer from the given string. pub fn new(value: &'de str) -> BorrowedStrDeserializer<'de, E> { @@ -438,12 +464,22 @@ where /// A deserializer holding a `String`. #[cfg(any(feature = "std", feature = "alloc"))] -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct StringDeserializer { value: String, marker: PhantomData, } +#[cfg(any(feature = "std", feature = "alloc"))] +impl Clone for StringDeserializer { + fn clone(&self) -> Self { + StringDeserializer { + value: self.value.clone(), + marker: PhantomData, + } + } +} + #[cfg(any(feature = "std", feature = "alloc"))] impl<'de, E> IntoDeserializer<'de, E> for String where @@ -514,12 +550,22 @@ where /// A deserializer holding a `Cow`. #[cfg(any(feature = "std", feature = "alloc"))] -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct CowStrDeserializer<'a, E> { value: Cow<'a, str>, marker: PhantomData, } +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a, E> Clone for CowStrDeserializer<'a, E> { + fn clone(&self) -> Self { + CowStrDeserializer { + value: self.value.clone(), + marker: PhantomData, + } + } +} + #[cfg(any(feature = "std", feature = "alloc"))] impl<'de, 'a, E> IntoDeserializer<'de, E> for Cow<'a, str> where @@ -593,12 +639,14 @@ where /// A deserializer holding a `&[u8]` with a lifetime tied to another /// deserializer. -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct BorrowedBytesDeserializer<'de, E> { value: &'de [u8], marker: PhantomData, } +impl_copy_clone!(BorrowedBytesDeserializer<'de>); + impl<'de, E> BorrowedBytesDeserializer<'de, E> { /// Create a new borrowed deserializer from the given byte slice. pub fn new(value: &'de [u8]) -> BorrowedBytesDeserializer<'de, E> { diff --git a/test_suite/tests/test_value.rs b/test_suite/tests/test_value.rs index 80554663..d2d9e67c 100644 --- a/test_suite/tests/test_value.rs +++ b/test_suite/tests/test_value.rs @@ -32,14 +32,14 @@ fn test_integer128() { let de_i128 = IntoDeserializer::::into_deserializer(1i128); // u128 to u128 - assert_eq!(1u128, u128::deserialize(de_u128.clone()).unwrap()); + assert_eq!(1u128, u128::deserialize(de_u128).unwrap()); // u128 to i128 - assert_eq!(1i128, i128::deserialize(de_u128.clone()).unwrap()); + assert_eq!(1i128, i128::deserialize(de_u128).unwrap()); // i128 to u128 - assert_eq!(1u128, u128::deserialize(de_i128.clone()).unwrap()); + assert_eq!(1u128, u128::deserialize(de_i128).unwrap()); // i128 to i128 - assert_eq!(1i128, i128::deserialize(de_i128.clone()).unwrap()); + assert_eq!(1i128, i128::deserialize(de_i128).unwrap()); }