mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-25 22:07:56 +00:00
Format with rustfmt-nightly 0.3.4
This commit is contained in:
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
use lib::*;
|
use lib::*;
|
||||||
|
|
||||||
use de::{Deserialize, Deserializer, Visitor, SeqAccess, MapAccess, Error};
|
use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
|
||||||
|
|
||||||
/// An efficient way of discarding data from a deserializer.
|
/// An efficient way of discarding data from a deserializer.
|
||||||
///
|
///
|
||||||
|
|||||||
+57
-27
@@ -52,7 +52,6 @@ impl<'de> Deserialize<'de> for () {
|
|||||||
|
|
||||||
struct BoolVisitor;
|
struct BoolVisitor;
|
||||||
|
|
||||||
|
|
||||||
impl<'de> Visitor<'de> for BoolVisitor {
|
impl<'de> Visitor<'de> for BoolVisitor {
|
||||||
type Value = bool;
|
type Value = bool;
|
||||||
|
|
||||||
@@ -253,7 +252,10 @@ impl<'de> Visitor<'de> for StringVisitor {
|
|||||||
{
|
{
|
||||||
match String::from_utf8(v) {
|
match String::from_utf8(v) {
|
||||||
Ok(s) => Ok(s),
|
Ok(s) => Ok(s),
|
||||||
Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self),),
|
Err(e) => Err(Error::invalid_value(
|
||||||
|
Unexpected::Bytes(&e.into_bytes()),
|
||||||
|
&self,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -306,7 +308,10 @@ impl<'a, 'de> Visitor<'de> for StringInPlaceVisitor<'a> {
|
|||||||
*self.0 = s;
|
*self.0 = s;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self),),
|
Err(e) => Err(Error::invalid_value(
|
||||||
|
Unexpected::Bytes(&e.into_bytes()),
|
||||||
|
&self,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -529,7 +534,9 @@ where
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
deserializer.deserialize_option(OptionVisitor { marker: PhantomData })
|
deserializer.deserialize_option(OptionVisitor {
|
||||||
|
marker: PhantomData,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// The Some variant's repr is opaque, so we can't play cute tricks with its
|
// The Some variant's repr is opaque, so we can't play cute tricks with its
|
||||||
@@ -566,7 +573,9 @@ impl<'de, T> Deserialize<'de> for PhantomData<T> {
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let visitor = PhantomDataVisitor { marker: PhantomData };
|
let visitor = PhantomDataVisitor {
|
||||||
|
marker: PhantomData,
|
||||||
|
};
|
||||||
deserializer.deserialize_unit_struct("PhantomData", visitor)
|
deserializer.deserialize_unit_struct("PhantomData", visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -699,7 +708,8 @@ seq_impl!(
|
|||||||
LinkedList::clear,
|
LinkedList::clear,
|
||||||
LinkedList::new(),
|
LinkedList::new(),
|
||||||
nop_reserve,
|
nop_reserve,
|
||||||
LinkedList::push_back);
|
LinkedList::push_back
|
||||||
|
);
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
seq_impl!(
|
seq_impl!(
|
||||||
@@ -719,7 +729,8 @@ seq_impl!(
|
|||||||
Vec::clear,
|
Vec::clear,
|
||||||
Vec::with_capacity(size_hint::cautious(seq.size_hint())),
|
Vec::with_capacity(size_hint::cautious(seq.size_hint())),
|
||||||
Vec::reserve,
|
Vec::reserve,
|
||||||
Vec::push);
|
Vec::push
|
||||||
|
);
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
seq_impl!(
|
seq_impl!(
|
||||||
@@ -729,7 +740,8 @@ seq_impl!(
|
|||||||
VecDeque::clear,
|
VecDeque::clear,
|
||||||
VecDeque::with_capacity(size_hint::cautious(seq.size_hint())),
|
VecDeque::with_capacity(size_hint::cautious(seq.size_hint())),
|
||||||
VecDeque::reserve,
|
VecDeque::reserve,
|
||||||
VecDeque::push_back);
|
VecDeque::push_back
|
||||||
|
);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -740,7 +752,9 @@ struct ArrayInPlaceVisitor<'a, A: 'a>(&'a mut A);
|
|||||||
|
|
||||||
impl<A> ArrayVisitor<A> {
|
impl<A> ArrayVisitor<A> {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
ArrayVisitor { marker: PhantomData }
|
ArrayVisitor {
|
||||||
|
marker: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1257,7 +1271,12 @@ impl<'de> Deserialize<'de> for net::SocketAddr {
|
|||||||
parse_socket_impl!(net::SocketAddrV4, net::SocketAddrV4::new);
|
parse_socket_impl!(net::SocketAddrV4, net::SocketAddrV4::new);
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
parse_socket_impl!(net::SocketAddrV6, |ip, port| net::SocketAddrV6::new(ip, port, 0, 0));
|
parse_socket_impl!(net::SocketAddrV6, |ip, port| net::SocketAddrV6::new(
|
||||||
|
ip,
|
||||||
|
port,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
));
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -1368,7 +1387,9 @@ impl<'de> Visitor<'de> for OsStringVisitor {
|
|||||||
|
|
||||||
match try!(data.variant()) {
|
match try!(data.variant()) {
|
||||||
(OsStringKind::Unix, v) => v.newtype_variant().map(OsString::from_vec),
|
(OsStringKind::Unix, v) => v.newtype_variant().map(OsString::from_vec),
|
||||||
(OsStringKind::Windows, _) => Err(Error::custom("cannot deserialize Windows OS string on Unix",),),
|
(OsStringKind::Windows, _) => Err(Error::custom(
|
||||||
|
"cannot deserialize Windows OS string on Unix",
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1380,11 +1401,11 @@ impl<'de> Visitor<'de> for OsStringVisitor {
|
|||||||
use std::os::windows::ffi::OsStringExt;
|
use std::os::windows::ffi::OsStringExt;
|
||||||
|
|
||||||
match try!(data.variant()) {
|
match try!(data.variant()) {
|
||||||
(OsStringKind::Windows, v) => {
|
(OsStringKind::Windows, v) => v.newtype_variant::<Vec<u16>>()
|
||||||
v.newtype_variant::<Vec<u16>>()
|
.map(|vec| OsString::from_wide(&vec)),
|
||||||
.map(|vec| OsString::from_wide(&vec))
|
(OsStringKind::Unix, _) => Err(Error::custom(
|
||||||
}
|
"cannot deserialize Unix OS string on Windows",
|
||||||
(OsStringKind::Unix, _) => Err(Error::custom("cannot deserialize Unix OS string on Windows",),),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1710,13 +1731,17 @@ impl<'de> Deserialize<'de> for SystemTime {
|
|||||||
match key {
|
match key {
|
||||||
Field::Secs => {
|
Field::Secs => {
|
||||||
if secs.is_some() {
|
if secs.is_some() {
|
||||||
return Err(<A::Error as Error>::duplicate_field("secs_since_epoch"));
|
return Err(<A::Error as Error>::duplicate_field(
|
||||||
|
"secs_since_epoch",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
secs = Some(try!(map.next_value()));
|
secs = Some(try!(map.next_value()));
|
||||||
}
|
}
|
||||||
Field::Nanos => {
|
Field::Nanos => {
|
||||||
if nanos.is_some() {
|
if nanos.is_some() {
|
||||||
return Err(<A::Error as Error>::duplicate_field("nanos_since_epoch"));
|
return Err(<A::Error as Error>::duplicate_field(
|
||||||
|
"nanos_since_epoch",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
nanos = Some(try!(map.next_value()));
|
nanos = Some(try!(map.next_value()));
|
||||||
}
|
}
|
||||||
@@ -1880,7 +1905,13 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
const FIELDS: &'static [&'static str] = &["start", "end"];
|
const FIELDS: &'static [&'static str] = &["start", "end"];
|
||||||
deserializer.deserialize_struct("Range", FIELDS, RangeVisitor { phantom: PhantomData })
|
deserializer.deserialize_struct(
|
||||||
|
"Range",
|
||||||
|
FIELDS,
|
||||||
|
RangeVisitor {
|
||||||
|
phantom: PhantomData,
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1945,9 +1976,10 @@ where
|
|||||||
match value {
|
match value {
|
||||||
0 => Ok(Field::Ok),
|
0 => Ok(Field::Ok),
|
||||||
1 => Ok(Field::Err),
|
1 => Ok(Field::Err),
|
||||||
_ => {
|
_ => Err(Error::invalid_value(
|
||||||
Err(Error::invalid_value(Unexpected::Unsigned(value as u64), &self),)
|
Unexpected::Unsigned(value as u64),
|
||||||
}
|
&self,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1969,14 +2001,12 @@ where
|
|||||||
match value {
|
match value {
|
||||||
b"Ok" => Ok(Field::Ok),
|
b"Ok" => Ok(Field::Ok),
|
||||||
b"Err" => Ok(Field::Err),
|
b"Err" => Ok(Field::Err),
|
||||||
_ => {
|
_ => match str::from_utf8(value) {
|
||||||
match str::from_utf8(value) {
|
|
||||||
Ok(value) => Err(Error::unknown_variant(value, VARIANTS)),
|
Ok(value) => Err(Error::unknown_variant(value, VARIANTS)),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
Err(Error::invalid_value(Unexpected::Bytes(value), &self))
|
Err(Error::invalid_value(Unexpected::Bytes(value), &self))
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2020,7 +2050,7 @@ where
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<'de, T> Deserialize<'de> for Wrapping<T>
|
impl<'de, T> Deserialize<'de> for Wrapping<T>
|
||||||
where
|
where
|
||||||
T: Deserialize<'de>
|
T: Deserialize<'de>,
|
||||||
{
|
{
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Wrapping<T>, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Wrapping<T>, D::Error>
|
||||||
where
|
where
|
||||||
|
|||||||
+5
-2
@@ -526,7 +526,8 @@ pub trait Deserialize<'de>: Sized {
|
|||||||
/// than it deserves.
|
/// than it deserves.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
|
fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
|
||||||
where D: Deserializer<'de>
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
// Default implementation just delegates to `deserialize` impl.
|
// Default implementation just delegates to `deserialize` impl.
|
||||||
*place = Deserialize::deserialize(deserializer)?;
|
*place = Deserialize::deserialize(deserializer)?;
|
||||||
@@ -1106,7 +1107,9 @@ pub trait Deserializer<'de>: Sized {
|
|||||||
/// change, as a value serialized in human-readable mode is not required to
|
/// change, as a value serialized in human-readable mode is not required to
|
||||||
/// deserialize from the same data in compact mode.
|
/// deserialize from the same data in compact mode.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_human_readable(&self) -> bool { true }
|
fn is_human_readable(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
+34
-14
@@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
use lib::*;
|
use lib::*;
|
||||||
|
|
||||||
use de::{self, IntoDeserializer, Expected, SeqAccess};
|
use de::{self, Expected, IntoDeserializer, SeqAccess};
|
||||||
use private::de::size_hint;
|
use private::de::size_hint;
|
||||||
use ser;
|
use ser;
|
||||||
use self::private::{First, Second};
|
use self::private::{First, Second};
|
||||||
@@ -62,7 +62,9 @@ impl de::Error for Error {
|
|||||||
where
|
where
|
||||||
T: Display,
|
T: Display,
|
||||||
{
|
{
|
||||||
Error { err: msg.to_string().into_boxed_str() }
|
Error {
|
||||||
|
err: msg.to_string().into_boxed_str(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(feature = "std", feature = "alloc")))]
|
#[cfg(not(any(feature = "std", feature = "alloc")))]
|
||||||
@@ -112,7 +114,9 @@ where
|
|||||||
type Deserializer = UnitDeserializer<E>;
|
type Deserializer = UnitDeserializer<E>;
|
||||||
|
|
||||||
fn into_deserializer(self) -> UnitDeserializer<E> {
|
fn into_deserializer(self) -> UnitDeserializer<E> {
|
||||||
UnitDeserializer { marker: PhantomData }
|
UnitDeserializer {
|
||||||
|
marker: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -658,7 +662,10 @@ where
|
|||||||
} else {
|
} else {
|
||||||
// First argument is the number of elements in the data, second
|
// First argument is the number of elements in the data, second
|
||||||
// argument is the number of elements expected by the Deserialize.
|
// argument is the number of elements expected by the Deserialize.
|
||||||
Err(de::Error::invalid_length(self.count + remaining, &ExpectedInSeq(self.count)),)
|
Err(de::Error::invalid_length(
|
||||||
|
self.count + remaining,
|
||||||
|
&ExpectedInSeq(self.count),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -852,7 +859,10 @@ where
|
|||||||
} else {
|
} else {
|
||||||
// First argument is the number of elements in the data, second
|
// First argument is the number of elements in the data, second
|
||||||
// argument is the number of elements expected by the Deserialize.
|
// argument is the number of elements expected by the Deserialize.
|
||||||
Err(de::Error::invalid_length(self.count + remaining, &ExpectedInMap(self.count)),)
|
Err(de::Error::invalid_length(
|
||||||
|
self.count + remaining,
|
||||||
|
&ExpectedInMap(self.count),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -901,11 +911,7 @@ where
|
|||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_tuple<V>(
|
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
self,
|
|
||||||
len: usize,
|
|
||||||
visitor: V,
|
|
||||||
) -> Result<V::Value, Self::Error>
|
|
||||||
where
|
where
|
||||||
V: de::Visitor<'de>,
|
V: de::Visitor<'de>,
|
||||||
{
|
{
|
||||||
@@ -1223,7 +1229,12 @@ mod private {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn unit_only<T, E>(t: T) -> (T, UnitOnly<E>) {
|
pub fn unit_only<T, E>(t: T) -> (T, UnitOnly<E>) {
|
||||||
(t, UnitOnly { marker: PhantomData })
|
(
|
||||||
|
t,
|
||||||
|
UnitOnly {
|
||||||
|
marker: PhantomData,
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, E> de::VariantAccess<'de> for UnitOnly<E>
|
impl<'de, E> de::VariantAccess<'de> for UnitOnly<E>
|
||||||
@@ -1240,14 +1251,20 @@ mod private {
|
|||||||
where
|
where
|
||||||
T: de::DeserializeSeed<'de>,
|
T: de::DeserializeSeed<'de>,
|
||||||
{
|
{
|
||||||
Err(de::Error::invalid_type(Unexpected::UnitVariant, &"newtype variant"),)
|
Err(de::Error::invalid_type(
|
||||||
|
Unexpected::UnitVariant,
|
||||||
|
&"newtype variant",
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error>
|
fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: de::Visitor<'de>,
|
V: de::Visitor<'de>,
|
||||||
{
|
{
|
||||||
Err(de::Error::invalid_type(Unexpected::UnitVariant, &"tuple variant"),)
|
Err(de::Error::invalid_type(
|
||||||
|
Unexpected::UnitVariant,
|
||||||
|
&"tuple variant",
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn struct_variant<V>(
|
fn struct_variant<V>(
|
||||||
@@ -1258,7 +1275,10 @@ mod private {
|
|||||||
where
|
where
|
||||||
V: de::Visitor<'de>,
|
V: de::Visitor<'de>,
|
||||||
{
|
{
|
||||||
Err(de::Error::invalid_type(Unexpected::UnitVariant, &"struct variant"),)
|
Err(de::Error::invalid_type(
|
||||||
|
Unexpected::UnitVariant,
|
||||||
|
&"struct variant",
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ pub use lib::default::Default;
|
|||||||
pub use lib::fmt::{self, Formatter};
|
pub use lib::fmt::{self, Formatter};
|
||||||
pub use lib::marker::PhantomData;
|
pub use lib::marker::PhantomData;
|
||||||
pub use lib::option::Option::{self, None, Some};
|
pub use lib::option::Option::{self, None, Some};
|
||||||
pub use lib::result::Result::{self, Ok, Err};
|
pub use lib::result::Result::{self, Err, Ok};
|
||||||
|
|
||||||
pub use self::string::from_utf8_lossy;
|
pub use self::string::from_utf8_lossy;
|
||||||
|
|
||||||
|
|||||||
+10
-20
@@ -80,29 +80,20 @@
|
|||||||
|
|
||||||
// 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.24")]
|
#![doc(html_root_url = "https://docs.rs/serde/1.0.24")]
|
||||||
|
|
||||||
// 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
|
||||||
// discussion of these features please refer to this issue:
|
// discussion of these features please refer to this issue:
|
||||||
//
|
//
|
||||||
// https://github.com/serde-rs/serde/issues/812
|
// https://github.com/serde-rs/serde/issues/812
|
||||||
#![cfg_attr(feature = "unstable", feature(nonzero, specialization))]
|
#![cfg_attr(feature = "unstable", feature(nonzero, specialization))]
|
||||||
#![cfg_attr(feature = "alloc", feature(alloc))]
|
#![cfg_attr(feature = "alloc", feature(alloc))]
|
||||||
|
|
||||||
#![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(
|
#![cfg_attr(feature = "cargo-clippy",
|
||||||
cast_lossless,
|
allow(cast_lossless, const_static_lifetime, doc_markdown, linkedlist,
|
||||||
const_static_lifetime,
|
needless_pass_by_value, type_complexity, unreadable_literal,
|
||||||
doc_markdown,
|
zero_prefixed_literal))]
|
||||||
linkedlist,
|
|
||||||
needless_pass_by_value,
|
|
||||||
type_complexity,
|
|
||||||
unreadable_literal,
|
|
||||||
zero_prefixed_literal,
|
|
||||||
))]
|
|
||||||
// Whitelisted clippy_pedantic lints
|
// Whitelisted clippy_pedantic lints
|
||||||
#![cfg_attr(feature = "cargo-clippy", allow(
|
#![cfg_attr(feature = "cargo-clippy", allow(
|
||||||
// integer and float ser/de requires these sorts of casts
|
// integer and float ser/de requires these sorts of casts
|
||||||
@@ -125,7 +116,6 @@
|
|||||||
empty_enum,
|
empty_enum,
|
||||||
use_debug,
|
use_debug,
|
||||||
))]
|
))]
|
||||||
|
|
||||||
// Blacklisted Rust lints.
|
// Blacklisted Rust lints.
|
||||||
#![deny(missing_docs, unused_imports)]
|
#![deny(missing_docs, unused_imports)]
|
||||||
|
|
||||||
@@ -149,8 +139,8 @@ mod lib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub use self::core::{cmp, iter, mem, ops, slice, str};
|
pub use self::core::{cmp, iter, mem, ops, slice, str};
|
||||||
pub use self::core::{i8, i16, i32, i64, isize};
|
pub use self::core::{isize, i16, i32, i64, i8};
|
||||||
pub use self::core::{u8, u16, u32, u64, usize};
|
pub use self::core::{usize, u16, u32, u64, u8};
|
||||||
pub use self::core::{f32, f64};
|
pub use self::core::{f32, f64};
|
||||||
|
|
||||||
pub use self::core::cell::{Cell, RefCell};
|
pub use self::core::cell::{Cell, RefCell};
|
||||||
@@ -193,9 +183,9 @@ mod lib {
|
|||||||
pub use alloc::arc::Arc;
|
pub use alloc::arc::Arc;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use std::collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque};
|
pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
|
||||||
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
||||||
pub use alloc::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque};
|
pub use alloc::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use std::{error, net};
|
pub use std::{error, net};
|
||||||
@@ -203,9 +193,9 @@ mod lib {
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use std::collections::{HashMap, HashSet};
|
pub use std::collections::{HashMap, HashSet};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use std::ffi::{CString, CStr, OsString, OsStr};
|
pub use std::ffi::{CStr, CString, OsStr, OsString};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use std::hash::{Hash, BuildHasher};
|
pub use std::hash::{BuildHasher, Hash};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use std::io::Write;
|
pub use std::io::Write;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
|
|||||||
+123
-87
@@ -8,16 +8,16 @@
|
|||||||
|
|
||||||
use lib::*;
|
use lib::*;
|
||||||
|
|
||||||
use de::{Deserialize, Deserializer, DeserializeSeed, IntoDeserializer, Error, Visitor};
|
use de::{Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, Visitor};
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
use de::Unexpected;
|
use de::Unexpected;
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub use self::content::{Content, ContentRefDeserializer, ContentDeserializer,
|
pub use self::content::{Content, ContentDeserializer, ContentRefDeserializer,
|
||||||
TaggedContentVisitor, TagOrContentField, TagOrContentFieldVisitor,
|
InternallyTaggedUnitVisitor, TagContentOtherField,
|
||||||
TagContentOtherField, TagContentOtherFieldVisitor,
|
TagContentOtherFieldVisitor, TagOrContentField, TagOrContentFieldVisitor,
|
||||||
InternallyTaggedUnitVisitor, UntaggedUnitVisitor};
|
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.
|
||||||
@@ -120,7 +120,10 @@ where
|
|||||||
{
|
{
|
||||||
match String::from_utf8(v) {
|
match String::from_utf8(v) {
|
||||||
Ok(s) => Ok(Cow::Owned(s)),
|
Ok(s) => Ok(Cow::Owned(s)),
|
||||||
Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self),),
|
Err(e) => Err(Error::invalid_value(
|
||||||
|
Unexpected::Bytes(&e.into_bytes()),
|
||||||
|
&self,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -225,8 +228,8 @@ mod content {
|
|||||||
|
|
||||||
use lib::*;
|
use lib::*;
|
||||||
|
|
||||||
use de::{self, Deserialize, DeserializeSeed, Deserializer, Visitor, SeqAccess, MapAccess,
|
use de::{self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, MapAccess, SeqAccess,
|
||||||
EnumAccess, Unexpected};
|
Unexpected, Visitor};
|
||||||
use super::size_hint;
|
use super::size_hint;
|
||||||
|
|
||||||
/// Used from generated code to buffer the contents of the Deserializer when
|
/// Used from generated code to buffer the contents of the Deserializer when
|
||||||
@@ -502,7 +505,9 @@ mod content {
|
|||||||
where
|
where
|
||||||
V: EnumAccess<'de>,
|
V: EnumAccess<'de>,
|
||||||
{
|
{
|
||||||
Err(de::Error::custom("untagged and internally tagged enums do not support enum input",),)
|
Err(de::Error::custom(
|
||||||
|
"untagged and internally tagged enums do not support enum input",
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,7 +526,10 @@ mod content {
|
|||||||
|
|
||||||
impl<'de> TagOrContentVisitor<'de> {
|
impl<'de> TagOrContentVisitor<'de> {
|
||||||
fn new(name: &'static str) -> Self {
|
fn new(name: &'static str) -> Self {
|
||||||
TagOrContentVisitor { name: name, value: PhantomData }
|
TagOrContentVisitor {
|
||||||
|
name: name,
|
||||||
|
value: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -558,7 +566,9 @@ mod content {
|
|||||||
where
|
where
|
||||||
F: de::Error,
|
F: de::Error,
|
||||||
{
|
{
|
||||||
ContentVisitor::new().visit_i8(value).map(TagOrContent::Content)
|
ContentVisitor::new()
|
||||||
|
.visit_i8(value)
|
||||||
|
.map(TagOrContent::Content)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_i16<F>(self, value: i16) -> Result<Self::Value, F>
|
fn visit_i16<F>(self, value: i16) -> Result<Self::Value, F>
|
||||||
@@ -592,7 +602,9 @@ mod content {
|
|||||||
where
|
where
|
||||||
F: de::Error,
|
F: de::Error,
|
||||||
{
|
{
|
||||||
ContentVisitor::new().visit_u8(value).map(TagOrContent::Content)
|
ContentVisitor::new()
|
||||||
|
.visit_u8(value)
|
||||||
|
.map(TagOrContent::Content)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_u16<F>(self, value: u16) -> Result<Self::Value, F>
|
fn visit_u16<F>(self, value: u16) -> Result<Self::Value, F>
|
||||||
@@ -731,14 +743,18 @@ mod content {
|
|||||||
where
|
where
|
||||||
F: de::Error,
|
F: de::Error,
|
||||||
{
|
{
|
||||||
ContentVisitor::new().visit_unit().map(TagOrContent::Content)
|
ContentVisitor::new()
|
||||||
|
.visit_unit()
|
||||||
|
.map(TagOrContent::Content)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_none<F>(self) -> Result<Self::Value, F>
|
fn visit_none<F>(self) -> Result<Self::Value, F>
|
||||||
where
|
where
|
||||||
F: de::Error,
|
F: de::Error,
|
||||||
{
|
{
|
||||||
ContentVisitor::new().visit_none().map(TagOrContent::Content)
|
ContentVisitor::new()
|
||||||
|
.visit_none()
|
||||||
|
.map(TagOrContent::Content)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
||||||
@@ -861,8 +877,7 @@ mod content {
|
|||||||
{
|
{
|
||||||
let mut tag = None;
|
let mut tag = None;
|
||||||
let mut vec = Vec::with_capacity(size_hint::cautious(map.size_hint()));
|
let mut vec = Vec::with_capacity(size_hint::cautious(map.size_hint()));
|
||||||
while let Some(k) =
|
while let Some(k) = try!(map.next_key_seed(TagOrContentVisitor::new(self.tag_name))) {
|
||||||
try!(map.next_key_seed(TagOrContentVisitor::new(self.tag_name))) {
|
|
||||||
match k {
|
match k {
|
||||||
TagOrContent::Tag => {
|
TagOrContent::Tag => {
|
||||||
if tag.is_some() {
|
if tag.is_some() {
|
||||||
@@ -878,14 +893,10 @@ mod content {
|
|||||||
}
|
}
|
||||||
match tag {
|
match tag {
|
||||||
None => Err(de::Error::missing_field(self.tag_name)),
|
None => Err(de::Error::missing_field(self.tag_name)),
|
||||||
Some(tag) => {
|
Some(tag) => Ok(TaggedContent {
|
||||||
Ok(
|
|
||||||
TaggedContent {
|
|
||||||
tag: tag,
|
tag: tag,
|
||||||
content: Content::Map(vec),
|
content: Content::Map(vec),
|
||||||
},
|
}),
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -967,7 +978,11 @@ mod content {
|
|||||||
type Value = TagContentOtherField;
|
type Value = TagContentOtherField;
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(formatter, "{:?}, {:?}, or other ignored fields", self.tag, self.content)
|
write!(
|
||||||
|
formatter,
|
||||||
|
"{:?}, {:?}, or other ignored fields",
|
||||||
|
self.tag, self.content
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_str<E>(self, field: &str) -> Result<Self::Value, E>
|
fn visit_str<E>(self, field: &str) -> Result<Self::Value, E>
|
||||||
@@ -1031,10 +1046,8 @@ mod content {
|
|||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
Content::Map(v) => {
|
Content::Map(v) => {
|
||||||
let map = v.into_iter().map(|(k, v)| {
|
let map = v.into_iter()
|
||||||
(ContentDeserializer::new(k),
|
.map(|(k, v)| (ContentDeserializer::new(k), ContentDeserializer::new(v)));
|
||||||
ContentDeserializer::new(v))
|
|
||||||
});
|
|
||||||
let mut map_visitor = de::value::MapDeserializer::new(map);
|
let mut map_visitor = de::value::MapDeserializer::new(map);
|
||||||
let value = try!(visitor.visit_map(&mut map_visitor));
|
let value = try!(visitor.visit_map(&mut map_visitor));
|
||||||
try!(map_visitor.end());
|
try!(map_visitor.end());
|
||||||
@@ -1081,44 +1094,41 @@ mod content {
|
|||||||
let (variant, value) = match iter.next() {
|
let (variant, value) = match iter.next() {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
None => {
|
None => {
|
||||||
return Err(
|
return Err(de::Error::invalid_value(
|
||||||
de::Error::invalid_value(
|
|
||||||
de::Unexpected::Map,
|
de::Unexpected::Map,
|
||||||
&"map with a single key",
|
&"map with a single key",
|
||||||
),
|
));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// enums are encoded in json as maps with a single key:value pair
|
// enums are encoded in json as maps with a single key:value pair
|
||||||
if iter.next().is_some() {
|
if iter.next().is_some() {
|
||||||
return Err(
|
return Err(de::Error::invalid_value(
|
||||||
de::Error::invalid_value(
|
|
||||||
de::Unexpected::Map,
|
de::Unexpected::Map,
|
||||||
&"map with a single key",
|
&"map with a single key",
|
||||||
),
|
));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
(variant, Some(value))
|
(variant, Some(value))
|
||||||
}
|
}
|
||||||
s @ Content::String(_) | s @ Content::Str(_) => (s, None),
|
s @ Content::String(_) | s @ Content::Str(_) => (s, None),
|
||||||
other => {
|
other => {
|
||||||
return Err(de::Error::invalid_type(other.unexpected(), &"string or map"),);
|
return Err(de::Error::invalid_type(
|
||||||
|
other.unexpected(),
|
||||||
|
&"string or map",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
visitor.visit_enum(
|
visitor.visit_enum(EnumDeserializer {
|
||||||
EnumDeserializer {
|
|
||||||
variant: variant,
|
variant: variant,
|
||||||
value: value,
|
value: value,
|
||||||
err: PhantomData,
|
err: PhantomData,
|
||||||
},
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_unit_struct<V>(
|
fn deserialize_unit_struct<V>(
|
||||||
self,
|
self,
|
||||||
_name: &'static str,
|
_name: &'static str,
|
||||||
visitor: V
|
visitor: V,
|
||||||
) -> Result<V::Value, Self::Error>
|
) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
@@ -1216,9 +1226,10 @@ mod content {
|
|||||||
{
|
{
|
||||||
match self.value {
|
match self.value {
|
||||||
Some(value) => seed.deserialize(ContentDeserializer::new(value)),
|
Some(value) => seed.deserialize(ContentDeserializer::new(value)),
|
||||||
None => {
|
None => Err(de::Error::invalid_type(
|
||||||
Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"newtype variant"),)
|
de::Unexpected::UnitVariant,
|
||||||
}
|
&"newtype variant",
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1230,8 +1241,14 @@ mod content {
|
|||||||
Some(Content::Seq(v)) => {
|
Some(Content::Seq(v)) => {
|
||||||
de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor)
|
de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor)
|
||||||
}
|
}
|
||||||
Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"tuple variant"),),
|
Some(other) => Err(de::Error::invalid_type(
|
||||||
None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"tuple variant"),),
|
other.unexpected(),
|
||||||
|
&"tuple variant",
|
||||||
|
)),
|
||||||
|
None => Err(de::Error::invalid_type(
|
||||||
|
de::Unexpected::UnitVariant,
|
||||||
|
&"tuple variant",
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1250,8 +1267,14 @@ mod content {
|
|||||||
Some(Content::Seq(v)) => {
|
Some(Content::Seq(v)) => {
|
||||||
de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor)
|
de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor)
|
||||||
}
|
}
|
||||||
Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant"),),
|
Some(other) => Err(de::Error::invalid_type(
|
||||||
_ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant"),),
|
other.unexpected(),
|
||||||
|
&"struct variant",
|
||||||
|
)),
|
||||||
|
_ => Err(de::Error::invalid_type(
|
||||||
|
de::Unexpected::UnitVariant,
|
||||||
|
&"struct variant",
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1319,10 +1342,7 @@ mod content {
|
|||||||
T: de::DeserializeSeed<'de>,
|
T: de::DeserializeSeed<'de>,
|
||||||
{
|
{
|
||||||
match self.iter.next() {
|
match self.iter.next() {
|
||||||
Some(value) => {
|
Some(value) => seed.deserialize(ContentDeserializer::new(value)).map(Some),
|
||||||
seed.deserialize(ContentDeserializer::new(value))
|
|
||||||
.map(Some)
|
|
||||||
}
|
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1458,12 +1478,12 @@ mod content {
|
|||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
Content::Map(ref v) => {
|
Content::Map(ref v) => {
|
||||||
let map = v.into_iter()
|
let map = v.into_iter().map(|&(ref k, ref v)| {
|
||||||
.map(
|
(
|
||||||
|&(ref k, ref v)| {
|
ContentRefDeserializer::new(k),
|
||||||
(ContentRefDeserializer::new(k), ContentRefDeserializer::new(v))
|
ContentRefDeserializer::new(v),
|
||||||
},
|
)
|
||||||
);
|
});
|
||||||
let mut map_visitor = de::value::MapDeserializer::new(map);
|
let mut map_visitor = de::value::MapDeserializer::new(map);
|
||||||
let value = try!(visitor.visit_map(&mut map_visitor));
|
let value = try!(visitor.visit_map(&mut map_visitor));
|
||||||
try!(map_visitor.end());
|
try!(map_visitor.end());
|
||||||
@@ -1506,38 +1526,35 @@ mod content {
|
|||||||
let &(ref variant, ref value) = match iter.next() {
|
let &(ref variant, ref value) = match iter.next() {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
None => {
|
None => {
|
||||||
return Err(
|
return Err(de::Error::invalid_value(
|
||||||
de::Error::invalid_value(
|
|
||||||
de::Unexpected::Map,
|
de::Unexpected::Map,
|
||||||
&"map with a single key",
|
&"map with a single key",
|
||||||
),
|
));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// enums are encoded in json as maps with a single key:value pair
|
// enums are encoded in json as maps with a single key:value pair
|
||||||
if iter.next().is_some() {
|
if iter.next().is_some() {
|
||||||
return Err(
|
return Err(de::Error::invalid_value(
|
||||||
de::Error::invalid_value(
|
|
||||||
de::Unexpected::Map,
|
de::Unexpected::Map,
|
||||||
&"map with a single key",
|
&"map with a single key",
|
||||||
),
|
));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
(variant, Some(value))
|
(variant, Some(value))
|
||||||
}
|
}
|
||||||
ref s @ Content::String(_) | ref s @ Content::Str(_) => (s, None),
|
ref s @ Content::String(_) | ref s @ Content::Str(_) => (s, None),
|
||||||
ref other => {
|
ref other => {
|
||||||
return Err(de::Error::invalid_type(other.unexpected(), &"string or map"),);
|
return Err(de::Error::invalid_type(
|
||||||
|
other.unexpected(),
|
||||||
|
&"string or map",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
visitor.visit_enum(
|
visitor.visit_enum(EnumRefDeserializer {
|
||||||
EnumRefDeserializer {
|
|
||||||
variant: variant,
|
variant: variant,
|
||||||
value: value,
|
value: value,
|
||||||
err: PhantomData,
|
err: PhantomData,
|
||||||
},
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
forward_to_deserialize_any! {
|
forward_to_deserialize_any! {
|
||||||
@@ -1613,9 +1630,10 @@ mod content {
|
|||||||
{
|
{
|
||||||
match self.value {
|
match self.value {
|
||||||
Some(value) => seed.deserialize(ContentRefDeserializer::new(value)),
|
Some(value) => seed.deserialize(ContentRefDeserializer::new(value)),
|
||||||
None => {
|
None => Err(de::Error::invalid_type(
|
||||||
Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"newtype variant"),)
|
de::Unexpected::UnitVariant,
|
||||||
}
|
&"newtype variant",
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1627,8 +1645,14 @@ mod content {
|
|||||||
Some(&Content::Seq(ref v)) => {
|
Some(&Content::Seq(ref v)) => {
|
||||||
de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
|
de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
|
||||||
}
|
}
|
||||||
Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"tuple variant"),),
|
Some(other) => Err(de::Error::invalid_type(
|
||||||
None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"tuple variant"),),
|
other.unexpected(),
|
||||||
|
&"tuple variant",
|
||||||
|
)),
|
||||||
|
None => Err(de::Error::invalid_type(
|
||||||
|
de::Unexpected::UnitVariant,
|
||||||
|
&"tuple variant",
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1647,8 +1671,14 @@ mod content {
|
|||||||
Some(&Content::Seq(ref v)) => {
|
Some(&Content::Seq(ref v)) => {
|
||||||
de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
|
de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
|
||||||
}
|
}
|
||||||
Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant"),),
|
Some(other) => Err(de::Error::invalid_type(
|
||||||
_ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant"),),
|
other.unexpected(),
|
||||||
|
&"struct variant",
|
||||||
|
)),
|
||||||
|
_ => Err(de::Error::invalid_type(
|
||||||
|
de::Unexpected::UnitVariant,
|
||||||
|
&"struct variant",
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1716,10 +1746,8 @@ mod content {
|
|||||||
T: de::DeserializeSeed<'de>,
|
T: de::DeserializeSeed<'de>,
|
||||||
{
|
{
|
||||||
match self.iter.next() {
|
match self.iter.next() {
|
||||||
Some(value) => {
|
Some(value) => seed.deserialize(ContentRefDeserializer::new(value))
|
||||||
seed.deserialize(ContentRefDeserializer::new(value))
|
.map(Some),
|
||||||
.map(Some)
|
|
||||||
}
|
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1764,8 +1792,7 @@ mod content {
|
|||||||
match self.iter.next() {
|
match self.iter.next() {
|
||||||
Some(&(ref key, ref value)) => {
|
Some(&(ref key, ref value)) => {
|
||||||
self.value = Some(value);
|
self.value = Some(value);
|
||||||
seed.deserialize(ContentRefDeserializer::new(key))
|
seed.deserialize(ContentRefDeserializer::new(key)).map(Some)
|
||||||
.map(Some)
|
|
||||||
}
|
}
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
}
|
}
|
||||||
@@ -1851,7 +1878,11 @@ mod content {
|
|||||||
type Value = ();
|
type Value = ();
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(formatter, "unit variant {}::{}", self.type_name, self.variant_name)
|
write!(
|
||||||
|
formatter,
|
||||||
|
"unit variant {}::{}",
|
||||||
|
self.type_name, self.variant_name
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_seq<S>(self, _: S) -> Result<(), S::Error>
|
fn visit_seq<S>(self, _: S) -> Result<(), S::Error>
|
||||||
@@ -1891,7 +1922,11 @@ mod content {
|
|||||||
type Value = ();
|
type Value = ();
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(formatter, "unit variant {}::{}", self.type_name, self.variant_name)
|
write!(
|
||||||
|
formatter,
|
||||||
|
"unit variant {}::{}",
|
||||||
|
self.type_name, self.variant_name
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_unit<E>(self) -> Result<(), E>
|
fn visit_unit<E>(self) -> Result<(), E>
|
||||||
@@ -2016,7 +2051,8 @@ where
|
|||||||
pub struct InPlaceSeed<'a, T: 'a>(pub &'a mut T);
|
pub struct InPlaceSeed<'a, T: 'a>(pub &'a mut T);
|
||||||
|
|
||||||
impl<'a, 'de, T> DeserializeSeed<'de> for InPlaceSeed<'a, T>
|
impl<'a, 'de, T> DeserializeSeed<'de> for InPlaceSeed<'a, T>
|
||||||
where T: Deserialize<'de>,
|
where
|
||||||
|
T: Deserialize<'de>,
|
||||||
{
|
{
|
||||||
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>
|
||||||
|
|||||||
+64
-54
@@ -8,10 +8,10 @@
|
|||||||
|
|
||||||
use lib::*;
|
use lib::*;
|
||||||
|
|
||||||
use ser::{self, Serialize, Serializer, SerializeMap, SerializeStruct, Impossible};
|
use ser::{self, Impossible, Serialize, SerializeMap, SerializeStruct, Serializer};
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
use self::content::{SerializeTupleVariantAsMapValue, SerializeStructVariantAsMapValue};
|
use self::content::{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.
|
||||||
@@ -32,15 +32,13 @@ where
|
|||||||
S: Serializer,
|
S: Serializer,
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
value.serialize(
|
value.serialize(TaggedSerializer {
|
||||||
TaggedSerializer {
|
|
||||||
type_ident: type_ident,
|
type_ident: type_ident,
|
||||||
variant_ident: variant_ident,
|
variant_ident: variant_ident,
|
||||||
tag: tag,
|
tag: tag,
|
||||||
variant_name: variant_name,
|
variant_name: variant_name,
|
||||||
delegate: serializer,
|
delegate: serializer,
|
||||||
},
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TaggedSerializer<S> {
|
struct TaggedSerializer<S> {
|
||||||
@@ -63,8 +61,7 @@ enum Unsupported {
|
|||||||
Sequence,
|
Sequence,
|
||||||
Tuple,
|
Tuple,
|
||||||
TupleStruct,
|
TupleStruct,
|
||||||
#[cfg(not(any(feature = "std", feature = "alloc")))]
|
#[cfg(not(any(feature = "std", feature = "alloc")))] Enum,
|
||||||
Enum,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Unsupported {
|
impl Display for Unsupported {
|
||||||
@@ -92,13 +89,10 @@ where
|
|||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
fn bad_type(self, what: Unsupported) -> S::Error {
|
fn bad_type(self, what: Unsupported) -> S::Error {
|
||||||
ser::Error::custom(
|
ser::Error::custom(format_args!(
|
||||||
format_args!(
|
|
||||||
"cannot serialize tagged newtype variant {}::{} containing {}",
|
"cannot serialize tagged newtype variant {}::{} containing {}",
|
||||||
self.type_ident,
|
self.type_ident, self.variant_ident, what
|
||||||
self.variant_ident,
|
))
|
||||||
what),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,7 +275,11 @@ where
|
|||||||
let mut map = try!(self.delegate.serialize_map(Some(2)));
|
let mut map = try!(self.delegate.serialize_map(Some(2)));
|
||||||
try!(map.serialize_entry(self.tag, self.variant_name));
|
try!(map.serialize_entry(self.tag, self.variant_name));
|
||||||
try!(map.serialize_key(inner_variant));
|
try!(map.serialize_key(inner_variant));
|
||||||
Ok(SerializeTupleVariantAsMapValue::new(map, inner_variant, len),)
|
Ok(SerializeTupleVariantAsMapValue::new(
|
||||||
|
map,
|
||||||
|
inner_variant,
|
||||||
|
len,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
|
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
|
||||||
@@ -324,7 +322,11 @@ where
|
|||||||
let mut map = try!(self.delegate.serialize_map(Some(2)));
|
let mut map = try!(self.delegate.serialize_map(Some(2)));
|
||||||
try!(map.serialize_entry(self.tag, self.variant_name));
|
try!(map.serialize_entry(self.tag, self.variant_name));
|
||||||
try!(map.serialize_key(inner_variant));
|
try!(map.serialize_key(inner_variant));
|
||||||
Ok(SerializeStructVariantAsMapValue::new(map, inner_variant, len),)
|
Ok(SerializeStructVariantAsMapValue::new(
|
||||||
|
map,
|
||||||
|
inner_variant,
|
||||||
|
len,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(feature = "std", feature = "alloc")))]
|
#[cfg(not(any(feature = "std", feature = "alloc")))]
|
||||||
@@ -402,7 +404,10 @@ mod content {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn end(mut self) -> Result<M::Ok, M::Error> {
|
fn end(mut self) -> Result<M::Ok, M::Error> {
|
||||||
try!(self.map.serialize_value(&Content::TupleStruct(self.name, self.fields)));
|
try!(
|
||||||
|
self.map
|
||||||
|
.serialize_value(&Content::TupleStruct(self.name, self.fields))
|
||||||
|
);
|
||||||
self.map.end()
|
self.map.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -444,7 +449,10 @@ mod content {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn end(mut self) -> Result<M::Ok, M::Error> {
|
fn end(mut self) -> Result<M::Ok, M::Error> {
|
||||||
try!(self.map.serialize_value(&Content::Struct(self.name, self.fields)));
|
try!(
|
||||||
|
self.map
|
||||||
|
.serialize_value(&Content::Struct(self.name, self.fields))
|
||||||
|
);
|
||||||
self.map.end()
|
self.map.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -485,7 +493,12 @@ mod content {
|
|||||||
TupleVariant(&'static str, u32, &'static str, Vec<Content>),
|
TupleVariant(&'static str, u32, &'static str, Vec<Content>),
|
||||||
Map(Vec<(Content, Content)>),
|
Map(Vec<(Content, Content)>),
|
||||||
Struct(&'static str, Vec<(&'static str, Content)>),
|
Struct(&'static str, Vec<(&'static str, Content)>),
|
||||||
StructVariant(&'static str, u32, &'static str, Vec<(&'static str, Content)>),
|
StructVariant(
|
||||||
|
&'static str,
|
||||||
|
u32,
|
||||||
|
&'static str,
|
||||||
|
Vec<(&'static str, Content)>,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for Content {
|
impl Serialize for Content {
|
||||||
@@ -687,7 +700,10 @@ mod content {
|
|||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
Ok(Content::NewtypeStruct(name, Box::new(try!(value.serialize(self)))),)
|
Ok(Content::NewtypeStruct(
|
||||||
|
name,
|
||||||
|
Box::new(try!(value.serialize(self))),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_newtype_variant<T: ?Sized>(
|
fn serialize_newtype_variant<T: ?Sized>(
|
||||||
@@ -700,32 +716,26 @@ mod content {
|
|||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
Ok(
|
Ok(Content::NewtypeVariant(
|
||||||
Content::NewtypeVariant(
|
|
||||||
name,
|
name,
|
||||||
variant_index,
|
variant_index,
|
||||||
variant,
|
variant,
|
||||||
Box::new(try!(value.serialize(self))),
|
Box::new(try!(value.serialize(self))),
|
||||||
),
|
))
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, E> {
|
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, E> {
|
||||||
Ok(
|
Ok(SerializeSeq {
|
||||||
SerializeSeq {
|
|
||||||
elements: Vec::with_capacity(len.unwrap_or(0)),
|
elements: Vec::with_capacity(len.unwrap_or(0)),
|
||||||
error: PhantomData,
|
error: PhantomData,
|
||||||
},
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, E> {
|
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, E> {
|
||||||
Ok(
|
Ok(SerializeTuple {
|
||||||
SerializeTuple {
|
|
||||||
elements: Vec::with_capacity(len),
|
elements: Vec::with_capacity(len),
|
||||||
error: PhantomData,
|
error: PhantomData,
|
||||||
},
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_tuple_struct(
|
fn serialize_tuple_struct(
|
||||||
@@ -733,13 +743,11 @@ mod content {
|
|||||||
name: &'static str,
|
name: &'static str,
|
||||||
len: usize,
|
len: usize,
|
||||||
) -> Result<Self::SerializeTupleStruct, E> {
|
) -> Result<Self::SerializeTupleStruct, E> {
|
||||||
Ok(
|
Ok(SerializeTupleStruct {
|
||||||
SerializeTupleStruct {
|
|
||||||
name: name,
|
name: name,
|
||||||
fields: Vec::with_capacity(len),
|
fields: Vec::with_capacity(len),
|
||||||
error: PhantomData,
|
error: PhantomData,
|
||||||
},
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_tuple_variant(
|
fn serialize_tuple_variant(
|
||||||
@@ -749,25 +757,21 @@ mod content {
|
|||||||
variant: &'static str,
|
variant: &'static str,
|
||||||
len: usize,
|
len: usize,
|
||||||
) -> Result<Self::SerializeTupleVariant, E> {
|
) -> Result<Self::SerializeTupleVariant, E> {
|
||||||
Ok(
|
Ok(SerializeTupleVariant {
|
||||||
SerializeTupleVariant {
|
|
||||||
name: name,
|
name: name,
|
||||||
variant_index: variant_index,
|
variant_index: variant_index,
|
||||||
variant: variant,
|
variant: variant,
|
||||||
fields: Vec::with_capacity(len),
|
fields: Vec::with_capacity(len),
|
||||||
error: PhantomData,
|
error: PhantomData,
|
||||||
},
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, E> {
|
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, E> {
|
||||||
Ok(
|
Ok(SerializeMap {
|
||||||
SerializeMap {
|
|
||||||
entries: Vec::with_capacity(len.unwrap_or(0)),
|
entries: Vec::with_capacity(len.unwrap_or(0)),
|
||||||
key: None,
|
key: None,
|
||||||
error: PhantomData,
|
error: PhantomData,
|
||||||
},
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_struct(
|
fn serialize_struct(
|
||||||
@@ -775,13 +779,11 @@ mod content {
|
|||||||
name: &'static str,
|
name: &'static str,
|
||||||
len: usize,
|
len: usize,
|
||||||
) -> Result<Self::SerializeStruct, E> {
|
) -> Result<Self::SerializeStruct, E> {
|
||||||
Ok(
|
Ok(SerializeStruct {
|
||||||
SerializeStruct {
|
|
||||||
name: name,
|
name: name,
|
||||||
fields: Vec::with_capacity(len),
|
fields: Vec::with_capacity(len),
|
||||||
error: PhantomData,
|
error: PhantomData,
|
||||||
},
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_struct_variant(
|
fn serialize_struct_variant(
|
||||||
@@ -791,15 +793,13 @@ mod content {
|
|||||||
variant: &'static str,
|
variant: &'static str,
|
||||||
len: usize,
|
len: usize,
|
||||||
) -> Result<Self::SerializeStructVariant, E> {
|
) -> Result<Self::SerializeStructVariant, E> {
|
||||||
Ok(
|
Ok(SerializeStructVariant {
|
||||||
SerializeStructVariant {
|
|
||||||
name: name,
|
name: name,
|
||||||
variant_index: variant_index,
|
variant_index: variant_index,
|
||||||
variant: variant,
|
variant: variant,
|
||||||
fields: Vec::with_capacity(len),
|
fields: Vec::with_capacity(len),
|
||||||
error: PhantomData,
|
error: PhantomData,
|
||||||
},
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -907,7 +907,12 @@ mod content {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn end(self) -> Result<Content, E> {
|
fn end(self) -> Result<Content, E> {
|
||||||
Ok(Content::TupleVariant(self.name, self.variant_index, self.variant, self.fields),)
|
Ok(Content::TupleVariant(
|
||||||
|
self.name,
|
||||||
|
self.variant_index,
|
||||||
|
self.variant,
|
||||||
|
self.fields,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1013,7 +1018,12 @@ mod content {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn end(self) -> Result<Content, E> {
|
fn end(self) -> Result<Content, E> {
|
||||||
Ok(Content::StructVariant(self.name, self.variant_index, self.variant, self.fields),)
|
Ok(Content::StructVariant(
|
||||||
|
self.name,
|
||||||
|
self.variant_index,
|
||||||
|
self.variant,
|
||||||
|
self.fields,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-10
@@ -464,7 +464,8 @@ impl Serialize for SystemTime {
|
|||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
use super::SerializeStruct;
|
use super::SerializeStruct;
|
||||||
let duration_since_epoch = self.duration_since(UNIX_EPOCH).expect("SystemTime must be later than UNIX_EPOCH");
|
let duration_since_epoch = self.duration_since(UNIX_EPOCH)
|
||||||
|
.expect("SystemTime must be later than UNIX_EPOCH");
|
||||||
let mut state = try!(serializer.serialize_struct("SystemTime", 2));
|
let mut state = try!(serializer.serialize_struct("SystemTime", 2));
|
||||||
try!(state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs()));
|
try!(state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs()));
|
||||||
try!(state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos()));
|
try!(state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos()));
|
||||||
@@ -513,10 +514,12 @@ impl Serialize for net::IpAddr {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match *self {
|
match *self {
|
||||||
net::IpAddr::V4(ref a) =>
|
net::IpAddr::V4(ref a) => {
|
||||||
serializer.serialize_newtype_variant("IpAddr", 0, "V4", a),
|
serializer.serialize_newtype_variant("IpAddr", 0, "V4", a)
|
||||||
net::IpAddr::V6(ref a) =>
|
}
|
||||||
serializer.serialize_newtype_variant("IpAddr", 1, "V6", a),
|
net::IpAddr::V6(ref a) => {
|
||||||
|
serializer.serialize_newtype_variant("IpAddr", 1, "V6", a)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -567,10 +570,12 @@ impl Serialize for net::SocketAddr {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match *self {
|
match *self {
|
||||||
net::SocketAddr::V4(ref addr) =>
|
net::SocketAddr::V4(ref addr) => {
|
||||||
serializer.serialize_newtype_variant("SocketAddr", 0, "V4", addr),
|
serializer.serialize_newtype_variant("SocketAddr", 0, "V4", addr)
|
||||||
net::SocketAddr::V6(ref addr) =>
|
}
|
||||||
serializer.serialize_newtype_variant("SocketAddr", 1, "V6", addr),
|
net::SocketAddr::V6(ref addr) => {
|
||||||
|
serializer.serialize_newtype_variant("SocketAddr", 1, "V6", addr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -600,7 +605,10 @@ impl Serialize for net::SocketAddrV6 {
|
|||||||
{
|
{
|
||||||
if serializer.is_human_readable() {
|
if serializer.is_human_readable() {
|
||||||
const MAX_LEN: usize = 47;
|
const MAX_LEN: usize = 47;
|
||||||
debug_assert_eq!(MAX_LEN, "[1001:1002:1003:1004:1005:1006:1007:1008]:65000".len());
|
debug_assert_eq!(
|
||||||
|
MAX_LEN,
|
||||||
|
"[1001:1002:1003:1004:1005:1006:1007:1008]:65000".len()
|
||||||
|
);
|
||||||
serialize_display_bounded_length!(self, MAX_LEN, serializer)
|
serialize_display_bounded_length!(self, MAX_LEN, serializer)
|
||||||
} else {
|
} else {
|
||||||
(self.ip(), self.port()).serialize(serializer)
|
(self.ip(), self.port()).serialize(serializer)
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
|
|
||||||
use lib::*;
|
use lib::*;
|
||||||
|
|
||||||
use ser::{self, Serialize, SerializeSeq, SerializeTuple, SerializeTupleStruct,
|
use ser::{self, Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant,
|
||||||
SerializeTupleVariant, SerializeMap, 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.
|
||||||
|
|||||||
@@ -1412,7 +1412,9 @@ pub trait Serializer: Sized {
|
|||||||
/// change, as a value serialized in human-readable mode is not required to
|
/// change, as a value serialized in human-readable mode is not required to
|
||||||
/// deserialize from the same data in compact mode.
|
/// deserialize from the same data in compact mode.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_human_readable(&self) -> bool { true }
|
fn is_human_readable(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returned from `Serializer::serialize_seq`.
|
/// Returned from `Serializer::serialize_seq`.
|
||||||
|
|||||||
+12
-28
@@ -27,14 +27,10 @@ pub fn without_defaults(generics: &syn::Generics) -> syn::Generics {
|
|||||||
ty_params: generics
|
ty_params: generics
|
||||||
.ty_params
|
.ty_params
|
||||||
.iter()
|
.iter()
|
||||||
.map(
|
.map(|ty_param| syn::TyParam {
|
||||||
|ty_param| {
|
|
||||||
syn::TyParam {
|
|
||||||
default: None,
|
default: None,
|
||||||
..ty_param.clone()
|
..ty_param.clone()
|
||||||
}
|
})
|
||||||
},
|
|
||||||
)
|
|
||||||
.collect(),
|
.collect(),
|
||||||
..generics.clone()
|
..generics.clone()
|
||||||
}
|
}
|
||||||
@@ -137,8 +133,7 @@ where
|
|||||||
relevant_ty_params: HashSet::new(),
|
relevant_ty_params: HashSet::new(),
|
||||||
};
|
};
|
||||||
match cont.body {
|
match cont.body {
|
||||||
Body::Enum(ref variants) => {
|
Body::Enum(ref variants) => for variant in variants.iter() {
|
||||||
for variant in variants.iter() {
|
|
||||||
let relevant_fields = variant
|
let relevant_fields = variant
|
||||||
.fields
|
.fields
|
||||||
.iter()
|
.iter()
|
||||||
@@ -146,8 +141,7 @@ where
|
|||||||
for field in relevant_fields {
|
for field in relevant_fields {
|
||||||
visit::walk_ty(&mut visitor, field.ty);
|
visit::walk_ty(&mut visitor, field.ty);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
Body::Struct(_, ref fields) => {
|
Body::Struct(_, ref fields) => {
|
||||||
for field in fields.iter().filter(|field| filter(&field.attrs, None)) {
|
for field in fields.iter().filter(|field| filter(&field.attrs, None)) {
|
||||||
visit::walk_ty(&mut visitor, field.ty);
|
visit::walk_ty(&mut visitor, field.ty);
|
||||||
@@ -160,10 +154,8 @@ where
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|ty_param| ty_param.ident.clone())
|
.map(|ty_param| ty_param.ident.clone())
|
||||||
.filter(|id| visitor.relevant_ty_params.contains(id))
|
.filter(|id| visitor.relevant_ty_params.contains(id))
|
||||||
.map(
|
.map(|id| {
|
||||||
|id| {
|
syn::WherePredicate::BoundPredicate(syn::WhereBoundPredicate {
|
||||||
syn::WherePredicate::BoundPredicate(
|
|
||||||
syn::WhereBoundPredicate {
|
|
||||||
bound_lifetimes: Vec::new(),
|
bound_lifetimes: Vec::new(),
|
||||||
// the type parameter that is being bounded e.g. T
|
// the type parameter that is being bounded e.g. T
|
||||||
bounded_ty: syn::Ty::Path(None, id.into()),
|
bounded_ty: syn::Ty::Path(None, id.into()),
|
||||||
@@ -177,10 +169,8 @@ where
|
|||||||
syn::TraitBoundModifier::None,
|
syn::TraitBoundModifier::None,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
},
|
})
|
||||||
)
|
});
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut generics = generics.clone();
|
let mut generics = generics.clone();
|
||||||
generics.where_clause.predicates.extend(new_predicates);
|
generics.where_clause.predicates.extend(new_predicates);
|
||||||
@@ -196,8 +186,7 @@ pub fn with_self_bound(
|
|||||||
generics
|
generics
|
||||||
.where_clause
|
.where_clause
|
||||||
.predicates
|
.predicates
|
||||||
.push(
|
.push(syn::WherePredicate::BoundPredicate(
|
||||||
syn::WherePredicate::BoundPredicate(
|
|
||||||
syn::WhereBoundPredicate {
|
syn::WhereBoundPredicate {
|
||||||
bound_lifetimes: Vec::new(),
|
bound_lifetimes: Vec::new(),
|
||||||
// the type that is being bounded e.g. MyStruct<'a, T>
|
// the type that is being bounded e.g. MyStruct<'a, T>
|
||||||
@@ -213,8 +202,7 @@ pub fn with_self_bound(
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
),
|
));
|
||||||
);
|
|
||||||
generics
|
generics
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,15 +219,11 @@ pub fn with_lifetime_bound(generics: &syn::Generics, lifetime: &str) -> syn::Gen
|
|||||||
.push(syn::TyParamBound::Region(syn::Lifetime::new(lifetime)));
|
.push(syn::TyParamBound::Region(syn::Lifetime::new(lifetime)));
|
||||||
}
|
}
|
||||||
|
|
||||||
generics
|
generics.lifetimes.push(syn::LifetimeDef {
|
||||||
.lifetimes
|
|
||||||
.push(
|
|
||||||
syn::LifetimeDef {
|
|
||||||
attrs: Vec::new(),
|
attrs: Vec::new(),
|
||||||
lifetime: syn::Lifetime::new(lifetime),
|
lifetime: syn::Lifetime::new(lifetime),
|
||||||
bounds: Vec::new(),
|
bounds: Vec::new(),
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
generics
|
generics
|
||||||
}
|
}
|
||||||
|
|||||||
+196
-256
@@ -7,10 +7,10 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use syn::{self, Ident};
|
use syn::{self, Ident};
|
||||||
use quote::{self, Tokens, ToTokens};
|
use quote::{self, ToTokens, Tokens};
|
||||||
|
|
||||||
use bound;
|
use bound;
|
||||||
use fragment::{Fragment, Expr, Stmts, Match};
|
use fragment::{Expr, Fragment, Match, Stmts};
|
||||||
use internals::ast::{Body, Container, Field, Style, Variant};
|
use internals::ast::{Body, Container, Field, Style, Variant};
|
||||||
use internals::{self, attr};
|
use internals::{self, attr};
|
||||||
|
|
||||||
@@ -129,8 +129,7 @@ fn build_generics(cont: &Container, borrowed: &BorrowedLifetimes) -> syn::Generi
|
|||||||
attr::Default::Default => {
|
attr::Default::Default => {
|
||||||
bound::with_self_bound(cont, &generics, &path!(_serde::export::Default))
|
bound::with_self_bound(cont, &generics, &path!(_serde::export::Default))
|
||||||
}
|
}
|
||||||
attr::Default::None |
|
attr::Default::None | attr::Default::Path(_) => generics,
|
||||||
attr::Default::Path(_) => generics,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let delife = borrowed.de_lifetime();
|
let delife = borrowed.de_lifetime();
|
||||||
@@ -156,10 +155,8 @@ fn build_generics(cont: &Container, borrowed: &BorrowedLifetimes) -> syn::Generi
|
|||||||
// attribute specify their own bound so we do not generate one. All other fields
|
// 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.
|
// 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 {
|
fn needs_deserialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
|
||||||
!field.skip_deserializing() &&
|
!field.skip_deserializing() && field.deserialize_with().is_none() && field.de_bound().is_none()
|
||||||
field.deserialize_with().is_none() &&
|
&& variant.map_or(true, |variant| variant.deserialize_with().is_none())
|
||||||
field.de_bound().is_none() &&
|
|
||||||
variant.map_or(true, |variant| variant.deserialize_with().is_none())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fields with a `default` attribute (not `default=...`), and fields with a
|
// Fields with a `default` attribute (not `default=...`), and fields with a
|
||||||
@@ -183,13 +180,11 @@ impl BorrowedLifetimes {
|
|||||||
|
|
||||||
fn de_lifetime_def(&self) -> Option<syn::LifetimeDef> {
|
fn de_lifetime_def(&self) -> Option<syn::LifetimeDef> {
|
||||||
match *self {
|
match *self {
|
||||||
BorrowedLifetimes::Borrowed(ref bounds) => {
|
BorrowedLifetimes::Borrowed(ref bounds) => Some(syn::LifetimeDef {
|
||||||
Some(syn::LifetimeDef {
|
|
||||||
attrs: Vec::new(),
|
attrs: Vec::new(),
|
||||||
lifetime: syn::Lifetime::new("'de"),
|
lifetime: syn::Lifetime::new("'de"),
|
||||||
bounds: bounds.iter().cloned().collect(),
|
bounds: bounds.iter().cloned().collect(),
|
||||||
})
|
}),
|
||||||
}
|
|
||||||
BorrowedLifetimes::Static => None,
|
BorrowedLifetimes::Static => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,8 +225,7 @@ fn deserialize_body(cont: &Container, params: &Parameters) -> Fragment {
|
|||||||
}
|
}
|
||||||
deserialize_struct(None, params, fields, &cont.attrs, None, Untagged::No)
|
deserialize_struct(None, params, fields, &cont.attrs, None, Untagged::No)
|
||||||
}
|
}
|
||||||
Body::Struct(Style::Tuple, ref fields) |
|
Body::Struct(Style::Tuple, ref fields) | Body::Struct(Style::Newtype, ref fields) => {
|
||||||
Body::Struct(Style::Newtype, ref fields) => {
|
|
||||||
if fields.iter().any(|field| field.ident.is_some()) {
|
if fields.iter().any(|field| field.ident.is_some()) {
|
||||||
panic!("tuple struct has named fields");
|
panic!("tuple struct has named fields");
|
||||||
}
|
}
|
||||||
@@ -255,9 +249,10 @@ fn deserialize_in_place_body(cont: &Container, params: &Parameters) -> Option<St
|
|||||||
// deserialize_in_place for remote derives.
|
// deserialize_in_place for remote derives.
|
||||||
assert!(!params.has_getter);
|
assert!(!params.has_getter);
|
||||||
|
|
||||||
if cont.attrs.from_type().is_some()
|
if cont.attrs.from_type().is_some() || cont.attrs.identifier().is_some()
|
||||||
|| cont.attrs.identifier().is_some()
|
|| cont.body
|
||||||
|| cont.body.all_fields().all(|f| f.attrs.deserialize_with().is_some())
|
.all_fields()
|
||||||
|
.all(|f| f.attrs.deserialize_with().is_some())
|
||||||
{
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@@ -266,8 +261,7 @@ fn deserialize_in_place_body(cont: &Container, params: &Parameters) -> Option<St
|
|||||||
Body::Struct(Style::Struct, ref fields) => {
|
Body::Struct(Style::Struct, ref fields) => {
|
||||||
deserialize_struct_in_place(None, params, fields, &cont.attrs, None, Untagged::No)
|
deserialize_struct_in_place(None, params, fields, &cont.attrs, None, Untagged::No)
|
||||||
}
|
}
|
||||||
Body::Struct(Style::Tuple, ref fields) |
|
Body::Struct(Style::Tuple, ref fields) | Body::Struct(Style::Newtype, ref fields) => {
|
||||||
Body::Struct(Style::Newtype, ref fields) => {
|
|
||||||
deserialize_tuple_in_place(None, params, fields, &cont.attrs, None)
|
deserialize_tuple_in_place(None, params, fields, &cont.attrs, None)
|
||||||
}
|
}
|
||||||
Body::Enum(_) | Body::Struct(Style::Unit, _) => {
|
Body::Enum(_) | Body::Struct(Style::Unit, _) => {
|
||||||
@@ -338,7 +332,8 @@ fn deserialize_tuple(
|
|||||||
deserializer: Option<Tokens>,
|
deserializer: Option<Tokens>,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let this = ¶ms.this;
|
let this = ¶ms.this;
|
||||||
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
|
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
||||||
|
split_with_de_lifetime(params);
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
|
|
||||||
// If there are getters (implying private fields), construct the local type
|
// If there are getters (implying private fields), construct the local type
|
||||||
@@ -389,9 +384,7 @@ fn deserialize_tuple(
|
|||||||
quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #nfields, #visitor_expr))
|
quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #nfields, #visitor_expr))
|
||||||
};
|
};
|
||||||
|
|
||||||
let all_skipped = fields
|
let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
|
||||||
.iter()
|
|
||||||
.all(|field| field.attrs.skip_deserializing());
|
|
||||||
let visitor_var = if all_skipped {
|
let visitor_var = if all_skipped {
|
||||||
quote!(_)
|
quote!(_)
|
||||||
} else {
|
} else {
|
||||||
@@ -434,7 +427,8 @@ fn deserialize_tuple_in_place(
|
|||||||
deserializer: Option<Tokens>,
|
deserializer: Option<Tokens>,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let this = ¶ms.this;
|
let this = ¶ms.this;
|
||||||
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
|
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
||||||
|
split_with_de_lifetime(params);
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
|
|
||||||
let is_enum = variant_ident.is_some();
|
let is_enum = variant_ident.is_some();
|
||||||
@@ -472,9 +466,7 @@ fn deserialize_tuple_in_place(
|
|||||||
quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #nfields, #visitor_expr))
|
quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #nfields, #visitor_expr))
|
||||||
};
|
};
|
||||||
|
|
||||||
let all_skipped = fields
|
let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
|
||||||
.iter()
|
|
||||||
.all(|field| field.attrs.skip_deserializing());
|
|
||||||
let visitor_var = if all_skipped {
|
let visitor_var = if all_skipped {
|
||||||
quote!(_)
|
quote!(_)
|
||||||
} else {
|
} else {
|
||||||
@@ -528,8 +520,7 @@ fn deserialize_seq(
|
|||||||
let expecting = format!("tuple of {} elements", deserialized_count);
|
let expecting = format!("tuple of {} elements", deserialized_count);
|
||||||
|
|
||||||
let mut index_in_seq = 0usize;
|
let mut index_in_seq = 0usize;
|
||||||
let let_values = vars.clone().zip(fields)
|
let let_values = vars.clone().zip(fields).map(|(var, field)| {
|
||||||
.map(|(var, field)| {
|
|
||||||
if field.attrs.skip_deserializing() {
|
if field.attrs.skip_deserializing() {
|
||||||
let default = Expr(expr_is_missing(&field, cattrs));
|
let default = Expr(expr_is_missing(&field, cattrs));
|
||||||
quote! {
|
quote! {
|
||||||
@@ -542,8 +533,7 @@ fn deserialize_seq(
|
|||||||
quote!(try!(_serde::de::SeqAccess::next_element::<#field_ty>(&mut __seq)))
|
quote!(try!(_serde::de::SeqAccess::next_element::<#field_ty>(&mut __seq)))
|
||||||
}
|
}
|
||||||
Some(path) => {
|
Some(path) => {
|
||||||
let (wrapper, wrapper_ty) = wrap_deserialize_field_with(
|
let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
|
||||||
params, field.ty, path);
|
|
||||||
quote!({
|
quote!({
|
||||||
#wrapper
|
#wrapper
|
||||||
_serde::export::Option::map(
|
_serde::export::Option::map(
|
||||||
@@ -584,20 +574,12 @@ fn deserialize_seq(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let let_default = match *cattrs.default() {
|
let let_default = match *cattrs.default() {
|
||||||
attr::Default::Default => {
|
attr::Default::Default => Some(quote!(
|
||||||
Some(
|
|
||||||
quote!(
|
|
||||||
let __default: Self::Value = _serde::export::Default::default();
|
let __default: Self::Value = _serde::export::Default::default();
|
||||||
),
|
)),
|
||||||
)
|
attr::Default::Path(ref path) => Some(quote!(
|
||||||
}
|
|
||||||
attr::Default::Path(ref path) => {
|
|
||||||
Some(
|
|
||||||
quote!(
|
|
||||||
let __default: Self::Value = #path();
|
let __default: Self::Value = #path();
|
||||||
),
|
)),
|
||||||
)
|
|
||||||
}
|
|
||||||
attr::Default::None => {
|
attr::Default::None => {
|
||||||
// We don't need the default value, to prevent an unused variable warning
|
// We don't need the default value, to prevent an unused variable warning
|
||||||
// we'll leave the line empty.
|
// we'll leave the line empty.
|
||||||
@@ -627,10 +609,14 @@ fn deserialize_seq_in_place(
|
|||||||
let expecting = format!("tuple of {} elements", deserialized_count);
|
let expecting = format!("tuple of {} elements", deserialized_count);
|
||||||
|
|
||||||
let mut index_in_seq = 0usize;
|
let mut index_in_seq = 0usize;
|
||||||
let write_values = vars.clone().zip(fields).enumerate()
|
let write_values = vars.clone()
|
||||||
|
.zip(fields)
|
||||||
|
.enumerate()
|
||||||
.map(|(field_index, (_, field))| {
|
.map(|(field_index, (_, field))| {
|
||||||
// If there's no field name, assume we're a tuple-struct and use a numeric index
|
// If there's no field name, assume we're a tuple-struct and use a numeric index
|
||||||
let field_name = field.ident.clone()
|
let field_name = field
|
||||||
|
.ident
|
||||||
|
.clone()
|
||||||
.unwrap_or_else(|| Ident::new(field_index.to_string()));
|
.unwrap_or_else(|| Ident::new(field_index.to_string()));
|
||||||
|
|
||||||
if field.attrs.skip_deserializing() {
|
if field.attrs.skip_deserializing() {
|
||||||
@@ -653,8 +639,8 @@ fn deserialize_seq_in_place(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(path) => {
|
Some(path) => {
|
||||||
let (wrapper, wrapper_ty) = wrap_deserialize_field_with(
|
let (wrapper, wrapper_ty) =
|
||||||
params, field.ty, path);
|
wrap_deserialize_field_with(params, field.ty, path);
|
||||||
quote!({
|
quote!({
|
||||||
#wrapper
|
#wrapper
|
||||||
match try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)) {
|
match try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)) {
|
||||||
@@ -676,20 +662,12 @@ fn deserialize_seq_in_place(
|
|||||||
let this = ¶ms.this;
|
let this = ¶ms.this;
|
||||||
let (_, ty_generics, _) = params.generics.split_for_impl();
|
let (_, ty_generics, _) = params.generics.split_for_impl();
|
||||||
let let_default = match *cattrs.default() {
|
let let_default = match *cattrs.default() {
|
||||||
attr::Default::Default => {
|
attr::Default::Default => Some(quote!(
|
||||||
Some(
|
|
||||||
quote!(
|
|
||||||
let __default: #this #ty_generics = _serde::export::Default::default();
|
let __default: #this #ty_generics = _serde::export::Default::default();
|
||||||
),
|
)),
|
||||||
)
|
attr::Default::Path(ref path) => Some(quote!(
|
||||||
}
|
|
||||||
attr::Default::Path(ref path) => {
|
|
||||||
Some(
|
|
||||||
quote!(
|
|
||||||
let __default: #this #ty_generics = #path();
|
let __default: #this #ty_generics = #path();
|
||||||
),
|
)),
|
||||||
)
|
|
||||||
}
|
|
||||||
attr::Default::None => {
|
attr::Default::None => {
|
||||||
// We don't need the default value, to prevent an unused variable warning
|
// We don't need the default value, to prevent an unused variable warning
|
||||||
// we'll leave the line empty.
|
// we'll leave the line empty.
|
||||||
@@ -742,10 +720,7 @@ fn deserialize_newtype_struct(type_path: &Tokens, params: &Parameters, field: &F
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "deserialize_in_place")]
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
fn deserialize_newtype_struct_in_place(
|
fn deserialize_newtype_struct_in_place(params: &Parameters, field: &Field) -> Tokens {
|
||||||
params: &Parameters,
|
|
||||||
field: &Field
|
|
||||||
) -> Tokens {
|
|
||||||
// We do not generate deserialize_in_place if every field has a deserialize_with.
|
// We do not generate deserialize_in_place if every field has a deserialize_with.
|
||||||
assert!(field.attrs.deserialize_with().is_none());
|
assert!(field.attrs.deserialize_with().is_none());
|
||||||
|
|
||||||
@@ -777,7 +752,8 @@ fn deserialize_struct(
|
|||||||
let is_enum = variant_ident.is_some();
|
let is_enum = variant_ident.is_some();
|
||||||
|
|
||||||
let this = ¶ms.this;
|
let this = ¶ms.this;
|
||||||
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
|
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
||||||
|
split_with_de_lifetime(params);
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
|
|
||||||
// If there are getters (implying private fields), construct the local type
|
// If there are getters (implying private fields), construct the local type
|
||||||
@@ -828,9 +804,7 @@ fn deserialize_struct(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let all_skipped = fields
|
let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
|
||||||
.iter()
|
|
||||||
.all(|field| field.attrs.skip_deserializing());
|
|
||||||
let visitor_var = if all_skipped {
|
let visitor_var = if all_skipped {
|
||||||
quote!(_)
|
quote!(_)
|
||||||
} else {
|
} else {
|
||||||
@@ -840,16 +814,14 @@ fn deserialize_struct(
|
|||||||
// untagged struct variants do not get a visit_seq method
|
// untagged struct variants do not get a visit_seq method
|
||||||
let visit_seq = match untagged {
|
let visit_seq = match untagged {
|
||||||
Untagged::Yes => None,
|
Untagged::Yes => None,
|
||||||
Untagged::No => {
|
Untagged::No => Some(quote! {
|
||||||
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
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
quote_block! {
|
quote_block! {
|
||||||
@@ -895,7 +867,8 @@ fn deserialize_struct_in_place(
|
|||||||
let is_enum = variant_ident.is_some();
|
let is_enum = variant_ident.is_some();
|
||||||
|
|
||||||
let this = ¶ms.this;
|
let this = ¶ms.this;
|
||||||
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
|
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
||||||
|
split_with_de_lifetime(params);
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
|
|
||||||
let expecting = match variant_ident {
|
let expecting = match variant_ident {
|
||||||
@@ -932,10 +905,7 @@ fn deserialize_struct_in_place(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
|
||||||
let all_skipped = fields
|
|
||||||
.iter()
|
|
||||||
.all(|field| field.attrs.skip_deserializing());
|
|
||||||
let visitor_var = if all_skipped {
|
let visitor_var = if all_skipped {
|
||||||
quote!(_)
|
quote!(_)
|
||||||
} else {
|
} else {
|
||||||
@@ -945,17 +915,14 @@ fn deserialize_struct_in_place(
|
|||||||
// untagged struct variants do not get a visit_seq method
|
// untagged struct variants do not get a visit_seq method
|
||||||
let visit_seq = match untagged {
|
let visit_seq = match untagged {
|
||||||
Untagged::Yes => None,
|
Untagged::Yes => None,
|
||||||
Untagged::No => {
|
Untagged::No => Some(quote! {
|
||||||
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
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let in_place_impl_generics = de_impl_generics.in_place();
|
let in_place_impl_generics = de_impl_generics.in_place();
|
||||||
@@ -1017,7 +984,8 @@ fn deserialize_externally_tagged_enum(
|
|||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let this = ¶ms.this;
|
let this = ¶ms.this;
|
||||||
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
|
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
||||||
|
split_with_de_lifetime(params);
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
|
|
||||||
let type_name = cattrs.name().deserialize_name();
|
let type_name = cattrs.name().deserialize_name();
|
||||||
@@ -1028,7 +996,7 @@ fn deserialize_externally_tagged_enum(
|
|||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
|
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
|
||||||
.map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)),)
|
.map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let variants_stmt = {
|
let variants_stmt = {
|
||||||
@@ -1038,24 +1006,30 @@ fn deserialize_externally_tagged_enum(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let variant_visitor = Stmts(deserialize_generated_identifier(variant_names_idents, cattrs, true),);
|
let variant_visitor = Stmts(deserialize_generated_identifier(
|
||||||
|
variant_names_idents,
|
||||||
|
cattrs,
|
||||||
|
true,
|
||||||
|
));
|
||||||
|
|
||||||
// Match arms to extract a variant from a string
|
// Match arms to extract a variant from a string
|
||||||
let variant_arms = variants
|
let variant_arms = variants
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
|
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
|
||||||
.map(
|
.map(|(i, variant)| {
|
||||||
|(i, variant)| {
|
|
||||||
let variant_name = field_i(i);
|
let variant_name = field_i(i);
|
||||||
|
|
||||||
let block = Match(deserialize_externally_tagged_variant(params, variant, cattrs),);
|
let block = Match(deserialize_externally_tagged_variant(
|
||||||
|
params,
|
||||||
|
variant,
|
||||||
|
cattrs,
|
||||||
|
));
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
(__Field::#variant_name, __variant) => #block
|
(__Field::#variant_name, __variant) => #block
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
let all_skipped = variants
|
let all_skipped = variants
|
||||||
.iter()
|
.iter()
|
||||||
@@ -1121,7 +1095,7 @@ fn deserialize_internally_tagged_enum(
|
|||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
|
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
|
||||||
.map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)),)
|
.map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let variants_stmt = {
|
let variants_stmt = {
|
||||||
@@ -1131,10 +1105,15 @@ fn deserialize_internally_tagged_enum(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let variant_visitor = Stmts(deserialize_generated_identifier(variant_names_idents, cattrs, true),);
|
let variant_visitor = Stmts(deserialize_generated_identifier(
|
||||||
|
variant_names_idents,
|
||||||
|
cattrs,
|
||||||
|
true,
|
||||||
|
));
|
||||||
|
|
||||||
// Match arms to extract a variant from a string
|
// Match arms to extract a variant from a string
|
||||||
let variant_arms = variants.iter()
|
let variant_arms = variants
|
||||||
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
|
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
|
||||||
.map(|(i, variant)| {
|
.map(|(i, variant)| {
|
||||||
@@ -1144,7 +1123,9 @@ fn deserialize_internally_tagged_enum(
|
|||||||
params,
|
params,
|
||||||
variant,
|
variant,
|
||||||
cattrs,
|
cattrs,
|
||||||
quote!(_serde::private::de::ContentDeserializer::<__D::Error>::new(__tagged.content)),
|
quote!(
|
||||||
|
_serde::private::de::ContentDeserializer::<__D::Error>::new(__tagged.content)
|
||||||
|
),
|
||||||
));
|
));
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
@@ -1175,14 +1156,15 @@ fn deserialize_adjacently_tagged_enum(
|
|||||||
content: &str,
|
content: &str,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let this = ¶ms.this;
|
let this = ¶ms.this;
|
||||||
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
|
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
||||||
|
split_with_de_lifetime(params);
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
|
|
||||||
let variant_names_idents: Vec<_> = variants
|
let variant_names_idents: Vec<_> = variants
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
|
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
|
||||||
.map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)),)
|
.map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let variants_stmt = {
|
let variants_stmt = {
|
||||||
@@ -1192,30 +1174,30 @@ fn deserialize_adjacently_tagged_enum(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let variant_visitor = Stmts(deserialize_generated_identifier(variant_names_idents, cattrs, true),);
|
let variant_visitor = Stmts(deserialize_generated_identifier(
|
||||||
|
variant_names_idents,
|
||||||
|
cattrs,
|
||||||
|
true,
|
||||||
|
));
|
||||||
|
|
||||||
let ref variant_arms: Vec<_> = variants
|
let ref variant_arms: Vec<_> = variants
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
|
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
|
||||||
.map(
|
.map(|(i, variant)| {
|
||||||
|(i, variant)| {
|
|
||||||
let variant_index = field_i(i);
|
let variant_index = field_i(i);
|
||||||
|
|
||||||
let block = Match(
|
let block = Match(deserialize_untagged_variant(
|
||||||
deserialize_untagged_variant(
|
|
||||||
params,
|
params,
|
||||||
variant,
|
variant,
|
||||||
cattrs,
|
cattrs,
|
||||||
quote!(__deserializer),
|
quote!(__deserializer),
|
||||||
),
|
));
|
||||||
);
|
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
__Field::#variant_index => #block
|
__Field::#variant_index => #block
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
)
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let expecting = format!("adjacently tagged enum {}", params.type_name());
|
let expecting = format!("adjacently tagged enum {}", params.type_name());
|
||||||
@@ -1251,25 +1233,21 @@ fn deserialize_adjacently_tagged_enum(
|
|||||||
let fallthrough = if variants.iter().all(is_unit) {
|
let fallthrough = if variants.iter().all(is_unit) {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(
|
Some(quote! {
|
||||||
quote! {
|
|
||||||
_ => #missing_content
|
_ => #missing_content
|
||||||
},
|
})
|
||||||
)
|
|
||||||
};
|
};
|
||||||
let arms = variants
|
let arms = variants
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|&(_, variant)| !variant.attrs.skip_deserializing() && is_unit(variant),)
|
.filter(|&(_, variant)| !variant.attrs.skip_deserializing() && is_unit(variant))
|
||||||
.map(
|
.map(|(i, variant)| {
|
||||||
|(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),
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
);
|
|
||||||
missing_content = quote! {
|
missing_content = quote! {
|
||||||
match __field {
|
match __field {
|
||||||
#(#arms)*
|
#(#arms)*
|
||||||
@@ -1288,8 +1266,7 @@ fn deserialize_adjacently_tagged_enum(
|
|||||||
let next_relevant_key = if deny_unknown_fields {
|
let next_relevant_key = if deny_unknown_fields {
|
||||||
next_key
|
next_key
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
quote!({
|
||||||
{
|
|
||||||
let mut __rk : _serde::export::Option<_serde::private::de::TagOrContentField> = _serde::export::None;
|
let mut __rk : _serde::export::Option<_serde::private::de::TagOrContentField> = _serde::export::None;
|
||||||
while let _serde::export::Some(__k) = #next_key {
|
while let _serde::export::Some(__k) = #next_key {
|
||||||
match __k {
|
match __k {
|
||||||
@@ -1309,8 +1286,7 @@ fn deserialize_adjacently_tagged_enum(
|
|||||||
}
|
}
|
||||||
|
|
||||||
__rk
|
__rk
|
||||||
}
|
})
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Step through remaining keys, looking for duplicates of previously-seen
|
// Step through remaining keys, looking for duplicates of previously-seen
|
||||||
@@ -1472,16 +1448,14 @@ fn deserialize_untagged_enum(
|
|||||||
let attempts = variants
|
let attempts = variants
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|variant| !variant.attrs.skip_deserializing())
|
.filter(|variant| !variant.attrs.skip_deserializing())
|
||||||
.map(
|
.map(|variant| {
|
||||||
|variant| {
|
|
||||||
Expr(deserialize_untagged_variant(
|
Expr(deserialize_untagged_variant(
|
||||||
params,
|
params,
|
||||||
variant,
|
variant,
|
||||||
cattrs,
|
cattrs,
|
||||||
quote!(_serde::private::de::ContentRefDeserializer::<__D::Error>::new(&__content)),
|
quote!(_serde::private::de::ContentRefDeserializer::<__D::Error>::new(&__content)),
|
||||||
))
|
))
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
// TODO this message could be better by saving the errors from the failed
|
// TODO this message could be better by saving the errors from the failed
|
||||||
// attempts. The heuristic used by TOML was to count the number of fields
|
// attempts. The heuristic used by TOML was to count the number of fields
|
||||||
@@ -1489,8 +1463,10 @@ fn deserialize_untagged_enum(
|
|||||||
// largest number of fields. I'm not sure I like that. Maybe it would be
|
// largest number of fields. I'm not sure I like that. Maybe it would be
|
||||||
// better to save all the errors and combine them into one message that
|
// better to save all the errors and combine them into one message that
|
||||||
// explains why none of the variants matched.
|
// explains why none of the variants matched.
|
||||||
let fallthrough_msg =
|
let fallthrough_msg = format!(
|
||||||
format!("data did not match any variant of untagged enum {}", params.type_name());
|
"data did not match any variant of untagged enum {}",
|
||||||
|
params.type_name()
|
||||||
|
);
|
||||||
|
|
||||||
quote_block! {
|
quote_block! {
|
||||||
let __content = try!(<_serde::private::de::Content as _serde::Deserialize>::deserialize(__deserializer));
|
let __content = try!(<_serde::private::de::Content as _serde::Deserialize>::deserialize(__deserializer));
|
||||||
@@ -1536,9 +1512,14 @@ fn deserialize_externally_tagged_variant(
|
|||||||
Style::Tuple => {
|
Style::Tuple => {
|
||||||
deserialize_tuple(Some(variant_ident), params, &variant.fields, cattrs, None)
|
deserialize_tuple(Some(variant_ident), params, &variant.fields, cattrs, None)
|
||||||
}
|
}
|
||||||
Style::Struct => {
|
Style::Struct => deserialize_struct(
|
||||||
deserialize_struct(Some(variant_ident), params, &variant.fields, cattrs, None, Untagged::No)
|
Some(variant_ident),
|
||||||
}
|
params,
|
||||||
|
&variant.fields,
|
||||||
|
cattrs,
|
||||||
|
None,
|
||||||
|
Untagged::No,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1564,24 +1545,20 @@ fn deserialize_internally_tagged_variant(
|
|||||||
_serde::export::Ok(#this::#variant_ident)
|
_serde::export::Ok(#this::#variant_ident)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Style::Newtype => {
|
Style::Newtype => deserialize_untagged_newtype_variant(
|
||||||
deserialize_untagged_newtype_variant(
|
|
||||||
variant_ident,
|
variant_ident,
|
||||||
params,
|
params,
|
||||||
&variant.fields[0],
|
&variant.fields[0],
|
||||||
deserializer,
|
deserializer,
|
||||||
)
|
),
|
||||||
}
|
Style::Struct => deserialize_struct(
|
||||||
Style::Struct => {
|
|
||||||
deserialize_struct(
|
|
||||||
Some(variant_ident),
|
Some(variant_ident),
|
||||||
params,
|
params,
|
||||||
&variant.fields,
|
&variant.fields,
|
||||||
cattrs,
|
cattrs,
|
||||||
Some(deserializer),
|
Some(deserializer),
|
||||||
Untagged::No,
|
Untagged::No,
|
||||||
)
|
),
|
||||||
}
|
|
||||||
Style::Tuple => unreachable!("checked in serde_derive_internals"),
|
Style::Tuple => unreachable!("checked in serde_derive_internals"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1618,33 +1595,27 @@ fn deserialize_untagged_variant(
|
|||||||
|()| #this::#variant_ident)
|
|()| #this::#variant_ident)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Style::Newtype => {
|
Style::Newtype => deserialize_untagged_newtype_variant(
|
||||||
deserialize_untagged_newtype_variant(
|
|
||||||
variant_ident,
|
variant_ident,
|
||||||
params,
|
params,
|
||||||
&variant.fields[0],
|
&variant.fields[0],
|
||||||
deserializer,
|
deserializer,
|
||||||
)
|
),
|
||||||
}
|
Style::Tuple => deserialize_tuple(
|
||||||
Style::Tuple => {
|
|
||||||
deserialize_tuple(
|
|
||||||
Some(variant_ident),
|
Some(variant_ident),
|
||||||
params,
|
params,
|
||||||
&variant.fields,
|
&variant.fields,
|
||||||
cattrs,
|
cattrs,
|
||||||
Some(deserializer),
|
Some(deserializer),
|
||||||
)
|
),
|
||||||
}
|
Style::Struct => deserialize_struct(
|
||||||
Style::Struct => {
|
|
||||||
deserialize_struct(
|
|
||||||
Some(variant_ident),
|
Some(variant_ident),
|
||||||
params,
|
params,
|
||||||
&variant.fields,
|
&variant.fields,
|
||||||
cattrs,
|
cattrs,
|
||||||
Some(deserializer),
|
Some(deserializer),
|
||||||
Untagged::Yes,
|
Untagged::Yes,
|
||||||
)
|
),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1719,7 +1690,12 @@ fn deserialize_generated_identifier(
|
|||||||
(Some(ignore_variant), Some(fallthrough))
|
(Some(ignore_variant), Some(fallthrough))
|
||||||
};
|
};
|
||||||
|
|
||||||
let visitor_impl = Stmts(deserialize_identifier(this, &fields, is_variant, fallthrough),);
|
let visitor_impl = Stmts(deserialize_identifier(
|
||||||
|
this,
|
||||||
|
&fields,
|
||||||
|
is_variant,
|
||||||
|
fallthrough,
|
||||||
|
));
|
||||||
|
|
||||||
quote_block! {
|
quote_block! {
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
@@ -1785,7 +1761,12 @@ fn deserialize_custom_identifier(
|
|||||||
|
|
||||||
let names_idents: Vec<_> = ordinary
|
let names_idents: Vec<_> = ordinary
|
||||||
.iter()
|
.iter()
|
||||||
.map(|variant| (variant.attrs.name().deserialize_name(), variant.ident.clone()),)
|
.map(|variant| {
|
||||||
|
(
|
||||||
|
variant.attrs.name().deserialize_name(),
|
||||||
|
variant.ident.clone(),
|
||||||
|
)
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let names = names_idents.iter().map(|&(ref name, _)| name);
|
let names = names_idents.iter().map(|&(ref name, _)| name);
|
||||||
@@ -1804,10 +1785,15 @@ fn deserialize_custom_identifier(
|
|||||||
Some(fields)
|
Some(fields)
|
||||||
};
|
};
|
||||||
|
|
||||||
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
|
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
||||||
|
split_with_de_lifetime(params);
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
let visitor_impl =
|
let visitor_impl = Stmts(deserialize_identifier(
|
||||||
Stmts(deserialize_identifier(this.clone(), &names_idents, is_variant, fallthrough),);
|
this.clone(),
|
||||||
|
&names_idents,
|
||||||
|
is_variant,
|
||||||
|
fallthrough,
|
||||||
|
));
|
||||||
|
|
||||||
quote_block! {
|
quote_block! {
|
||||||
#names_const
|
#names_const
|
||||||
@@ -1851,11 +1837,7 @@ fn deserialize_identifier(
|
|||||||
"field identifier"
|
"field identifier"
|
||||||
};
|
};
|
||||||
|
|
||||||
let index_expecting = if is_variant {
|
let index_expecting = if is_variant { "variant" } else { "field" };
|
||||||
"variant"
|
|
||||||
} else {
|
|
||||||
"field"
|
|
||||||
};
|
|
||||||
|
|
||||||
let variant_indices = 0u64..;
|
let variant_indices = 0u64..;
|
||||||
let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len());
|
let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len());
|
||||||
@@ -1939,7 +1921,7 @@ fn deserialize_struct_visitor(
|
|||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|&(_, field)| !field.attrs.skip_deserializing())
|
.filter(|&(_, field)| !field.attrs.skip_deserializing())
|
||||||
.map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i)),)
|
.map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i)))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let fields_stmt = {
|
let fields_stmt = {
|
||||||
@@ -1973,17 +1955,16 @@ fn deserialize_map(
|
|||||||
let let_values = fields_names
|
let let_values = fields_names
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|&&(field, _)| !field.attrs.skip_deserializing())
|
.filter(|&&(field, _)| !field.attrs.skip_deserializing())
|
||||||
.map(
|
.map(|&(field, ref name)| {
|
||||||
|&(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;
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
// Match arms to extract a value for a field.
|
// Match arms to extract a value for a field.
|
||||||
let value_arms = fields_names.iter()
|
let value_arms = fields_names
|
||||||
|
.iter()
|
||||||
.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();
|
||||||
@@ -1996,8 +1977,7 @@ fn deserialize_map(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(path) => {
|
Some(path) => {
|
||||||
let (wrapper, wrapper_ty) = wrap_deserialize_field_with(
|
let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
|
||||||
params, field.ty, path);
|
|
||||||
quote!({
|
quote!({
|
||||||
#wrapper
|
#wrapper
|
||||||
try!(_serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map)).value
|
try!(_serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map)).value
|
||||||
@@ -2023,9 +2003,7 @@ fn deserialize_map(
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let all_skipped = fields
|
let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
|
||||||
.iter()
|
|
||||||
.all(|field| field.attrs.skip_deserializing());
|
|
||||||
let match_keys = if cattrs.deny_unknown_fields() && all_skipped {
|
let match_keys = if cattrs.deny_unknown_fields() && all_skipped {
|
||||||
quote! {
|
quote! {
|
||||||
// FIXME: Once we drop support for Rust 1.15:
|
// FIXME: Once we drop support for Rust 1.15:
|
||||||
@@ -2048,8 +2026,7 @@ fn deserialize_map(
|
|||||||
let extract_values = fields_names
|
let extract_values = fields_names
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|&&(field, _)| !field.attrs.skip_deserializing())
|
.filter(|&&(field, _)| !field.attrs.skip_deserializing())
|
||||||
.map(
|
.map(|&(field, ref name)| {
|
||||||
|&(field, ref name)| {
|
|
||||||
let missing_expr = Match(expr_is_missing(&field, cattrs));
|
let missing_expr = Match(expr_is_missing(&field, cattrs));
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
@@ -2058,41 +2035,25 @@ fn deserialize_map(
|
|||||||
_serde::export::None => #missing_expr
|
_serde::export::None => #missing_expr
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
let result = fields_names
|
let result = fields_names.iter().map(|&(field, ref name)| {
|
||||||
.iter()
|
let ident = field.ident.clone().expect("struct contains unnamed fields");
|
||||||
.map(
|
|
||||||
|&(field, ref name)| {
|
|
||||||
let ident = field
|
|
||||||
.ident
|
|
||||||
.clone()
|
|
||||||
.expect("struct contains unnamed fields");
|
|
||||||
if field.attrs.skip_deserializing() {
|
if field.attrs.skip_deserializing() {
|
||||||
let value = Expr(expr_is_missing(&field, cattrs));
|
let value = Expr(expr_is_missing(&field, cattrs));
|
||||||
quote!(#ident: #value)
|
quote!(#ident: #value)
|
||||||
} else {
|
} else {
|
||||||
quote!(#ident: #name)
|
quote!(#ident: #name)
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
let let_default = match *cattrs.default() {
|
let let_default = match *cattrs.default() {
|
||||||
attr::Default::Default => {
|
attr::Default::Default => Some(quote!(
|
||||||
Some(
|
|
||||||
quote!(
|
|
||||||
let __default: Self::Value = _serde::export::Default::default();
|
let __default: Self::Value = _serde::export::Default::default();
|
||||||
),
|
)),
|
||||||
)
|
attr::Default::Path(ref path) => Some(quote!(
|
||||||
}
|
|
||||||
attr::Default::Path(ref path) => {
|
|
||||||
Some(
|
|
||||||
quote!(
|
|
||||||
let __default: Self::Value = #path();
|
let __default: Self::Value = #path();
|
||||||
),
|
)),
|
||||||
)
|
|
||||||
}
|
|
||||||
attr::Default::None => {
|
attr::Default::None => {
|
||||||
// We don't need the default value, to prevent an unused variable warning
|
// We don't need the default value, to prevent an unused variable warning
|
||||||
// we'll leave the line empty.
|
// we'll leave the line empty.
|
||||||
@@ -2131,7 +2092,7 @@ fn deserialize_struct_in_place_visitor(
|
|||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|&(_, field)| !field.attrs.skip_deserializing())
|
.filter(|&(_, field)| !field.attrs.skip_deserializing())
|
||||||
.map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i)),)
|
.map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i)))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let fields_stmt = {
|
let fields_stmt = {
|
||||||
@@ -2165,16 +2126,15 @@ fn deserialize_map_in_place(
|
|||||||
let let_flags = fields_names
|
let let_flags = fields_names
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|&&(field, _)| !field.attrs.skip_deserializing())
|
.filter(|&&(field, _)| !field.attrs.skip_deserializing())
|
||||||
.map(
|
.map(|&(_, ref name)| {
|
||||||
|&(_, ref name)| {
|
|
||||||
quote! {
|
quote! {
|
||||||
let mut #name: bool = false;
|
let mut #name: bool = false;
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
// Match arms to extract a value for a field.
|
// Match arms to extract a value for a field.
|
||||||
let value_arms_from = fields_names.iter()
|
let value_arms_from = fields_names
|
||||||
|
.iter()
|
||||||
.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();
|
||||||
@@ -2187,8 +2147,7 @@ fn deserialize_map_in_place(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(path) => {
|
Some(path) => {
|
||||||
let (wrapper, wrapper_ty) = wrap_deserialize_field_with(
|
let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
|
||||||
params, field.ty, path);
|
|
||||||
quote!({
|
quote!({
|
||||||
#wrapper
|
#wrapper
|
||||||
self.place.#field_name = try!(_serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map)).value
|
self.place.#field_name = try!(_serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map)).value
|
||||||
@@ -2215,9 +2174,7 @@ fn deserialize_map_in_place(
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let all_skipped = fields
|
let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
|
||||||
.iter()
|
|
||||||
.all(|field| field.attrs.skip_deserializing());
|
|
||||||
|
|
||||||
let match_keys = if cattrs.deny_unknown_fields() && all_skipped {
|
let match_keys = if cattrs.deny_unknown_fields() && all_skipped {
|
||||||
quote! {
|
quote! {
|
||||||
@@ -2241,8 +2198,7 @@ fn deserialize_map_in_place(
|
|||||||
let check_flags = fields_names
|
let check_flags = fields_names
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|&&(field, _)| !field.attrs.skip_deserializing())
|
.filter(|&&(field, _)| !field.attrs.skip_deserializing())
|
||||||
.map(
|
.map(|&(field, ref name)| {
|
||||||
|&(field, ref name)| {
|
|
||||||
let missing_expr = expr_is_missing(&field, cattrs);
|
let missing_expr = expr_is_missing(&field, cattrs);
|
||||||
// If missing_expr unconditionally returns an error, don't try
|
// If missing_expr unconditionally returns an error, don't try
|
||||||
// to assign its value to self.place. Maybe this could be handled
|
// to assign its value to self.place. Maybe this could be handled
|
||||||
@@ -2263,27 +2219,18 @@ fn deserialize_map_in_place(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
let this = ¶ms.this;
|
let this = ¶ms.this;
|
||||||
let (_, _, ty_generics, _) = split_with_de_lifetime(params,);
|
let (_, _, ty_generics, _) = split_with_de_lifetime(params);
|
||||||
|
|
||||||
let let_default = match *cattrs.default() {
|
let let_default = match *cattrs.default() {
|
||||||
attr::Default::Default => {
|
attr::Default::Default => Some(quote!(
|
||||||
Some(
|
|
||||||
quote!(
|
|
||||||
let __default: #this #ty_generics = _serde::export::Default::default();
|
let __default: #this #ty_generics = _serde::export::Default::default();
|
||||||
),
|
)),
|
||||||
)
|
attr::Default::Path(ref path) => Some(quote!(
|
||||||
}
|
|
||||||
attr::Default::Path(ref path) => {
|
|
||||||
Some(
|
|
||||||
quote!(
|
|
||||||
let __default: #this #ty_generics = #path();
|
let __default: #this #ty_generics = #path();
|
||||||
),
|
)),
|
||||||
)
|
|
||||||
}
|
|
||||||
attr::Default::None => {
|
attr::Default::None => {
|
||||||
// We don't need the default value, to prevent an unused variable warning
|
// We don't need the default value, to prevent an unused variable warning
|
||||||
// we'll leave the line empty.
|
// we'll leave the line empty.
|
||||||
@@ -2316,7 +2263,8 @@ fn wrap_deserialize_with(
|
|||||||
deserialize_with: &syn::Path,
|
deserialize_with: &syn::Path,
|
||||||
) -> (Tokens, Tokens) {
|
) -> (Tokens, Tokens) {
|
||||||
let this = ¶ms.this;
|
let this = ¶ms.this;
|
||||||
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
|
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
||||||
|
split_with_de_lifetime(params);
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
|
|
||||||
let wrapper = quote! {
|
let wrapper = quote! {
|
||||||
@@ -2367,40 +2315,29 @@ fn wrap_deserialize_variant_with(
|
|||||||
let field_access = (0..variant.fields.len()).map(|n| Ident::new(format!("{}", n)));
|
let field_access = (0..variant.fields.len()).map(|n| Ident::new(format!("{}", n)));
|
||||||
let unwrap_fn = match variant.style {
|
let unwrap_fn = match variant.style {
|
||||||
Style::Struct => {
|
Style::Struct => {
|
||||||
let field_idents = variant.fields.iter().map(|field| field.ident.as_ref().unwrap());
|
let field_idents = variant
|
||||||
quote! {
|
.fields
|
||||||
{
|
.iter()
|
||||||
|
.map(|field| field.ident.as_ref().unwrap());
|
||||||
|
quote!({
|
||||||
|__wrap| {
|
|__wrap| {
|
||||||
#this::#variant_ident { #(#field_idents: __wrap.value.#field_access),* }
|
#this::#variant_ident { #(#field_idents: __wrap.value.#field_access),* }
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
Style::Tuple => quote!({
|
||||||
}
|
|
||||||
Style::Tuple => {
|
|
||||||
quote! {
|
|
||||||
{
|
|
||||||
|__wrap| {
|
|__wrap| {
|
||||||
#this::#variant_ident(#(__wrap.value.#field_access),*)
|
#this::#variant_ident(#(__wrap.value.#field_access),*)
|
||||||
}
|
}
|
||||||
}
|
}),
|
||||||
}
|
Style::Newtype => quote!({
|
||||||
}
|
|
||||||
Style::Newtype => {
|
|
||||||
quote! {
|
|
||||||
{
|
|
||||||
|__wrap| {
|
|__wrap| {
|
||||||
#this::#variant_ident(__wrap.value)
|
#this::#variant_ident(__wrap.value)
|
||||||
}
|
}
|
||||||
}
|
}),
|
||||||
}
|
Style::Unit => quote!({
|
||||||
}
|
|
||||||
Style::Unit => {
|
|
||||||
quote! {
|
|
||||||
{
|
|
||||||
|__wrap| { #this::#variant_ident }
|
|__wrap| { #this::#variant_ident }
|
||||||
}
|
}),
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
(wrapper, wrapper_ty, unwrap_fn)
|
(wrapper, wrapper_ty, unwrap_fn)
|
||||||
@@ -2418,8 +2355,7 @@ fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match *cattrs.default() {
|
match *cattrs.default() {
|
||||||
attr::Default::Default |
|
attr::Default::Default | attr::Default::Path(_) => {
|
||||||
attr::Default::Path(_) => {
|
|
||||||
let ident = &field.ident;
|
let ident = &field.ident;
|
||||||
return quote_expr!(__default.#ident);
|
return quote_expr!(__default.#ident);
|
||||||
}
|
}
|
||||||
@@ -2467,7 +2403,9 @@ impl<'a> ToTokens for InPlaceImplGenerics<'a> {
|
|||||||
lifetime.bounds.push(place_lifetime.lifetime.clone());
|
lifetime.bounds.push(place_lifetime.lifetime.clone());
|
||||||
}
|
}
|
||||||
for generic in &mut generics.ty_params {
|
for generic in &mut generics.ty_params {
|
||||||
generic.bounds.push(syn::TyParamBound::Region(place_lifetime.lifetime.clone()));
|
generic
|
||||||
|
.bounds
|
||||||
|
.push(syn::TyParamBound::Region(place_lifetime.lifetime.clone()));
|
||||||
}
|
}
|
||||||
generics.lifetimes.insert(0, place_lifetime);
|
generics.lifetimes.insert(0, place_lifetime);
|
||||||
if let Some(de_lifetime) = self.0.borrowed.de_lifetime_def() {
|
if let Some(de_lifetime) = self.0.borrowed.de_lifetime_def() {
|
||||||
@@ -2493,9 +2431,7 @@ impl<'a> ToTokens for DeTyGenerics<'a> {
|
|||||||
fn to_tokens(&self, tokens: &mut Tokens) {
|
fn to_tokens(&self, tokens: &mut Tokens) {
|
||||||
let mut generics = self.0.generics.clone();
|
let mut generics = self.0.generics.clone();
|
||||||
if self.0.borrowed.de_lifetime_def().is_some() {
|
if self.0.borrowed.de_lifetime_def().is_some() {
|
||||||
generics
|
generics.lifetimes.insert(0, syn::LifetimeDef::new("'de"));
|
||||||
.lifetimes
|
|
||||||
.insert(0, syn::LifetimeDef::new("'de"));
|
|
||||||
}
|
}
|
||||||
let (_, ty_generics, _) = generics.split_for_impl();
|
let (_, ty_generics, _) = generics.split_for_impl();
|
||||||
ty_generics.to_tokens(tokens);
|
ty_generics.to_tokens(tokens);
|
||||||
@@ -2509,9 +2445,7 @@ impl<'a> ToTokens for InPlaceTyGenerics<'a> {
|
|||||||
generics.lifetimes.insert(0, place_lifetime());
|
generics.lifetimes.insert(0, place_lifetime());
|
||||||
|
|
||||||
if self.0.borrowed.de_lifetime_def().is_some() {
|
if self.0.borrowed.de_lifetime_def().is_some() {
|
||||||
generics
|
generics.lifetimes.insert(0, syn::LifetimeDef::new("'de"));
|
||||||
.lifetimes
|
|
||||||
.insert(0, syn::LifetimeDef::new("'de"));
|
|
||||||
}
|
}
|
||||||
let (_, ty_generics, _) = generics.split_for_impl();
|
let (_, ty_generics, _) = generics.split_for_impl();
|
||||||
ty_generics.to_tokens(tokens);
|
ty_generics.to_tokens(tokens);
|
||||||
@@ -2530,8 +2464,14 @@ fn place_lifetime() -> syn::LifetimeDef {
|
|||||||
syn::LifetimeDef::new("'place")
|
syn::LifetimeDef::new("'place")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_with_de_lifetime(params: &Parameters,)
|
fn split_with_de_lifetime(
|
||||||
-> (DeImplGenerics, DeTyGenerics, syn::TyGenerics, &syn::WhereClause) {
|
params: &Parameters,
|
||||||
|
) -> (
|
||||||
|
DeImplGenerics,
|
||||||
|
DeTyGenerics,
|
||||||
|
syn::TyGenerics,
|
||||||
|
&syn::WhereClause,
|
||||||
|
) {
|
||||||
let de_impl_generics = DeImplGenerics(¶ms);
|
let de_impl_generics = DeImplGenerics(¶ms);
|
||||||
let de_ty_generics = DeTyGenerics(¶ms);
|
let de_ty_generics = DeTyGenerics(¶ms);
|
||||||
let (_, ty_generics, where_clause) = params.generics.split_for_impl();
|
let (_, ty_generics, where_clause) = params.generics.split_for_impl();
|
||||||
|
|||||||
@@ -6,7 +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 quote::{Tokens, ToTokens};
|
use quote::{ToTokens, Tokens};
|
||||||
|
|
||||||
pub enum Fragment {
|
pub enum Fragment {
|
||||||
/// Tokens that can be used as an expression.
|
/// Tokens that can be used as an expression.
|
||||||
|
|||||||
@@ -23,16 +23,14 @@
|
|||||||
//! [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.24")]
|
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.24")]
|
||||||
|
|
||||||
#![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]
|
#![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]
|
||||||
#![cfg_attr(feature = "cargo-clippy", allow(used_underscore_binding))]
|
#![cfg_attr(feature = "cargo-clippy", allow(used_underscore_binding))]
|
||||||
|
|
||||||
// The `quote!` macro requires deep recursion.
|
// The `quote!` macro requires deep recursion.
|
||||||
#![recursion_limit = "192"]
|
#![recursion_limit = "192"]
|
||||||
|
|
||||||
extern crate syn;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate quote;
|
extern crate quote;
|
||||||
|
extern crate syn;
|
||||||
|
|
||||||
extern crate serde_derive_internals as internals;
|
extern crate serde_derive_internals as internals;
|
||||||
|
|
||||||
|
|||||||
+61
-101
@@ -10,7 +10,7 @@ use syn::{self, Ident};
|
|||||||
use quote::Tokens;
|
use quote::Tokens;
|
||||||
|
|
||||||
use bound;
|
use bound;
|
||||||
use fragment::{Fragment, Stmts, Match};
|
use fragment::{Fragment, Match, Stmts};
|
||||||
use internals::ast::{Body, Container, Field, Style, Variant};
|
use internals::ast::{Body, Container, Field, Style, Variant};
|
||||||
use internals::{attr, Ctxt};
|
use internals::{attr, Ctxt};
|
||||||
|
|
||||||
@@ -132,14 +132,12 @@ fn build_generics(cont: &Container) -> syn::Generics {
|
|||||||
|
|
||||||
match cont.attrs.ser_bound() {
|
match cont.attrs.ser_bound() {
|
||||||
Some(predicates) => bound::with_where_predicates(&generics, predicates),
|
Some(predicates) => bound::with_where_predicates(&generics, predicates),
|
||||||
None => {
|
None => bound::with_bound(
|
||||||
bound::with_bound(
|
|
||||||
cont,
|
cont,
|
||||||
&generics,
|
&generics,
|
||||||
needs_serialize_bound,
|
needs_serialize_bound,
|
||||||
&path!(_serde::Serialize),
|
&path!(_serde::Serialize),
|
||||||
)
|
),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,10 +147,8 @@ fn build_generics(cont: &Container) -> syn::Generics {
|
|||||||
// their own bound so we do not generate one. All other fields may need a `T:
|
// 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.
|
// Serialize` bound where T is the type of the field.
|
||||||
fn needs_serialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
|
fn needs_serialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
|
||||||
!field.skip_serializing() &&
|
!field.skip_serializing() && field.serialize_with().is_none() && field.ser_bound().is_none()
|
||||||
field.serialize_with().is_none() &&
|
&& variant.map_or(true, |variant| variant.serialize_with().is_none())
|
||||||
field.ser_bound().is_none() &&
|
|
||||||
variant.map_or(true, |variant| variant.serialize_with().is_none())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_body(cont: &Container, params: &Parameters) -> Fragment {
|
fn serialize_body(cont: &Container, params: &Parameters) -> Fragment {
|
||||||
@@ -259,16 +255,14 @@ fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Contai
|
|||||||
let let_mut = mut_if(serialized_fields.peek().is_some());
|
let let_mut = mut_if(serialized_fields.peek().is_some());
|
||||||
|
|
||||||
let len = serialized_fields
|
let len = serialized_fields
|
||||||
.map(
|
.map(|field| match field.attrs.skip_serializing_if() {
|
||||||
|field| match field.attrs.skip_serializing_if() {
|
|
||||||
None => quote!(1),
|
None => quote!(1),
|
||||||
Some(path) => {
|
Some(path) => {
|
||||||
let ident = field.ident.clone().expect("struct has unnamed fields");
|
let ident = field.ident.clone().expect("struct has unnamed fields");
|
||||||
let field_expr = get_field(params, field, ident);
|
let field_expr = get_field(params, field, ident);
|
||||||
quote!(if #path(#field_expr) { 0 } else { 1 })
|
quote!(if #path(#field_expr) { 0 } else { 1 })
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
)
|
|
||||||
.fold(quote!(0), |sum, expr| quote!(#sum + #expr));
|
.fold(quote!(0), |sum, expr| quote!(#sum + #expr));
|
||||||
|
|
||||||
quote_block! {
|
quote_block! {
|
||||||
@@ -286,11 +280,9 @@ fn serialize_enum(params: &Parameters, variants: &[Variant], cattrs: &attr::Cont
|
|||||||
let arms: Vec<_> = variants
|
let arms: Vec<_> = variants
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(
|
.map(|(variant_index, variant)| {
|
||||||
|(variant_index, variant)| {
|
|
||||||
serialize_variant(params, variant, variant_index as u32, cattrs)
|
serialize_variant(params, variant, variant_index as u32, cattrs)
|
||||||
},
|
})
|
||||||
)
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
quote_expr! {
|
quote_expr! {
|
||||||
@@ -321,13 +313,7 @@ fn serialize_variant(
|
|||||||
let fields_pat = match variant.style {
|
let fields_pat = match variant.style {
|
||||||
Style::Unit => quote!(),
|
Style::Unit => quote!(),
|
||||||
Style::Newtype | Style::Tuple => quote!((..)),
|
Style::Newtype | Style::Tuple => quote!((..)),
|
||||||
Style::Struct => {
|
Style::Struct => quote!({ .. }),
|
||||||
quote!(
|
|
||||||
{
|
|
||||||
..
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
quote! {
|
quote! {
|
||||||
#this::#variant_ident #fields_pat => #skipped_err,
|
#this::#variant_ident #fields_pat => #skipped_err,
|
||||||
@@ -356,21 +342,14 @@ fn serialize_variant(
|
|||||||
let fields = variant
|
let fields = variant
|
||||||
.fields
|
.fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(
|
.map(|f| f.ident.clone().expect("struct variant has unnamed fields"));
|
||||||
|f| {
|
|
||||||
f.ident
|
|
||||||
.clone()
|
|
||||||
.expect("struct variant has unnamed fields")
|
|
||||||
},
|
|
||||||
);
|
|
||||||
quote! {
|
quote! {
|
||||||
#this::#variant_ident { #(ref #fields),* }
|
#this::#variant_ident { #(ref #fields),* }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let body = Match(
|
let body = Match(match *cattrs.tag() {
|
||||||
match *cattrs.tag() {
|
|
||||||
attr::EnumTag::External => {
|
attr::EnumTag::External => {
|
||||||
serialize_externally_tagged_variant(params, variant, variant_index, cattrs)
|
serialize_externally_tagged_variant(params, variant, variant_index, cattrs)
|
||||||
}
|
}
|
||||||
@@ -382,8 +361,7 @@ fn serialize_variant(
|
|||||||
ref content,
|
ref content,
|
||||||
} => serialize_adjacently_tagged_variant(params, variant, cattrs, tag, content),
|
} => serialize_adjacently_tagged_variant(params, variant, cattrs, tag, content),
|
||||||
attr::EnumTag::None => serialize_untagged_variant(params, variant, cattrs),
|
attr::EnumTag::None => serialize_untagged_variant(params, variant, cattrs),
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#case => #body
|
#case => #body
|
||||||
@@ -441,8 +419,7 @@ fn serialize_externally_tagged_variant(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Style::Tuple => {
|
Style::Tuple => serialize_tuple_variant(
|
||||||
serialize_tuple_variant(
|
|
||||||
TupleVariant::ExternallyTagged {
|
TupleVariant::ExternallyTagged {
|
||||||
type_name: type_name,
|
type_name: type_name,
|
||||||
variant_index: variant_index,
|
variant_index: variant_index,
|
||||||
@@ -450,10 +427,8 @@ fn serialize_externally_tagged_variant(
|
|||||||
},
|
},
|
||||||
params,
|
params,
|
||||||
&variant.fields,
|
&variant.fields,
|
||||||
)
|
),
|
||||||
}
|
Style::Struct => serialize_struct_variant(
|
||||||
Style::Struct => {
|
|
||||||
serialize_struct_variant(
|
|
||||||
StructVariant::ExternallyTagged {
|
StructVariant::ExternallyTagged {
|
||||||
variant_index: variant_index,
|
variant_index: variant_index,
|
||||||
variant_name: variant_name,
|
variant_name: variant_name,
|
||||||
@@ -461,8 +436,7 @@ fn serialize_externally_tagged_variant(
|
|||||||
params,
|
params,
|
||||||
&variant.fields,
|
&variant.fields,
|
||||||
&type_name,
|
&type_name,
|
||||||
)
|
),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -520,8 +494,7 @@ fn serialize_internally_tagged_variant(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Style::Struct => {
|
Style::Struct => serialize_struct_variant(
|
||||||
serialize_struct_variant(
|
|
||||||
StructVariant::InternallyTagged {
|
StructVariant::InternallyTagged {
|
||||||
tag: tag,
|
tag: tag,
|
||||||
variant_name: variant_name,
|
variant_name: variant_name,
|
||||||
@@ -529,8 +502,7 @@ fn serialize_internally_tagged_variant(
|
|||||||
params,
|
params,
|
||||||
&variant.fields,
|
&variant.fields,
|
||||||
&type_name,
|
&type_name,
|
||||||
)
|
),
|
||||||
}
|
|
||||||
Style::Tuple => unreachable!("checked in serde_derive_internals"),
|
Style::Tuple => unreachable!("checked in serde_derive_internals"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -546,8 +518,7 @@ fn serialize_adjacently_tagged_variant(
|
|||||||
let type_name = cattrs.name().serialize_name();
|
let type_name = cattrs.name().serialize_name();
|
||||||
let variant_name = variant.attrs.name().serialize_name();
|
let variant_name = variant.attrs.name().serialize_name();
|
||||||
|
|
||||||
let inner = Stmts(
|
let inner = Stmts(if let Some(path) = variant.attrs.serialize_with() {
|
||||||
if let Some(path) = variant.attrs.serialize_with() {
|
|
||||||
let ser = wrap_serialize_variant_with(params, path, &variant);
|
let ser = wrap_serialize_variant_with(params, path, &variant);
|
||||||
quote_expr! {
|
quote_expr! {
|
||||||
_serde::Serialize::serialize(#ser, __serializer)
|
_serde::Serialize::serialize(#ser, __serializer)
|
||||||
@@ -577,17 +548,14 @@ fn serialize_adjacently_tagged_variant(
|
|||||||
Style::Tuple => {
|
Style::Tuple => {
|
||||||
serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields)
|
serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields)
|
||||||
}
|
}
|
||||||
Style::Struct => {
|
Style::Struct => serialize_struct_variant(
|
||||||
serialize_struct_variant(
|
|
||||||
StructVariant::Untagged,
|
StructVariant::Untagged,
|
||||||
params,
|
params,
|
||||||
&variant.fields,
|
&variant.fields,
|
||||||
&variant_name,
|
&variant_name,
|
||||||
)
|
),
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
let fields_ty = variant.fields.iter().map(|f| &f.ty);
|
let fields_ty = variant.fields.iter().map(|f| &f.ty);
|
||||||
let ref fields_ident: Vec<_> = match variant.style {
|
let ref fields_ident: Vec<_> = match variant.style {
|
||||||
@@ -599,24 +567,14 @@ fn serialize_adjacently_tagged_variant(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Style::Newtype => vec![Ident::new("__field0")],
|
Style::Newtype => vec![Ident::new("__field0")],
|
||||||
Style::Tuple => {
|
Style::Tuple => (0..variant.fields.len())
|
||||||
(0..variant.fields.len())
|
|
||||||
.map(|i| Ident::new(format!("__field{}", i)))
|
.map(|i| Ident::new(format!("__field{}", i)))
|
||||||
.collect()
|
.collect(),
|
||||||
}
|
Style::Struct => variant
|
||||||
Style::Struct => {
|
|
||||||
variant
|
|
||||||
.fields
|
.fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(
|
.map(|f| f.ident.clone().expect("struct variant has unnamed fields"))
|
||||||
|f| {
|
.collect(),
|
||||||
f.ident
|
|
||||||
.clone()
|
|
||||||
.expect("struct variant has unnamed fields")
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let (_, ty_generics, where_clause) = params.generics.split_for_impl();
|
let (_, ty_generics, where_clause) = params.generics.split_for_impl();
|
||||||
@@ -753,7 +711,10 @@ enum StructVariant<'a> {
|
|||||||
variant_index: u32,
|
variant_index: u32,
|
||||||
variant_name: String,
|
variant_name: String,
|
||||||
},
|
},
|
||||||
InternallyTagged { tag: &'a str, variant_name: String },
|
InternallyTagged {
|
||||||
|
tag: &'a str,
|
||||||
|
variant_name: String,
|
||||||
|
},
|
||||||
Untagged,
|
Untagged,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -764,19 +725,14 @@ fn serialize_struct_variant<'a>(
|
|||||||
name: &str,
|
name: &str,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let (method, skip_method) = match context {
|
let (method, skip_method) = match context {
|
||||||
StructVariant::ExternallyTagged { .. } => {
|
StructVariant::ExternallyTagged { .. } => (
|
||||||
(
|
|
||||||
quote!(_serde::ser::SerializeStructVariant::serialize_field),
|
quote!(_serde::ser::SerializeStructVariant::serialize_field),
|
||||||
quote!(_serde::ser::SerializeStructVariant::skip_field),
|
quote!(_serde::ser::SerializeStructVariant::skip_field),
|
||||||
)
|
),
|
||||||
}
|
StructVariant::InternallyTagged { .. } | StructVariant::Untagged => (
|
||||||
StructVariant::InternallyTagged { .. } |
|
|
||||||
StructVariant::Untagged => {
|
|
||||||
(
|
|
||||||
quote!(_serde::ser::SerializeStruct::serialize_field),
|
quote!(_serde::ser::SerializeStruct::serialize_field),
|
||||||
quote!(_serde::ser::SerializeStruct::skip_field),
|
quote!(_serde::ser::SerializeStruct::skip_field),
|
||||||
)
|
),
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let serialize_fields = serialize_struct_visitor(fields, params, true, method, skip_method);
|
let serialize_fields = serialize_struct_visitor(fields, params, true, method, skip_method);
|
||||||
@@ -789,16 +745,14 @@ fn serialize_struct_variant<'a>(
|
|||||||
let let_mut = mut_if(serialized_fields.peek().is_some());
|
let let_mut = mut_if(serialized_fields.peek().is_some());
|
||||||
|
|
||||||
let len = serialized_fields
|
let len = serialized_fields
|
||||||
.map(
|
.map(|field| {
|
||||||
|field| {
|
|
||||||
let ident = field.ident.clone().expect("struct has unnamed fields");
|
let ident = field.ident.clone().expect("struct has unnamed fields");
|
||||||
|
|
||||||
match field.attrs.skip_serializing_if() {
|
match field.attrs.skip_serializing_if() {
|
||||||
Some(path) => quote!(if #path(#ident) { 0 } else { 1 }),
|
Some(path) => quote!(if #path(#ident) { 0 } else { 1 }),
|
||||||
None => quote!(1),
|
None => quote!(1),
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
)
|
|
||||||
.fold(quote!(0), |sum, expr| quote!(#sum + #expr));
|
.fold(quote!(0), |sum, expr| quote!(#sum + #expr));
|
||||||
|
|
||||||
match context {
|
match context {
|
||||||
@@ -857,8 +811,7 @@ fn serialize_tuple_struct_visitor(
|
|||||||
fields
|
fields
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(
|
.map(|(i, field)| {
|
||||||
|(i, field)| {
|
|
||||||
let mut field_expr = if is_enum {
|
let mut field_expr = if is_enum {
|
||||||
let id = Ident::new(format!("__field{}", i));
|
let id = Ident::new(format!("__field{}", i));
|
||||||
quote!(#id)
|
quote!(#id)
|
||||||
@@ -883,8 +836,7 @@ fn serialize_tuple_struct_visitor(
|
|||||||
None => ser,
|
None => ser,
|
||||||
Some(skip) => quote!(if !#skip { #ser }),
|
Some(skip) => quote!(if !#skip { #ser }),
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
)
|
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -898,8 +850,7 @@ fn serialize_struct_visitor(
|
|||||||
fields
|
fields
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|&field| !field.attrs.skip_serializing())
|
.filter(|&field| !field.attrs.skip_serializing())
|
||||||
.map(
|
.map(|field| {
|
||||||
|field| {
|
|
||||||
let field_ident = field.ident.clone().expect("struct has unnamed field");
|
let field_ident = field.ident.clone().expect("struct has unnamed field");
|
||||||
let mut field_expr = if is_enum {
|
let mut field_expr = if is_enum {
|
||||||
quote!(#field_ident)
|
quote!(#field_ident)
|
||||||
@@ -934,8 +885,7 @@ fn serialize_struct_visitor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
)
|
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -945,10 +895,7 @@ fn wrap_serialize_field_with(
|
|||||||
serialize_with: &syn::Path,
|
serialize_with: &syn::Path,
|
||||||
field_expr: Tokens,
|
field_expr: Tokens,
|
||||||
) -> Tokens {
|
) -> Tokens {
|
||||||
wrap_serialize_with(params,
|
wrap_serialize_with(params, serialize_with, &[field_ty], &[quote!(#field_expr)])
|
||||||
serialize_with,
|
|
||||||
&[field_ty],
|
|
||||||
&[quote!(#field_expr)])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wrap_serialize_variant_with(
|
fn wrap_serialize_variant_with(
|
||||||
@@ -957,15 +904,24 @@ fn wrap_serialize_variant_with(
|
|||||||
variant: &Variant,
|
variant: &Variant,
|
||||||
) -> Tokens {
|
) -> Tokens {
|
||||||
let field_tys: Vec<_> = variant.fields.iter().map(|field| field.ty).collect();
|
let field_tys: Vec<_> = variant.fields.iter().map(|field| field.ty).collect();
|
||||||
let field_exprs: Vec<_> = variant.fields.iter()
|
let field_exprs: Vec<_> = variant
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, field)| {
|
.map(|(i, field)| {
|
||||||
let id = field.ident.as_ref().map_or_else(|| Ident::new(format!("__field{}", i)),
|
let id = field
|
||||||
|id| id.clone());
|
.ident
|
||||||
|
.as_ref()
|
||||||
|
.map_or_else(|| Ident::new(format!("__field{}", i)), |id| id.clone());
|
||||||
quote!(#id)
|
quote!(#id)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
wrap_serialize_with(params, serialize_with, field_tys.as_slice(), field_exprs.as_slice())
|
wrap_serialize_with(
|
||||||
|
params,
|
||||||
|
serialize_with,
|
||||||
|
field_tys.as_slice(),
|
||||||
|
field_exprs.as_slice(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wrap_serialize_with(
|
fn wrap_serialize_with(
|
||||||
@@ -1014,7 +970,11 @@ fn wrap_serialize_with(
|
|||||||
//
|
//
|
||||||
// where we want to omit the `mut` to avoid a warning.
|
// where we want to omit the `mut` to avoid a warning.
|
||||||
fn mut_if(is_mut: bool) -> Option<Tokens> {
|
fn mut_if(is_mut: bool) -> Option<Tokens> {
|
||||||
if is_mut { Some(quote!(mut)) } else { None }
|
if is_mut {
|
||||||
|
Some(quote!(mut))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_field<I>(params: &Parameters, field: &Field, ident: I) -> Tokens
|
fn get_field<I>(params: &Parameters, field: &Field, ident: I) -> Tokens
|
||||||
|
|||||||
@@ -59,19 +59,15 @@ impl<'a> Container<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match body {
|
match body {
|
||||||
Body::Enum(ref mut variants) => {
|
Body::Enum(ref mut variants) => for ref mut variant in variants {
|
||||||
for ref mut variant in variants {
|
|
||||||
variant.attrs.rename_by_rule(attrs.rename_all());
|
variant.attrs.rename_by_rule(attrs.rename_all());
|
||||||
for ref mut field in &mut variant.fields {
|
for ref mut field in &mut variant.fields {
|
||||||
field.attrs.rename_by_rule(variant.attrs.rename_all());
|
field.attrs.rename_by_rule(variant.attrs.rename_all());
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
Body::Struct(_, ref mut fields) => for field in fields {
|
||||||
Body::Struct(_, ref mut fields) => {
|
|
||||||
for field in fields {
|
|
||||||
field.attrs.rename_by_rule(attrs.rename_all());
|
field.attrs.rename_by_rule(attrs.rename_all());
|
||||||
}
|
},
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let item = Container {
|
let item = Container {
|
||||||
@@ -128,16 +124,18 @@ fn struct_from_ast<'a>(
|
|||||||
container_default: &attr::Default,
|
container_default: &attr::Default,
|
||||||
) -> (Style, Vec<Field<'a>>) {
|
) -> (Style, Vec<Field<'a>>) {
|
||||||
match *data {
|
match *data {
|
||||||
syn::VariantData::Struct(ref fields) => {
|
syn::VariantData::Struct(ref fields) => (
|
||||||
(Style::Struct, fields_from_ast(cx, fields, attrs, container_default))
|
Style::Struct,
|
||||||
}
|
fields_from_ast(cx, fields, attrs, container_default),
|
||||||
|
),
|
||||||
syn::VariantData::Tuple(ref fields) if fields.len() == 1 => (
|
syn::VariantData::Tuple(ref fields) if fields.len() == 1 => (
|
||||||
Style::Newtype,
|
Style::Newtype,
|
||||||
fields_from_ast(cx, fields, attrs, container_default),
|
fields_from_ast(cx, fields, attrs, container_default),
|
||||||
),
|
),
|
||||||
syn::VariantData::Tuple(ref fields) => {
|
syn::VariantData::Tuple(ref fields) => (
|
||||||
(Style::Tuple, fields_from_ast(cx, fields, attrs, container_default))
|
Style::Tuple,
|
||||||
}
|
fields_from_ast(cx, fields, attrs, container_default),
|
||||||
|
),
|
||||||
syn::VariantData::Unit => (Style::Unit, Vec::new()),
|
syn::VariantData::Unit => (Style::Unit, Vec::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -151,14 +149,10 @@ fn fields_from_ast<'a>(
|
|||||||
fields
|
fields
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(
|
.map(|(i, field)| Field {
|
||||||
|(i, field)| {
|
|
||||||
Field {
|
|
||||||
ident: field.ident.clone(),
|
ident: field.ident.clone(),
|
||||||
attrs: attr::Field::from_ast(cx, i, field, attrs, container_default),
|
attrs: attr::Field::from_ast(cx, i, field, attrs, container_default),
|
||||||
ty: &field.ty,
|
ty: &field.ty,
|
||||||
}
|
})
|
||||||
},
|
|
||||||
)
|
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -216,11 +216,11 @@ impl Container {
|
|||||||
if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
|
if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
|
||||||
match RenameRule::from_str(&s) {
|
match RenameRule::from_str(&s) {
|
||||||
Ok(rename_rule) => rename_all.set(rename_rule),
|
Ok(rename_rule) => rename_all.set(rename_rule),
|
||||||
Err(()) => {
|
Err(()) => cx.error(format!(
|
||||||
cx.error(format!("unknown rename rule for #[serde(rename_all \
|
"unknown rename rule for #[serde(rename_all \
|
||||||
= {:?})]",
|
= {:?})]",
|
||||||
s))
|
s
|
||||||
}
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -231,19 +231,15 @@ impl Container {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(default)]`
|
// Parse `#[serde(default)]`
|
||||||
MetaItem(Word(ref name)) if name == "default" => {
|
MetaItem(Word(ref name)) if name == "default" => match item.body {
|
||||||
match item.body {
|
|
||||||
syn::Body::Struct(syn::VariantData::Struct(_)) => {
|
syn::Body::Struct(syn::VariantData::Struct(_)) => {
|
||||||
default.set(Default::Default);
|
default.set(Default::Default);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => cx.error(
|
||||||
cx.error(
|
|
||||||
"#[serde(default)] can only be used on structs \
|
"#[serde(default)] can only be used on structs \
|
||||||
with named fields",
|
with named fields",
|
||||||
)
|
),
|
||||||
}
|
},
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse `#[serde(default = "...")]`
|
// Parse `#[serde(default = "...")]`
|
||||||
MetaItem(NameValue(ref name, ref lit)) if name == "default" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "default" => {
|
||||||
@@ -252,12 +248,10 @@ impl Container {
|
|||||||
syn::Body::Struct(syn::VariantData::Struct(_)) => {
|
syn::Body::Struct(syn::VariantData::Struct(_)) => {
|
||||||
default.set(Default::Path(path));
|
default.set(Default::Path(path));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => cx.error(
|
||||||
cx.error(
|
|
||||||
"#[serde(default = \"...\")] can only be used \
|
"#[serde(default = \"...\")] can only be used \
|
||||||
on structs with named fields",
|
on structs with named fields",
|
||||||
)
|
),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -265,7 +259,8 @@ impl Container {
|
|||||||
// Parse `#[serde(bound = "D: Serialize")]`
|
// Parse `#[serde(bound = "D: Serialize")]`
|
||||||
MetaItem(NameValue(ref name, ref lit)) if name == "bound" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "bound" => {
|
||||||
if let Ok(where_predicates) =
|
if let Ok(where_predicates) =
|
||||||
parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit) {
|
parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit)
|
||||||
|
{
|
||||||
ser_bound.set(where_predicates.clone());
|
ser_bound.set(where_predicates.clone());
|
||||||
de_bound.set(where_predicates);
|
de_bound.set(where_predicates);
|
||||||
}
|
}
|
||||||
@@ -280,16 +275,14 @@ impl Container {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(untagged)]`
|
// Parse `#[serde(untagged)]`
|
||||||
MetaItem(Word(ref name)) if name == "untagged" => {
|
MetaItem(Word(ref name)) if name == "untagged" => match item.body {
|
||||||
match item.body {
|
|
||||||
syn::Body::Enum(_) => {
|
syn::Body::Enum(_) => {
|
||||||
untagged.set_true();
|
untagged.set_true();
|
||||||
}
|
}
|
||||||
syn::Body::Struct(_) => {
|
syn::Body::Struct(_) => {
|
||||||
cx.error("#[serde(untagged)] can only be used on enums")
|
cx.error("#[serde(untagged)] can only be used on enums")
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
|
|
||||||
// Parse `#[serde(tag = "type")]`
|
// Parse `#[serde(tag = "type")]`
|
||||||
MetaItem(NameValue(ref name, ref lit)) if name == "tag" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "tag" => {
|
||||||
@@ -312,12 +305,10 @@ impl Container {
|
|||||||
syn::Body::Enum(_) => {
|
syn::Body::Enum(_) => {
|
||||||
content.set(s);
|
content.set(s);
|
||||||
}
|
}
|
||||||
syn::Body::Struct(_) => {
|
syn::Body::Struct(_) => cx.error(
|
||||||
cx.error(
|
|
||||||
"#[serde(content = \"...\")] can only be used on \
|
"#[serde(content = \"...\")] can only be used on \
|
||||||
enums",
|
enums",
|
||||||
)
|
),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -354,8 +345,10 @@ impl Container {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MetaItem(ref meta_item) => {
|
MetaItem(ref meta_item) => {
|
||||||
cx.error(format!("unknown serde container attribute `{}`",
|
cx.error(format!(
|
||||||
meta_item.name()));
|
"unknown serde container attribute `{}`",
|
||||||
|
meta_item.name()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Literal(_) => {
|
Literal(_) => {
|
||||||
@@ -443,8 +436,7 @@ fn decide_tag(
|
|||||||
if let syn::Body::Enum(ref variants) = item.body {
|
if let syn::Body::Enum(ref variants) = item.body {
|
||||||
for variant in variants {
|
for variant in variants {
|
||||||
match variant.data {
|
match variant.data {
|
||||||
syn::VariantData::Struct(_) |
|
syn::VariantData::Struct(_) | syn::VariantData::Unit => {}
|
||||||
syn::VariantData::Unit => {}
|
|
||||||
syn::VariantData::Tuple(ref fields) => {
|
syn::VariantData::Tuple(ref fields) => {
|
||||||
if fields.len() != 1 {
|
if fields.len() != 1 {
|
||||||
cx.error(
|
cx.error(
|
||||||
@@ -464,21 +456,19 @@ fn decide_tag(
|
|||||||
EnumTag::External // doesn't matter, will error
|
EnumTag::External // doesn't matter, will error
|
||||||
}
|
}
|
||||||
(false, None, Some(_)) => {
|
(false, None, Some(_)) => {
|
||||||
cx.error("#[serde(tag = \"...\", content = \"...\")] must be used together",);
|
cx.error("#[serde(tag = \"...\", content = \"...\")] must be used together");
|
||||||
EnumTag::External
|
EnumTag::External
|
||||||
}
|
}
|
||||||
(true, None, Some(_)) => {
|
(true, None, Some(_)) => {
|
||||||
cx.error("untagged enum cannot have #[serde(content = \"...\")]");
|
cx.error("untagged enum cannot have #[serde(content = \"...\")]");
|
||||||
EnumTag::External
|
EnumTag::External
|
||||||
}
|
}
|
||||||
(false, Some(tag), Some(content)) => {
|
(false, Some(tag), Some(content)) => EnumTag::Adjacent {
|
||||||
EnumTag::Adjacent {
|
|
||||||
tag: tag,
|
tag: tag,
|
||||||
content: content,
|
content: content,
|
||||||
}
|
},
|
||||||
}
|
|
||||||
(true, Some(_), Some(_)) => {
|
(true, Some(_), Some(_)) => {
|
||||||
cx.error("untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]",);
|
cx.error("untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]");
|
||||||
EnumTag::External
|
EnumTag::External
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -493,7 +483,7 @@ fn decide_identifier(
|
|||||||
match (&item.body, field_identifier.get(), variant_identifier.get()) {
|
match (&item.body, field_identifier.get(), variant_identifier.get()) {
|
||||||
(_, false, false) => Identifier::No,
|
(_, false, false) => Identifier::No,
|
||||||
(_, true, true) => {
|
(_, true, true) => {
|
||||||
cx.error("`field_identifier` and `variant_identifier` cannot both be set",);
|
cx.error("`field_identifier` and `variant_identifier` cannot both be set");
|
||||||
Identifier::No
|
Identifier::No
|
||||||
}
|
}
|
||||||
(&syn::Body::Struct(_), true, false) => {
|
(&syn::Body::Struct(_), true, false) => {
|
||||||
@@ -560,11 +550,11 @@ impl Variant {
|
|||||||
if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
|
if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
|
||||||
match RenameRule::from_str(&s) {
|
match RenameRule::from_str(&s) {
|
||||||
Ok(rename_rule) => rename_all.set(rename_rule),
|
Ok(rename_rule) => rename_all.set(rename_rule),
|
||||||
Err(()) => {
|
Err(()) => cx.error(format!(
|
||||||
cx.error(format!("unknown rename rule for #[serde(rename_all \
|
"unknown rename rule for #[serde(rename_all \
|
||||||
= {:?})]",
|
= {:?})]",
|
||||||
s))
|
s
|
||||||
}
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -611,19 +601,20 @@ impl Variant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Defer `#[serde(borrow)]` and `#[serde(borrow = "'a + 'b")]`
|
// Defer `#[serde(borrow)]` and `#[serde(borrow = "'a + 'b")]`
|
||||||
MetaItem(ref mi) if mi.name() == "borrow" => {
|
MetaItem(ref mi) if mi.name() == "borrow" => match variant.data {
|
||||||
match variant.data {
|
|
||||||
syn::VariantData::Tuple(ref fields) if fields.len() == 1 => {
|
syn::VariantData::Tuple(ref fields) if fields.len() == 1 => {
|
||||||
borrow.set(mi.clone());
|
borrow.set(mi.clone());
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
cx.error("#[serde(borrow)] may only be used on newtype variants");
|
cx.error("#[serde(borrow)] may only be used on newtype variants");
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
|
|
||||||
MetaItem(ref meta_item) => {
|
MetaItem(ref meta_item) => {
|
||||||
cx.error(format!("unknown serde variant attribute `{}`", meta_item.name()));
|
cx.error(format!(
|
||||||
|
"unknown serde variant attribute `{}`",
|
||||||
|
meta_item.name()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Literal(_) => {
|
Literal(_) => {
|
||||||
@@ -754,7 +745,12 @@ impl Field {
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|borrow| vec![MetaItem(borrow.clone())]);
|
.map(|borrow| vec![MetaItem(borrow.clone())]);
|
||||||
|
|
||||||
for meta_items in field.attrs.iter().filter_map(get_serde_meta_items).chain(variant_borrow) {
|
for meta_items in field
|
||||||
|
.attrs
|
||||||
|
.iter()
|
||||||
|
.filter_map(get_serde_meta_items)
|
||||||
|
.chain(variant_borrow)
|
||||||
|
{
|
||||||
for meta_item in meta_items {
|
for meta_item in meta_items {
|
||||||
match meta_item {
|
match meta_item {
|
||||||
// Parse `#[serde(rename = "foo")]`
|
// Parse `#[serde(rename = "foo")]`
|
||||||
@@ -799,7 +795,7 @@ impl Field {
|
|||||||
MetaItem(Word(ref name)) if name == "skip" => {
|
MetaItem(Word(ref name)) if name == "skip" => {
|
||||||
skip_serializing.set_true();
|
skip_serializing.set_true();
|
||||||
skip_deserializing.set_true();
|
skip_deserializing.set_true();
|
||||||
},
|
}
|
||||||
|
|
||||||
// Parse `#[serde(skip_serializing_if = "...")]`
|
// Parse `#[serde(skip_serializing_if = "...")]`
|
||||||
MetaItem(NameValue(ref name, ref lit)) if name == "skip_serializing_if" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "skip_serializing_if" => {
|
||||||
@@ -837,7 +833,8 @@ impl Field {
|
|||||||
// Parse `#[serde(bound = "D: Serialize")]`
|
// Parse `#[serde(bound = "D: Serialize")]`
|
||||||
MetaItem(NameValue(ref name, ref lit)) if name == "bound" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "bound" => {
|
||||||
if let Ok(where_predicates) =
|
if let Ok(where_predicates) =
|
||||||
parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit) {
|
parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit)
|
||||||
|
{
|
||||||
ser_bound.set(where_predicates.clone());
|
ser_bound.set(where_predicates.clone());
|
||||||
de_bound.set(where_predicates);
|
de_bound.set(where_predicates);
|
||||||
}
|
}
|
||||||
@@ -864,13 +861,10 @@ impl Field {
|
|||||||
if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, &field.ty) {
|
if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, &field.ty) {
|
||||||
for lifetime in &lifetimes {
|
for lifetime in &lifetimes {
|
||||||
if !borrowable.contains(lifetime) {
|
if !borrowable.contains(lifetime) {
|
||||||
cx.error(
|
cx.error(format!(
|
||||||
format!(
|
|
||||||
"field `{}` does not have lifetime {}",
|
"field `{}` does not have lifetime {}",
|
||||||
ident,
|
ident, lifetime.ident
|
||||||
lifetime.ident
|
));
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
borrowed_lifetimes.set(lifetimes);
|
borrowed_lifetimes.set(lifetimes);
|
||||||
@@ -886,7 +880,10 @@ impl Field {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MetaItem(ref meta_item) => {
|
MetaItem(ref meta_item) => {
|
||||||
cx.error(format!("unknown serde field attribute `{}`", meta_item.name()),);
|
cx.error(format!(
|
||||||
|
"unknown serde field attribute `{}`",
|
||||||
|
meta_item.name()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Literal(_) => {
|
Literal(_) => {
|
||||||
@@ -1034,13 +1031,11 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
cx.error(
|
cx.error(format!(
|
||||||
format!(
|
|
||||||
"malformed {0} attribute, expected `{0}(serialize = ..., \
|
"malformed {0} attribute, expected `{0}(serialize = ..., \
|
||||||
deserialize = ...)`",
|
deserialize = ...)`",
|
||||||
attr_name
|
attr_name
|
||||||
),
|
));
|
||||||
);
|
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1076,13 +1071,10 @@ fn get_string_from_lit(
|
|||||||
if let syn::Lit::Str(ref s, _) = *lit {
|
if let syn::Lit::Str(ref s, _) = *lit {
|
||||||
Ok(s.clone())
|
Ok(s.clone())
|
||||||
} else {
|
} else {
|
||||||
cx.error(
|
cx.error(format!(
|
||||||
format!(
|
|
||||||
"expected serde {} attribute to be a string: `{} = \"...\"`",
|
"expected serde {} attribute to be a string: `{} = \"...\"`",
|
||||||
attr_name,
|
attr_name, meta_item_name
|
||||||
meta_item_name
|
));
|
||||||
),
|
|
||||||
);
|
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1113,11 +1105,12 @@ fn parse_lit_into_where(
|
|||||||
fn parse_lit_into_ty(cx: &Ctxt, attr_name: &str, lit: &syn::Lit) -> Result<syn::Ty, ()> {
|
fn parse_lit_into_ty(cx: &Ctxt, attr_name: &str, lit: &syn::Lit) -> Result<syn::Ty, ()> {
|
||||||
let string = try!(get_string_from_lit(cx, attr_name, attr_name, lit));
|
let string = try!(get_string_from_lit(cx, attr_name, attr_name, lit));
|
||||||
|
|
||||||
syn::parse_type(&string).map_err(
|
syn::parse_type(&string).map_err(|_| {
|
||||||
|_| {
|
cx.error(format!(
|
||||||
cx.error(format!("failed to parse type: {} = {:?}", attr_name, string),)
|
"failed to parse type: {} = {:?}",
|
||||||
},
|
attr_name, string
|
||||||
)
|
))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parses a string literal like "'a + 'b + 'c" containing a nonempty list of
|
// Parses a string literal like "'a + 'b + 'c" containing a nonempty list of
|
||||||
@@ -1148,7 +1141,7 @@ fn parse_lit_into_lifetimes(
|
|||||||
return Ok(set);
|
return Ok(set);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(cx.error(format!("failed to parse borrowed lifetimes: {:?}", string)),)
|
Err(cx.error(format!("failed to parse borrowed lifetimes: {:?}", string)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Whether the type looks like it might be `std::borrow::Cow<T>` where elem="T".
|
// Whether the type looks like it might be `std::borrow::Cow<T>` where elem="T".
|
||||||
@@ -1192,8 +1185,8 @@ fn is_cow(ty: &syn::Ty, elem: &str) -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
seg.ident == "Cow" && params.lifetimes.len() == 1 &&
|
seg.ident == "Cow" && params.lifetimes.len() == 1
|
||||||
params.types == vec![syn::parse_type(elem).unwrap()] && params.bindings.is_empty()
|
&& params.types == vec![syn::parse_type(elem).unwrap()] && params.bindings.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Whether the type looks like it might be `&T` where elem="T". This can have
|
// Whether the type looks like it might be `&T` where elem="T". This can have
|
||||||
@@ -1219,8 +1212,8 @@ fn is_cow(ty: &syn::Ty, elem: &str) -> bool {
|
|||||||
fn is_rptr(ty: &syn::Ty, elem: &str) -> bool {
|
fn is_rptr(ty: &syn::Ty, elem: &str) -> bool {
|
||||||
match *ty {
|
match *ty {
|
||||||
syn::Ty::Rptr(Some(_), ref mut_ty) => {
|
syn::Ty::Rptr(Some(_), ref mut_ty) => {
|
||||||
mut_ty.mutability == syn::Mutability::Immutable &&
|
mut_ty.mutability == syn::Mutability::Immutable
|
||||||
mut_ty.ty == syn::parse_type(elem).unwrap()
|
&& mut_ty.ty == syn::parse_type(elem).unwrap()
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
@@ -1241,7 +1234,7 @@ fn borrowable_lifetimes(
|
|||||||
let mut lifetimes = BTreeSet::new();
|
let mut lifetimes = BTreeSet::new();
|
||||||
collect_lifetimes(ty, &mut lifetimes);
|
collect_lifetimes(ty, &mut lifetimes);
|
||||||
if lifetimes.is_empty() {
|
if lifetimes.is_empty() {
|
||||||
Err(cx.error(format!("field `{}` has no lifetimes to borrow", name)),)
|
Err(cx.error(format!("field `{}` has no lifetimes to borrow", name)))
|
||||||
} else {
|
} else {
|
||||||
Ok(lifetimes)
|
Ok(lifetimes)
|
||||||
}
|
}
|
||||||
@@ -1249,9 +1242,7 @@ fn borrowable_lifetimes(
|
|||||||
|
|
||||||
fn collect_lifetimes(ty: &syn::Ty, out: &mut BTreeSet<syn::Lifetime>) {
|
fn collect_lifetimes(ty: &syn::Ty, out: &mut BTreeSet<syn::Lifetime>) {
|
||||||
match *ty {
|
match *ty {
|
||||||
syn::Ty::Slice(ref elem) |
|
syn::Ty::Slice(ref elem) | syn::Ty::Array(ref elem, _) | syn::Ty::Paren(ref elem) => {
|
||||||
syn::Ty::Array(ref elem, _) |
|
|
||||||
syn::Ty::Paren(ref elem) => {
|
|
||||||
collect_lifetimes(elem, out);
|
collect_lifetimes(elem, out);
|
||||||
}
|
}
|
||||||
syn::Ty::Ptr(ref elem) => {
|
syn::Ty::Ptr(ref elem) => {
|
||||||
@@ -1261,11 +1252,9 @@ fn collect_lifetimes(ty: &syn::Ty, out: &mut BTreeSet<syn::Lifetime>) {
|
|||||||
out.extend(lifetime.iter().cloned());
|
out.extend(lifetime.iter().cloned());
|
||||||
collect_lifetimes(&elem.ty, out);
|
collect_lifetimes(&elem.ty, out);
|
||||||
}
|
}
|
||||||
syn::Ty::Tup(ref elems) => {
|
syn::Ty::Tup(ref elems) => for elem in elems {
|
||||||
for elem in elems {
|
|
||||||
collect_lifetimes(elem, out);
|
collect_lifetimes(elem, out);
|
||||||
}
|
},
|
||||||
}
|
|
||||||
syn::Ty::Path(ref qself, ref path) => {
|
syn::Ty::Path(ref qself, ref path) => {
|
||||||
if let Some(ref qself) = *qself {
|
if let Some(ref qself) = *qself {
|
||||||
collect_lifetimes(&qself.ty, out);
|
collect_lifetimes(&qself.ty, out);
|
||||||
@@ -1282,11 +1271,11 @@ fn collect_lifetimes(ty: &syn::Ty, out: &mut BTreeSet<syn::Lifetime>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
syn::Ty::BareFn(_) |
|
syn::Ty::BareFn(_)
|
||||||
syn::Ty::Never |
|
| syn::Ty::Never
|
||||||
syn::Ty::TraitObject(_) |
|
| syn::Ty::TraitObject(_)
|
||||||
syn::Ty::ImplTrait(_) |
|
| syn::Ty::ImplTrait(_)
|
||||||
syn::Ty::Infer |
|
| syn::Ty::Infer
|
||||||
syn::Ty::Mac(_) => {}
|
| syn::Ty::Mac(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ pub enum RenameRule {
|
|||||||
/// Rename direct children to "kebab-case" style.
|
/// Rename direct children to "kebab-case" style.
|
||||||
KebabCase,
|
KebabCase,
|
||||||
/// Rename direct children to "SCREAMING-KEBAB-CASE" style.
|
/// Rename direct children to "SCREAMING-KEBAB-CASE" style.
|
||||||
ScreamingKebabCase
|
ScreamingKebabCase,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenameRule {
|
impl RenameRule {
|
||||||
@@ -52,7 +52,9 @@ impl RenameRule {
|
|||||||
}
|
}
|
||||||
ScreamingSnakeCase => SnakeCase.apply_to_variant(variant).to_ascii_uppercase(),
|
ScreamingSnakeCase => SnakeCase.apply_to_variant(variant).to_ascii_uppercase(),
|
||||||
KebabCase => SnakeCase.apply_to_variant(variant).replace('_', "-"),
|
KebabCase => SnakeCase.apply_to_variant(variant).replace('_', "-"),
|
||||||
ScreamingKebabCase => ScreamingSnakeCase.apply_to_variant(variant).replace('_', "-")
|
ScreamingKebabCase => ScreamingSnakeCase
|
||||||
|
.apply_to_variant(variant)
|
||||||
|
.replace('_', "-"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +82,7 @@ impl RenameRule {
|
|||||||
}
|
}
|
||||||
ScreamingSnakeCase => field.to_ascii_uppercase(),
|
ScreamingSnakeCase => field.to_ascii_uppercase(),
|
||||||
KebabCase => field.replace('_', "-"),
|
KebabCase => field.replace('_', "-"),
|
||||||
ScreamingKebabCase => ScreamingSnakeCase.apply_to_field(field).replace('_', "-")
|
ScreamingKebabCase => ScreamingSnakeCase.apply_to_field(field).replace('_', "-"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,10 +106,25 @@ impl FromStr for RenameRule {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rename_variants() {
|
fn rename_variants() {
|
||||||
for &(original, lower, camel, snake, screaming, kebab, screaming_kebab) in
|
for &(original, lower, camel, snake, screaming, kebab, screaming_kebab) in &[
|
||||||
&[
|
(
|
||||||
("Outcome", "outcome", "outcome", "outcome", "OUTCOME", "outcome", "OUTCOME"),
|
"Outcome",
|
||||||
("VeryTasty", "verytasty", "veryTasty", "very_tasty", "VERY_TASTY", "very-tasty", "VERY-TASTY"),
|
"outcome",
|
||||||
|
"outcome",
|
||||||
|
"outcome",
|
||||||
|
"OUTCOME",
|
||||||
|
"outcome",
|
||||||
|
"OUTCOME",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"VeryTasty",
|
||||||
|
"verytasty",
|
||||||
|
"veryTasty",
|
||||||
|
"very_tasty",
|
||||||
|
"VERY_TASTY",
|
||||||
|
"very-tasty",
|
||||||
|
"VERY-TASTY",
|
||||||
|
),
|
||||||
("A", "a", "a", "a", "A", "a", "A"),
|
("A", "a", "a", "a", "A", "a", "A"),
|
||||||
("Z42", "z42", "z42", "z42", "Z42", "z42", "Z42"),
|
("Z42", "z42", "z42", "z42", "Z42", "z42", "Z42"),
|
||||||
] {
|
] {
|
||||||
@@ -118,16 +135,32 @@ fn rename_variants() {
|
|||||||
assert_eq!(SnakeCase.apply_to_variant(original), snake);
|
assert_eq!(SnakeCase.apply_to_variant(original), snake);
|
||||||
assert_eq!(ScreamingSnakeCase.apply_to_variant(original), screaming);
|
assert_eq!(ScreamingSnakeCase.apply_to_variant(original), screaming);
|
||||||
assert_eq!(KebabCase.apply_to_variant(original), kebab);
|
assert_eq!(KebabCase.apply_to_variant(original), kebab);
|
||||||
assert_eq!(ScreamingKebabCase.apply_to_variant(original), screaming_kebab);
|
assert_eq!(
|
||||||
|
ScreamingKebabCase.apply_to_variant(original),
|
||||||
|
screaming_kebab
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rename_fields() {
|
fn rename_fields() {
|
||||||
for &(original, pascal, camel, screaming, kebab, screaming_kebab) in
|
for &(original, pascal, camel, screaming, kebab, screaming_kebab) in &[
|
||||||
&[
|
(
|
||||||
("outcome", "Outcome", "outcome", "OUTCOME", "outcome", "OUTCOME"),
|
"outcome",
|
||||||
("very_tasty", "VeryTasty", "veryTasty", "VERY_TASTY", "very-tasty", "VERY-TASTY"),
|
"Outcome",
|
||||||
|
"outcome",
|
||||||
|
"OUTCOME",
|
||||||
|
"outcome",
|
||||||
|
"OUTCOME",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"very_tasty",
|
||||||
|
"VeryTasty",
|
||||||
|
"veryTasty",
|
||||||
|
"VERY_TASTY",
|
||||||
|
"very-tasty",
|
||||||
|
"VERY-TASTY",
|
||||||
|
),
|
||||||
("a", "A", "a", "A", "a", "A"),
|
("a", "A", "a", "A", "a", "A"),
|
||||||
("z42", "Z42", "z42", "Z42", "z42", "Z42"),
|
("z42", "Z42", "z42", "Z42", "z42", "Z42"),
|
||||||
] {
|
] {
|
||||||
|
|||||||
@@ -53,10 +53,13 @@ fn check_identifier(cx: &Ctxt, cont: &Container) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (i, variant) in variants.iter().enumerate() {
|
for (i, variant) in variants.iter().enumerate() {
|
||||||
match (variant.style, cont.attrs.identifier(), variant.attrs.other()) {
|
match (
|
||||||
|
variant.style,
|
||||||
|
cont.attrs.identifier(),
|
||||||
|
variant.attrs.other(),
|
||||||
|
) {
|
||||||
// The `other` attribute may only be used in a field_identifier.
|
// The `other` attribute may only be used in a field_identifier.
|
||||||
(_, Identifier::Variant, true) |
|
(_, Identifier::Variant, true) | (_, Identifier::No, true) => {
|
||||||
(_, Identifier::No, true) => {
|
|
||||||
cx.error("#[serde(other)] may only be used inside a field_identifier");
|
cx.error("#[serde(other)] may only be used inside a field_identifier");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,42 +112,58 @@ fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
|
|||||||
for variant in variants.iter() {
|
for variant in variants.iter() {
|
||||||
if variant.attrs.serialize_with().is_some() {
|
if variant.attrs.serialize_with().is_some() {
|
||||||
if variant.attrs.skip_serializing() {
|
if variant.attrs.skip_serializing() {
|
||||||
cx.error(format!("variant `{}` cannot have both #[serde(serialize_with)] and \
|
cx.error(format!(
|
||||||
#[serde(skip_serializing)]", variant.ident));
|
"variant `{}` cannot have both #[serde(serialize_with)] and \
|
||||||
|
#[serde(skip_serializing)]",
|
||||||
|
variant.ident
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, field) in variant.fields.iter().enumerate() {
|
for (i, field) in variant.fields.iter().enumerate() {
|
||||||
let ident = field.ident.as_ref().map_or_else(|| format!("{}", i),
|
let ident = field
|
||||||
|ident| format!("`{}`", ident));
|
.ident
|
||||||
|
.as_ref()
|
||||||
|
.map_or_else(|| format!("{}", i), |ident| format!("`{}`", ident));
|
||||||
|
|
||||||
if field.attrs.skip_serializing() {
|
if field.attrs.skip_serializing() {
|
||||||
cx.error(format!("variant `{}` cannot have both #[serde(serialize_with)] and \
|
cx.error(format!(
|
||||||
|
"variant `{}` cannot have both #[serde(serialize_with)] and \
|
||||||
a field {} marked with #[serde(skip_serializing)]",
|
a field {} marked with #[serde(skip_serializing)]",
|
||||||
variant.ident, ident));
|
variant.ident, ident
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if field.attrs.skip_serializing_if().is_some() {
|
if field.attrs.skip_serializing_if().is_some() {
|
||||||
cx.error(format!("variant `{}` cannot have both #[serde(serialize_with)] and \
|
cx.error(format!(
|
||||||
|
"variant `{}` cannot have both #[serde(serialize_with)] and \
|
||||||
a field {} marked with #[serde(skip_serializing_if)]",
|
a field {} marked with #[serde(skip_serializing_if)]",
|
||||||
variant.ident, ident));
|
variant.ident, ident
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if variant.attrs.deserialize_with().is_some() {
|
if variant.attrs.deserialize_with().is_some() {
|
||||||
if variant.attrs.skip_deserializing() {
|
if variant.attrs.skip_deserializing() {
|
||||||
cx.error(format!("variant `{}` cannot have both #[serde(deserialize_with)] and \
|
cx.error(format!(
|
||||||
#[serde(skip_deserializing)]", variant.ident));
|
"variant `{}` cannot have both #[serde(deserialize_with)] and \
|
||||||
|
#[serde(skip_deserializing)]",
|
||||||
|
variant.ident
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, field) in variant.fields.iter().enumerate() {
|
for (i, field) in variant.fields.iter().enumerate() {
|
||||||
if field.attrs.skip_deserializing() {
|
if field.attrs.skip_deserializing() {
|
||||||
let ident = field.ident.as_ref().map_or_else(|| format!("{}", i),
|
let ident = field
|
||||||
|ident| format!("`{}`", ident));
|
.ident
|
||||||
|
.as_ref()
|
||||||
|
.map_or_else(|| format!("{}", i), |ident| format!("`{}`", ident));
|
||||||
|
|
||||||
cx.error(format!("variant `{}` cannot have both #[serde(deserialize_with)] \
|
cx.error(format!(
|
||||||
|
"variant `{}` cannot have both #[serde(deserialize_with)] \
|
||||||
and a field {} marked with #[serde(skip_deserializing)]",
|
and a field {} marked with #[serde(skip_deserializing)]",
|
||||||
variant.ident, ident));
|
variant.ident, ident
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ pub struct Ctxt {
|
|||||||
|
|
||||||
impl Ctxt {
|
impl Ctxt {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Ctxt { errors: RefCell::new(Some(Vec::new())) }
|
Ctxt {
|
||||||
|
errors: RefCell::new(Some(Vec::new())),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn error<T: Display>(&self, msg: T) {
|
pub fn error<T: Display>(&self, msg: T) {
|
||||||
|
|||||||
@@ -73,11 +73,17 @@ pub struct Compact<T: ?Sized>(T);
|
|||||||
/// ```
|
/// ```
|
||||||
pub trait Configure {
|
pub trait Configure {
|
||||||
/// Marks `self` as using `is_human_readable == true`
|
/// Marks `self` as using `is_human_readable == true`
|
||||||
fn readable(self) -> Readable<Self> where Self: Sized {
|
fn readable(self) -> Readable<Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
Readable(self)
|
Readable(self)
|
||||||
}
|
}
|
||||||
/// Marks `self` as using `is_human_readable == false`
|
/// Marks `self` as using `is_human_readable == false`
|
||||||
fn compact(self) -> Compact<Self> where Self: Sized {
|
fn compact(self) -> Compact<Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
Compact(self)
|
Compact(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,7 +164,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
macro_rules! forward_method {
|
macro_rules! forward_method {
|
||||||
($name: ident (self $(, $arg: ident : $arg_type: ty)* ) -> $return_type: ty) => {
|
($name: ident (self $(, $arg: ident : $arg_type: ty)* ) -> $return_type: ty) => {
|
||||||
fn $name (self $(, $arg : $arg_type)* ) -> $return_type {
|
fn $name (self $(, $arg : $arg_type)* ) -> $return_type {
|
||||||
@@ -455,8 +460,7 @@ macro_rules! impl_serializer {
|
|||||||
impl_serializer!(Readable, true);
|
impl_serializer!(Readable, true);
|
||||||
impl_serializer!(Compact, false);
|
impl_serializer!(Compact, false);
|
||||||
|
|
||||||
|
use serde::de::{DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor};
|
||||||
use serde::de::{Visitor, EnumAccess, VariantAccess, MapAccess, DeserializeSeed, SeqAccess, Error};
|
|
||||||
|
|
||||||
macro_rules! forward_deserialize_methods {
|
macro_rules! forward_deserialize_methods {
|
||||||
( $wrapper : ident ( $( $name: ident ),* ) ) => {
|
( $wrapper : ident ( $( $name: ident ),* ) ) => {
|
||||||
@@ -468,7 +472,6 @@ macro_rules! forward_deserialize_methods {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
macro_rules! impl_deserializer {
|
macro_rules! impl_deserializer {
|
||||||
($wrapper : ident, $is_human_readable : expr) => {
|
($wrapper : ident, $is_human_readable : expr) => {
|
||||||
impl <'de, D> Deserializer<'de> for $wrapper<D> where D: Deserializer<'de> {
|
impl <'de, D> Deserializer<'de> for $wrapper<D> where D: Deserializer<'de> {
|
||||||
|
|||||||
+58
-44
@@ -95,15 +95,11 @@ impl<'de> Deserializer<'de> {
|
|||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
let value = try!(
|
let value = try!(visitor.visit_seq(DeserializerSeqVisitor {
|
||||||
visitor.visit_seq(
|
|
||||||
DeserializerSeqVisitor {
|
|
||||||
de: self,
|
de: self,
|
||||||
len: len,
|
len: len,
|
||||||
end: end,
|
end: end,
|
||||||
},
|
},));
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_next_token!(self, end);
|
assert_next_token!(self, end);
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
@@ -117,15 +113,11 @@ impl<'de> Deserializer<'de> {
|
|||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
let value = try!(
|
let value = try!(visitor.visit_map(DeserializerMapVisitor {
|
||||||
visitor.visit_map(
|
|
||||||
DeserializerMapVisitor {
|
|
||||||
de: self,
|
de: self,
|
||||||
len: len,
|
len: len,
|
||||||
end: end,
|
end: end,
|
||||||
},
|
},));
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_next_token!(self, end);
|
assert_next_token!(self, end);
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
@@ -169,7 +161,9 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
|||||||
Token::NewtypeStruct { .. } => visitor.visit_newtype_struct(self),
|
Token::NewtypeStruct { .. } => visitor.visit_newtype_struct(self),
|
||||||
Token::Seq { len } => self.visit_seq(len, Token::SeqEnd, visitor),
|
Token::Seq { len } => self.visit_seq(len, Token::SeqEnd, visitor),
|
||||||
Token::Tuple { len } => self.visit_seq(Some(len), Token::TupleEnd, visitor),
|
Token::Tuple { len } => self.visit_seq(Some(len), Token::TupleEnd, visitor),
|
||||||
Token::TupleStruct { len, .. } => self.visit_seq(Some(len), Token::TupleStructEnd, visitor),
|
Token::TupleStruct { len, .. } => {
|
||||||
|
self.visit_seq(Some(len), Token::TupleStructEnd, visitor)
|
||||||
|
}
|
||||||
Token::Map { len } => self.visit_map(len, Token::MapEnd, visitor),
|
Token::Map { len } => self.visit_map(len, Token::MapEnd, visitor),
|
||||||
Token::Struct { len, .. } => self.visit_map(Some(len), Token::StructEnd, visitor),
|
Token::Struct { len, .. } => self.visit_map(Some(len), Token::StructEnd, visitor),
|
||||||
Token::Enum { .. } => {
|
Token::Enum { .. } => {
|
||||||
@@ -195,17 +189,28 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Token::UnitVariant { variant, .. } => visitor.visit_str(variant),
|
Token::UnitVariant { variant, .. } => visitor.visit_str(variant),
|
||||||
Token::NewtypeVariant { variant, .. } => {
|
Token::NewtypeVariant { variant, .. } => visitor.visit_map(EnumMapVisitor::new(
|
||||||
visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Any),)
|
self,
|
||||||
}
|
Token::Str(variant),
|
||||||
Token::TupleVariant { variant, .. } => {
|
EnumFormat::Any,
|
||||||
visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Seq),)
|
)),
|
||||||
}
|
Token::TupleVariant { variant, .. } => visitor.visit_map(EnumMapVisitor::new(
|
||||||
Token::StructVariant { variant, .. } => {
|
self,
|
||||||
visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Map),)
|
Token::Str(variant),
|
||||||
}
|
EnumFormat::Seq,
|
||||||
Token::SeqEnd | Token::TupleEnd | Token::TupleStructEnd | Token::MapEnd |
|
)),
|
||||||
Token::StructEnd | Token::TupleVariantEnd | Token::StructVariantEnd => {
|
Token::StructVariant { variant, .. } => visitor.visit_map(EnumMapVisitor::new(
|
||||||
|
self,
|
||||||
|
Token::Str(variant),
|
||||||
|
EnumFormat::Map,
|
||||||
|
)),
|
||||||
|
Token::SeqEnd
|
||||||
|
| Token::TupleEnd
|
||||||
|
| Token::TupleStructEnd
|
||||||
|
| Token::MapEnd
|
||||||
|
| Token::StructEnd
|
||||||
|
| Token::TupleVariantEnd
|
||||||
|
| Token::StructVariantEnd => {
|
||||||
unexpected!(token);
|
unexpected!(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,8 +221,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
|||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
match self.peek_token() {
|
match self.peek_token() {
|
||||||
Token::Unit |
|
Token::Unit | Token::None => {
|
||||||
Token::None => {
|
|
||||||
self.next_token();
|
self.next_token();
|
||||||
visitor.visit_none()
|
visitor.visit_none()
|
||||||
}
|
}
|
||||||
@@ -244,10 +248,11 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
|||||||
|
|
||||||
visitor.visit_enum(DeserializerEnumVisitor { de: self })
|
visitor.visit_enum(DeserializerEnumVisitor { de: self })
|
||||||
}
|
}
|
||||||
Token::UnitVariant { name: n, .. } |
|
Token::UnitVariant { name: n, .. }
|
||||||
Token::NewtypeVariant { name: n, .. } |
|
| Token::NewtypeVariant { name: n, .. }
|
||||||
Token::TupleVariant { name: n, .. } |
|
| Token::TupleVariant { name: n, .. }
|
||||||
Token::StructVariant { name: n, .. } if name == n => {
|
| Token::StructVariant { name: n, .. } if name == n =>
|
||||||
|
{
|
||||||
visitor.visit_enum(DeserializerEnumVisitor { de: self })
|
visitor.visit_enum(DeserializerEnumVisitor { de: self })
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -269,7 +274,11 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value, Error>
|
fn deserialize_newtype_struct<V>(
|
||||||
|
self,
|
||||||
|
name: &'static str,
|
||||||
|
visitor: V,
|
||||||
|
) -> Result<V::Value, Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
@@ -287,8 +296,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
|
|||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
match self.peek_token() {
|
match self.peek_token() {
|
||||||
Token::Unit |
|
Token::Unit | Token::UnitStruct { .. } => {
|
||||||
Token::UnitStruct { .. } => {
|
|
||||||
self.next_token();
|
self.next_token();
|
||||||
visitor.visit_unit()
|
visitor.visit_unit()
|
||||||
}
|
}
|
||||||
@@ -448,10 +456,10 @@ impl<'de, 'a> EnumAccess<'de> for DeserializerEnumVisitor<'a, 'de> {
|
|||||||
V: DeserializeSeed<'de>,
|
V: DeserializeSeed<'de>,
|
||||||
{
|
{
|
||||||
match self.de.peek_token() {
|
match self.de.peek_token() {
|
||||||
Token::UnitVariant { variant: v, .. } |
|
Token::UnitVariant { variant: v, .. }
|
||||||
Token::NewtypeVariant { variant: v, .. } |
|
| Token::NewtypeVariant { variant: v, .. }
|
||||||
Token::TupleVariant { variant: v, .. } |
|
| Token::TupleVariant { variant: v, .. }
|
||||||
Token::StructVariant { variant: v, .. } => {
|
| Token::StructVariant { variant: v, .. } => {
|
||||||
let de = v.into_deserializer();
|
let de = v.into_deserializer();
|
||||||
let value = try!(seed.deserialize(de));
|
let value = try!(seed.deserialize(de));
|
||||||
Ok((value, self))
|
Ok((value, self))
|
||||||
@@ -505,7 +513,9 @@ impl<'de, 'a> VariantAccess<'de> for DeserializerEnumVisitor<'a, 'de> {
|
|||||||
unexpected!(token);
|
unexpected!(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Token::Seq { len: Some(enum_len) } => {
|
Token::Seq {
|
||||||
|
len: Some(enum_len),
|
||||||
|
} => {
|
||||||
let token = self.de.next_token();
|
let token = self.de.next_token();
|
||||||
|
|
||||||
if len == enum_len {
|
if len == enum_len {
|
||||||
@@ -518,7 +528,11 @@ impl<'de, 'a> VariantAccess<'de> for DeserializerEnumVisitor<'a, 'de> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value, Error>
|
fn struct_variant<V>(
|
||||||
|
self,
|
||||||
|
fields: &'static [&'static str],
|
||||||
|
visitor: V,
|
||||||
|
) -> Result<V::Value, Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
@@ -533,7 +547,9 @@ impl<'de, 'a> VariantAccess<'de> for DeserializerEnumVisitor<'a, 'de> {
|
|||||||
unexpected!(token);
|
unexpected!(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Token::Map { len: Some(enum_len) } => {
|
Token::Map {
|
||||||
|
len: Some(enum_len),
|
||||||
|
} => {
|
||||||
let token = self.de.next_token();
|
let token = self.de.next_token();
|
||||||
|
|
||||||
if fields.len() == enum_len {
|
if fields.len() == enum_len {
|
||||||
@@ -581,10 +597,8 @@ impl<'de, 'a> MapAccess<'de> for EnumMapVisitor<'a, 'de> {
|
|||||||
{
|
{
|
||||||
match self.variant.take() {
|
match self.variant.take() {
|
||||||
Some(Token::Str(variant)) => seed.deserialize(variant.into_deserializer()).map(Some),
|
Some(Token::Str(variant)) => seed.deserialize(variant.into_deserializer()).map(Some),
|
||||||
Some(Token::Bytes(variant)) => {
|
Some(Token::Bytes(variant)) => seed.deserialize(BytesDeserializer { value: variant })
|
||||||
seed.deserialize(BytesDeserializer { value: variant })
|
.map(Some),
|
||||||
.map(Some)
|
|
||||||
}
|
|
||||||
Some(Token::U32(variant)) => seed.deserialize(variant.into_deserializer()).map(Some),
|
Some(Token::U32(variant)) => seed.deserialize(variant.into_deserializer()).map(Some),
|
||||||
Some(other) => unexpected!(other),
|
Some(other) => unexpected!(other),
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
use std::error;
|
use std::error;
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::{self, Display};
|
||||||
|
|
||||||
use serde::{ser, de};
|
use serde::{de, ser};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Error {
|
pub struct Error {
|
||||||
@@ -18,13 +18,17 @@ pub struct Error {
|
|||||||
|
|
||||||
impl ser::Error for Error {
|
impl ser::Error for Error {
|
||||||
fn custom<T: Display>(msg: T) -> Self {
|
fn custom<T: Display>(msg: T) -> Self {
|
||||||
Error { msg: msg.to_string() }
|
Error {
|
||||||
|
msg: msg.to_string(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl de::Error for Error {
|
impl de::Error for Error {
|
||||||
fn custom<T: Display>(msg: T) -> Self {
|
fn custom<T: Display>(msg: T) -> Self {
|
||||||
Error { msg: msg.to_string() }
|
Error {
|
||||||
|
msg: msg.to_string(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -156,17 +156,12 @@
|
|||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.24")]
|
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.24")]
|
||||||
|
|
||||||
#![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))]
|
||||||
// Whitelisted clippy_pedantic lints
|
// Whitelisted clippy_pedantic lints
|
||||||
#![cfg_attr(feature = "cargo-clippy", allow(
|
#![cfg_attr(feature = "cargo-clippy",
|
||||||
missing_docs_in_private_items,
|
allow(missing_docs_in_private_items, stutter, use_debug, use_self))]
|
||||||
stutter,
|
|
||||||
use_debug,
|
|
||||||
use_self,
|
|
||||||
))]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
|
|||||||
+18
-4
@@ -232,7 +232,10 @@ pub enum Token {
|
|||||||
/// assert_tokens(&a, &[Token::UnitVariant { name: "E", variant: "A" }]);
|
/// assert_tokens(&a, &[Token::UnitVariant { name: "E", variant: "A" }]);
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
UnitVariant { name: &'static str, variant: &'static str },
|
UnitVariant {
|
||||||
|
name: &'static str,
|
||||||
|
variant: &'static str,
|
||||||
|
},
|
||||||
|
|
||||||
/// The header to a serialized newtype struct of the given name.
|
/// The header to a serialized newtype struct of the given name.
|
||||||
///
|
///
|
||||||
@@ -286,7 +289,10 @@ pub enum Token {
|
|||||||
/// ]);
|
/// ]);
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
NewtypeVariant { name: &'static str, variant: &'static str },
|
NewtypeVariant {
|
||||||
|
name: &'static str,
|
||||||
|
variant: &'static str,
|
||||||
|
},
|
||||||
|
|
||||||
/// The header to a sequence.
|
/// The header to a sequence.
|
||||||
///
|
///
|
||||||
@@ -391,7 +397,11 @@ pub enum Token {
|
|||||||
/// ]);
|
/// ]);
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
TupleVariant { name: &'static str, variant: &'static str, len: usize },
|
TupleVariant {
|
||||||
|
name: &'static str,
|
||||||
|
variant: &'static str,
|
||||||
|
len: usize,
|
||||||
|
},
|
||||||
|
|
||||||
/// An indicator of the end of a tuple variant.
|
/// An indicator of the end of a tuple variant.
|
||||||
TupleVariantEnd,
|
TupleVariantEnd,
|
||||||
@@ -488,7 +498,11 @@ pub enum Token {
|
|||||||
/// ]);
|
/// ]);
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
StructVariant { name: &'static str, variant: &'static str, len: usize },
|
StructVariant {
|
||||||
|
name: &'static str,
|
||||||
|
variant: &'static str,
|
||||||
|
len: usize,
|
||||||
|
},
|
||||||
|
|
||||||
/// An indicator of the end of a struct variant.
|
/// An indicator of the end of a struct variant.
|
||||||
StructVariantEnd,
|
StructVariantEnd,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,7 @@ extern crate serde;
|
|||||||
use serde::{Deserialize, Deserializer};
|
use serde::{Deserialize, Deserializer};
|
||||||
|
|
||||||
extern crate serde_test;
|
extern crate serde_test;
|
||||||
use serde_test::{Token, assert_de_tokens, assert_de_tokens_error};
|
use serde_test::{assert_de_tokens, assert_de_tokens_error, Token};
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
@@ -91,14 +91,14 @@ fn test_struct() {
|
|||||||
bb: b"bytes",
|
bb: b"bytes",
|
||||||
},
|
},
|
||||||
&[
|
&[
|
||||||
Token::Struct { name: "Borrowing", len: 2 },
|
Token::Struct {
|
||||||
|
name: "Borrowing",
|
||||||
|
len: 2,
|
||||||
|
},
|
||||||
Token::BorrowedStr("bs"),
|
Token::BorrowedStr("bs"),
|
||||||
Token::BorrowedStr("str"),
|
Token::BorrowedStr("str"),
|
||||||
|
|
||||||
Token::BorrowedStr("bb"),
|
Token::BorrowedStr("bb"),
|
||||||
Token::BorrowedBytes(b"bytes"),
|
Token::BorrowedBytes(b"bytes"),
|
||||||
|
|
||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -110,19 +110,18 @@ fn test_cow() {
|
|||||||
struct Cows<'a, 'b> {
|
struct Cows<'a, 'b> {
|
||||||
copied: Cow<'a, str>,
|
copied: Cow<'a, str>,
|
||||||
|
|
||||||
#[serde(borrow)]
|
#[serde(borrow)] borrowed: Cow<'b, str>,
|
||||||
borrowed: Cow<'b, str>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let tokens = &[
|
let tokens = &[
|
||||||
Token::Struct { name: "Cows", len: 2 },
|
Token::Struct {
|
||||||
|
name: "Cows",
|
||||||
|
len: 2,
|
||||||
|
},
|
||||||
Token::Str("copied"),
|
Token::Str("copied"),
|
||||||
Token::BorrowedStr("copied"),
|
Token::BorrowedStr("copied"),
|
||||||
|
|
||||||
Token::Str("borrowed"),
|
Token::Str("borrowed"),
|
||||||
Token::BorrowedStr("borrowed"),
|
Token::BorrowedStr("borrowed"),
|
||||||
|
|
||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -146,8 +145,7 @@ fn test_lifetimes() {
|
|||||||
struct Cows<'a, 'b> {
|
struct Cows<'a, 'b> {
|
||||||
_copied: Cow<'a, str>,
|
_copied: Cow<'a, str>,
|
||||||
|
|
||||||
#[serde(borrow)]
|
#[serde(borrow)] _borrowed: Cow<'b, str>,
|
||||||
_borrowed: Cow<'b, str>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that `'de: 'a` is not required by the Deserialize impl.
|
// Tests that `'de: 'a` is not required by the Deserialize impl.
|
||||||
@@ -160,8 +158,7 @@ fn test_lifetimes() {
|
|||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Wrap<'a, 'b> {
|
struct Wrap<'a, 'b> {
|
||||||
#[serde(borrow = "'b")]
|
#[serde(borrow = "'b")] _cows: Cows<'a, 'b>,
|
||||||
_cows: Cows<'a, 'b>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that `'de: 'a` is not required by the Deserialize impl.
|
// Tests that `'de: 'a` is not required by the Deserialize impl.
|
||||||
|
|||||||
@@ -94,9 +94,7 @@ struct StructSkipDefaultGeneric<T> {
|
|||||||
|
|
||||||
impl Default for StructSkipDefault {
|
impl Default for StructSkipDefault {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
StructSkipDefault {
|
StructSkipDefault { a: 16 }
|
||||||
a: 16,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +112,11 @@ enum Enum {
|
|||||||
Unit,
|
Unit,
|
||||||
Simple(i32),
|
Simple(i32),
|
||||||
Seq(i32, i32, i32),
|
Seq(i32, i32, i32),
|
||||||
Map { a: i32, b: i32, c: i32 },
|
Map {
|
||||||
|
a: i32,
|
||||||
|
b: i32,
|
||||||
|
c: i32,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Deserialize)]
|
#[derive(PartialEq, Debug, Deserialize)]
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
// types involved.
|
// types involved.
|
||||||
|
|
||||||
#![deny(warnings)]
|
#![deny(warnings)]
|
||||||
|
|
||||||
#![cfg_attr(feature = "unstable", feature(non_ascii_idents))]
|
#![cfg_attr(feature = "unstable", feature(non_ascii_idents))]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@@ -47,25 +46,21 @@ fn test_gen() {
|
|||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct With<T> {
|
struct With<T> {
|
||||||
t: T,
|
t: T,
|
||||||
#[serde(serialize_with="ser_x", deserialize_with="de_x")]
|
#[serde(serialize_with = "ser_x", deserialize_with = "de_x")] x: X,
|
||||||
x: X,
|
|
||||||
}
|
}
|
||||||
assert::<With<i32>>();
|
assert::<With<i32>>();
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct WithTogether<T> {
|
struct WithTogether<T> {
|
||||||
t: T,
|
t: T,
|
||||||
#[serde(with="both_x")]
|
#[serde(with = "both_x")] x: X,
|
||||||
x: X,
|
|
||||||
}
|
}
|
||||||
assert::<WithTogether<i32>>();
|
assert::<WithTogether<i32>>();
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct WithRef<'a, T: 'a> {
|
struct WithRef<'a, T: 'a> {
|
||||||
#[serde(skip_deserializing)]
|
#[serde(skip_deserializing)] t: StdOption<&'a T>,
|
||||||
t: StdOption<&'a T>,
|
#[serde(serialize_with = "ser_x", deserialize_with = "de_x")] x: X,
|
||||||
#[serde(serialize_with="ser_x", deserialize_with="de_x")]
|
|
||||||
x: X,
|
|
||||||
}
|
}
|
||||||
assert::<WithRef<i32>>();
|
assert::<WithRef<i32>>();
|
||||||
|
|
||||||
@@ -93,19 +88,14 @@ fn test_gen() {
|
|||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
enum EnumWith<T> {
|
enum EnumWith<T> {
|
||||||
Unit,
|
Unit,
|
||||||
Newtype(
|
Newtype(#[serde(serialize_with = "ser_x", deserialize_with = "de_x")] X),
|
||||||
#[serde(serialize_with="ser_x", deserialize_with="de_x")]
|
|
||||||
X
|
|
||||||
),
|
|
||||||
Tuple(
|
Tuple(
|
||||||
T,
|
T,
|
||||||
#[serde(serialize_with="ser_x", deserialize_with="de_x")]
|
#[serde(serialize_with = "ser_x", deserialize_with = "de_x")] X,
|
||||||
X
|
|
||||||
),
|
),
|
||||||
Struct {
|
Struct {
|
||||||
t: T,
|
t: T,
|
||||||
#[serde(serialize_with="ser_x", deserialize_with="de_x")]
|
#[serde(serialize_with = "ser_x", deserialize_with = "de_x")] x: X,
|
||||||
x: X,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
assert::<EnumWith<i32>>();
|
assert::<EnumWith<i32>>();
|
||||||
@@ -123,17 +113,13 @@ fn test_gen() {
|
|||||||
assert_ser::<MultipleRef<i32>>();
|
assert_ser::<MultipleRef<i32>>();
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct Newtype(
|
struct Newtype(#[serde(serialize_with = "ser_x", deserialize_with = "de_x")] X);
|
||||||
#[serde(serialize_with="ser_x", deserialize_with="de_x")]
|
|
||||||
X
|
|
||||||
);
|
|
||||||
assert::<Newtype>();
|
assert::<Newtype>();
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct Tuple<T>(
|
struct Tuple<T>(
|
||||||
T,
|
T,
|
||||||
#[serde(serialize_with="ser_x", deserialize_with="de_x")]
|
#[serde(serialize_with = "ser_x", deserialize_with = "de_x")] X,
|
||||||
X
|
|
||||||
);
|
);
|
||||||
assert::<Tuple<i32>>();
|
assert::<Tuple<i32>>();
|
||||||
|
|
||||||
@@ -143,7 +129,9 @@ fn test_gen() {
|
|||||||
left: Box<TreeNode<D>>,
|
left: Box<TreeNode<D>>,
|
||||||
right: Box<TreeNode<D>>,
|
right: Box<TreeNode<D>>,
|
||||||
},
|
},
|
||||||
Leaf { data: D },
|
Leaf {
|
||||||
|
data: D,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
assert::<TreeNode<i32>>();
|
assert::<TreeNode<i32>>();
|
||||||
|
|
||||||
@@ -201,8 +189,7 @@ fn test_gen() {
|
|||||||
assert::<WithTraits1<X, X>>();
|
assert::<WithTraits1<X, X>>();
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(bound(serialize="D: SerializeWith",
|
#[serde(bound(serialize = "D: SerializeWith", deserialize = "D: DeserializeWith"))]
|
||||||
deserialize="D: DeserializeWith"))]
|
|
||||||
struct WithTraits2<D, E> {
|
struct WithTraits2<D, E> {
|
||||||
#[serde(serialize_with = "SerializeWith::serialize_with",
|
#[serde(serialize_with = "SerializeWith::serialize_with",
|
||||||
deserialize_with = "DeserializeWith::deserialize_with")]
|
deserialize_with = "DeserializeWith::deserialize_with")]
|
||||||
@@ -249,15 +236,13 @@ fn test_gen() {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct BracedSkipAll {
|
struct BracedSkipAll {
|
||||||
#[serde(skip_deserializing)]
|
#[serde(skip_deserializing)] f: u8,
|
||||||
f: u8,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct BracedSkipAllDenyUnknown {
|
struct BracedSkipAllDenyUnknown {
|
||||||
#[serde(skip_deserializing)]
|
#[serde(skip_deserializing)] f: u8,
|
||||||
f: u8,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "unstable")]
|
#[cfg(feature = "unstable")]
|
||||||
@@ -270,17 +255,11 @@ fn test_gen() {
|
|||||||
struct EmptyTupleDenyUnknown();
|
struct EmptyTupleDenyUnknown();
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct TupleSkipAll(
|
struct TupleSkipAll(#[serde(skip_deserializing)] u8);
|
||||||
#[serde(skip_deserializing)]
|
|
||||||
u8
|
|
||||||
);
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct TupleSkipAllDenyUnknown(
|
struct TupleSkipAllDenyUnknown(#[serde(skip_deserializing)] u8);
|
||||||
#[serde(skip_deserializing)]
|
|
||||||
u8
|
|
||||||
);
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
enum EmptyEnum {}
|
enum EmptyEnum {}
|
||||||
@@ -301,14 +280,8 @@ fn test_gen() {
|
|||||||
enum EmptyVariants {
|
enum EmptyVariants {
|
||||||
Braced {},
|
Braced {},
|
||||||
Tuple(),
|
Tuple(),
|
||||||
BracedSkip {
|
BracedSkip { #[serde(skip_deserializing)] f: u8 },
|
||||||
#[serde(skip_deserializing)]
|
TupleSkip(#[serde(skip_deserializing)] u8),
|
||||||
f: u8,
|
|
||||||
},
|
|
||||||
TupleSkip(
|
|
||||||
#[serde(skip_deserializing)]
|
|
||||||
u8
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "unstable")]
|
#[cfg(feature = "unstable")]
|
||||||
@@ -317,14 +290,8 @@ fn test_gen() {
|
|||||||
enum EmptyVariantsDenyUnknown {
|
enum EmptyVariantsDenyUnknown {
|
||||||
Braced {},
|
Braced {},
|
||||||
Tuple(),
|
Tuple(),
|
||||||
BracedSkip {
|
BracedSkip { #[serde(skip_deserializing)] f: u8 },
|
||||||
#[serde(skip_deserializing)]
|
TupleSkip(#[serde(skip_deserializing)] u8),
|
||||||
f: u8,
|
|
||||||
},
|
|
||||||
TupleSkip(
|
|
||||||
#[serde(skip_deserializing)]
|
|
||||||
u8
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
@@ -344,10 +311,8 @@ 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)]
|
#[allow(dead_code)] A(A),
|
||||||
A(A),
|
#[allow(dead_code)] B(B),
|
||||||
#[allow(dead_code)]
|
|
||||||
B(B),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Str<'a>(&'a str);
|
struct Str<'a>(&'a str);
|
||||||
@@ -358,16 +323,13 @@ fn test_gen() {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct Remote<'a> {
|
struct Remote<'a> {
|
||||||
#[serde(with = "OrDef")]
|
#[serde(with = "OrDef")] or: Or<u8, bool>,
|
||||||
or: Or<u8, bool>,
|
#[serde(borrow, with = "StrDef")] s: Str<'a>,
|
||||||
#[serde(borrow, with = "StrDef")]
|
|
||||||
s: Str<'a>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
enum BorrowVariant<'a> {
|
enum BorrowVariant<'a> {
|
||||||
#[serde(borrow, with = "StrDef")]
|
#[serde(borrow, with = "StrDef")] S(Str<'a>),
|
||||||
S(Str<'a>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mod vis {
|
mod vis {
|
||||||
@@ -381,14 +343,14 @@ fn test_gen() {
|
|||||||
// This would not work if SDef::serialize / deserialize are private.
|
// This would not work if SDef::serialize / deserialize are private.
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct RemoteVisibility {
|
struct RemoteVisibility {
|
||||||
#[serde(with = "vis::SDef")]
|
#[serde(with = "vis::SDef")] s: vis::S,
|
||||||
s: vis::S,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
enum ExternallyTaggedVariantWith {
|
enum ExternallyTaggedVariantWith {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)] Normal {
|
||||||
Normal { f1: String },
|
f1: String,
|
||||||
|
},
|
||||||
|
|
||||||
#[serde(serialize_with = "ser_x")]
|
#[serde(serialize_with = "ser_x")]
|
||||||
#[serde(deserialize_with = "de_x")]
|
#[serde(deserialize_with = "de_x")]
|
||||||
@@ -418,8 +380,9 @@ fn test_gen() {
|
|||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(tag = "t")]
|
#[serde(tag = "t")]
|
||||||
enum InternallyTaggedVariantWith {
|
enum InternallyTaggedVariantWith {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)] Normal {
|
||||||
Normal { f1: String },
|
f1: String,
|
||||||
|
},
|
||||||
|
|
||||||
#[serde(serialize_with = "ser_x")]
|
#[serde(serialize_with = "ser_x")]
|
||||||
#[serde(deserialize_with = "de_x")]
|
#[serde(deserialize_with = "de_x")]
|
||||||
@@ -444,8 +407,9 @@ fn test_gen() {
|
|||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(tag = "t", content = "c")]
|
#[serde(tag = "t", content = "c")]
|
||||||
enum AdjacentlyTaggedVariantWith {
|
enum AdjacentlyTaggedVariantWith {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)] Normal {
|
||||||
Normal { f1: String },
|
f1: String,
|
||||||
|
},
|
||||||
|
|
||||||
#[serde(serialize_with = "ser_x")]
|
#[serde(serialize_with = "ser_x")]
|
||||||
#[serde(deserialize_with = "de_x")]
|
#[serde(deserialize_with = "de_x")]
|
||||||
@@ -475,8 +439,9 @@ fn test_gen() {
|
|||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
enum UntaggedVariantWith {
|
enum UntaggedVariantWith {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)] Normal {
|
||||||
Normal { f1: String },
|
f1: String,
|
||||||
|
},
|
||||||
|
|
||||||
#[serde(serialize_with = "ser_x")]
|
#[serde(serialize_with = "ser_x")]
|
||||||
#[serde(deserialize_with = "de_x")]
|
#[serde(deserialize_with = "de_x")]
|
||||||
@@ -517,18 +482,14 @@ fn test_gen() {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
enum StaticStrEnum<'a> {
|
enum StaticStrEnum<'a> {
|
||||||
Struct {
|
Struct { a: &'a str, b: &'static str },
|
||||||
a: &'a str,
|
|
||||||
b: &'static str,
|
|
||||||
},
|
|
||||||
Tuple(&'a str, &'static str),
|
Tuple(&'a str, &'static str),
|
||||||
Newtype(&'static str),
|
Newtype(&'static str),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct SkippedStaticStr {
|
struct SkippedStaticStr {
|
||||||
#[serde(skip_deserializing)]
|
#[serde(skip_deserializing)] skipped: &'static str,
|
||||||
skipped: &'static str,
|
|
||||||
other: isize,
|
other: isize,
|
||||||
}
|
}
|
||||||
assert::<SkippedStaticStr>();
|
assert::<SkippedStaticStr>();
|
||||||
@@ -570,7 +531,7 @@ pub fn de_x<'de, D: Deserializer<'de>>(_: D) -> StdResult<X, D::Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod both_x {
|
mod both_x {
|
||||||
pub use super::{ser_x as serialize, de_x as deserialize};
|
pub use super::{de_x as deserialize, ser_x as serialize};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SerializeWith for X {
|
impl SerializeWith for X {
|
||||||
@@ -586,27 +547,33 @@ impl DeserializeWith for X {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn serialize_some_unit_variant<S>(_: S) -> StdResult<S::Ok, S::Error>
|
pub fn serialize_some_unit_variant<S>(_: S) -> StdResult<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where
|
||||||
|
S: Serializer,
|
||||||
{
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deserialize_some_unit_variant<'de, D>(_: D) -> StdResult<(), D::Error>
|
pub fn deserialize_some_unit_variant<'de, D>(_: D) -> StdResult<(), D::Error>
|
||||||
where D: Deserializer<'de>,
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serialize_some_other_variant<S>(_: &str, _: &u8, _: S) -> StdResult<S::Ok, S::Error>
|
pub fn serialize_some_other_variant<S>(_: &str, _: &u8, _: S) -> StdResult<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where
|
||||||
|
S: Serializer,
|
||||||
{
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deserialize_some_other_variant<'de, D>(_: D) -> StdResult<(String, u8), D::Error>
|
pub fn deserialize_some_other_variant<'de, D>(_: D) -> StdResult<(String, u8), D::Error>
|
||||||
where D: Deserializer<'de>,
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_zero(n: &u8) -> bool { *n == 0 }
|
pub fn is_zero(n: &u8) -> bool {
|
||||||
|
*n == 0
|
||||||
|
}
|
||||||
|
|||||||
+276
-191
File diff suppressed because it is too large
Load Diff
@@ -118,9 +118,7 @@ struct PrimitivePubDef(u8);
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::NewtypePriv")]
|
#[serde(remote = "remote::NewtypePriv")]
|
||||||
struct NewtypePrivDef(
|
struct NewtypePrivDef(#[serde(getter = "remote::NewtypePriv::get", with = "UnitDef")] remote::Unit);
|
||||||
#[serde(getter = "remote::NewtypePriv::get", with = "UnitDef")] remote::Unit,
|
|
||||||
);
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::NewtypePub")]
|
#[serde(remote = "remote::NewtypePub")]
|
||||||
|
|||||||
Reference in New Issue
Block a user