Compare commits

...

24 Commits

Author SHA1 Message Date
David Tolnay 5098609935 Release 1.0.46 2018-05-06 13:44:55 -07:00
David Tolnay 6374467f02 Merge pull request #1245 from serde-rs/flat
Support deserializing a flattened internally tagged enum
2018-05-06 13:43:44 -07:00
David Tolnay 1f9fc61b98 Merge pull request #1246 from serde-rs/internals
Move derive internals into serde_derive crate
2018-05-05 23:58:41 -07:00
David Tolnay 3859f58d9b Move derive internals into serde_derive crate
We can continue to publish serde_derive_internals independently but
serde_derive no longer has a dependency on it. This improves compile
time of serde_derive by 7%.
2018-05-05 23:46:30 -07:00
David Tolnay aac1c65033 Simplify implementation of flattened internally tagged enum
The fact that the tag entry is consumed was only observable if there is
a later flattened map field, at which point the behavior is already
confusing anyway.

    #[derive(Deserialize)]
    struct Example {
        #[serde(flatten)]
        a: InternallyTagged,
        #[serde(flatten)]
        rest: BTreeMap<String, Value>,
    }

Before this simplification the map would receive all the fields of the
internally tagged enum but not its tag, after it receives all the fields
including the tag.
2018-05-05 22:30:46 -07:00
David Tolnay d8120e19bc Support deserializing a flattened internally tagged enum 2018-05-05 21:52:16 -07:00
David Tolnay ed425b3a6f Clean up indentation in VariantAccess doc 2018-05-05 18:40:28 -07:00
David Tolnay d1297deb36 Format where-clauses in serde docs like rustfmt 2018-05-05 18:33:33 -07:00
David Tolnay f263e3fcec Format serde_derive generated where-clauses 2018-05-05 18:24:16 -07:00
David Tolnay 40479336c1 Format serde_test doc where-clauses in the style of rustfmt 2018-05-05 18:20:26 -07:00
David Tolnay 6ca4dd2c4a Add an issue suggestion for documentation improvements 2018-05-05 10:01:54 -07:00
David Tolnay c04c233838 Generalize the help issue type 2018-05-05 10:00:17 -07:00
David Tolnay 175c638fdc Set up some issue templates 2018-05-05 01:45:24 -07:00
David Tolnay 97eff8e875 Format with rustfmt 0.6.1 2018-05-05 00:56:12 -07:00
David Tolnay 47676cdb49 Clean up references to Ident 2018-05-05 00:45:30 -07:00
David Tolnay 93bddb361e Fix toplevel_ref_arg lint 2018-05-05 00:39:26 -07:00
David Tolnay adb1c9540d Remove a layer of wrapping in deserialize_with untagged newtype variant 2018-05-05 00:25:27 -07:00
David Tolnay 0e1d065402 Format with rustfmt 0.6.1 2018-05-05 00:18:21 -07:00
David Tolnay 8c3b52e308 Remove a layer of wrapping in deserialize_with newtype struct 2018-05-05 00:17:00 -07:00
David Tolnay 3f0d3453d8 Release 1.0.45 2018-05-02 15:18:17 -07:00
David Tolnay b27a27ce22 Merge pull request #1241 from serde-rs/pretend
Pretend remote derives are not dead code
2018-05-02 15:17:19 -07:00
David Tolnay 80c0600657 Merge pull request #1243 from serde-rs/ci
Add a CI build on 1.15.0
2018-05-02 15:17:10 -07:00
David Tolnay 77f9e63661 Add a CI build on 1.15.0 2018-05-02 14:29:51 -07:00
David Tolnay b78f434086 Pretend remote derives are not dead code 2018-05-02 14:23:59 -07:00
38 changed files with 708 additions and 244 deletions
+7
View File
@@ -0,0 +1,7 @@
---
name: Problem
about: Something does not seem right
---
+7
View File
@@ -0,0 +1,7 @@
---
name: Feature request
about: Share how Serde could support your use case better
---
@@ -0,0 +1,7 @@
---
name: Documentation
about: Certainly there is room for improvement
---
+7
View File
@@ -0,0 +1,7 @@
---
name: Help or discussion
about: This is the right place
---
+1
View File
@@ -5,6 +5,7 @@ cache: cargo
# run builds for all the trains (and more) # run builds for all the trains (and more)
rust: rust:
- 1.13.0 - 1.13.0
- 1.15.0
- stable - stable
- beta - beta
- nightly - nightly
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde" name = "serde"
version = "1.0.44" # remember to update html_root_url version = "1.0.46" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework" description = "A generic serialization/deserialization framework"
+10 -5
View File
@@ -45,7 +45,8 @@ use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
/// } /// }
/// ///
/// impl<'de, T> Visitor<'de> for NthElement<T> /// impl<'de, T> Visitor<'de> for NthElement<T>
/// where T: Deserialize<'de> /// where
/// T: Deserialize<'de>,
/// { /// {
/// type Value = T; /// type Value = T;
/// ///
@@ -54,7 +55,8 @@ use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
/// } /// }
/// ///
/// fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> /// fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
/// where A: SeqAccess<'de> /// where
/// A: SeqAccess<'de>,
/// { /// {
/// // Skip over the first `n` elements. /// // Skip over the first `n` elements.
/// for i in 0..self.n { /// for i in 0..self.n {
@@ -82,19 +84,22 @@ use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
/// } /// }
/// ///
/// impl<'de, T> DeserializeSeed<'de> for NthElement<T> /// impl<'de, T> DeserializeSeed<'de> for NthElement<T>
/// where T: Deserialize<'de> /// where
/// T: Deserialize<'de>,
/// { /// {
/// type Value = T; /// type Value = T;
/// ///
/// fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> /// fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
/// where D: Deserializer<'de> /// where
/// D: Deserializer<'de>,
/// { /// {
/// deserializer.deserialize_seq(self) /// deserializer.deserialize_seq(self)
/// } /// }
/// } /// }
/// ///
/// # fn example<'de, D>(deserializer: D) -> Result<(), D::Error> /// # fn example<'de, D>(deserializer: D) -> Result<(), D::Error>
/// # where D: Deserializer<'de> /// # where
/// # D: Deserializer<'de>,
/// # { /// # {
/// // Deserialize only the sequence element at index 3 from this deserializer. /// // 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 /// // The element at index 3 is required to be a string. Elements before and
+3 -2
View File
@@ -8,8 +8,9 @@
use lib::*; use lib::*;
use de::{Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess, use de::{
Visitor}; Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess, Visitor,
};
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
use de::MapAccess; use de::MapAccess;
+77 -34
View File
@@ -172,7 +172,8 @@ macro_rules! declare_error_trait {
/// ///
/// impl<'de> Deserialize<'de> for IpAddr { /// impl<'de> Deserialize<'de> for IpAddr {
/// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> /// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
/// where D: Deserializer<'de> /// where
/// D: Deserializer<'de>,
/// { /// {
/// let s = try!(String::deserialize(deserializer)); /// let s = try!(String::deserialize(deserializer));
/// s.parse().map_err(de::Error::custom) /// s.parse().map_err(de::Error::custom)
@@ -306,7 +307,8 @@ declare_error_trait!(Error: Sized + Debug + Display);
/// # } /// # }
/// # /// #
/// fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E> /// fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
/// where E: de::Error /// where
/// E: de::Error,
/// { /// {
/// Err(de::Error::invalid_type(Unexpected::Bool(v), &self)) /// Err(de::Error::invalid_type(Unexpected::Bool(v), &self))
/// } /// }
@@ -430,7 +432,8 @@ impl<'a> fmt::Display for Unexpected<'a> {
/// # } /// # }
/// # /// #
/// fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E> /// fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
/// where E: de::Error /// where
/// E: de::Error,
/// { /// {
/// Err(de::Error::invalid_type(Unexpected::Bool(v), &self)) /// Err(de::Error::invalid_type(Unexpected::Bool(v), &self))
/// } /// }
@@ -443,7 +446,8 @@ impl<'a> fmt::Display for Unexpected<'a> {
/// # use serde::de::{self, Unexpected}; /// # use serde::de::{self, Unexpected};
/// # /// #
/// # fn example<E>() -> Result<(), E> /// # fn example<E>() -> Result<(), E>
/// # where E: de::Error /// # where
/// # E: de::Error,
/// # { /// # {
/// # let v = true; /// # let v = true;
/// return Err(de::Error::invalid_type(Unexpected::Bool(v), &"a negative integer")); /// return Err(de::Error::invalid_type(Unexpected::Bool(v), &"a negative integer"));
@@ -557,11 +561,13 @@ pub trait Deserialize<'de>: Sized {
/// # /// #
/// # trait Ignore { /// # trait Ignore {
/// fn from_str<'a, T>(s: &'a str) -> Result<T> /// fn from_str<'a, T>(s: &'a str) -> Result<T>
/// where T: Deserialize<'a>; /// where
/// T: Deserialize<'a>;
/// ///
/// fn from_reader<R, T>(rdr: R) -> Result<T> /// fn from_reader<R, T>(rdr: R) -> Result<T>
/// where R: Read, /// where
/// T: DeserializeOwned; /// R: Read,
/// T: DeserializeOwned;
/// # } /// # }
/// ``` /// ```
pub trait DeserializeOwned: for<'de> Deserialize<'de> {} pub trait DeserializeOwned: for<'de> Deserialize<'de> {}
@@ -637,7 +643,8 @@ where
/// struct ExtendVec<'a, T: 'a>(&'a mut Vec<T>); /// struct ExtendVec<'a, T: 'a>(&'a mut Vec<T>);
/// ///
/// impl<'de, 'a, T> DeserializeSeed<'de> for ExtendVec<'a, T> /// impl<'de, 'a, T> DeserializeSeed<'de> for ExtendVec<'a, T>
/// where T: Deserialize<'de> /// where
/// T: Deserialize<'de>,
/// { /// {
/// // The return type of the `deserialize` method. This implementation /// // The return type of the `deserialize` method. This implementation
/// // appends onto an existing vector but does not create any new data /// // appends onto an existing vector but does not create any new data
@@ -645,14 +652,16 @@ where
/// type Value = (); /// type Value = ();
/// ///
/// fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> /// fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
/// where D: Deserializer<'de> /// where
/// D: Deserializer<'de>,
/// { /// {
/// // Visitor implementation that will walk an inner array of the JSON /// // Visitor implementation that will walk an inner array of the JSON
/// // input. /// // input.
/// struct ExtendVecVisitor<'a, T: 'a>(&'a mut Vec<T>); /// struct ExtendVecVisitor<'a, T: 'a>(&'a mut Vec<T>);
/// ///
/// impl<'de, 'a, T> Visitor<'de> for ExtendVecVisitor<'a, T> /// impl<'de, 'a, T> Visitor<'de> for ExtendVecVisitor<'a, T>
/// where T: Deserialize<'de> /// where
/// T: Deserialize<'de>,
/// { /// {
/// type Value = (); /// type Value = ();
/// ///
@@ -661,7 +670,8 @@ where
/// } /// }
/// ///
/// fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error> /// fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error>
/// where A: SeqAccess<'de> /// where
/// A: SeqAccess<'de>,
/// { /// {
/// // Visit each element in the inner array and push it onto /// // Visit each element in the inner array and push it onto
/// // the existing vector. /// // the existing vector.
@@ -680,7 +690,8 @@ where
/// struct FlattenedVecVisitor<T>(PhantomData<T>); /// struct FlattenedVecVisitor<T>(PhantomData<T>);
/// ///
/// impl<'de, T> Visitor<'de> for FlattenedVecVisitor<T> /// impl<'de, T> Visitor<'de> for FlattenedVecVisitor<T>
/// where T: Deserialize<'de> /// where
/// T: Deserialize<'de>,
/// { /// {
/// // This Visitor constructs a single Vec<T> to hold the flattened /// // This Visitor constructs a single Vec<T> to hold the flattened
/// // contents of the inner arrays. /// // contents of the inner arrays.
@@ -691,7 +702,8 @@ where
/// } /// }
/// ///
/// fn visit_seq<A>(self, mut seq: A) -> Result<Vec<T>, A::Error> /// fn visit_seq<A>(self, mut seq: A) -> Result<Vec<T>, A::Error>
/// where A: SeqAccess<'de> /// where
/// A: SeqAccess<'de>,
/// { /// {
/// // Create a single Vec to hold the flattened contents. /// // Create a single Vec to hold the flattened contents.
/// let mut vec = Vec::new(); /// let mut vec = Vec::new();
@@ -707,7 +719,8 @@ where
/// } /// }
/// ///
/// # fn example<'de, D>(deserializer: D) -> Result<(), D::Error> /// # fn example<'de, D>(deserializer: D) -> Result<(), D::Error>
/// # where D: Deserializer<'de> /// # where
/// # D: Deserializer<'de>,
/// # { /// # {
/// let visitor = FlattenedVecVisitor(PhantomData); /// let visitor = FlattenedVecVisitor(PhantomData);
/// let flattened: Vec<u64> = deserializer.deserialize_seq(visitor)?; /// let flattened: Vec<u64> = deserializer.deserialize_seq(visitor)?;
@@ -1092,7 +1105,8 @@ pub trait Deserializer<'de>: Sized {
/// ///
/// impl<'de> Deserialize<'de> for Timestamp { /// impl<'de> Deserialize<'de> for Timestamp {
/// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> /// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
/// where D: Deserializer<'de> /// where
/// D: Deserializer<'de>,
/// { /// {
/// if deserializer.is_human_readable() { /// if deserializer.is_human_readable() {
/// // Deserialize from a human-readable string like "2015-05-15T17:01:00Z". /// // Deserialize from a human-readable string like "2015-05-15T17:01:00Z".
@@ -1118,6 +1132,18 @@ pub trait Deserializer<'de>: Sized {
fn is_human_readable(&self) -> bool { fn is_human_readable(&self) -> bool {
true true
} }
// Not public API.
#[doc(hidden)]
fn private_deserialize_internally_tagged_enum<V>(
self,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_any(visitor)
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -1143,7 +1169,8 @@ pub trait Deserializer<'de>: Sized {
/// } /// }
/// ///
/// fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> /// fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
/// where E: de::Error /// where
/// E: de::Error,
/// { /// {
/// if s.len() >= self.min { /// if s.len() >= self.min {
/// Ok(s.to_owned()) /// Ok(s.to_owned())
@@ -1823,15 +1850,18 @@ pub trait VariantAccess<'de>: Sized {
/// } /// }
/// # /// #
/// # fn newtype_variant_seed<T>(self, _: T) -> Result<T::Value, Self::Error> /// # fn newtype_variant_seed<T>(self, _: T) -> Result<T::Value, Self::Error>
/// # where T: DeserializeSeed<'de> /// # where
/// # T: DeserializeSeed<'de>,
/// # { unimplemented!() } /// # { unimplemented!() }
/// # /// #
/// # fn tuple_variant<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error> /// # fn tuple_variant<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error>
/// # where V: Visitor<'de> /// # where
/// # V: Visitor<'de>,
/// # { unimplemented!() } /// # { unimplemented!() }
/// # /// #
/// # fn struct_variant<V>(self, _: &[&str], _: V) -> Result<V::Value, Self::Error> /// # fn struct_variant<V>(self, _: &[&str], _: V) -> Result<V::Value, Self::Error>
/// # where V: Visitor<'de> /// # where
/// # V: Visitor<'de>,
/// # { unimplemented!() } /// # { unimplemented!() }
/// # } /// # }
/// ``` /// ```
@@ -1858,7 +1888,8 @@ pub trait VariantAccess<'de>: Sized {
/// # } /// # }
/// # /// #
/// fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error> /// fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error>
/// where T: DeserializeSeed<'de> /// where
/// T: DeserializeSeed<'de>,
/// { /// {
/// // What the data actually contained; suppose it is a unit variant. /// // What the data actually contained; suppose it is a unit variant.
/// let unexp = Unexpected::UnitVariant; /// let unexp = Unexpected::UnitVariant;
@@ -1866,11 +1897,13 @@ pub trait VariantAccess<'de>: Sized {
/// } /// }
/// # /// #
/// # fn tuple_variant<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error> /// # fn tuple_variant<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error>
/// # where V: Visitor<'de> /// # where
/// # V: Visitor<'de>,
/// # { unimplemented!() } /// # { unimplemented!() }
/// # /// #
/// # fn struct_variant<V>(self, _: &[&str], _: V) -> Result<V::Value, Self::Error> /// # fn struct_variant<V>(self, _: &[&str], _: V) -> Result<V::Value, Self::Error>
/// # where V: Visitor<'de> /// # where
/// # V: Visitor<'de>,
/// # { unimplemented!() } /// # { unimplemented!() }
/// # } /// # }
/// ``` /// ```
@@ -1911,13 +1944,17 @@ pub trait VariantAccess<'de>: Sized {
/// # } /// # }
/// # /// #
/// # fn newtype_variant_seed<T>(self, _: T) -> Result<T::Value, Self::Error> /// # fn newtype_variant_seed<T>(self, _: T) -> Result<T::Value, Self::Error>
/// # where T: DeserializeSeed<'de> /// # where
/// # T: DeserializeSeed<'de>,
/// # { unimplemented!() } /// # { unimplemented!() }
/// # /// #
/// fn tuple_variant<V>(self, /// fn tuple_variant<V>(
/// _len: usize, /// self,
/// _visitor: V) -> Result<V::Value, Self::Error> /// _len: usize,
/// where V: Visitor<'de> /// _visitor: V,
/// ) -> Result<V::Value, Self::Error>
/// where
/// V: Visitor<'de>,
/// { /// {
/// // What the data actually contained; suppose it is a unit variant. /// // What the data actually contained; suppose it is a unit variant.
/// let unexp = Unexpected::UnitVariant; /// let unexp = Unexpected::UnitVariant;
@@ -1925,7 +1962,8 @@ pub trait VariantAccess<'de>: Sized {
/// } /// }
/// # /// #
/// # fn struct_variant<V>(self, _: &[&str], _: V) -> Result<V::Value, Self::Error> /// # fn struct_variant<V>(self, _: &[&str], _: V) -> Result<V::Value, Self::Error>
/// # where V: Visitor<'de> /// # where
/// # V: Visitor<'de>,
/// # { unimplemented!() } /// # { unimplemented!() }
/// # } /// # }
/// ``` /// ```
@@ -1953,17 +1991,22 @@ pub trait VariantAccess<'de>: Sized {
/// # } /// # }
/// # /// #
/// # fn newtype_variant_seed<T>(self, _: T) -> Result<T::Value, Self::Error> /// # fn newtype_variant_seed<T>(self, _: T) -> Result<T::Value, Self::Error>
/// # where T: DeserializeSeed<'de> /// # where
/// # T: DeserializeSeed<'de>,
/// # { unimplemented!() } /// # { unimplemented!() }
/// # /// #
/// # fn tuple_variant<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error> /// # fn tuple_variant<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error>
/// # where V: Visitor<'de> /// # where
/// # V: Visitor<'de>,
/// # { unimplemented!() } /// # { unimplemented!() }
/// # /// #
/// fn struct_variant<V>(self, /// fn struct_variant<V>(
/// _fields: &'static [&'static str], /// self,
/// _visitor: V) -> Result<V::Value, Self::Error> /// _fields: &'static [&'static str],
/// where V: Visitor<'de> /// _visitor: V,
/// ) -> Result<V::Value, Self::Error>
/// where
/// V: Visitor<'de>,
/// { /// {
/// // What the data actually contained; suppose it is a unit variant. /// // What the data actually contained; suppose it is a unit variant.
/// let unexp = Unexpected::UnitVariant; /// let unexp = Unexpected::UnitVariant;
+1 -1
View File
@@ -79,7 +79,7 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here. // Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.44")] #![doc(html_root_url = "https://docs.rs/serde/1.0.46")]
// Support using Serde without the standard library! // Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and // Unstable functionality only if the user asks for it. For tracking and
+8 -4
View File
@@ -31,14 +31,16 @@
/// # type Error = value::Error; /// # type Error = value::Error;
/// # /// #
/// # fn deserialize_any<V>(self, _: V) -> Result<V::Value, Self::Error> /// # fn deserialize_any<V>(self, _: V) -> Result<V::Value, Self::Error>
/// # where V: Visitor<'de> /// # where
/// # V: Visitor<'de>,
/// # { /// # {
/// # unimplemented!() /// # unimplemented!()
/// # } /// # }
/// # /// #
/// #[inline] /// #[inline]
/// fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error> /// fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
/// where V: Visitor<'de> /// where
/// V: Visitor<'de>,
/// { /// {
/// self.deserialize_any(visitor) /// self.deserialize_any(visitor)
/// } /// }
@@ -69,7 +71,8 @@
/// # type Error = value::Error; /// # type Error = value::Error;
/// # /// #
/// fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> /// fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
/// where V: Visitor<'de> /// where
/// V: Visitor<'de>,
/// { /// {
/// /* ... */ /// /* ... */
/// # let _ = visitor; /// # let _ = visitor;
@@ -105,7 +108,8 @@
/// # type Error = value::Error; /// # type Error = value::Error;
/// # /// #
/// # fn deserialize_any<W>(self, visitor: W) -> Result<W::Value, Self::Error> /// # fn deserialize_any<W>(self, visitor: W) -> Result<W::Value, Self::Error>
/// # where W: Visitor<'q> /// # where
/// # W: Visitor<'q>,
/// # { /// # {
/// # unimplemented!() /// # unimplemented!()
/// # } /// # }
+64 -6
View File
@@ -14,10 +14,11 @@ use de::{Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, Vi
use de::{MapAccess, Unexpected}; use de::{MapAccess, Unexpected};
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub use self::content::{Content, ContentDeserializer, ContentRefDeserializer, EnumDeserializer, pub use self::content::{
InternallyTaggedUnitVisitor, TagContentOtherField, Content, ContentDeserializer, ContentRefDeserializer, EnumDeserializer,
TagContentOtherFieldVisitor, TagOrContentField, TagOrContentFieldVisitor, InternallyTaggedUnitVisitor, TagContentOtherField, TagContentOtherFieldVisitor,
TaggedContentVisitor, UntaggedUnitVisitor}; TagOrContentField, TagOrContentFieldVisitor, TaggedContentVisitor, UntaggedUnitVisitor,
};
/// If the missing field is of type `Option<T>` then treat is as `None`, /// If the missing field is of type `Option<T>` then treat is as `None`,
/// otherwise it is an error. /// otherwise it is an error.
@@ -229,8 +230,10 @@ mod content {
use lib::*; use lib::*;
use super::size_hint; use super::size_hint;
use de::{self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, MapAccess, use de::{
SeqAccess, Unexpected, Visitor}; self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, MapAccess,
SeqAccess, Unexpected, Visitor,
};
/// Used from generated code to buffer the contents of the Deserializer when /// Used from generated code to buffer the contents of the Deserializer when
/// deserializing untagged enums and internally tagged enums. /// deserializing untagged enums and internally tagged enums.
@@ -2712,6 +2715,20 @@ where
byte_buf option unit unit_struct seq tuple tuple_struct identifier byte_buf option unit unit_struct seq tuple tuple_struct identifier
ignored_any ignored_any
} }
fn private_deserialize_internally_tagged_enum<V>(
self,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_map(FlatInternallyTaggedAccess {
iter: self.0.iter_mut(),
pending: None,
_marker: PhantomData,
})
}
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
@@ -2783,3 +2800,44 @@ where
} }
} }
} }
#[cfg(any(feature = "std", feature = "alloc"))]
pub struct FlatInternallyTaggedAccess<'a, 'de: 'a, E> {
iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
pending: Option<&'a Content<'de>>,
_marker: PhantomData<E>,
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, 'de, E> MapAccess<'de> for FlatInternallyTaggedAccess<'a, 'de, E>
where
E: Error,
{
type Error = E;
fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: DeserializeSeed<'de>,
{
while let Some(item) = self.iter.next() {
// Do not take(), instead borrow this entry. The internally tagged
// enum does its own buffering so we can't tell whether this entry
// is going to be consumed. Borrowing here leaves the entry
// available for later flattened fields.
let (ref key, ref content) = *item.as_ref().unwrap();
self.pending = Some(content);
return seed.deserialize(ContentRefDeserializer::new(key)).map(Some);
}
Ok(None)
}
fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
where
T: DeserializeSeed<'de>,
{
match self.pending.take() {
Some(value) => seed.deserialize(ContentRefDeserializer::new(value)),
None => panic!("value is missing"),
}
}
}
+3 -2
View File
@@ -11,8 +11,9 @@ use lib::*;
use ser::{self, Impossible, Serialize, SerializeMap, SerializeStruct, Serializer}; use ser::{self, Impossible, Serialize, SerializeMap, SerializeStruct, Serializer};
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
use self::content::{Content, ContentSerializer, SerializeStructVariantAsMapValue, use self::content::{
SerializeTupleVariantAsMapValue}; Content, ContentSerializer, SerializeStructVariantAsMapValue, SerializeTupleVariantAsMapValue,
};
/// Used to check that serde(getter) attributes return the expected type. /// Used to check that serde(getter) attributes return the expected type.
/// Not public API. /// Not public API.
+4 -2
View File
@@ -10,8 +10,10 @@
use lib::*; use lib::*;
use ser::{self, Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, use ser::{
SerializeTuple, SerializeTupleStruct, SerializeTupleVariant}; self, Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant,
SerializeTuple, SerializeTupleStruct, SerializeTupleVariant,
};
/// Helper type for implementing a `Serializer` that does not support /// Helper type for implementing a `Serializer` that does not support
/// serializing one of the compound types. /// serializing one of the compound types.
+110 -58
View File
@@ -152,7 +152,8 @@ macro_rules! declare_error_trait {
/// ///
/// impl Serialize for Path { /// impl Serialize for Path {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// match self.to_str() { /// match self.to_str() {
/// Some(s) => serializer.serialize_str(s), /// Some(s) => serializer.serialize_str(s),
@@ -223,7 +224,8 @@ pub trait Serialize {
/// // This is what #[derive(Serialize)] would generate. /// // This is what #[derive(Serialize)] would generate.
/// impl Serialize for Person { /// impl Serialize for Person {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// let mut s = serializer.serialize_struct("Person", 3)?; /// let mut s = serializer.serialize_struct("Person", 3)?;
/// s.serialize_field("name", &self.name)?; /// s.serialize_field("name", &self.name)?;
@@ -377,7 +379,8 @@ pub trait Serializer: Sized {
/// # /// #
/// impl Serialize for bool { /// impl Serialize for bool {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// serializer.serialize_bool(*self) /// serializer.serialize_bool(*self)
/// } /// }
@@ -403,7 +406,8 @@ pub trait Serializer: Sized {
/// # /// #
/// impl Serialize for i8 { /// impl Serialize for i8 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// serializer.serialize_i8(*self) /// serializer.serialize_i8(*self)
/// } /// }
@@ -429,7 +433,8 @@ pub trait Serializer: Sized {
/// # /// #
/// impl Serialize for i16 { /// impl Serialize for i16 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// serializer.serialize_i16(*self) /// serializer.serialize_i16(*self)
/// } /// }
@@ -455,7 +460,8 @@ pub trait Serializer: Sized {
/// # /// #
/// impl Serialize for i32 { /// impl Serialize for i32 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// serializer.serialize_i32(*self) /// serializer.serialize_i32(*self)
/// } /// }
@@ -477,7 +483,8 @@ pub trait Serializer: Sized {
/// # /// #
/// impl Serialize for i64 { /// impl Serialize for i64 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// serializer.serialize_i64(*self) /// serializer.serialize_i64(*self)
/// } /// }
@@ -503,7 +510,8 @@ pub trait Serializer: Sized {
/// # /// #
/// impl Serialize for u8 { /// impl Serialize for u8 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// serializer.serialize_u8(*self) /// serializer.serialize_u8(*self)
/// } /// }
@@ -529,7 +537,8 @@ pub trait Serializer: Sized {
/// # /// #
/// impl Serialize for u16 { /// impl Serialize for u16 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// serializer.serialize_u16(*self) /// serializer.serialize_u16(*self)
/// } /// }
@@ -555,7 +564,8 @@ pub trait Serializer: Sized {
/// # /// #
/// impl Serialize for u32 { /// impl Serialize for u32 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// serializer.serialize_u32(*self) /// serializer.serialize_u32(*self)
/// } /// }
@@ -577,7 +587,8 @@ pub trait Serializer: Sized {
/// # /// #
/// impl Serialize for u64 { /// impl Serialize for u64 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// serializer.serialize_u64(*self) /// serializer.serialize_u64(*self)
/// } /// }
@@ -603,7 +614,8 @@ pub trait Serializer: Sized {
/// # /// #
/// impl Serialize for f32 { /// impl Serialize for f32 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// serializer.serialize_f32(*self) /// serializer.serialize_f32(*self)
/// } /// }
@@ -625,7 +637,8 @@ pub trait Serializer: Sized {
/// # /// #
/// impl Serialize for f64 { /// impl Serialize for f64 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// serializer.serialize_f64(*self) /// serializer.serialize_f64(*self)
/// } /// }
@@ -650,7 +663,8 @@ pub trait Serializer: Sized {
/// # /// #
/// impl Serialize for char { /// impl Serialize for char {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// serializer.serialize_char(*self) /// serializer.serialize_char(*self)
/// } /// }
@@ -672,7 +686,8 @@ pub trait Serializer: Sized {
/// # /// #
/// impl Serialize for str { /// impl Serialize for str {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// serializer.serialize_str(self) /// serializer.serialize_str(self)
/// } /// }
@@ -737,10 +752,12 @@ pub trait Serializer: Sized {
/// # use Option::{Some, None}; /// # use Option::{Some, None};
/// # /// #
/// impl<T> Serialize for Option<T> /// impl<T> Serialize for Option<T>
/// where T: Serialize /// where
/// T: Serialize,
/// { /// {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// match *self { /// match *self {
/// Some(ref value) => serializer.serialize_some(value), /// Some(ref value) => serializer.serialize_some(value),
@@ -770,10 +787,12 @@ pub trait Serializer: Sized {
/// # use Option::{Some, None}; /// # use Option::{Some, None};
/// # /// #
/// impl<T> Serialize for Option<T> /// impl<T> Serialize for Option<T>
/// where T: Serialize /// where
/// T: Serialize,
/// { /// {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// match *self { /// match *self {
/// Some(ref value) => serializer.serialize_some(value), /// Some(ref value) => serializer.serialize_some(value),
@@ -802,7 +821,8 @@ pub trait Serializer: Sized {
/// # /// #
/// impl Serialize for () { /// impl Serialize for () {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// serializer.serialize_unit() /// serializer.serialize_unit()
/// } /// }
@@ -823,7 +843,8 @@ pub trait Serializer: Sized {
/// ///
/// impl Serialize for Nothing { /// impl Serialize for Nothing {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// serializer.serialize_unit_struct("Nothing") /// serializer.serialize_unit_struct("Nothing")
/// } /// }
@@ -847,7 +868,8 @@ pub trait Serializer: Sized {
/// ///
/// impl Serialize for E { /// impl Serialize for E {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// match *self { /// match *self {
/// E::A => serializer.serialize_unit_variant("E", 0, "A"), /// E::A => serializer.serialize_unit_variant("E", 0, "A"),
@@ -876,7 +898,8 @@ pub trait Serializer: Sized {
/// ///
/// impl Serialize for Millimeters { /// impl Serialize for Millimeters {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// serializer.serialize_newtype_struct("Millimeters", &self.0) /// serializer.serialize_newtype_struct("Millimeters", &self.0)
/// } /// }
@@ -906,7 +929,8 @@ pub trait Serializer: Sized {
/// ///
/// impl Serialize for E { /// impl Serialize for E {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// match *self { /// match *self {
/// E::M(ref s) => serializer.serialize_newtype_variant("E", 0, "M", s), /// E::M(ref s) => serializer.serialize_newtype_variant("E", 0, "M", s),
@@ -956,10 +980,12 @@ pub trait Serializer: Sized {
/// use serde::ser::{Serialize, Serializer, SerializeSeq}; /// use serde::ser::{Serialize, Serializer, SerializeSeq};
/// ///
/// impl<T> Serialize for Vec<T> /// impl<T> Serialize for Vec<T>
/// where T: Serialize /// where
/// T: Serialize,
/// { /// {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// let mut seq = serializer.serialize_seq(Some(self.len()))?; /// let mut seq = serializer.serialize_seq(Some(self.len()))?;
/// for element in self { /// for element in self {
@@ -988,12 +1014,14 @@ pub trait Serializer: Sized {
/// # struct Tuple3<A, B, C>(A, B, C); /// # struct Tuple3<A, B, C>(A, B, C);
/// # /// #
/// # impl<A, B, C> Serialize for Tuple3<A, B, C> /// # impl<A, B, C> Serialize for Tuple3<A, B, C>
/// where A: Serialize, /// where
/// B: Serialize, /// A: Serialize,
/// C: Serialize /// B: Serialize,
/// C: Serialize,
/// { /// {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// let mut tup = serializer.serialize_tuple(3)?; /// let mut tup = serializer.serialize_tuple(3)?;
/// tup.serialize_element(&self.0)?; /// tup.serialize_element(&self.0)?;
@@ -1012,7 +1040,8 @@ pub trait Serializer: Sized {
/// ///
/// impl Serialize for Vram { /// impl Serialize for Vram {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// let mut seq = serializer.serialize_tuple(VRAM_SIZE)?; /// let mut seq = serializer.serialize_tuple(VRAM_SIZE)?;
/// for element in &self.0[..] { /// for element in &self.0[..] {
@@ -1038,7 +1067,8 @@ pub trait Serializer: Sized {
/// ///
/// impl Serialize for Rgb { /// impl Serialize for Rgb {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?; /// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?;
/// ts.serialize_field(&self.0)?; /// ts.serialize_field(&self.0)?;
@@ -1072,7 +1102,8 @@ pub trait Serializer: Sized {
/// ///
/// impl Serialize for E { /// impl Serialize for E {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// match *self { /// match *self {
/// E::T(ref a, ref b) => { /// E::T(ref a, ref b) => {
@@ -1130,11 +1161,13 @@ pub trait Serializer: Sized {
/// use serde::ser::{Serialize, Serializer, SerializeMap}; /// use serde::ser::{Serialize, Serializer, SerializeMap};
/// ///
/// impl<K, V> Serialize for HashMap<K, V> /// impl<K, V> Serialize for HashMap<K, V>
/// where K: Serialize, /// where
/// V: Serialize /// K: Serialize,
/// V: Serialize,
/// { /// {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// let mut map = serializer.serialize_map(Some(self.len()))?; /// let mut map = serializer.serialize_map(Some(self.len()))?;
/// for (k, v) in self { /// for (k, v) in self {
@@ -1164,7 +1197,8 @@ pub trait Serializer: Sized {
/// ///
/// impl Serialize for Rgb { /// impl Serialize for Rgb {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// let mut rgb = serializer.serialize_struct("Rgb", 3)?; /// let mut rgb = serializer.serialize_struct("Rgb", 3)?;
/// rgb.serialize_field("r", &self.r)?; /// rgb.serialize_field("r", &self.r)?;
@@ -1197,7 +1231,8 @@ pub trait Serializer: Sized {
/// ///
/// impl Serialize for E { /// impl Serialize for E {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// match *self { /// match *self {
/// E::S { ref r, ref g, ref b } => { /// E::S { ref r, ref g, ref b } => {
@@ -1234,7 +1269,8 @@ pub trait Serializer: Sized {
/// ///
/// impl Serialize for SecretlyOneHigher { /// impl Serialize for SecretlyOneHigher {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// serializer.collect_seq(self.data.iter().map(|x| x + 1)) /// serializer.collect_seq(self.data.iter().map(|x| x + 1))
/// } /// }
@@ -1272,7 +1308,8 @@ pub trait Serializer: Sized {
/// // Serializes as a map in which the values are all unit. /// // Serializes as a map in which the values are all unit.
/// impl Serialize for MapToUnit { /// impl Serialize for MapToUnit {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// serializer.collect_map(self.keys.iter().map(|k| (k, ()))) /// serializer.collect_map(self.keys.iter().map(|k| (k, ())))
/// } /// }
@@ -1312,7 +1349,8 @@ pub trait Serializer: Sized {
/// ///
/// impl Serialize for DateTime { /// impl Serialize for DateTime {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// serializer.collect_str(&format_args!("{:?}{:?}", /// serializer.collect_str(&format_args!("{:?}{:?}",
/// self.naive_local(), /// self.naive_local(),
@@ -1352,7 +1390,8 @@ pub trait Serializer: Sized {
/// ///
/// impl Serialize for DateTime { /// impl Serialize for DateTime {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// serializer.collect_str(&format_args!("{:?}{:?}", /// serializer.collect_str(&format_args!("{:?}{:?}",
/// self.naive_local(), /// self.naive_local(),
@@ -1393,7 +1432,8 @@ pub trait Serializer: Sized {
/// ///
/// impl Serialize for Timestamp { /// impl Serialize for Timestamp {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// if serializer.is_human_readable() { /// if serializer.is_human_readable() {
/// // Serialize to a human-readable string "2015-05-15T17:01:00Z". /// // Serialize to a human-readable string "2015-05-15T17:01:00Z".
@@ -1442,10 +1482,12 @@ pub trait Serializer: Sized {
/// use serde::ser::{Serialize, Serializer, SerializeSeq}; /// use serde::ser::{Serialize, Serializer, SerializeSeq};
/// ///
/// impl<T> Serialize for Vec<T> /// impl<T> Serialize for Vec<T>
/// where T: Serialize /// where
/// T: Serialize,
/// { /// {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// let mut seq = serializer.serialize_seq(Some(self.len()))?; /// let mut seq = serializer.serialize_seq(Some(self.len()))?;
/// for element in self { /// for element in self {
@@ -1485,12 +1527,14 @@ pub trait SerializeSeq {
/// # struct Tuple3<A, B, C>(A, B, C); /// # struct Tuple3<A, B, C>(A, B, C);
/// # /// #
/// # impl<A, B, C> Serialize for Tuple3<A, B, C> /// # impl<A, B, C> Serialize for Tuple3<A, B, C>
/// where A: Serialize, /// where
/// B: Serialize, /// A: Serialize,
/// C: Serialize /// B: Serialize,
/// C: Serialize,
/// { /// {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// let mut tup = serializer.serialize_tuple(3)?; /// let mut tup = serializer.serialize_tuple(3)?;
/// tup.serialize_element(&self.0)?; /// tup.serialize_element(&self.0)?;
@@ -1529,10 +1573,12 @@ pub trait SerializeSeq {
/// # } /// # }
/// # /// #
/// # impl<T> Serialize for Array<T> /// # impl<T> Serialize for Array<T>
/// where T: Serialize /// where
/// T: Serialize,
/// { /// {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// let mut seq = serializer.serialize_tuple(16)?; /// let mut seq = serializer.serialize_tuple(16)?;
/// for element in self { /// for element in self {
@@ -1567,7 +1613,8 @@ pub trait SerializeTuple {
/// ///
/// impl Serialize for Rgb { /// impl Serialize for Rgb {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?; /// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?;
/// ts.serialize_field(&self.0)?; /// ts.serialize_field(&self.0)?;
@@ -1605,7 +1652,8 @@ pub trait SerializeTupleStruct {
/// ///
/// impl Serialize for E { /// impl Serialize for E {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// match *self { /// match *self {
/// E::T(ref a, ref b) => { /// E::T(ref a, ref b) => {
@@ -1666,11 +1714,13 @@ pub trait SerializeTupleVariant {
/// use serde::ser::{Serialize, Serializer, SerializeMap}; /// use serde::ser::{Serialize, Serializer, SerializeMap};
/// ///
/// impl<K, V> Serialize for HashMap<K, V> /// impl<K, V> Serialize for HashMap<K, V>
/// where K: Serialize, /// where
/// V: Serialize /// K: Serialize,
/// V: Serialize,
/// { /// {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// let mut map = serializer.serialize_map(Some(self.len()))?; /// let mut map = serializer.serialize_map(Some(self.len()))?;
/// for (k, v) in self { /// for (k, v) in self {
@@ -1754,7 +1804,8 @@ pub trait SerializeMap {
/// ///
/// impl Serialize for Rgb { /// impl Serialize for Rgb {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// let mut rgb = serializer.serialize_struct("Rgb", 3)?; /// let mut rgb = serializer.serialize_struct("Rgb", 3)?;
/// rgb.serialize_field("r", &self.r)?; /// rgb.serialize_field("r", &self.r)?;
@@ -1802,7 +1853,8 @@ pub trait SerializeStruct {
/// ///
/// impl Serialize for E { /// impl Serialize for E {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer /// where
/// S: Serializer,
/// { /// {
/// match *self { /// match *self {
/// E::S { ref r, ref g, ref b } => { /// E::S { ref r, ref g, ref b } => {
+1 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_derive" name = "serde_derive"
version = "1.0.44" # remember to update html_root_url version = "1.0.46" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
@@ -25,7 +25,6 @@ proc-macro = true
[dependencies] [dependencies]
proc-macro2 = "0.3" proc-macro2 = "0.3"
quote = "0.5.2" quote = "0.5.2"
serde_derive_internals = { version = "=0.23.1", default-features = false, path = "../serde_derive_internals" }
syn = { version = "0.13", features = ["visit"] } syn = { version = "0.13", features = ["visit"] }
[dev-dependencies] [dev-dependencies]
+108 -72
View File
@@ -16,6 +16,7 @@ use bound;
use fragment::{Expr, Fragment, Match, Stmts}; use fragment::{Expr, Fragment, Match, Stmts};
use internals::ast::{Container, Data, Field, Style, Variant}; use internals::ast::{Container, Data, Field, Style, Variant};
use internals::{self, attr}; use internals::{self, attr};
use pretend;
use try; use try;
use std::collections::BTreeSet; use std::collections::BTreeSet;
@@ -25,7 +26,7 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, Str
let cont = Container::from_ast(&ctxt, input); let cont = Container::from_ast(&ctxt, input);
try!(ctxt.check()); try!(ctxt.check());
let ident = &cont.ident; let ident = cont.ident;
let params = Parameters::new(&cont); let params = Parameters::new(&cont);
let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(&params); let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(&params);
let dummy_const = Ident::new( let dummy_const = Ident::new(
@@ -37,11 +38,14 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, Str
let impl_block = if let Some(remote) = cont.attrs.remote() { let impl_block = if let Some(remote) = cont.attrs.remote() {
let vis = &input.vis; let vis = &input.vis;
let used = pretend::pretend_used(&cont);
quote! { quote! {
impl #de_impl_generics #ident #ty_generics #where_clause { impl #de_impl_generics #ident #ty_generics #where_clause {
#vis fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error> #vis fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error>
where __D: _serde::Deserializer<#delife> where
__D: _serde::Deserializer<#delife>,
{ {
#used
#body #body
} }
} }
@@ -53,7 +57,8 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, Str
#[automatically_derived] #[automatically_derived]
impl #de_impl_generics _serde::Deserialize<#delife> for #ident #ty_generics #where_clause { impl #de_impl_generics _serde::Deserialize<#delife> for #ident #ty_generics #where_clause {
fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error> fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error>
where __D: _serde::Deserializer<#delife> where
__D: _serde::Deserializer<#delife>,
{ {
#body #body
} }
@@ -293,7 +298,8 @@ fn deserialize_in_place_body(cont: &Container, params: &Parameters) -> Option<St
let fn_deserialize_in_place = quote_block! { let fn_deserialize_in_place = quote_block! {
fn deserialize_in_place<__D>(__deserializer: __D, __place: &mut Self) -> _serde::export::Result<(), __D::Error> fn deserialize_in_place<__D>(__deserializer: __D, __place: &mut Self) -> _serde::export::Result<(), __D::Error>
where __D: _serde::Deserializer<#delife> where
__D: _serde::Deserializer<#delife>,
{ {
#stmts #stmts
} }
@@ -333,7 +339,8 @@ fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fra
#[inline] #[inline]
fn visit_unit<__E>(self) -> _serde::export::Result<Self::Value, __E> fn visit_unit<__E>(self) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error where
__E: _serde::de::Error,
{ {
_serde::export::Ok(#this) _serde::export::Ok(#this)
} }
@@ -344,7 +351,7 @@ fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fra
} }
fn deserialize_tuple( fn deserialize_tuple(
variant_ident: Option<&syn::Ident>, variant_ident: Option<syn::Ident>,
params: &Parameters, params: &Parameters,
fields: &[Field], fields: &[Field],
cattrs: &attr::Container, cattrs: &attr::Container,
@@ -361,7 +368,7 @@ fn deserialize_tuple(
// and use an `Into` conversion to get the remote type. If there are no // and use an `Into` conversion to get the remote type. If there are no
// getters then construct the target type directly. // getters then construct the target type directly.
let construct = if params.has_getter { let construct = if params.has_getter {
let local = &params.local; let local = params.local;
quote!(#local) quote!(#local)
} else { } else {
quote!(#this) quote!(#this)
@@ -429,7 +436,8 @@ fn deserialize_tuple(
#[inline] #[inline]
fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error> fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
where __A: _serde::de::SeqAccess<#delife> where
__A: _serde::de::SeqAccess<#delife>,
{ {
#visit_seq #visit_seq
} }
@@ -441,7 +449,7 @@ fn deserialize_tuple(
#[cfg(feature = "deserialize_in_place")] #[cfg(feature = "deserialize_in_place")]
fn deserialize_tuple_in_place( fn deserialize_tuple_in_place(
variant_ident: Option<&syn::Ident>, variant_ident: Option<syn::Ident>,
params: &Parameters, params: &Parameters,
fields: &[Field], fields: &[Field],
cattrs: &attr::Container, cattrs: &attr::Container,
@@ -517,7 +525,8 @@ fn deserialize_tuple_in_place(
#[inline] #[inline]
fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error> fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
where __A: _serde::de::SeqAccess<#delife> where
__A: _serde::de::SeqAccess<#delife>,
{ {
#visit_seq #visit_seq
} }
@@ -554,7 +563,7 @@ fn deserialize_seq(
} else { } else {
let visit = match field.attrs.deserialize_with() { let visit = match field.attrs.deserialize_with() {
None => { None => {
let field_ty = &field.ty; let field_ty = field.ty;
let span = field.original.span(); let span = field.original.span();
let func = let func =
quote_spanned!(span=> _serde::de::SeqAccess::next_element::<#field_ty>); quote_spanned!(span=> _serde::de::SeqAccess::next_element::<#field_ty>);
@@ -716,20 +725,18 @@ fn deserialize_seq_in_place(
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 delife = params.borrowed.de_lifetime(); let delife = params.borrowed.de_lifetime();
let field_ty = field.ty;
let value = match field.attrs.deserialize_with() { let value = match field.attrs.deserialize_with() {
None => { None => {
let field_ty = &field.ty;
quote! { quote! {
try!(<#field_ty as _serde::Deserialize>::deserialize(__e)) try!(<#field_ty as _serde::Deserialize>::deserialize(__e))
} }
} }
Some(path) => { Some(path) => {
let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); quote! {
quote!({ try!(#path(__e))
#wrapper }
try!(<#wrapper_ty as _serde::Deserialize>::deserialize(__e)).value
})
} }
}; };
@@ -744,9 +751,10 @@ fn deserialize_newtype_struct(type_path: &Tokens, params: &Parameters, field: &F
quote! { quote! {
#[inline] #[inline]
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error> fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
where __E: _serde::Deserializer<#delife> where
__E: _serde::Deserializer<#delife>,
{ {
let __field0 = #value; let __field0: #field_ty = #value;
_serde::export::Ok(#result) _serde::export::Ok(#result)
} }
} }
@@ -762,7 +770,8 @@ fn deserialize_newtype_struct_in_place(params: &Parameters, field: &Field) -> To
quote! { quote! {
#[inline] #[inline]
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error> fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
where __E: _serde::Deserializer<#delife> where
__E: _serde::Deserializer<#delife>,
{ {
_serde::Deserialize::deserialize_in_place(__e, &mut self.place.0) _serde::Deserialize::deserialize_in_place(__e, &mut self.place.0)
} }
@@ -775,7 +784,7 @@ enum Untagged {
} }
fn deserialize_struct( fn deserialize_struct(
variant_ident: Option<&syn::Ident>, variant_ident: Option<syn::Ident>,
params: &Parameters, params: &Parameters,
fields: &[Field], fields: &[Field],
cattrs: &attr::Container, cattrs: &attr::Container,
@@ -793,7 +802,7 @@ fn deserialize_struct(
// and use an `Into` conversion to get the remote type. If there are no // and use an `Into` conversion to get the remote type. If there are no
// getters then construct the target type directly. // getters then construct the target type directly.
let construct = if params.has_getter { let construct = if params.has_getter {
let local = &params.local; let local = params.local;
quote!(#local) quote!(#local)
} else { } else {
quote!(#this) quote!(#this)
@@ -857,7 +866,8 @@ fn deserialize_struct(
Untagged::No if !cattrs.has_flatten() => Some(quote! { Untagged::No if !cattrs.has_flatten() => Some(quote! {
#[inline] #[inline]
fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error> fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
where __A: _serde::de::SeqAccess<#delife> where
__A: _serde::de::SeqAccess<#delife>,
{ {
#visit_seq #visit_seq
} }
@@ -884,7 +894,8 @@ fn deserialize_struct(
#[inline] #[inline]
fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result<Self::Value, __A::Error> fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result<Self::Value, __A::Error>
where __A: _serde::de::MapAccess<#delife> where
__A: _serde::de::MapAccess<#delife>,
{ {
#visit_map #visit_map
} }
@@ -898,7 +909,7 @@ fn deserialize_struct(
#[cfg(feature = "deserialize_in_place")] #[cfg(feature = "deserialize_in_place")]
fn deserialize_struct_in_place( fn deserialize_struct_in_place(
variant_ident: Option<&syn::Ident>, variant_ident: Option<syn::Ident>,
params: &Parameters, params: &Parameters,
fields: &[Field], fields: &[Field],
cattrs: &attr::Container, cattrs: &attr::Container,
@@ -962,7 +973,8 @@ fn deserialize_struct_in_place(
let visit_seq = quote! { let visit_seq = quote! {
#[inline] #[inline]
fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error> fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
where __A: _serde::de::SeqAccess<#delife> where
__A: _serde::de::SeqAccess<#delife>,
{ {
#visit_seq #visit_seq
} }
@@ -991,7 +1003,8 @@ fn deserialize_struct_in_place(
#[inline] #[inline]
fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result<Self::Value, __A::Error> fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result<Self::Value, __A::Error>
where __A: _serde::de::MapAccess<#delife> where
__A: _serde::de::MapAccess<#delife>,
{ {
#visit_map #visit_map
} }
@@ -1110,7 +1123,8 @@ fn deserialize_externally_tagged_enum(
} }
fn visit_enum<__A>(self, __data: __A) -> _serde::export::Result<Self::Value, __A::Error> fn visit_enum<__A>(self, __data: __A) -> _serde::export::Result<Self::Value, __A::Error>
where __A: _serde::de::EnumAccess<#delife> where
__A: _serde::de::EnumAccess<#delife>,
{ {
#match_variant #match_variant
} }
@@ -1179,7 +1193,7 @@ fn deserialize_internally_tagged_enum(
#variants_stmt #variants_stmt
let __tagged = try!(_serde::Deserializer::deserialize_any( let __tagged = try!(_serde::Deserializer::private_deserialize_internally_tagged_enum(
__deserializer, __deserializer,
_serde::private::de::TaggedContentVisitor::<__Field>::new(#tag))); _serde::private::de::TaggedContentVisitor::<__Field>::new(#tag)));
@@ -1284,7 +1298,7 @@ fn deserialize_adjacently_tagged_enum(
.filter(|&(_, variant)| !variant.attrs.skip_deserializing() && is_unit(variant)) .filter(|&(_, variant)| !variant.attrs.skip_deserializing() && is_unit(variant))
.map(|(i, variant)| { .map(|(i, variant)| {
let variant_index = field_i(i); let variant_index = field_i(i);
let variant_ident = &variant.ident; let variant_ident = variant.ident;
quote! { quote! {
__Field::#variant_index => _serde::export::Ok(#this::#variant_ident), __Field::#variant_index => _serde::export::Ok(#this::#variant_ident),
} }
@@ -1360,7 +1374,8 @@ fn deserialize_adjacently_tagged_enum(
type Value = #this #ty_generics; type Value = #this #ty_generics;
fn deserialize<__D>(self, __deserializer: __D) -> _serde::export::Result<Self::Value, __D::Error> fn deserialize<__D>(self, __deserializer: __D) -> _serde::export::Result<Self::Value, __D::Error>
where __D: _serde::Deserializer<#delife> where
__D: _serde::Deserializer<#delife>,
{ {
match self.field { match self.field {
#(#variant_arms)* #(#variant_arms)*
@@ -1381,7 +1396,8 @@ fn deserialize_adjacently_tagged_enum(
} }
fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result<Self::Value, __A::Error> fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result<Self::Value, __A::Error>
where __A: _serde::de::MapAccess<#delife> where
__A: _serde::de::MapAccess<#delife>,
{ {
// Visit the first relevant key. // Visit the first relevant key.
match #next_relevant_key { match #next_relevant_key {
@@ -1445,7 +1461,8 @@ fn deserialize_adjacently_tagged_enum(
} }
fn visit_seq<__A>(self, mut __seq: __A) -> _serde::export::Result<Self::Value, __A::Error> fn visit_seq<__A>(self, mut __seq: __A) -> _serde::export::Result<Self::Value, __A::Error>
where __A: _serde::de::SeqAccess<#delife> where
__A: _serde::de::SeqAccess<#delife>,
{ {
// Visit the first element - the tag. // Visit the first element - the tag.
match try!(_serde::de::SeqAccess::next_element(&mut __seq)) { match try!(_serde::de::SeqAccess::next_element(&mut __seq)) {
@@ -1536,7 +1553,7 @@ fn deserialize_externally_tagged_variant(
}; };
} }
let variant_ident = &variant.ident; let variant_ident = variant.ident;
match variant.style { match variant.style {
Style::Unit => { Style::Unit => {
@@ -1573,7 +1590,7 @@ fn deserialize_internally_tagged_variant(
return deserialize_untagged_variant(params, variant, cattrs, deserializer); return deserialize_untagged_variant(params, variant, cattrs, deserializer);
} }
let variant_ident = &variant.ident; let variant_ident = variant.ident;
match variant.style { match variant.style {
Style::Unit => { Style::Unit => {
@@ -1618,7 +1635,7 @@ fn deserialize_untagged_variant(
}; };
} }
let variant_ident = &variant.ident; let variant_ident = variant.ident;
match variant.style { match variant.style {
Style::Unit => { Style::Unit => {
@@ -1660,14 +1677,14 @@ fn deserialize_untagged_variant(
} }
fn deserialize_externally_tagged_newtype_variant( fn deserialize_externally_tagged_newtype_variant(
variant_ident: &syn::Ident, variant_ident: syn::Ident,
params: &Parameters, params: &Parameters,
field: &Field, field: &Field,
) -> Fragment { ) -> Fragment {
let this = &params.this; let this = &params.this;
match field.attrs.deserialize_with() { match field.attrs.deserialize_with() {
None => { None => {
let field_ty = &field.ty; let field_ty = field.ty;
quote_expr! { quote_expr! {
_serde::export::Result::map( _serde::export::Result::map(
_serde::de::VariantAccess::newtype_variant::<#field_ty>(__variant), _serde::de::VariantAccess::newtype_variant::<#field_ty>(__variant),
@@ -1687,15 +1704,15 @@ fn deserialize_externally_tagged_newtype_variant(
} }
fn deserialize_untagged_newtype_variant( fn deserialize_untagged_newtype_variant(
variant_ident: &syn::Ident, variant_ident: syn::Ident,
params: &Parameters, params: &Parameters,
field: &Field, field: &Field,
deserializer: &Tokens, deserializer: &Tokens,
) -> Fragment { ) -> Fragment {
let this = &params.this; let this = &params.this;
let field_ty = field.ty;
match field.attrs.deserialize_with() { match field.attrs.deserialize_with() {
None => { None => {
let field_ty = &field.ty;
quote_expr! { quote_expr! {
_serde::export::Result::map( _serde::export::Result::map(
<#field_ty as _serde::Deserialize>::deserialize(#deserializer), <#field_ty as _serde::Deserialize>::deserialize(#deserializer),
@@ -1703,12 +1720,11 @@ fn deserialize_untagged_newtype_variant(
} }
} }
Some(path) => { Some(path) => {
let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
quote_block! { quote_block! {
#wrapper let __value: #field_ty = _serde::export::Result::map(
_serde::export::Result::map( #path(#deserializer),
<#wrapper_ty as _serde::Deserialize>::deserialize(#deserializer), #this::#variant_ident);
|__wrapper| #this::#variant_ident(__wrapper.value)) __value
} }
} }
} }
@@ -1766,7 +1782,8 @@ fn deserialize_generated_identifier(
impl<'de> _serde::Deserialize<'de> for __Field #lifetime { impl<'de> _serde::Deserialize<'de> for __Field #lifetime {
#[inline] #[inline]
fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error> fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error>
where __D: _serde::Deserializer<'de> where
__D: _serde::Deserializer<'de>,
{ {
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor) _serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
} }
@@ -1789,7 +1806,7 @@ fn deserialize_custom_identifier(
let this = quote!(#this); let this = quote!(#this);
let (ordinary, fallthrough) = if let Some(last) = variants.last() { let (ordinary, fallthrough) = if let Some(last) = variants.last() {
let last_ident = &last.ident; let last_ident = last.ident;
if last.attrs.other() { if last.attrs.other() {
let ordinary = &variants[..variants.len() - 1]; let ordinary = &variants[..variants.len() - 1];
let fallthrough = quote!(_serde::export::Ok(#this::#last_ident)); let fallthrough = quote!(_serde::export::Ok(#this::#last_ident));
@@ -1942,85 +1959,99 @@ fn deserialize_identifier(
let visit_other = if collect_other_fields { let visit_other = if collect_other_fields {
quote! { quote! {
fn visit_bool<__E>(self, __value: bool) -> _serde::export::Result<Self::Value, __E> fn visit_bool<__E>(self, __value: bool) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error where
__E: _serde::de::Error,
{ {
_serde::export::Ok(__Field::__other(_serde::private::de::Content::Bool(__value))) _serde::export::Ok(__Field::__other(_serde::private::de::Content::Bool(__value)))
} }
fn visit_i8<__E>(self, __value: i8) -> _serde::export::Result<Self::Value, __E> fn visit_i8<__E>(self, __value: i8) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error where
__E: _serde::de::Error,
{ {
_serde::export::Ok(__Field::__other(_serde::private::de::Content::I8(__value))) _serde::export::Ok(__Field::__other(_serde::private::de::Content::I8(__value)))
} }
fn visit_i16<__E>(self, __value: i16) -> _serde::export::Result<Self::Value, __E> fn visit_i16<__E>(self, __value: i16) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error where
__E: _serde::de::Error,
{ {
_serde::export::Ok(__Field::__other(_serde::private::de::Content::I16(__value))) _serde::export::Ok(__Field::__other(_serde::private::de::Content::I16(__value)))
} }
fn visit_i32<__E>(self, __value: i32) -> _serde::export::Result<Self::Value, __E> fn visit_i32<__E>(self, __value: i32) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error where
__E: _serde::de::Error,
{ {
_serde::export::Ok(__Field::__other(_serde::private::de::Content::I32(__value))) _serde::export::Ok(__Field::__other(_serde::private::de::Content::I32(__value)))
} }
fn visit_i64<__E>(self, __value: i64) -> _serde::export::Result<Self::Value, __E> fn visit_i64<__E>(self, __value: i64) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error where
__E: _serde::de::Error,
{ {
_serde::export::Ok(__Field::__other(_serde::private::de::Content::I64(__value))) _serde::export::Ok(__Field::__other(_serde::private::de::Content::I64(__value)))
} }
fn visit_u8<__E>(self, __value: u8) -> _serde::export::Result<Self::Value, __E> fn visit_u8<__E>(self, __value: u8) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error where
__E: _serde::de::Error,
{ {
_serde::export::Ok(__Field::__other(_serde::private::de::Content::U8(__value))) _serde::export::Ok(__Field::__other(_serde::private::de::Content::U8(__value)))
} }
fn visit_u16<__E>(self, __value: u16) -> _serde::export::Result<Self::Value, __E> fn visit_u16<__E>(self, __value: u16) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error where
__E: _serde::de::Error,
{ {
_serde::export::Ok(__Field::__other(_serde::private::de::Content::U16(__value))) _serde::export::Ok(__Field::__other(_serde::private::de::Content::U16(__value)))
} }
fn visit_u32<__E>(self, __value: u32) -> _serde::export::Result<Self::Value, __E> fn visit_u32<__E>(self, __value: u32) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error where
__E: _serde::de::Error,
{ {
_serde::export::Ok(__Field::__other(_serde::private::de::Content::U32(__value))) _serde::export::Ok(__Field::__other(_serde::private::de::Content::U32(__value)))
} }
fn visit_u64<__E>(self, __value: u64) -> _serde::export::Result<Self::Value, __E> fn visit_u64<__E>(self, __value: u64) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error where
__E: _serde::de::Error,
{ {
_serde::export::Ok(__Field::__other(_serde::private::de::Content::U64(__value))) _serde::export::Ok(__Field::__other(_serde::private::de::Content::U64(__value)))
} }
fn visit_f32<__E>(self, __value: f32) -> _serde::export::Result<Self::Value, __E> fn visit_f32<__E>(self, __value: f32) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error where
__E: _serde::de::Error,
{ {
_serde::export::Ok(__Field::__other(_serde::private::de::Content::F32(__value))) _serde::export::Ok(__Field::__other(_serde::private::de::Content::F32(__value)))
} }
fn visit_f64<__E>(self, __value: f64) -> _serde::export::Result<Self::Value, __E> fn visit_f64<__E>(self, __value: f64) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error where
__E: _serde::de::Error,
{ {
_serde::export::Ok(__Field::__other(_serde::private::de::Content::F64(__value))) _serde::export::Ok(__Field::__other(_serde::private::de::Content::F64(__value)))
} }
fn visit_char<__E>(self, __value: char) -> _serde::export::Result<Self::Value, __E> fn visit_char<__E>(self, __value: char) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error where
__E: _serde::de::Error,
{ {
_serde::export::Ok(__Field::__other(_serde::private::de::Content::Char(__value))) _serde::export::Ok(__Field::__other(_serde::private::de::Content::Char(__value)))
} }
fn visit_unit<__E>(self) -> _serde::export::Result<Self::Value, __E> fn visit_unit<__E>(self) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error where
__E: _serde::de::Error,
{ {
_serde::export::Ok(__Field::__other(_serde::private::de::Content::Unit)) _serde::export::Ok(__Field::__other(_serde::private::de::Content::Unit))
} }
fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::export::Result<Self::Value, __E> fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error where
__E: _serde::de::Error,
{ {
match __value { match __value {
#( #(
@@ -2034,7 +2065,8 @@ fn deserialize_identifier(
} }
fn visit_borrowed_bytes<__E>(self, __value: &'de [u8]) -> _serde::export::Result<Self::Value, __E> fn visit_borrowed_bytes<__E>(self, __value: &'de [u8]) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error where
__E: _serde::de::Error,
{ {
match __value { match __value {
#( #(
@@ -2051,7 +2083,8 @@ fn deserialize_identifier(
} else { } else {
quote! { quote! {
fn visit_u64<__E>(self, __value: u64) -> _serde::export::Result<Self::Value, __E> fn visit_u64<__E>(self, __value: u64) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error where
__E: _serde::de::Error,
{ {
match __value { match __value {
#( #(
@@ -2073,7 +2106,8 @@ fn deserialize_identifier(
#visit_other #visit_other
fn visit_str<__E>(self, __value: &str) -> _serde::export::Result<Self::Value, __E> fn visit_str<__E>(self, __value: &str) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error where
__E: _serde::de::Error,
{ {
match __value { match __value {
#( #(
@@ -2087,7 +2121,8 @@ fn deserialize_identifier(
} }
fn visit_bytes<__E>(self, __value: &[u8]) -> _serde::export::Result<Self::Value, __E> fn visit_bytes<__E>(self, __value: &[u8]) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error where
__E: _serde::de::Error,
{ {
match __value { match __value {
#( #(
@@ -2170,7 +2205,7 @@ fn deserialize_map(
.iter() .iter()
.filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten()) .filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
.map(|&(field, ref name)| { .map(|&(field, ref name)| {
let field_ty = &field.ty; let field_ty = field.ty;
quote! { quote! {
let mut #name: _serde::export::Option<#field_ty> = _serde::export::None; let mut #name: _serde::export::Option<#field_ty> = _serde::export::None;
} }
@@ -2197,7 +2232,7 @@ fn deserialize_map(
let visit = match field.attrs.deserialize_with() { let visit = match field.attrs.deserialize_with() {
None => { None => {
let field_ty = &field.ty; let field_ty = field.ty;
let span = field.original.span(); let span = field.original.span();
let func = let func =
quote_spanned!(span=> _serde::de::MapAccess::next_value::<#field_ty>); quote_spanned!(span=> _serde::de::MapAccess::next_value::<#field_ty>);
@@ -2418,7 +2453,7 @@ fn deserialize_map_in_place(
.filter(|&&(field, _)| !field.attrs.skip_deserializing()) .filter(|&&(field, _)| !field.attrs.skip_deserializing())
.map(|&(field, ref name)| { .map(|&(field, ref name)| {
let deser_name = field.attrs.name().deserialize_name(); let deser_name = field.attrs.name().deserialize_name();
let field_name = &field.ident; let field_name = field.ident;
let visit = match field.attrs.deserialize_with() { let visit = match field.attrs.deserialize_with() {
None => { None => {
@@ -2496,7 +2531,7 @@ fn deserialize_map_in_place(
} }
} }
} else { } else {
let field_name = &field.ident; let field_name = field.ident;
let missing_expr = Expr(missing_expr); let missing_expr = Expr(missing_expr);
quote! { quote! {
if !#name { if !#name {
@@ -2561,7 +2596,8 @@ fn wrap_deserialize_with(
impl #de_impl_generics _serde::Deserialize<#delife> for __DeserializeWith #de_ty_generics #where_clause { impl #de_impl_generics _serde::Deserialize<#delife> for __DeserializeWith #de_ty_generics #where_clause {
fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error> fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error>
where __D: _serde::Deserializer<#delife> where
__D: _serde::Deserializer<#delife>,
{ {
_serde::export::Ok(__DeserializeWith { _serde::export::Ok(__DeserializeWith {
value: try!(#deserialize_with(__deserializer)), value: try!(#deserialize_with(__deserializer)),
@@ -2591,7 +2627,7 @@ fn wrap_deserialize_variant_with(
deserialize_with: &syn::ExprPath, deserialize_with: &syn::ExprPath,
) -> (Tokens, Tokens, Tokens) { ) -> (Tokens, Tokens, Tokens) {
let this = &params.this; let this = &params.this;
let variant_ident = &variant.ident; let variant_ident = variant.ident;
let field_tys = variant.fields.iter().map(|field| field.ty); let field_tys = variant.fields.iter().map(|field| field.ty);
let (wrapper, wrapper_ty) = let (wrapper, wrapper_ty) =
@@ -2646,7 +2682,7 @@ fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment {
match *cattrs.default() { match *cattrs.default() {
attr::Default::Default | attr::Default::Path(_) => { attr::Default::Default | attr::Default::Path(_) => {
let ident = &field.ident; let ident = field.ident;
return quote_expr!(__default.#ident); return quote_expr!(__default.#ident);
} }
attr::Default::None => { /* below */ } attr::Default::None => { /* below */ }
@@ -6,11 +6,11 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use attr; use internals::attr;
use check; use internals::check;
use internals::Ctxt;
use syn; use syn;
use syn::punctuated::Punctuated; use syn::punctuated::Punctuated;
use Ctxt;
pub struct Container<'a> { pub struct Container<'a> {
pub ident: syn::Ident, pub ident: syn::Ident,
@@ -6,6 +6,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use internals::Ctxt;
use proc_macro2::{Group, Span, TokenStream, TokenTree}; use proc_macro2::{Group, Span, TokenStream, TokenTree};
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::str::FromStr; use std::str::FromStr;
@@ -15,7 +16,6 @@ use syn::synom::{ParseError, Synom};
use syn::Ident; use syn::Ident;
use syn::Meta::{List, NameValue, Word}; use syn::Meta::{List, NameValue, Word};
use syn::NestedMeta::{Literal, Meta}; use syn::NestedMeta::{Literal, Meta};
use Ctxt;
// This module handles parsing of `#[serde(...)]` attributes. The entrypoints // This module handles parsing of `#[serde(...)]` attributes. The entrypoints
// are `attr::Container::from_ast`, `attr::Variant::from_ast`, and // are `attr::Container::from_ast`, `attr::Variant::from_ast`, and
@@ -25,7 +25,7 @@ use Ctxt;
// user will see errors simultaneously for all bad attributes in the crate // user will see errors simultaneously for all bad attributes in the crate
// rather than just the first. // rather than just the first.
pub use case::RenameRule; pub use internals::case::RenameRule;
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
struct Attr<'c, T> { struct Attr<'c, T> {
@@ -167,6 +167,7 @@ pub enum Identifier {
} }
impl Identifier { impl Identifier {
#[cfg(feature = "deserialize_in_place")]
pub fn is_some(self) -> bool { pub fn is_some(self) -> bool {
match self { match self {
Identifier::No => false, Identifier::No => false,
@@ -6,9 +6,9 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use ast::{Container, Data, Style}; use internals::ast::{Container, Data, Style};
use attr::{EnumTag, Identifier}; use internals::attr::{EnumTag, Identifier};
use Ctxt; use internals::Ctxt;
/// Cross-cutting checks that require looking at more than a single attrs /// Cross-cutting checks that require looking at more than a single attrs
/// object. Simpler checks should happen when parsing and building the attrs. /// object. Simpler checks should happen when parsing and building the attrs.
+16
View File
@@ -0,0 +1,16 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub mod ast;
pub mod attr;
mod ctxt;
pub use self::ctxt::Ctxt;
mod case;
mod check;
+4 -3
View File
@@ -22,7 +22,7 @@
//! //!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html //! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.44")] #![doc(html_root_url = "https://docs.rs/serde_derive/1.0.46")]
#![cfg_attr( #![cfg_attr(
feature = "cargo-clippy", feature = "cargo-clippy",
allow(enum_variant_names, redundant_field_names, too_many_arguments, used_underscore_binding) allow(enum_variant_names, redundant_field_names, too_many_arguments, used_underscore_binding)
@@ -35,11 +35,11 @@ extern crate quote;
#[macro_use] #[macro_use]
extern crate syn; extern crate syn;
extern crate serde_derive_internals as internals;
extern crate proc_macro; extern crate proc_macro;
extern crate proc_macro2; extern crate proc_macro2;
mod internals;
use proc_macro::TokenStream; use proc_macro::TokenStream;
use syn::DeriveInput; use syn::DeriveInput;
@@ -49,6 +49,7 @@ mod bound;
mod fragment; mod fragment;
mod de; mod de;
mod pretend;
mod ser; mod ser;
mod try; mod try;
+141
View File
@@ -0,0 +1,141 @@
use proc_macro2::Span;
use quote::Tokens;
use syn::Ident;
use internals::ast::{Container, Data, Field, Style};
// Suppress dead_code warnings that would otherwise appear when using a remote
// derive. Other than this pretend code, a struct annotated with remote derive
// never has its fields referenced and an enum annotated with remote derive
// never has its variants constructed.
//
// warning: field is never used: `i`
// --> src/main.rs:4:20
// |
// 4 | struct StructDef { i: i32 }
// | ^^^^^^
//
// warning: variant is never constructed: `V`
// --> src/main.rs:8:16
// |
// 8 | enum EnumDef { V }
// | ^
//
pub fn pretend_used(cont: &Container) -> Tokens {
let pretend_fields = pretend_fields_used(cont);
let pretend_variants = pretend_variants_used(cont);
quote! {
#pretend_fields
#pretend_variants
}
}
// For structs with named fields, expands to:
//
// match None::<T> {
// Some(T { a: ref __v0, b: ref __v1 }) => {}
// _ => {}
// }
//
// For enums, expands to the following but only including struct variants:
//
// match None::<T> {
// Some(T::A { a: ref __v0 }) => {}
// Some(T::B { b: ref __v0 }) => {}
// _ => {}
// }
//
// The `ref` is important in case the user has written a Drop impl on their
// type. Rust does not allow destructuring a struct or enum that has a Drop
// impl.
fn pretend_fields_used(cont: &Container) -> Tokens {
let type_ident = cont.ident;
let (_, ty_generics, _) = cont.generics.split_for_impl();
let patterns = match cont.data {
Data::Enum(ref variants) => variants
.iter()
.filter_map(|variant| match variant.style {
Style::Struct => {
let variant_ident = variant.ident;
let pat = struct_pattern(&variant.fields);
Some(quote!(#type_ident::#variant_ident #pat))
}
_ => None,
})
.collect::<Vec<_>>(),
Data::Struct(Style::Struct, ref fields) => {
let pat = struct_pattern(fields);
vec![quote!(#type_ident #pat)]
}
Data::Struct(_, _) => {
return quote!();
}
};
quote! {
match _serde::export::None::<#type_ident #ty_generics> {
#(
_serde::export::Some(#patterns) => {}
)*
_ => {}
}
}
}
// Expands to one of these per enum variant:
//
// match None {
// Some((__v0, __v1,)) => {
// let _ = E::V { a: __v0, b: __v1 };
// }
// _ => {}
// }
//
fn pretend_variants_used(cont: &Container) -> Tokens {
let variants = match cont.data {
Data::Enum(ref variants) => variants,
Data::Struct(_, _) => {
return quote!();
}
};
let type_ident = cont.ident;
let (_, ty_generics, _) = cont.generics.split_for_impl();
let turbofish = ty_generics.as_turbofish();
let cases = variants.iter().map(|variant| {
let variant_ident = variant.ident;
let placeholders = &(0..variant.fields.len())
.map(|i| Ident::new(&format!("__v{}", i), Span::call_site()))
.collect::<Vec<_>>();
let pat = match variant.style {
Style::Struct => {
let names = variant.fields.iter().map(|field| field.ident);
quote!({ #(#names: #placeholders),* })
}
Style::Tuple | Style::Newtype => quote!(( #(#placeholders),* )),
Style::Unit => quote!(),
};
quote! {
match _serde::export::None {
_serde::export::Some((#(#placeholders,)*)) => {
let _ = #type_ident::#variant_ident #turbofish #pat;
}
_ => {}
}
}
});
quote!(#(#cases)*)
}
fn struct_pattern(fields: &[Field]) -> Tokens {
let names = fields.iter().map(|field| field.ident);
let placeholders =
(0..fields.len()).map(|i| Ident::new(&format!("__v{}", i), Span::call_site()));
quote!({ #(#names: ref #placeholders),* })
}
+15 -8
View File
@@ -15,6 +15,7 @@ use bound;
use fragment::{Fragment, Match, Stmts}; use fragment::{Fragment, Match, Stmts};
use internals::ast::{Container, Data, Field, Style, Variant}; use internals::ast::{Container, Data, Field, Style, Variant};
use internals::{attr, Ctxt}; use internals::{attr, Ctxt};
use pretend;
use try; use try;
use std::u32; use std::u32;
@@ -25,7 +26,7 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<Tokens, Strin
precondition(&ctxt, &cont); precondition(&ctxt, &cont);
try!(ctxt.check()); try!(ctxt.check());
let ident = &cont.ident; let ident = cont.ident;
let params = Parameters::new(&cont); let params = Parameters::new(&cont);
let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl(); let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl();
let dummy_const = Ident::new(&format!("_IMPL_SERIALIZE_FOR_{}", ident), Span::call_site()); let dummy_const = Ident::new(&format!("_IMPL_SERIALIZE_FOR_{}", ident), Span::call_site());
@@ -33,11 +34,14 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<Tokens, Strin
let impl_block = if let Some(remote) = cont.attrs.remote() { let impl_block = if let Some(remote) = cont.attrs.remote() {
let vis = &input.vis; let vis = &input.vis;
let used = pretend::pretend_used(&cont);
quote! { quote! {
impl #impl_generics #ident #ty_generics #where_clause { impl #impl_generics #ident #ty_generics #where_clause {
#vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error> #vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
where __S: _serde::Serializer where
__S: _serde::Serializer,
{ {
#used
#body #body
} }
} }
@@ -47,7 +51,8 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<Tokens, Strin
#[automatically_derived] #[automatically_derived]
impl #impl_generics _serde::Serialize for #ident #ty_generics #where_clause { impl #impl_generics _serde::Serialize for #ident #ty_generics #where_clause {
fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error> fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
where __S: _serde::Serializer where
__S: _serde::Serializer,
{ {
#body #body
} }
@@ -183,7 +188,7 @@ fn serialize_body(cont: &Container, params: &Parameters) -> Fragment {
} }
fn serialize_into(params: &Parameters, type_into: &syn::Type) -> Fragment { fn serialize_into(params: &Parameters, type_into: &syn::Type) -> Fragment {
let self_var = &params.self_var; let self_var = params.self_var;
quote_block! { quote_block! {
_serde::Serialize::serialize( _serde::Serialize::serialize(
&_serde::export::Into::<#type_into>::into(_serde::export::Clone::clone(#self_var)), &_serde::export::Into::<#type_into>::into(_serde::export::Clone::clone(#self_var)),
@@ -330,7 +335,7 @@ fn serialize_struct_as_map(
fn serialize_enum(params: &Parameters, variants: &[Variant], cattrs: &attr::Container) -> Fragment { fn serialize_enum(params: &Parameters, variants: &[Variant], cattrs: &attr::Container) -> Fragment {
assert!(variants.len() as u64 <= u64::from(u32::MAX)); assert!(variants.len() as u64 <= u64::from(u32::MAX));
let self_var = &params.self_var; let self_var = params.self_var;
let arms: Vec<_> = variants let arms: Vec<_> = variants
.iter() .iter()
@@ -655,7 +660,8 @@ fn serialize_adjacently_tagged_variant(
impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause { impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause {
fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error> fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
where __S: _serde::Serializer where
__S: _serde::Serializer,
{ {
let (#(#fields_ident,)*) = self.data; let (#(#fields_ident,)*) = self.data;
#inner #inner
@@ -1034,7 +1040,8 @@ fn wrap_serialize_with(
impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause { impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause {
fn serialize<__S>(&self, __s: __S) -> _serde::export::Result<__S::Ok, __S::Error> fn serialize<__S>(&self, __s: __S) -> _serde::export::Result<__S::Ok, __S::Error>
where __S: _serde::Serializer where
__S: _serde::Serializer,
{ {
#serialize_with(#(self.values.#field_access, )* __s) #serialize_with(#(self.values.#field_access, )* __s)
} }
@@ -1062,7 +1069,7 @@ fn mut_if(is_mut: bool) -> Option<Tokens> {
} }
fn get_member(params: &Parameters, field: &Field, member: &Member) -> Tokens { fn get_member(params: &Parameters, field: &Field, member: &Member) -> Tokens {
let self_var = &params.self_var; let self_var = params.self_var;
match (params.is_remote, field.attrs.getter()) { match (params.is_remote, field.attrs.getter()) {
(false, None) => quote!(&#self_var.#member), (false, None) => quote!(&#self_var.#member),
(true, None) => { (true, None) => {
+4 -1
View File
@@ -9,7 +9,10 @@ repository = "https://github.com/serde-rs/serde"
documentation = "https://docs.serde.rs/serde_derive_internals/" documentation = "https://docs.serde.rs/serde_derive_internals/"
keywords = ["serde", "serialization"] keywords = ["serde", "serialization"]
readme = "README.md" readme = "README.md"
include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] include = ["Cargo.toml", "lib.rs", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
[lib]
path = "lib.rs"
[dependencies] [dependencies]
proc-macro2 = "0.3" proc-macro2 = "0.3"
@@ -17,11 +17,7 @@ extern crate syn;
extern crate proc_macro2; extern crate proc_macro2;
pub mod ast; #[path = "src/mod.rs"]
pub mod attr; mod internals;
mod ctxt; pub use internals::*;
pub use ctxt::Ctxt;
mod case;
mod check;
+1
View File
@@ -0,0 +1 @@
../serde_derive/src/internals/
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_test" name = "serde_test"
version = "1.0.44" # remember to update html_root_url version = "1.0.46" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "Token De/Serializer for testing De/Serialize implementations" description = "Token De/Serializer for testing De/Serialize implementations"
+12 -5
View File
@@ -1,7 +1,9 @@
use std::fmt; use std::fmt;
use serde::ser::{SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, use serde::ser::{
SerializeTuple, SerializeTupleStruct, SerializeTupleVariant}; SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,
SerializeTupleStruct, SerializeTupleVariant,
};
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
@@ -24,7 +26,8 @@ pub struct Compact<T: ?Sized>(T);
/// ///
/// impl Serialize for Example { /// impl Serialize for Example {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer, /// where
/// S: Serializer,
/// { /// {
/// if serializer.is_human_readable() { /// if serializer.is_human_readable() {
/// format!("{}.{}", self.0, self.1).serialize(serializer) /// format!("{}.{}", self.0, self.1).serialize(serializer)
@@ -36,7 +39,8 @@ pub struct Compact<T: ?Sized>(T);
/// ///
/// impl<'de> Deserialize<'de> for Example { /// impl<'de> Deserialize<'de> for Example {
/// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> /// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
/// where D: Deserializer<'de>, /// where
/// D: Deserializer<'de>,
/// { /// {
/// use serde::de::Error; /// use serde::de::Error;
/// if deserializer.is_human_readable() { /// if deserializer.is_human_readable() {
@@ -476,7 +480,10 @@ use serde::de::{DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, Varian
macro_rules! forward_deserialize_methods { macro_rules! forward_deserialize_methods {
( $wrapper : ident ( $( $name: ident ),* ) ) => { ( $wrapper : ident ( $( $name: ident ),* ) ) => {
$( $(
fn $name<V>(self, visitor: V) -> Result<V::Value, D::Error> where V: Visitor<'de> { fn $name<V>(self, visitor: V) -> Result<V::Value, D::Error>
where
V: Visitor<'de>,
{
(self.0).$name($wrapper(visitor)) (self.0).$name($wrapper(visitor))
} }
)* )*
+4 -2
View File
@@ -7,8 +7,10 @@
// except according to those terms. // except according to those terms.
use serde::de::value::{MapAccessDeserializer, SeqAccessDeserializer}; use serde::de::value::{MapAccessDeserializer, SeqAccessDeserializer};
use serde::de::{self, Deserialize, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, use serde::de::{
SeqAccess, VariantAccess, Visitor}; self, Deserialize, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, SeqAccess,
VariantAccess, Visitor,
};
use error::Error; use error::Error;
use token::Token; use token::Token;
+20 -12
View File
@@ -68,11 +68,13 @@
//! # } //! # }
//! # //! #
//! # impl<K, V> Serialize for LinkedHashMap<K, V> //! # impl<K, V> Serialize for LinkedHashMap<K, V>
//! # where K: Serialize, //! # where
//! # V: Serialize //! # K: Serialize,
//! # V: Serialize,
//! # { //! # {
//! # fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> //! # fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
//! # where S: Serializer //! # where
//! # S: Serializer,
//! # { //! # {
//! # let mut map = serializer.serialize_map(Some(self.0.len()))?; //! # let mut map = serializer.serialize_map(Some(self.0.len()))?;
//! # for &(ref k, ref v) in &self.0 { //! # for &(ref k, ref v) in &self.0 {
@@ -85,8 +87,9 @@
//! # struct LinkedHashMapVisitor<K, V>(PhantomData<(K, V)>); //! # struct LinkedHashMapVisitor<K, V>(PhantomData<(K, V)>);
//! # //! #
//! # impl<'de, K, V> Visitor<'de> for LinkedHashMapVisitor<K, V> //! # impl<'de, K, V> Visitor<'de> for LinkedHashMapVisitor<K, V>
//! # where K: Deserialize<'de>, //! # where
//! # V: Deserialize<'de> //! # K: Deserialize<'de>,
//! # V: Deserialize<'de>,
//! # { //! # {
//! # type Value = LinkedHashMap<K, V>; //! # type Value = LinkedHashMap<K, V>;
//! # //! #
@@ -95,7 +98,8 @@
//! # } //! # }
//! # //! #
//! # fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error> //! # fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
//! # where M: MapAccess<'de> //! # where
//! # M: MapAccess<'de>,
//! # { //! # {
//! # let mut map = LinkedHashMap::new(); //! # let mut map = LinkedHashMap::new();
//! # while let Some((key, value)) = access.next_entry()? { //! # while let Some((key, value)) = access.next_entry()? {
@@ -106,11 +110,13 @@
//! # } //! # }
//! # //! #
//! # impl<'de, K, V> Deserialize<'de> for LinkedHashMap<K, V> //! # impl<'de, K, V> Deserialize<'de> for LinkedHashMap<K, V>
//! # where K: Deserialize<'de>, //! # where
//! # V: Deserialize<'de> //! # K: Deserialize<'de>,
//! # V: Deserialize<'de>,
//! # { //! # {
//! # fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> //! # fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
//! # where D: Deserializer<'de> //! # where
//! # D: Deserializer<'de>,
//! # { //! # {
//! # deserializer.deserialize_map(LinkedHashMapVisitor(PhantomData)) //! # deserializer.deserialize_map(LinkedHashMapVisitor(PhantomData))
//! # } //! # }
@@ -155,7 +161,7 @@
//! # } //! # }
//! ``` //! ```
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.44")] #![doc(html_root_url = "https://docs.rs/serde_test/1.0.46")]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))] #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints // Whitelisted clippy lints
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp))] #![cfg_attr(feature = "cargo-clippy", allow(float_cmp))]
@@ -179,8 +185,10 @@ mod assert;
mod configure; mod configure;
mod token; mod token;
pub use assert::{assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, pub use assert::{
assert_ser_tokens_error, assert_tokens}; assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_ser_tokens_error,
assert_tokens,
};
pub use token::Token; pub use token::Token;
pub use configure::{Compact, Configure, Readable}; pub use configure::{Compact, Configure, Readable};
+50 -2
View File
@@ -17,8 +17,10 @@ use self::serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::collections::HashMap; use std::collections::HashMap;
extern crate serde_test; extern crate serde_test;
use self::serde_test::{assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, use self::serde_test::{
assert_ser_tokens_error, assert_tokens, Token}; assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_ser_tokens_error,
assert_tokens, Token,
};
trait MyDefault: Sized { trait MyDefault: Sized {
fn my_default() -> Self; fn my_default() -> Self;
@@ -1791,3 +1793,49 @@ fn test_flatten_enum_newtype() {
], ],
); );
} }
#[test]
fn test_flatten_internally_tagged() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct S {
#[serde(flatten)]
x: X,
#[serde(flatten)]
y: Y,
}
#[derive(Serialize, Deserialize, PartialEq, Debug)]
#[serde(tag = "typeX")]
enum X {
A { a: i32 },
B { b: i32 },
}
#[derive(Serialize, Deserialize, PartialEq, Debug)]
#[serde(tag = "typeY")]
enum Y {
C { c: i32 },
D { d: i32 },
}
let s = S {
x: X::B { b: 1 },
y: Y::D { d: 2 },
};
assert_tokens(
&s,
&[
Token::Map { len: None },
Token::Str("typeX"),
Token::Str("B"),
Token::Str("b"),
Token::I32(1),
Token::Str("typeY"),
Token::Str("D"),
Token::Str("d"),
Token::I32(2),
Token::MapEnd,
],
);
}
-2
View File
@@ -333,9 +333,7 @@ fn test_gen() {
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
#[serde(untagged, remote = "Or")] #[serde(untagged, remote = "Or")]
enum OrDef<A, B> { enum OrDef<A, B> {
#[allow(dead_code)]
A(A), A(A),
#[allow(dead_code)]
B(B), B(B),
} }
+3 -2
View File
@@ -17,8 +17,9 @@ extern crate serde_test;
mod bytes; mod bytes;
use self::serde_test::{assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_tokens, use self::serde_test::{
Token}; assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_tokens, Token,
};
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::marker::PhantomData; use std::marker::PhantomData;
-2
View File
@@ -160,10 +160,8 @@ struct StructPrivDef {
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
#[serde(remote = "remote::StructPub")] #[serde(remote = "remote::StructPub")]
struct StructPubDef { struct StructPubDef {
#[allow(dead_code)]
a: u8, a: u8,
#[allow(dead_code)]
#[serde(with = "UnitDef")] #[serde(with = "UnitDef")]
b: remote::Unit, b: remote::Unit,
} }
+6
View File
@@ -87,4 +87,10 @@ else
channel build --no-default-features channel build --no-default-features
cd "$DIR/serde_test" cd "$DIR/serde_test"
channel build channel build
CHANNEL=1.15.0
cd "$DIR"
cargo clean
cd "$DIR/serde_derive"
channel build
fi fi