Implement Copy for value deserializers of primitive types

This commit is contained in:
David Tolnay 2018-05-26 15:28:07 -07:00
parent cd0b2d312c
commit 927ec7d38e
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
2 changed files with 60 additions and 12 deletions

View File

@ -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 /// A minimal representation of all possible errors that can occur using the
/// `IntoDeserializer` trait. /// `IntoDeserializer` trait.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
@ -124,11 +140,13 @@ where
} }
/// A deserializer holding a `()`. /// A deserializer holding a `()`.
#[derive(Clone, Debug)] #[derive(Debug)]
pub struct UnitDeserializer<E> { pub struct UnitDeserializer<E> {
marker: PhantomData<E>, marker: PhantomData<E>,
} }
impl_copy_clone!(UnitDeserializer);
impl<'de, E> de::Deserializer<'de> for UnitDeserializer<E> impl<'de, E> de::Deserializer<'de> for UnitDeserializer<E>
where where
E: de::Error, E: de::Error,
@ -162,12 +180,14 @@ macro_rules! primitive_deserializer {
($ty:ty, $doc:tt, $name:ident, $method:ident $($cast:tt)*) => { ($ty:ty, $doc:tt, $name:ident, $method:ident $($cast:tt)*) => {
#[doc = "A deserializer holding"] #[doc = "A deserializer holding"]
#[doc = $doc] #[doc = $doc]
#[derive(Clone, Debug)] #[derive(Debug)]
pub struct $name<E> { pub struct $name<E> {
value: $ty, value: $ty,
marker: PhantomData<E> marker: PhantomData<E>
} }
impl_copy_clone!($name);
impl<'de, E> IntoDeserializer<'de, E> for $ty impl<'de, E> IntoDeserializer<'de, E> for $ty
where where
E: de::Error, E: de::Error,
@ -224,12 +244,14 @@ serde_if_integer128! {
} }
/// A deserializer holding a `u32`. /// A deserializer holding a `u32`.
#[derive(Clone, Debug)] #[derive(Debug)]
pub struct U32Deserializer<E> { pub struct U32Deserializer<E> {
value: u32, value: u32,
marker: PhantomData<E>, marker: PhantomData<E>,
} }
impl_copy_clone!(U32Deserializer);
impl<'de, E> IntoDeserializer<'de, E> for u32 impl<'de, E> IntoDeserializer<'de, E> for u32
where where
E: de::Error, E: de::Error,
@ -296,12 +318,14 @@ where
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// A deserializer holding a `&str`. /// A deserializer holding a `&str`.
#[derive(Clone, Debug)] #[derive(Debug)]
pub struct StrDeserializer<'a, E> { pub struct StrDeserializer<'a, E> {
value: &'a str, value: &'a str,
marker: PhantomData<E>, marker: PhantomData<E>,
} }
impl_copy_clone!(StrDeserializer<'de>);
impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a str impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a str
where where
E: de::Error, E: de::Error,
@ -369,12 +393,14 @@ where
/// A deserializer holding a `&str` with a lifetime tied to another /// A deserializer holding a `&str` with a lifetime tied to another
/// deserializer. /// deserializer.
#[derive(Clone, Debug)] #[derive(Debug)]
pub struct BorrowedStrDeserializer<'de, E> { pub struct BorrowedStrDeserializer<'de, E> {
value: &'de str, value: &'de str,
marker: PhantomData<E>, marker: PhantomData<E>,
} }
impl_copy_clone!(BorrowedStrDeserializer<'de>);
impl<'de, E> BorrowedStrDeserializer<'de, E> { impl<'de, E> BorrowedStrDeserializer<'de, E> {
/// Create a new borrowed deserializer from the given string. /// Create a new borrowed deserializer from the given string.
pub fn new(value: &'de str) -> BorrowedStrDeserializer<'de, E> { pub fn new(value: &'de str) -> BorrowedStrDeserializer<'de, E> {
@ -438,12 +464,22 @@ where
/// A deserializer holding a `String`. /// A deserializer holding a `String`.
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
#[derive(Clone, Debug)] #[derive(Debug)]
pub struct StringDeserializer<E> { pub struct StringDeserializer<E> {
value: String, value: String,
marker: PhantomData<E>, marker: PhantomData<E>,
} }
#[cfg(any(feature = "std", feature = "alloc"))]
impl<E> Clone for StringDeserializer<E> {
fn clone(&self) -> Self {
StringDeserializer {
value: self.value.clone(),
marker: PhantomData,
}
}
}
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, E> IntoDeserializer<'de, E> for String impl<'de, E> IntoDeserializer<'de, E> for String
where where
@ -514,12 +550,22 @@ where
/// A deserializer holding a `Cow<str>`. /// A deserializer holding a `Cow<str>`.
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
#[derive(Clone, Debug)] #[derive(Debug)]
pub struct CowStrDeserializer<'a, E> { pub struct CowStrDeserializer<'a, E> {
value: Cow<'a, str>, value: Cow<'a, str>,
marker: PhantomData<E>, marker: PhantomData<E>,
} }
#[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"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, 'a, E> IntoDeserializer<'de, E> for Cow<'a, str> impl<'de, 'a, E> IntoDeserializer<'de, E> for Cow<'a, str>
where where
@ -593,12 +639,14 @@ where
/// A deserializer holding a `&[u8]` with a lifetime tied to another /// A deserializer holding a `&[u8]` with a lifetime tied to another
/// deserializer. /// deserializer.
#[derive(Clone, Debug)] #[derive(Debug)]
pub struct BorrowedBytesDeserializer<'de, E> { pub struct BorrowedBytesDeserializer<'de, E> {
value: &'de [u8], value: &'de [u8],
marker: PhantomData<E>, marker: PhantomData<E>,
} }
impl_copy_clone!(BorrowedBytesDeserializer<'de>);
impl<'de, E> BorrowedBytesDeserializer<'de, E> { impl<'de, E> BorrowedBytesDeserializer<'de, E> {
/// Create a new borrowed deserializer from the given byte slice. /// Create a new borrowed deserializer from the given byte slice.
pub fn new(value: &'de [u8]) -> BorrowedBytesDeserializer<'de, E> { pub fn new(value: &'de [u8]) -> BorrowedBytesDeserializer<'de, E> {

View File

@ -32,14 +32,14 @@ fn test_integer128() {
let de_i128 = IntoDeserializer::<value::Error>::into_deserializer(1i128); let de_i128 = IntoDeserializer::<value::Error>::into_deserializer(1i128);
// u128 to u128 // u128 to u128
assert_eq!(1u128, u128::deserialize(de_u128.clone()).unwrap()); assert_eq!(1u128, u128::deserialize(de_u128).unwrap());
// u128 to i128 // u128 to i128
assert_eq!(1i128, i128::deserialize(de_u128.clone()).unwrap()); assert_eq!(1i128, i128::deserialize(de_u128).unwrap());
// i128 to u128 // i128 to u128
assert_eq!(1u128, u128::deserialize(de_i128.clone()).unwrap()); assert_eq!(1u128, u128::deserialize(de_i128).unwrap());
// i128 to i128 // i128 to i128
assert_eq!(1i128, i128::deserialize(de_i128.clone()).unwrap()); assert_eq!(1i128, i128::deserialize(de_i128).unwrap());
} }