mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-23 04:48:01 +00:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b4076f4577 | |||
| c4181f46be | |||
| 8c0efc3d77 | |||
| 7e3efaf6c5 | |||
| 12fe42ed45 | |||
| 7cd4f49c76 | |||
| ff9c85d47f | |||
| 0025ef9aba | |||
| 536bdd77a0 | |||
| 6993b983d2 | |||
| 4bfeb05f22 | |||
| 4687c1b52b | |||
| a58abae193 | |||
| 0bc9c729b3 | |||
| dc921892be | |||
| 62557731c3 | |||
| ab62cd3b28 | |||
| 30824e9f61 | |||
| eecc0870fc | |||
| 6475e73b05 | |||
| 697234517d | |||
| 3cd9d071c2 |
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde"
|
||||
version = "1.0.47" # remember to update html_root_url
|
||||
version = "1.0.51" # remember to update html_root_url
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "A generic serialization/deserialization framework"
|
||||
|
||||
+108
-70
@@ -32,7 +32,7 @@ impl<'de> Visitor<'de> for UnitVisitor {
|
||||
formatter.write_str("unit")
|
||||
}
|
||||
|
||||
fn visit_unit<E>(self) -> Result<(), E>
|
||||
fn visit_unit<E>(self) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -41,7 +41,7 @@ impl<'de> Visitor<'de> for UnitVisitor {
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for () {
|
||||
fn deserialize<D>(deserializer: D) -> Result<(), D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -60,7 +60,7 @@ impl<'de> Visitor<'de> for BoolVisitor {
|
||||
formatter.write_str("a boolean")
|
||||
}
|
||||
|
||||
fn visit_bool<E>(self, v: bool) -> Result<bool, E>
|
||||
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -69,7 +69,7 @@ impl<'de> Visitor<'de> for BoolVisitor {
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for bool {
|
||||
fn deserialize<D>(deserializer: D) -> Result<bool, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -110,7 +110,7 @@ macro_rules! impl_deserialize_num {
|
||||
($ty:ident, $method:ident, $($visit:ident),*) => {
|
||||
impl<'de> Deserialize<'de> for $ty {
|
||||
#[inline]
|
||||
fn deserialize<D>(deserializer: D) -> Result<$ty, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -178,7 +178,7 @@ impl<'de> Visitor<'de> for CharVisitor {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_char<E>(self, v: char) -> Result<char, E>
|
||||
fn visit_char<E>(self, v: char) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -186,7 +186,7 @@ impl<'de> Visitor<'de> for CharVisitor {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_str<E>(self, v: &str) -> Result<char, E>
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -200,7 +200,7 @@ impl<'de> Visitor<'de> for CharVisitor {
|
||||
|
||||
impl<'de> Deserialize<'de> for char {
|
||||
#[inline]
|
||||
fn deserialize<D>(deserializer: D) -> Result<char, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -223,21 +223,21 @@ impl<'de> Visitor<'de> for StringVisitor {
|
||||
formatter.write_str("a string")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<String, E>
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
Ok(v.to_owned())
|
||||
}
|
||||
|
||||
fn visit_string<E>(self, v: String) -> Result<String, E>
|
||||
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<String, E>
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -247,7 +247,7 @@ impl<'de> Visitor<'de> for StringVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<String, E>
|
||||
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -269,7 +269,7 @@ impl<'a, 'de> Visitor<'de> for StringInPlaceVisitor<'a> {
|
||||
formatter.write_str("a string")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<(), E>
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -278,7 +278,7 @@ impl<'a, 'de> Visitor<'de> for StringInPlaceVisitor<'a> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_string<E>(self, v: String) -> Result<(), E>
|
||||
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -286,7 +286,7 @@ impl<'a, 'de> Visitor<'de> for StringInPlaceVisitor<'a> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<(), E>
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -300,7 +300,7 @@ impl<'a, 'de> Visitor<'de> for StringInPlaceVisitor<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<(), E>
|
||||
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -319,7 +319,7 @@ impl<'a, 'de> Visitor<'de> for StringInPlaceVisitor<'a> {
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
impl<'de> Deserialize<'de> for String {
|
||||
fn deserialize<D>(deserializer: D) -> Result<String, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -417,7 +417,7 @@ impl<'de> Visitor<'de> for CStringVisitor {
|
||||
formatter.write_str("byte array")
|
||||
}
|
||||
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<CString, A::Error>
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
{
|
||||
@@ -431,28 +431,28 @@ impl<'de> Visitor<'de> for CStringVisitor {
|
||||
CString::new(values).map_err(Error::custom)
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<CString, E>
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
CString::new(v).map_err(Error::custom)
|
||||
}
|
||||
|
||||
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<CString, E>
|
||||
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
CString::new(v).map_err(Error::custom)
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<CString, E>
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
CString::new(v).map_err(Error::custom)
|
||||
}
|
||||
|
||||
fn visit_string<E>(self, v: String) -> Result<CString, E>
|
||||
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -462,7 +462,7 @@ impl<'de> Visitor<'de> for CStringVisitor {
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<'de> Deserialize<'de> for CString {
|
||||
fn deserialize<D>(deserializer: D) -> Result<CString, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -507,7 +507,7 @@ where
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(self) -> Result<Option<T>, E>
|
||||
fn visit_unit<E>(self) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -515,7 +515,7 @@ where
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_none<E>(self) -> Result<Option<T>, E>
|
||||
fn visit_none<E>(self) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -523,7 +523,7 @@ where
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_some<D>(self, deserializer: D) -> Result<Option<T>, D::Error>
|
||||
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -535,7 +535,7 @@ impl<'de, T> Deserialize<'de> for Option<T>
|
||||
where
|
||||
T: Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Option<T>, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -565,7 +565,7 @@ impl<'de, T: ?Sized> Visitor<'de> for PhantomDataVisitor<T> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(self) -> Result<PhantomData<T>, E>
|
||||
fn visit_unit<E>(self) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -574,7 +574,7 @@ impl<'de, T: ?Sized> Visitor<'de> for PhantomDataVisitor<T> {
|
||||
}
|
||||
|
||||
impl<'de, T: ?Sized> Deserialize<'de> for PhantomData<T> {
|
||||
fn deserialize<D>(deserializer: D) -> Result<PhantomData<T>, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -659,7 +659,7 @@ macro_rules! seq_impl {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_seq<A>(mut self, mut $access: A) -> Result<(), A::Error>
|
||||
fn visit_seq<A>(mut self, mut $access: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
{
|
||||
@@ -771,7 +771,7 @@ impl<'de, T> Visitor<'de> for ArrayVisitor<[T; 0]> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_seq<A>(self, _: A) -> Result<[T; 0], A::Error>
|
||||
fn visit_seq<A>(self, _: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
{
|
||||
@@ -781,7 +781,7 @@ impl<'de, T> Visitor<'de> for ArrayVisitor<[T; 0]> {
|
||||
|
||||
// Does not require T: Deserialize<'de>.
|
||||
impl<'de, T> Deserialize<'de> for [T; 0] {
|
||||
fn deserialize<D>(deserializer: D) -> Result<[T; 0], D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -803,7 +803,7 @@ macro_rules! array_impls {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<[T; $len], A::Error>
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
{
|
||||
@@ -829,7 +829,7 @@ macro_rules! array_impls {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error>
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
{
|
||||
@@ -851,7 +851,7 @@ macro_rules! array_impls {
|
||||
where
|
||||
T: Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<[T; $len], D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -911,7 +911,7 @@ macro_rules! tuple_impls {
|
||||
$(
|
||||
impl<'de, $($name: Deserialize<'de>),+> Deserialize<'de> for ($($name,)+) {
|
||||
#[inline]
|
||||
fn deserialize<D>(deserializer: D) -> Result<($($name,)+), D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -928,7 +928,7 @@ macro_rules! tuple_impls {
|
||||
|
||||
#[inline]
|
||||
#[allow(non_snake_case)]
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<($($name,)+), A::Error>
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
{
|
||||
@@ -962,7 +962,7 @@ macro_rules! tuple_impls {
|
||||
|
||||
#[inline]
|
||||
#[allow(non_snake_case)]
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error>
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
{
|
||||
@@ -1331,14 +1331,14 @@ impl<'de> Visitor<'de> for PathBufVisitor {
|
||||
formatter.write_str("path string")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<PathBuf, E>
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
Ok(From::from(v))
|
||||
}
|
||||
|
||||
fn visit_string<E>(self, v: String) -> Result<PathBuf, E>
|
||||
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -1348,7 +1348,7 @@ impl<'de> Visitor<'de> for PathBufVisitor {
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<'de> Deserialize<'de> for PathBuf {
|
||||
fn deserialize<D>(deserializer: D) -> Result<PathBuf, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -1381,7 +1381,7 @@ impl<'de> Visitor<'de> for OsStringVisitor {
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn visit_enum<A>(self, data: A) -> Result<OsString, A::Error>
|
||||
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: EnumAccess<'de>,
|
||||
{
|
||||
@@ -1396,7 +1396,7 @@ impl<'de> Visitor<'de> for OsStringVisitor {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn visit_enum<A>(self, data: A) -> Result<OsString, A::Error>
|
||||
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: EnumAccess<'de>,
|
||||
{
|
||||
@@ -1414,7 +1414,7 @@ impl<'de> Visitor<'de> for OsStringVisitor {
|
||||
|
||||
#[cfg(all(feature = "std", any(unix, windows)))]
|
||||
impl<'de> Deserialize<'de> for OsString {
|
||||
fn deserialize<D>(deserializer: D) -> Result<OsString, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -1464,7 +1464,7 @@ where
|
||||
T::Owned: Deserialize<'de>,
|
||||
{
|
||||
#[inline]
|
||||
fn deserialize<D>(deserializer: D) -> Result<Cow<'a, T>, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -1474,6 +1474,44 @@ where
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// This impl requires the [`"rc"`] Cargo feature of Serde. The resulting
|
||||
/// `Weak<T>` has a reference count of 0 and cannot be upgraded.
|
||||
///
|
||||
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
|
||||
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
|
||||
impl<'de, T: ?Sized> Deserialize<'de> for RcWeak<T>
|
||||
where
|
||||
T: Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
try!(Option::<T>::deserialize(deserializer));
|
||||
Ok(RcWeak::new())
|
||||
}
|
||||
}
|
||||
|
||||
/// This impl requires the [`"rc"`] Cargo feature of Serde. The resulting
|
||||
/// `Weak<T>` has a reference count of 0 and cannot be upgraded.
|
||||
///
|
||||
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
|
||||
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
|
||||
impl<'de, T: ?Sized> Deserialize<'de> for ArcWeak<T>
|
||||
where
|
||||
T: Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
try!(Option::<T>::deserialize(deserializer));
|
||||
Ok(ArcWeak::new())
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[cfg(all(feature = "unstable", feature = "rc", any(feature = "std", feature = "alloc")))]
|
||||
macro_rules! box_forwarded_impl {
|
||||
(
|
||||
@@ -1525,7 +1563,7 @@ impl<'de, T> Deserialize<'de> for Cell<T>
|
||||
where
|
||||
T: Deserialize<'de> + Copy,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Cell<T>, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -1567,7 +1605,7 @@ impl<'de> Deserialize<'de> for Duration {
|
||||
};
|
||||
|
||||
impl<'de> Deserialize<'de> for Field {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -1580,7 +1618,7 @@ impl<'de> Deserialize<'de> for Duration {
|
||||
formatter.write_str("`secs` or `nanos`")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, value: &str) -> Result<Field, E>
|
||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -1591,7 +1629,7 @@ impl<'de> Deserialize<'de> for Duration {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, value: &[u8]) -> Result<Field, E>
|
||||
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -1619,7 +1657,7 @@ impl<'de> Deserialize<'de> for Duration {
|
||||
formatter.write_str("struct Duration")
|
||||
}
|
||||
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Duration, A::Error>
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
{
|
||||
@@ -1638,7 +1676,7 @@ impl<'de> Deserialize<'de> for Duration {
|
||||
Ok(Duration::new(secs, nanos))
|
||||
}
|
||||
|
||||
fn visit_map<A>(self, mut map: A) -> Result<Duration, A::Error>
|
||||
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: MapAccess<'de>,
|
||||
{
|
||||
@@ -1692,7 +1730,7 @@ impl<'de> Deserialize<'de> for SystemTime {
|
||||
};
|
||||
|
||||
impl<'de> Deserialize<'de> for Field {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -1705,7 +1743,7 @@ impl<'de> Deserialize<'de> for SystemTime {
|
||||
formatter.write_str("`secs_since_epoch` or `nanos_since_epoch`")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, value: &str) -> Result<Field, E>
|
||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -1716,7 +1754,7 @@ impl<'de> Deserialize<'de> for SystemTime {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, value: &[u8]) -> Result<Field, E>
|
||||
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -1744,7 +1782,7 @@ impl<'de> Deserialize<'de> for SystemTime {
|
||||
formatter.write_str("struct SystemTime")
|
||||
}
|
||||
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Duration, A::Error>
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
{
|
||||
@@ -1763,7 +1801,7 @@ impl<'de> Deserialize<'de> for SystemTime {
|
||||
Ok(Duration::new(secs, nanos))
|
||||
}
|
||||
|
||||
fn visit_map<A>(self, mut map: A) -> Result<Duration, A::Error>
|
||||
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: MapAccess<'de>,
|
||||
{
|
||||
@@ -1836,7 +1874,7 @@ where
|
||||
};
|
||||
|
||||
impl<'de> Deserialize<'de> for Field {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -1849,7 +1887,7 @@ where
|
||||
formatter.write_str("`start` or `end`")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, value: &str) -> Result<Field, E>
|
||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -1860,7 +1898,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, value: &[u8]) -> Result<Field, E>
|
||||
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -1893,7 +1931,7 @@ where
|
||||
formatter.write_str("struct Range")
|
||||
}
|
||||
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<ops::Range<Idx>, A::Error>
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
{
|
||||
@@ -1912,7 +1950,7 @@ where
|
||||
Ok(start..end)
|
||||
}
|
||||
|
||||
fn visit_map<A>(self, mut map: A) -> Result<ops::Range<Idx>, A::Error>
|
||||
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: MapAccess<'de>,
|
||||
{
|
||||
@@ -1965,7 +2003,7 @@ impl<'de, T> Deserialize<'de> for NonZero<T>
|
||||
where
|
||||
T: Deserialize<'de> + Zeroable,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<NonZero<T>, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -1982,7 +2020,7 @@ macro_rules! nonzero_integers {
|
||||
$(
|
||||
#[cfg(feature = "unstable")]
|
||||
impl<'de> Deserialize<'de> for $T {
|
||||
fn deserialize<D>(deserializer: D) -> Result<$T, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -2014,7 +2052,7 @@ where
|
||||
T: Deserialize<'de>,
|
||||
E: Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Result<T, E>, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -2029,7 +2067,7 @@ where
|
||||
|
||||
impl<'de> Deserialize<'de> for Field {
|
||||
#[inline]
|
||||
fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
@@ -2042,7 +2080,7 @@ where
|
||||
formatter.write_str("`Ok` or `Err`")
|
||||
}
|
||||
|
||||
fn visit_u32<E>(self, value: u32) -> Result<Field, E>
|
||||
fn visit_u32<E>(self, value: u32) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -2056,7 +2094,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, value: &str) -> Result<Field, E>
|
||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -2067,7 +2105,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, value: &[u8]) -> Result<Field, E>
|
||||
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
@@ -2101,7 +2139,7 @@ where
|
||||
formatter.write_str("enum Result")
|
||||
}
|
||||
|
||||
fn visit_enum<A>(self, data: A) -> Result<Result<T, E>, A::Error>
|
||||
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: EnumAccess<'de>,
|
||||
{
|
||||
@@ -2125,7 +2163,7 @@ impl<'de, T> Deserialize<'de> for Wrapping<T>
|
||||
where
|
||||
T: Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Wrapping<T>, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
|
||||
+5
-5
@@ -79,7 +79,7 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Serde types in rustdoc of other crates get linked to here.
|
||||
#![doc(html_root_url = "https://docs.rs/serde/1.0.47")]
|
||||
#![doc(html_root_url = "https://docs.rs/serde/1.0.51")]
|
||||
// Support using Serde without the standard library!
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
// Unstable functionality only if the user asks for it. For tracking and
|
||||
@@ -179,14 +179,14 @@ mod lib {
|
||||
pub use std::boxed::Box;
|
||||
|
||||
#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
|
||||
pub use alloc::rc::Rc;
|
||||
pub use alloc::rc::{Rc, Weak as RcWeak};
|
||||
#[cfg(all(feature = "rc", feature = "std"))]
|
||||
pub use std::rc::Rc;
|
||||
pub use std::rc::{Rc, Weak as RcWeak};
|
||||
|
||||
#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
|
||||
pub use alloc::arc::Arc;
|
||||
pub use alloc::arc::{Arc, Weak as ArcWeak};
|
||||
#[cfg(all(feature = "rc", feature = "std"))]
|
||||
pub use std::sync::Arc;
|
||||
pub use std::sync::{Arc, Weak as ArcWeak};
|
||||
|
||||
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
||||
pub use alloc::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
|
||||
|
||||
+11
-9
@@ -2819,16 +2819,18 @@ where
|
||||
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);
|
||||
match self.iter.next() {
|
||||
Some(item) => {
|
||||
// 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);
|
||||
seed.deserialize(ContentRefDeserializer::new(key)).map(Some)
|
||||
}
|
||||
None => Ok(None),
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
|
||||
|
||||
@@ -374,6 +374,40 @@ deref_impl!(<'a, T: ?Sized> Serialize for Cow<'a, T> where T: Serialize + ToOwne
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// This impl requires the [`"rc"`] Cargo feature of Serde.
|
||||
///
|
||||
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
|
||||
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
|
||||
impl<T: ?Sized> Serialize for RcWeak<T>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
self.upgrade().serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
/// This impl requires the [`"rc"`] Cargo feature of Serde.
|
||||
///
|
||||
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
|
||||
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
|
||||
impl<T: ?Sized> Serialize for ArcWeak<T>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
self.upgrade().serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[cfg(feature = "unstable")]
|
||||
#[allow(deprecated)]
|
||||
impl<T> Serialize for NonZero<T>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_derive"
|
||||
version = "1.0.47" # remember to update html_root_url
|
||||
version = "1.0.51" # remember to update html_root_url
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
||||
|
||||
+62
-26
@@ -15,15 +15,16 @@ use syn::{self, Ident, Index, Member};
|
||||
use bound;
|
||||
use fragment::{Expr, Fragment, Match, Stmts};
|
||||
use internals::ast::{Container, Data, Field, Style, Variant};
|
||||
use internals::{self, attr};
|
||||
use internals::{attr, Ctxt};
|
||||
use pretend;
|
||||
use try;
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, String> {
|
||||
let ctxt = internals::Ctxt::new();
|
||||
let ctxt = Ctxt::new();
|
||||
let cont = Container::from_ast(&ctxt, input);
|
||||
precondition(&ctxt, &cont);
|
||||
try!(ctxt.check());
|
||||
|
||||
let ident = cont.ident;
|
||||
@@ -80,6 +81,32 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, Str
|
||||
Ok(generated)
|
||||
}
|
||||
|
||||
fn precondition(cx: &Ctxt, cont: &Container) {
|
||||
precondition_sized(cx, cont);
|
||||
precondition_no_de_lifetime(cx, cont);
|
||||
}
|
||||
|
||||
fn precondition_sized(cx: &Ctxt, cont: &Container) {
|
||||
if let Data::Struct(_, ref fields) = cont.data {
|
||||
if let Some(last) = fields.last() {
|
||||
if let syn::Type::Slice(_) = *last.ty {
|
||||
cx.error("cannot deserialize a dynamically sized struct");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn precondition_no_de_lifetime(cx: &Ctxt, cont: &Container) {
|
||||
if let BorrowedLifetimes::Borrowed(_) = borrowed_lifetimes(cont) {
|
||||
for param in cont.generics.lifetimes() {
|
||||
if param.lifetime.to_string() == "'de" {
|
||||
cx.error("cannot deserialize when there is a lifetime parameter called 'de");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Parameters {
|
||||
/// Name of the type the `derive` is on.
|
||||
local: syn::Ident,
|
||||
@@ -164,13 +191,17 @@ fn build_generics(cont: &Container, borrowed: &BorrowedLifetimes) -> syn::Generi
|
||||
}
|
||||
}
|
||||
|
||||
// Fields with a `skip_deserializing` or `deserialize_with` attribute are not
|
||||
// deserialized by us so we do not generate a bound. Fields with a `bound`
|
||||
// attribute specify their own bound so we do not generate one. All other fields
|
||||
// may need a `T: Deserialize` bound where T is the type of the field.
|
||||
// Fields with a `skip_deserializing` or `deserialize_with` attribute, or which
|
||||
// belong to a variant with a `skip_deserializing` or `deserialize_with`
|
||||
// attribute, are not deserialized by us so we do not generate a bound. Fields
|
||||
// with a `bound` attribute specify their own bound so we do not generate one.
|
||||
// All other fields may need a `T: Deserialize` bound where T is the type of the
|
||||
// field.
|
||||
fn needs_deserialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
|
||||
!field.skip_deserializing() && field.deserialize_with().is_none() && field.de_bound().is_none()
|
||||
&& variant.map_or(true, |variant| variant.deserialize_with().is_none())
|
||||
&& variant.map_or(true, |variant| {
|
||||
!variant.skip_deserializing() && variant.deserialize_with().is_none()
|
||||
})
|
||||
}
|
||||
|
||||
// Fields with a `default` attribute (not `default=...`), and fields with a
|
||||
@@ -553,7 +584,7 @@ fn deserialize_seq(
|
||||
.count();
|
||||
let expecting = format!("tuple of {} elements", deserialized_count);
|
||||
|
||||
let mut index_in_seq = 0usize;
|
||||
let mut index_in_seq = 0_usize;
|
||||
let let_values = vars.clone().zip(fields).map(|(var, field)| {
|
||||
if field.attrs.skip_deserializing() {
|
||||
let default = Expr(expr_is_missing(field, cattrs));
|
||||
@@ -1382,6 +1413,21 @@ fn deserialize_adjacently_tagged_enum(
|
||||
}
|
||||
};
|
||||
|
||||
let finish_content_then_tag = if variant_arms.is_empty() {
|
||||
quote! {
|
||||
match try!(_serde::de::MapAccess::next_value::<__Field>(&mut __map)) {}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
let __ret = try!(match try!(_serde::de::MapAccess::next_value(&mut __map)) {
|
||||
// Deserialize the buffered content now that we know the variant.
|
||||
#(#variant_arms)*
|
||||
});
|
||||
// Visit remaining keys, looking for duplicates.
|
||||
#visit_remaining_keys
|
||||
}
|
||||
};
|
||||
|
||||
quote_block! {
|
||||
#variant_visitor
|
||||
|
||||
@@ -1458,13 +1504,7 @@ fn deserialize_adjacently_tagged_enum(
|
||||
// Second key is the tag.
|
||||
_serde::export::Some(_serde::private::de::TagOrContentField::Tag) => {
|
||||
let __deserializer = _serde::private::de::ContentDeserializer::<__A::Error>::new(__content);
|
||||
// Parse the tag.
|
||||
let __ret = try!(match try!(_serde::de::MapAccess::next_value(&mut __map)) {
|
||||
// Deserialize the buffered content now that we know the variant.
|
||||
#(#variant_arms)*
|
||||
});
|
||||
// Visit remaining keys, looking for duplicates.
|
||||
#visit_remaining_keys
|
||||
#finish_content_then_tag
|
||||
}
|
||||
// Second key is a duplicate of the content.
|
||||
_serde::export::Some(_serde::private::de::TagOrContentField::Content) => {
|
||||
@@ -1946,9 +1986,7 @@ fn deserialize_identifier(
|
||||
value_as_borrowed_str_content,
|
||||
value_as_bytes_content,
|
||||
value_as_borrowed_bytes_content,
|
||||
) = if !collect_other_fields {
|
||||
(None, None, None, None)
|
||||
} else {
|
||||
) = if collect_other_fields {
|
||||
(
|
||||
Some(quote! {
|
||||
let __value = _serde::private::de::Content::String(__value.to_string());
|
||||
@@ -1963,6 +2001,8 @@ fn deserialize_identifier(
|
||||
let __value = _serde::private::de::Content::Bytes(__value);
|
||||
}),
|
||||
)
|
||||
} else {
|
||||
(None, None, None, None)
|
||||
};
|
||||
|
||||
let fallthrough_arm = if let Some(fallthrough) = fallthrough {
|
||||
@@ -1977,7 +2017,7 @@ fn deserialize_identifier(
|
||||
}
|
||||
};
|
||||
|
||||
let variant_indices = 0u64..;
|
||||
let variant_indices = 0_u64..;
|
||||
let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len());
|
||||
let visit_other = if collect_other_fields {
|
||||
quote! {
|
||||
@@ -2539,13 +2579,9 @@ fn deserialize_map_in_place(
|
||||
.map(|&(field, ref name)| {
|
||||
let missing_expr = expr_is_missing(field, cattrs);
|
||||
// If missing_expr unconditionally returns an error, don't try
|
||||
// to assign its value to self.place. Maybe this could be handled
|
||||
// more elegantly.
|
||||
if missing_expr
|
||||
.as_ref()
|
||||
.into_tokens()
|
||||
.to_string()
|
||||
.starts_with("return ")
|
||||
// to assign its value to self.place.
|
||||
if field.attrs.default().is_none() && cattrs.default().is_none()
|
||||
&& field.attrs.deserialize_with().is_some()
|
||||
{
|
||||
let missing_expr = Stmts(missing_expr);
|
||||
quote! {
|
||||
|
||||
@@ -580,6 +580,12 @@ impl Variant {
|
||||
}
|
||||
}
|
||||
|
||||
// Parse `#[serde(skip)]`
|
||||
Meta(Word(word)) if word == "skip" => {
|
||||
skip_serializing.set_true();
|
||||
skip_deserializing.set_true();
|
||||
}
|
||||
|
||||
// Parse `#[serde(skip_deserializing)]`
|
||||
Meta(Word(word)) if word == "skip_deserializing" => {
|
||||
skip_deserializing.set_true();
|
||||
@@ -738,6 +744,16 @@ pub enum Default {
|
||||
Path(syn::ExprPath),
|
||||
}
|
||||
|
||||
impl Default {
|
||||
#[cfg(feature = "deserialize_in_place")]
|
||||
pub fn is_none(&self) -> bool {
|
||||
match *self {
|
||||
Default::None => true,
|
||||
Default::Default | Default::Path(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Field {
|
||||
/// Extract out the `#[serde(...)]` attributes from a struct field.
|
||||
pub fn from_ast(
|
||||
@@ -767,9 +783,7 @@ impl Field {
|
||||
};
|
||||
|
||||
let variant_borrow = attrs
|
||||
.map(|variant| &variant.borrow)
|
||||
.unwrap_or(&None)
|
||||
.as_ref()
|
||||
.and_then(|variant| variant.borrow.as_ref())
|
||||
.map(|borrow| vec![Meta(borrow.clone())]);
|
||||
|
||||
for meta_items in field
|
||||
|
||||
+15
-2
@@ -22,10 +22,23 @@
|
||||
//!
|
||||
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.47")]
|
||||
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.51")]
|
||||
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
||||
// Whitelisted clippy lints
|
||||
#![cfg_attr(
|
||||
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,
|
||||
cyclomatic_complexity
|
||||
)
|
||||
)]
|
||||
// Whitelisted clippy_pedantic lints
|
||||
#![cfg_attr(
|
||||
feature = "cargo-clippy",
|
||||
allow(
|
||||
items_after_statements, doc_markdown, stutter, similar_names, use_self, single_match_else,
|
||||
enum_glob_use, match_same_arms, filter_map, cast_possible_truncation
|
||||
)
|
||||
)]
|
||||
// The `quote!` macro requires deep recursion.
|
||||
#![recursion_limit = "512"]
|
||||
|
||||
+10
-10
@@ -18,8 +18,6 @@ use internals::{attr, Ctxt};
|
||||
use pretend;
|
||||
use try;
|
||||
|
||||
use std::u32;
|
||||
|
||||
pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<Tokens, String> {
|
||||
let ctxt = Ctxt::new();
|
||||
let cont = Container::from_ast(&ctxt, input);
|
||||
@@ -152,13 +150,15 @@ fn build_generics(cont: &Container) -> syn::Generics {
|
||||
}
|
||||
|
||||
// Fields with a `skip_serializing` or `serialize_with` attribute, or which
|
||||
// belong to a variant with a `serialize_with` attribute, are not serialized by
|
||||
// us so we do not generate a bound. Fields with a `bound` attribute specify
|
||||
// their own bound so we do not generate one. All other fields may need a `T:
|
||||
// Serialize` bound where T is the type of the field.
|
||||
// belong to a variant with a 'skip_serializing` or `serialize_with` attribute,
|
||||
// are not serialized by us so we do not generate a bound. Fields with a `bound`
|
||||
// attribute specify their own bound so we do not generate one. All other fields
|
||||
// may need a `T: Serialize` bound where T is the type of the field.
|
||||
fn needs_serialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
|
||||
!field.skip_serializing() && field.serialize_with().is_none() && field.ser_bound().is_none()
|
||||
&& variant.map_or(true, |variant| variant.serialize_with().is_none())
|
||||
&& variant.map_or(true, |variant| {
|
||||
!variant.skip_serializing() && variant.serialize_with().is_none()
|
||||
})
|
||||
}
|
||||
|
||||
fn serialize_body(cont: &Container, params: &Parameters) -> Fragment {
|
||||
@@ -250,7 +250,7 @@ fn serialize_tuple_struct(
|
||||
}
|
||||
|
||||
fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Container) -> Fragment {
|
||||
assert!(fields.len() as u64 <= u64::from(u32::MAX));
|
||||
assert!(fields.len() as u64 <= u64::from(u32::max_value()));
|
||||
|
||||
if cattrs.has_flatten() {
|
||||
serialize_struct_as_map(params, fields, cattrs)
|
||||
@@ -333,7 +333,7 @@ fn serialize_struct_as_map(
|
||||
}
|
||||
|
||||
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_value()));
|
||||
|
||||
let self_var = params.self_var;
|
||||
|
||||
@@ -645,7 +645,7 @@ fn serialize_adjacently_tagged_variant(
|
||||
|
||||
let (_, ty_generics, where_clause) = params.generics.split_for_impl();
|
||||
|
||||
let wrapper_generics = if let Style::Unit = variant.style {
|
||||
let wrapper_generics = if fields_ident.is_empty() {
|
||||
params.generics.clone()
|
||||
} else {
|
||||
bound::with_lifetime_bound(¶ms.generics, "'__a")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_test"
|
||||
version = "1.0.47" # remember to update html_root_url
|
||||
version = "1.0.51" # remember to update html_root_url
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "Token De/Serializer for testing De/Serialize implementations"
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.47")]
|
||||
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.51")]
|
||||
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
||||
// Whitelisted clippy lints
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp))]
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
|
||||
struct S<'de> {
|
||||
s: &'de str, //~^^ HELP: cannot deserialize when there is a lifetime parameter called 'de
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
|
||||
struct S {
|
||||
string: String,
|
||||
slice: [u8], //~^^^ HELP: cannot deserialize a dynamically sized struct
|
||||
}
|
||||
@@ -17,15 +17,15 @@ use std::ffi::{CString, OsString};
|
||||
use std::net;
|
||||
use std::num::Wrapping;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use std::rc::{Rc, Weak as RcWeak};
|
||||
use std::sync::{Arc, Weak as ArcWeak};
|
||||
use std::time::{Duration, UNIX_EPOCH};
|
||||
|
||||
#[cfg(feature = "unstable")]
|
||||
use std::ffi::CStr;
|
||||
|
||||
extern crate serde;
|
||||
use serde::Deserialize;
|
||||
use serde::{Deserialize, Deserializer};
|
||||
|
||||
extern crate fnv;
|
||||
use self::fnv::FnvHasher;
|
||||
@@ -182,6 +182,27 @@ macro_rules! declare_error_tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct SkipPartialEq<T>(T);
|
||||
|
||||
impl<'de, T> Deserialize<'de> for SkipPartialEq<T>
|
||||
where
|
||||
T: Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
T::deserialize(deserializer).map(SkipPartialEq)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> PartialEq for SkipPartialEq<T> {
|
||||
fn eq(&self, _other: &Self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_de_tokens_ignore(ignorable_tokens: &[Token]) {
|
||||
#[derive(PartialEq, Debug, Deserialize)]
|
||||
struct IgnoreBase {
|
||||
@@ -788,11 +809,33 @@ declare_tests! {
|
||||
Token::Bool(true),
|
||||
],
|
||||
}
|
||||
test_rc_weak_some {
|
||||
SkipPartialEq(RcWeak::<bool>::new()) => &[
|
||||
Token::Some,
|
||||
Token::Bool(true),
|
||||
],
|
||||
}
|
||||
test_rc_weak_none {
|
||||
SkipPartialEq(RcWeak::<bool>::new()) => &[
|
||||
Token::None,
|
||||
],
|
||||
}
|
||||
test_arc {
|
||||
Arc::new(true) => &[
|
||||
Token::Bool(true),
|
||||
],
|
||||
}
|
||||
test_arc_weak_some {
|
||||
SkipPartialEq(ArcWeak::<bool>::new()) => &[
|
||||
Token::Some,
|
||||
Token::Bool(true),
|
||||
],
|
||||
}
|
||||
test_arc_weak_none {
|
||||
SkipPartialEq(ArcWeak::<bool>::new()) => &[
|
||||
Token::None,
|
||||
],
|
||||
}
|
||||
test_wrapping {
|
||||
Wrapping(1usize) => &[
|
||||
Token::U32(1),
|
||||
|
||||
@@ -567,6 +567,41 @@ fn test_gen() {
|
||||
}
|
||||
|
||||
assert::<AssocDeriveMulti<i32, NoSerdeImpl>>();
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(tag = "t", content = "c")]
|
||||
enum EmptyAdjacentlyTagged {
|
||||
#[allow(dead_code)]
|
||||
Struct {},
|
||||
#[allow(dead_code)]
|
||||
Tuple(),
|
||||
}
|
||||
|
||||
assert_ser::<EmptyAdjacentlyTagged>();
|
||||
|
||||
mod restricted {
|
||||
mod inner {
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct Restricted {
|
||||
pub(super) a: usize,
|
||||
pub(in super::inner) b: usize,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(tag = "t", content = "c")]
|
||||
enum AdjacentlyTaggedVoid {}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
enum SkippedVariant<T> {
|
||||
#[serde(skip)]
|
||||
#[allow(dead_code)]
|
||||
T(T),
|
||||
Unit,
|
||||
}
|
||||
|
||||
assert::<SkippedVariant<X>>();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -11,11 +11,12 @@ extern crate serde_derive;
|
||||
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
||||
use std::ffi::CString;
|
||||
use std::mem;
|
||||
use std::net;
|
||||
use std::num::Wrapping;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use std::rc::{Rc, Weak as RcWeak};
|
||||
use std::sync::{Arc, Weak as ArcWeak};
|
||||
use std::time::{Duration, UNIX_EPOCH};
|
||||
|
||||
#[cfg(unix)]
|
||||
@@ -398,11 +399,41 @@ declare_tests! {
|
||||
Token::Bool(true),
|
||||
],
|
||||
}
|
||||
test_rc_weak_some {
|
||||
{
|
||||
let rc = Rc::new(true);
|
||||
mem::forget(rc.clone());
|
||||
Rc::downgrade(&rc)
|
||||
} => &[
|
||||
Token::Some,
|
||||
Token::Bool(true),
|
||||
],
|
||||
}
|
||||
test_rc_weak_none {
|
||||
RcWeak::<bool>::new() => &[
|
||||
Token::None,
|
||||
],
|
||||
}
|
||||
test_arc {
|
||||
Arc::new(true) => &[
|
||||
Token::Bool(true),
|
||||
],
|
||||
}
|
||||
test_arc_weak_some {
|
||||
{
|
||||
let arc = Arc::new(true);
|
||||
mem::forget(arc.clone());
|
||||
Arc::downgrade(&arc)
|
||||
} => &[
|
||||
Token::Some,
|
||||
Token::Bool(true),
|
||||
],
|
||||
}
|
||||
test_arc_weak_none {
|
||||
ArcWeak::<bool>::new() => &[
|
||||
Token::None,
|
||||
],
|
||||
}
|
||||
test_wrapping {
|
||||
Wrapping(1usize) => &[
|
||||
Token::U64(1),
|
||||
|
||||
Reference in New Issue
Block a user