mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-27 02:57:57 +00:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3f0d3453d8 | |||
| b27a27ce22 | |||
| 80c0600657 | |||
| 77f9e63661 | |||
| b78f434086 | |||
| 893c0578dd | |||
| cb2b92f828 | |||
| 47a4ffbd31 | |||
| d82d1707d6 | |||
| 89278996c5 | |||
| ecef937e26 | |||
| bceda5fb18 | |||
| f46a08b04e | |||
| f3cb7c7a32 | |||
| af795e2e54 | |||
| 6aa07fe0d6 | |||
| c455720f81 | |||
| b07a208716 | |||
| df93fab5fa | |||
| 1a972d2105 | |||
| 6d1807bb4a | |||
| b37cf858ce | |||
| 5f8fa33756 | |||
| f3f006f411 | |||
| 607966dcf7 | |||
| 6a8c39b2aa |
@@ -5,6 +5,7 @@ cache: cargo
|
|||||||
# run builds for all the trains (and more)
|
# run builds for all the trains (and more)
|
||||||
rust:
|
rust:
|
||||||
- 1.13.0
|
- 1.13.0
|
||||||
|
- 1.15.0
|
||||||
- stable
|
- stable
|
||||||
- beta
|
- beta
|
||||||
- nightly
|
- nightly
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.41" # remember to update html_root_url
|
version = "1.0.45" # remember to update html_root_url
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "A generic serialization/deserialization framework"
|
description = "A generic serialization/deserialization framework"
|
||||||
|
|||||||
@@ -196,6 +196,7 @@ macro_rules! declare_error_trait {
|
|||||||
/// For example if we try to deserialize a String out of a JSON file
|
/// For example if we try to deserialize a String out of a JSON file
|
||||||
/// containing an integer, the unexpected type is the integer and the
|
/// containing an integer, the unexpected type is the integer and the
|
||||||
/// expected type is the string.
|
/// expected type is the string.
|
||||||
|
#[cold]
|
||||||
fn invalid_type(unexp: Unexpected, exp: &Expected) -> Self {
|
fn invalid_type(unexp: Unexpected, exp: &Expected) -> Self {
|
||||||
Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp))
|
Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp))
|
||||||
}
|
}
|
||||||
@@ -213,6 +214,7 @@ macro_rules! declare_error_trait {
|
|||||||
/// For example if we try to deserialize a String out of some binary data
|
/// For example if we try to deserialize a String out of some binary data
|
||||||
/// that is not valid UTF-8, the unexpected value is the bytes and the
|
/// that is not valid UTF-8, the unexpected value is the bytes and the
|
||||||
/// expected value is a string.
|
/// expected value is a string.
|
||||||
|
#[cold]
|
||||||
fn invalid_value(unexp: Unexpected, exp: &Expected) -> Self {
|
fn invalid_value(unexp: Unexpected, exp: &Expected) -> Self {
|
||||||
Error::custom(format_args!("invalid value: {}, expected {}", unexp, exp))
|
Error::custom(format_args!("invalid value: {}, expected {}", unexp, exp))
|
||||||
}
|
}
|
||||||
@@ -226,12 +228,14 @@ macro_rules! declare_error_trait {
|
|||||||
/// The `exp` argument provides information about what data was being
|
/// The `exp` argument provides information about what data was being
|
||||||
/// expected. For example `exp` might say that a tuple of size 6 was
|
/// expected. For example `exp` might say that a tuple of size 6 was
|
||||||
/// expected.
|
/// expected.
|
||||||
|
#[cold]
|
||||||
fn invalid_length(len: usize, exp: &Expected) -> Self {
|
fn invalid_length(len: usize, exp: &Expected) -> Self {
|
||||||
Error::custom(format_args!("invalid length {}, expected {}", len, exp))
|
Error::custom(format_args!("invalid length {}, expected {}", len, exp))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Raised when a `Deserialize` enum type received a variant with an
|
/// Raised when a `Deserialize` enum type received a variant with an
|
||||||
/// unrecognized name.
|
/// unrecognized name.
|
||||||
|
#[cold]
|
||||||
fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
|
fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
|
||||||
if expected.is_empty() {
|
if expected.is_empty() {
|
||||||
Error::custom(format_args!("unknown variant `{}`, there are no variants",
|
Error::custom(format_args!("unknown variant `{}`, there are no variants",
|
||||||
@@ -245,6 +249,7 @@ macro_rules! declare_error_trait {
|
|||||||
|
|
||||||
/// Raised when a `Deserialize` struct type received a field with an
|
/// Raised when a `Deserialize` struct type received a field with an
|
||||||
/// unrecognized name.
|
/// unrecognized name.
|
||||||
|
#[cold]
|
||||||
fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
|
fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
|
||||||
if expected.is_empty() {
|
if expected.is_empty() {
|
||||||
Error::custom(format_args!("unknown field `{}`, there are no fields",
|
Error::custom(format_args!("unknown field `{}`, there are no fields",
|
||||||
@@ -259,12 +264,14 @@ macro_rules! declare_error_trait {
|
|||||||
/// Raised when a `Deserialize` struct type expected to receive a required
|
/// Raised when a `Deserialize` struct type expected to receive a required
|
||||||
/// field with a particular name but that field was not present in the
|
/// field with a particular name but that field was not present in the
|
||||||
/// input.
|
/// input.
|
||||||
|
#[cold]
|
||||||
fn missing_field(field: &'static str) -> Self {
|
fn missing_field(field: &'static str) -> Self {
|
||||||
Error::custom(format_args!("missing field `{}`", field))
|
Error::custom(format_args!("missing field `{}`", field))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Raised when a `Deserialize` struct type received more than one of the
|
/// Raised when a `Deserialize` struct type received more than one of the
|
||||||
/// same field.
|
/// same field.
|
||||||
|
#[cold]
|
||||||
fn duplicate_field(field: &'static str) -> Self {
|
fn duplicate_field(field: &'static str) -> Self {
|
||||||
Error::custom(format_args!("duplicate field `{}`", field))
|
Error::custom(format_args!("duplicate field `{}`", field))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ type ErrorImpl = ();
|
|||||||
|
|
||||||
impl de::Error for Error {
|
impl de::Error for Error {
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
|
#[cold]
|
||||||
fn custom<T>(msg: T) -> Self
|
fn custom<T>(msg: T) -> Self
|
||||||
where
|
where
|
||||||
T: Display,
|
T: Display,
|
||||||
@@ -68,6 +69,7 @@ impl de::Error for Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(feature = "std", feature = "alloc")))]
|
#[cfg(not(any(feature = "std", feature = "alloc")))]
|
||||||
|
#[cold]
|
||||||
fn custom<T>(msg: T) -> Self
|
fn custom<T>(msg: T) -> Self
|
||||||
where
|
where
|
||||||
T: Display,
|
T: Display,
|
||||||
@@ -78,6 +80,7 @@ impl de::Error for Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ser::Error for Error {
|
impl ser::Error for Error {
|
||||||
|
#[cold]
|
||||||
fn custom<T>(msg: T) -> Self
|
fn custom<T>(msg: T) -> Self
|
||||||
where
|
where
|
||||||
T: Display,
|
T: Display,
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ pub use lib::result::Result::{self, Err, Ok};
|
|||||||
|
|
||||||
pub use self::string::from_utf8_lossy;
|
pub use self::string::from_utf8_lossy;
|
||||||
|
|
||||||
|
#[cfg(any(feature = "alloc", feature = "std"))]
|
||||||
|
pub use lib::Vec;
|
||||||
|
|
||||||
mod string {
|
mod string {
|
||||||
use lib::*;
|
use lib::*;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -79,7 +79,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Serde types in rustdoc of other crates get linked to here.
|
// Serde types in rustdoc of other crates get linked to here.
|
||||||
#![doc(html_root_url = "https://docs.rs/serde/1.0.41")]
|
#![doc(html_root_url = "https://docs.rs/serde/1.0.45")]
|
||||||
// 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
|
||||||
|
|||||||
+11
-2
@@ -277,6 +277,7 @@ mod content {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cold]
|
||||||
fn unexpected(&self) -> Unexpected {
|
fn unexpected(&self) -> Unexpected {
|
||||||
match *self {
|
match *self {
|
||||||
Content::Bool(b) => Unexpected::Bool(b),
|
Content::Bool(b) => Unexpected::Bool(b),
|
||||||
@@ -1309,7 +1310,10 @@ mod content {
|
|||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
visitor.visit_newtype_struct(self)
|
match self.content {
|
||||||
|
Content::Newtype(v) => visitor.visit_newtype_struct(ContentDeserializer::new(*v)),
|
||||||
|
_ => visitor.visit_newtype_struct(self),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
@@ -2000,7 +2004,12 @@ mod content {
|
|||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
visitor.visit_newtype_struct(self)
|
match *self.content {
|
||||||
|
Content::Newtype(ref v) => {
|
||||||
|
visitor.visit_newtype_struct(ContentRefDeserializer::new(v))
|
||||||
|
}
|
||||||
|
_ => visitor.visit_newtype_struct(self),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.41" # remember to update html_root_url
|
version = "1.0.45" # remember to update html_root_url
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
||||||
@@ -24,7 +24,7 @@ proc-macro = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
proc-macro2 = "0.3"
|
proc-macro2 = "0.3"
|
||||||
quote = "0.5"
|
quote = "0.5.2"
|
||||||
serde_derive_internals = { version = "=0.23.1", default-features = false, path = "../serde_derive_internals" }
|
serde_derive_internals = { version = "=0.23.1", default-features = false, path = "../serde_derive_internals" }
|
||||||
syn = { version = "0.13", features = ["visit"] }
|
syn = { version = "0.13", features = ["visit"] }
|
||||||
|
|
||||||
|
|||||||
+60
-51
@@ -16,6 +16,8 @@ use bound;
|
|||||||
use fragment::{Expr, Fragment, Match, Stmts};
|
use fragment::{Expr, Fragment, Match, Stmts};
|
||||||
use internals::ast::{Container, Data, Field, Style, Variant};
|
use internals::ast::{Container, Data, Field, Style, Variant};
|
||||||
use internals::{self, attr};
|
use internals::{self, attr};
|
||||||
|
use pretend;
|
||||||
|
use try;
|
||||||
|
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
@@ -36,12 +38,13 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, Str
|
|||||||
|
|
||||||
let impl_block = if let Some(remote) = cont.attrs.remote() {
|
let impl_block = if let Some(remote) = cont.attrs.remote() {
|
||||||
let vis = &input.vis;
|
let vis = &input.vis;
|
||||||
let fun = quote_spanned!(Span::call_site()=> deserialize);
|
let used = pretend::pretend_used(&cont);
|
||||||
quote! {
|
quote! {
|
||||||
impl #de_impl_generics #ident #ty_generics #where_clause {
|
impl #de_impl_generics #ident #ty_generics #where_clause {
|
||||||
#vis fn #fun<__D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error>
|
#vis fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error>
|
||||||
where __D: _serde::Deserializer<#delife>
|
where __D: _serde::Deserializer<#delife>
|
||||||
{
|
{
|
||||||
|
#used
|
||||||
#body
|
#body
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,10 +66,12 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, Str
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let try_replacement = try::replacement();
|
||||||
let generated = quote! {
|
let generated = quote! {
|
||||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||||
const #dummy_const: () = {
|
const #dummy_const: () = {
|
||||||
extern crate serde as _serde;
|
extern crate serde as _serde;
|
||||||
|
#try_replacement
|
||||||
#impl_block
|
#impl_block
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -583,11 +588,11 @@ fn deserialize_seq(
|
|||||||
|
|
||||||
let mut result = if is_struct {
|
let mut result = if is_struct {
|
||||||
let names = fields.iter().map(|f| &f.ident);
|
let names = fields.iter().map(|f| &f.ident);
|
||||||
quote_spanned! {Span::call_site()=>
|
quote! {
|
||||||
#type_path { #( #names: #vars ),* }
|
#type_path { #( #names: #vars ),* }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
quote_spanned! {Span::call_site()=>
|
quote! {
|
||||||
#type_path ( #(#vars),* )
|
#type_path ( #(#vars),* )
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -649,11 +654,10 @@ fn deserialize_seq_in_place(
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
let dot = quote_spanned!(Span::call_site()=> .);
|
|
||||||
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! {
|
||||||
self.place #dot #field_name = #default;
|
self.place.#field_name = #default;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let return_invalid_length = quote! {
|
let return_invalid_length = quote! {
|
||||||
@@ -663,7 +667,7 @@ fn deserialize_seq_in_place(
|
|||||||
None => {
|
None => {
|
||||||
quote! {
|
quote! {
|
||||||
if let _serde::export::None = try!(_serde::de::SeqAccess::next_element_seed(&mut __seq,
|
if let _serde::export::None = try!(_serde::de::SeqAccess::next_element_seed(&mut __seq,
|
||||||
_serde::private::de::InPlaceSeed(&mut self.place #dot #field_name)))
|
_serde::private::de::InPlaceSeed(&mut self.place.#field_name)))
|
||||||
{
|
{
|
||||||
#return_invalid_length
|
#return_invalid_length
|
||||||
}
|
}
|
||||||
@@ -676,7 +680,7 @@ fn deserialize_seq_in_place(
|
|||||||
#wrapper
|
#wrapper
|
||||||
match try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)) {
|
match try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)) {
|
||||||
_serde::export::Some(__wrap) => {
|
_serde::export::Some(__wrap) => {
|
||||||
self.place #dot #field_name = __wrap.value;
|
self.place.#field_name = __wrap.value;
|
||||||
}
|
}
|
||||||
_serde::export::None => {
|
_serde::export::None => {
|
||||||
#return_invalid_length
|
#return_invalid_length
|
||||||
@@ -732,7 +736,7 @@ fn deserialize_newtype_struct(type_path: &Tokens, params: &Parameters, field: &F
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut result = quote_spanned!(Span::call_site()=> #type_path(#value));
|
let mut result = quote!(#type_path(__field0));
|
||||||
if params.has_getter {
|
if params.has_getter {
|
||||||
let this = ¶ms.this;
|
let this = ¶ms.this;
|
||||||
result = quote! {
|
result = quote! {
|
||||||
@@ -745,6 +749,7 @@ fn deserialize_newtype_struct(type_path: &Tokens, params: &Parameters, field: &F
|
|||||||
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
|
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
|
||||||
where __E: _serde::Deserializer<#delife>
|
where __E: _serde::Deserializer<#delife>
|
||||||
{
|
{
|
||||||
|
let __field0 = #value;
|
||||||
_serde::export::Ok(#result)
|
_serde::export::Ok(#result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -757,13 +762,12 @@ fn deserialize_newtype_struct_in_place(params: &Parameters, field: &Field) -> To
|
|||||||
|
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
|
|
||||||
let elem = quote_spanned!(Span::call_site()=> .0);
|
|
||||||
quote! {
|
quote! {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
|
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
|
||||||
where __E: _serde::Deserializer<#delife>
|
where __E: _serde::Deserializer<#delife>
|
||||||
{
|
{
|
||||||
_serde::Deserialize::deserialize_in_place(__e, &mut self.place #elem)
|
_serde::Deserialize::deserialize_in_place(__e, &mut self.place.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1625,12 +1629,13 @@ fn deserialize_untagged_variant(
|
|||||||
let type_name = params.type_name();
|
let type_name = params.type_name();
|
||||||
let variant_name = variant.ident.as_ref();
|
let variant_name = variant.ident.as_ref();
|
||||||
quote_expr! {
|
quote_expr! {
|
||||||
_serde::export::Result::map(
|
match _serde::Deserializer::deserialize_any(
|
||||||
_serde::Deserializer::deserialize_any(
|
#deserializer,
|
||||||
#deserializer,
|
_serde::private::de::UntaggedUnitVisitor::new(#type_name, #variant_name)
|
||||||
_serde::private::de::UntaggedUnitVisitor::new(#type_name, #variant_name)
|
) {
|
||||||
),
|
_serde::export::Ok(()) => _serde::export::Ok(#this::#variant_ident),
|
||||||
|()| #this::#variant_ident)
|
_serde::export::Err(__err) => _serde::export::Err(__err),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Style::Newtype => deserialize_untagged_newtype_variant(
|
Style::Newtype => deserialize_untagged_newtype_variant(
|
||||||
@@ -1939,82 +1944,82 @@ fn deserialize_identifier(
|
|||||||
let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len());
|
let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len());
|
||||||
let visit_other = if collect_other_fields {
|
let visit_other = if collect_other_fields {
|
||||||
quote! {
|
quote! {
|
||||||
fn visit_bool<__E>(self, __value: bool) -> Result<Self::Value, __E>
|
fn visit_bool<__E>(self, __value: bool) -> _serde::export::Result<Self::Value, __E>
|
||||||
where __E: _serde::de::Error
|
where __E: _serde::de::Error
|
||||||
{
|
{
|
||||||
Ok(__Field::__other(_serde::private::de::Content::Bool(__value)))
|
_serde::export::Ok(__Field::__other(_serde::private::de::Content::Bool(__value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_i8<__E>(self, __value: i8) -> Result<Self::Value, __E>
|
fn visit_i8<__E>(self, __value: i8) -> _serde::export::Result<Self::Value, __E>
|
||||||
where __E: _serde::de::Error
|
where __E: _serde::de::Error
|
||||||
{
|
{
|
||||||
Ok(__Field::__other(_serde::private::de::Content::I8(__value)))
|
_serde::export::Ok(__Field::__other(_serde::private::de::Content::I8(__value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_i16<__E>(self, __value: i16) -> Result<Self::Value, __E>
|
fn visit_i16<__E>(self, __value: i16) -> _serde::export::Result<Self::Value, __E>
|
||||||
where __E: _serde::de::Error
|
where __E: _serde::de::Error
|
||||||
{
|
{
|
||||||
Ok(__Field::__other(_serde::private::de::Content::I16(__value)))
|
_serde::export::Ok(__Field::__other(_serde::private::de::Content::I16(__value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_i32<__E>(self, __value: i32) -> Result<Self::Value, __E>
|
fn visit_i32<__E>(self, __value: i32) -> _serde::export::Result<Self::Value, __E>
|
||||||
where __E: _serde::de::Error
|
where __E: _serde::de::Error
|
||||||
{
|
{
|
||||||
Ok(__Field::__other(_serde::private::de::Content::I32(__value)))
|
_serde::export::Ok(__Field::__other(_serde::private::de::Content::I32(__value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_i64<__E>(self, __value: i64) -> Result<Self::Value, __E>
|
fn visit_i64<__E>(self, __value: i64) -> _serde::export::Result<Self::Value, __E>
|
||||||
where __E: _serde::de::Error
|
where __E: _serde::de::Error
|
||||||
{
|
{
|
||||||
Ok(__Field::__other(_serde::private::de::Content::I64(__value)))
|
_serde::export::Ok(__Field::__other(_serde::private::de::Content::I64(__value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_u8<__E>(self, __value: u8) -> Result<Self::Value, __E>
|
fn visit_u8<__E>(self, __value: u8) -> _serde::export::Result<Self::Value, __E>
|
||||||
where __E: _serde::de::Error
|
where __E: _serde::de::Error
|
||||||
{
|
{
|
||||||
Ok(__Field::__other(_serde::private::de::Content::U8(__value)))
|
_serde::export::Ok(__Field::__other(_serde::private::de::Content::U8(__value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_u16<__E>(self, __value: u16) -> Result<Self::Value, __E>
|
fn visit_u16<__E>(self, __value: u16) -> _serde::export::Result<Self::Value, __E>
|
||||||
where __E: _serde::de::Error
|
where __E: _serde::de::Error
|
||||||
{
|
{
|
||||||
Ok(__Field::__other(_serde::private::de::Content::U16(__value)))
|
_serde::export::Ok(__Field::__other(_serde::private::de::Content::U16(__value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_u32<__E>(self, __value: u32) -> Result<Self::Value, __E>
|
fn visit_u32<__E>(self, __value: u32) -> _serde::export::Result<Self::Value, __E>
|
||||||
where __E: _serde::de::Error
|
where __E: _serde::de::Error
|
||||||
{
|
{
|
||||||
Ok(__Field::__other(_serde::private::de::Content::U32(__value)))
|
_serde::export::Ok(__Field::__other(_serde::private::de::Content::U32(__value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_u64<__E>(self, __value: u64) -> Result<Self::Value, __E>
|
fn visit_u64<__E>(self, __value: u64) -> _serde::export::Result<Self::Value, __E>
|
||||||
where __E: _serde::de::Error
|
where __E: _serde::de::Error
|
||||||
{
|
{
|
||||||
Ok(__Field::__other(_serde::private::de::Content::U64(__value)))
|
_serde::export::Ok(__Field::__other(_serde::private::de::Content::U64(__value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_f32<__E>(self, __value: f32) -> Result<Self::Value, __E>
|
fn visit_f32<__E>(self, __value: f32) -> _serde::export::Result<Self::Value, __E>
|
||||||
where __E: _serde::de::Error
|
where __E: _serde::de::Error
|
||||||
{
|
{
|
||||||
Ok(__Field::__other(_serde::private::de::Content::F32(__value)))
|
_serde::export::Ok(__Field::__other(_serde::private::de::Content::F32(__value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_f64<__E>(self, __value: f64) -> Result<Self::Value, __E>
|
fn visit_f64<__E>(self, __value: f64) -> _serde::export::Result<Self::Value, __E>
|
||||||
where __E: _serde::de::Error
|
where __E: _serde::de::Error
|
||||||
{
|
{
|
||||||
Ok(__Field::__other(_serde::private::de::Content::F64(__value)))
|
_serde::export::Ok(__Field::__other(_serde::private::de::Content::F64(__value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_char<__E>(self, __value: char) -> Result<Self::Value, __E>
|
fn visit_char<__E>(self, __value: char) -> _serde::export::Result<Self::Value, __E>
|
||||||
where __E: _serde::de::Error
|
where __E: _serde::de::Error
|
||||||
{
|
{
|
||||||
Ok(__Field::__other(_serde::private::de::Content::Char(__value)))
|
_serde::export::Ok(__Field::__other(_serde::private::de::Content::Char(__value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_unit<__E>(self) -> Result<Self::Value, __E>
|
fn visit_unit<__E>(self) -> _serde::export::Result<Self::Value, __E>
|
||||||
where __E: _serde::de::Error
|
where __E: _serde::de::Error
|
||||||
{
|
{
|
||||||
Ok(__Field::__other(_serde::private::de::Content::Unit))
|
_serde::export::Ok(__Field::__other(_serde::private::de::Content::Unit))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::export::Result<Self::Value, __E>
|
fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::export::Result<Self::Value, __E>
|
||||||
@@ -2177,7 +2182,7 @@ fn deserialize_map(
|
|||||||
// Collect contents for flatten fields into a buffer
|
// Collect contents for flatten fields into a buffer
|
||||||
let let_collect = if cattrs.has_flatten() {
|
let let_collect = if cattrs.has_flatten() {
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
let mut __collect = Vec::<Option<(
|
let mut __collect = _serde::export::Vec::<_serde::export::Option<(
|
||||||
_serde::private::de::Content,
|
_serde::private::de::Content,
|
||||||
_serde::private::de::Content
|
_serde::private::de::Content
|
||||||
)>>::new();
|
)>>::new();
|
||||||
@@ -2225,7 +2230,7 @@ fn deserialize_map(
|
|||||||
let ignored_arm = if cattrs.has_flatten() {
|
let ignored_arm = if cattrs.has_flatten() {
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
__Field::__other(__name) => {
|
__Field::__other(__name) => {
|
||||||
__collect.push(Some((
|
__collect.push(_serde::export::Some((
|
||||||
__name,
|
__name,
|
||||||
try!(_serde::de::MapAccess::next_value(&mut __map)))));
|
try!(_serde::de::MapAccess::next_value(&mut __map)))));
|
||||||
}
|
}
|
||||||
@@ -2277,8 +2282,12 @@ fn deserialize_map(
|
|||||||
.filter(|&&(field, _)| field.attrs.flatten())
|
.filter(|&&(field, _)| field.attrs.flatten())
|
||||||
.map(|&(field, ref name)| {
|
.map(|&(field, ref name)| {
|
||||||
let field_ty = field.ty;
|
let field_ty = field.ty;
|
||||||
|
let func = match field.attrs.deserialize_with() {
|
||||||
|
None => quote!(_serde::de::Deserialize::deserialize),
|
||||||
|
Some(path) => quote!(#path),
|
||||||
|
};
|
||||||
quote! {
|
quote! {
|
||||||
let #name: #field_ty = try!(_serde::de::Deserialize::deserialize(
|
let #name: #field_ty = try!(#func(
|
||||||
_serde::private::de::FlatMapDeserializer(
|
_serde::private::de::FlatMapDeserializer(
|
||||||
&mut __collect,
|
&mut __collect,
|
||||||
_serde::export::PhantomData)));
|
_serde::export::PhantomData)));
|
||||||
@@ -2287,8 +2296,8 @@ fn deserialize_map(
|
|||||||
|
|
||||||
let collected_deny_unknown_fields = if cattrs.has_flatten() && cattrs.deny_unknown_fields() {
|
let collected_deny_unknown_fields = if cattrs.has_flatten() && cattrs.deny_unknown_fields() {
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
if let Some(Some((__key, _))) = __collect.into_iter().filter(|x| x.is_some()).next() {
|
if let _serde::export::Some(_serde::export::Some((__key, _))) = __collect.into_iter().filter(|x| x.is_some()).next() {
|
||||||
if let Some(__key) = __key.as_str() {
|
if let _serde::export::Some(__key) = __key.as_str() {
|
||||||
return _serde::export::Err(
|
return _serde::export::Err(
|
||||||
_serde::de::Error::custom(format_args!("unknown field `{}`", &__key)));
|
_serde::de::Error::custom(format_args!("unknown field `{}`", &__key)));
|
||||||
} else {
|
} else {
|
||||||
@@ -2305,9 +2314,9 @@ fn deserialize_map(
|
|||||||
let ident = field.ident.expect("struct contains unnamed fields");
|
let ident = field.ident.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_spanned!(Span::call_site()=> #ident: #value)
|
quote!(#ident: #value)
|
||||||
} else {
|
} else {
|
||||||
quote_spanned!(Span::call_site()=> #ident: #name)
|
quote!(#ident: #name)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2325,7 +2334,7 @@ fn deserialize_map(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut result = quote_spanned!(Span::call_site()=> #struct_path { #(#result),* });
|
let mut result = quote!(#struct_path { #(#result),* });
|
||||||
if params.has_getter {
|
if params.has_getter {
|
||||||
let this = ¶ms.this;
|
let this = ¶ms.this;
|
||||||
result = quote! {
|
result = quote! {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
//!
|
//!
|
||||||
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
|
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
|
||||||
|
|
||||||
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.41")]
|
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.45")]
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
allow(enum_variant_names, redundant_field_names, too_many_arguments, used_underscore_binding)
|
allow(enum_variant_names, redundant_field_names, too_many_arguments, used_underscore_binding)
|
||||||
@@ -43,21 +43,15 @@ extern crate proc_macro2;
|
|||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use syn::DeriveInput;
|
use syn::DeriveInput;
|
||||||
|
|
||||||
// Quote's default is def_site but it appears call_site is likely to stabilize
|
|
||||||
// before def_site. Thus we try to use only call_site.
|
|
||||||
macro_rules! quote {
|
|
||||||
($($tt:tt)*) => {
|
|
||||||
quote_spanned!($crate::proc_macro2::Span::call_site()=> $($tt)*)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod bound;
|
mod bound;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod fragment;
|
mod fragment;
|
||||||
|
|
||||||
mod de;
|
mod de;
|
||||||
|
mod pretend;
|
||||||
mod ser;
|
mod ser;
|
||||||
|
mod try;
|
||||||
|
|
||||||
#[proc_macro_derive(Serialize, attributes(serde))]
|
#[proc_macro_derive(Serialize, attributes(serde))]
|
||||||
pub fn derive_serialize(input: TokenStream) -> TokenStream {
|
pub fn derive_serialize(input: TokenStream) -> TokenStream {
|
||||||
|
|||||||
@@ -0,0 +1,145 @@
|
|||||||
|
use proc_macro2::Span;
|
||||||
|
use quote::Tokens;
|
||||||
|
use syn::Ident;
|
||||||
|
|
||||||
|
use internals::ast::{Container, Data, Field, Style};
|
||||||
|
|
||||||
|
// Suppress dead_code warnings that would otherwise appear when using a remote
|
||||||
|
// derive. Other than this pretend code, a struct annotated with remote derive
|
||||||
|
// never has its fields referenced and an enum annotated with remote derive
|
||||||
|
// never has its variants constructed.
|
||||||
|
//
|
||||||
|
// warning: field is never used: `i`
|
||||||
|
// --> src/main.rs:4:20
|
||||||
|
// |
|
||||||
|
// 4 | struct StructDef { i: i32 }
|
||||||
|
// | ^^^^^^
|
||||||
|
//
|
||||||
|
// warning: variant is never constructed: `V`
|
||||||
|
// --> src/main.rs:8:16
|
||||||
|
// |
|
||||||
|
// 8 | enum EnumDef { V }
|
||||||
|
// | ^
|
||||||
|
//
|
||||||
|
pub fn pretend_used(cont: &Container) -> Tokens {
|
||||||
|
let pretend_fields = pretend_fields_used(cont);
|
||||||
|
let pretend_variants = pretend_variants_used(cont);
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#pretend_fields
|
||||||
|
#pretend_variants
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For structs with named fields, expands to:
|
||||||
|
//
|
||||||
|
// match None::<T> {
|
||||||
|
// Some(T { a: ref __v0, b: ref __v1 }) => {}
|
||||||
|
// _ => {}
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// For enums, expands to the following but only including struct variants:
|
||||||
|
//
|
||||||
|
// match None::<T> {
|
||||||
|
// Some(T::A { a: ref __v0 }) => {}
|
||||||
|
// Some(T::B { b: ref __v0 }) => {}
|
||||||
|
// _ => {}
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// The `ref` is important in case the user has written a Drop impl on their
|
||||||
|
// type. Rust does not allow destructuring a struct or enum that has a Drop
|
||||||
|
// impl.
|
||||||
|
fn pretend_fields_used(cont: &Container) -> Tokens {
|
||||||
|
let type_ident = cont.ident;
|
||||||
|
let (_, ty_generics, _) = cont.generics.split_for_impl();
|
||||||
|
|
||||||
|
let patterns = match cont.data {
|
||||||
|
Data::Enum(ref variants) => {
|
||||||
|
variants.iter()
|
||||||
|
.filter_map(|variant| match variant.style {
|
||||||
|
Style::Struct => {
|
||||||
|
let variant_ident = variant.ident;
|
||||||
|
let pat = struct_pattern(&variant.fields);
|
||||||
|
Some(quote!(#type_ident::#variant_ident #pat))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
}
|
||||||
|
Data::Struct(Style::Struct, ref fields) => {
|
||||||
|
let pat = struct_pattern(fields);
|
||||||
|
vec![quote!(#type_ident #pat)]
|
||||||
|
}
|
||||||
|
Data::Struct(_, _) => {
|
||||||
|
return quote!();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
match _serde::export::None::<#type_ident #ty_generics> {
|
||||||
|
#(
|
||||||
|
_serde::export::Some(#patterns) => {}
|
||||||
|
)*
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expands to one of these per enum variant:
|
||||||
|
//
|
||||||
|
// match None {
|
||||||
|
// Some((__v0, __v1,)) => {
|
||||||
|
// let _ = E::V { a: __v0, b: __v1 };
|
||||||
|
// }
|
||||||
|
// _ => {}
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
fn pretend_variants_used(cont: &Container) -> Tokens {
|
||||||
|
let variants = match cont.data {
|
||||||
|
Data::Enum(ref variants) => variants,
|
||||||
|
Data::Struct(_, _) => {
|
||||||
|
return quote!();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let type_ident = cont.ident;
|
||||||
|
let (_, ty_generics, _) = cont.generics.split_for_impl();
|
||||||
|
let turbofish = ty_generics.as_turbofish();
|
||||||
|
|
||||||
|
let cases = variants.iter()
|
||||||
|
.map(|variant| {
|
||||||
|
let variant_ident = variant.ident;
|
||||||
|
let ref placeholders = (0..variant.fields.len())
|
||||||
|
.map(|i| Ident::new(&format!("__v{}", i), Span::call_site()))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let pat = match variant.style {
|
||||||
|
Style::Struct => {
|
||||||
|
let names = variant.fields.iter().map(|field| field.ident);
|
||||||
|
quote!({ #(#names: #placeholders),* })
|
||||||
|
}
|
||||||
|
Style::Tuple | Style::Newtype => {
|
||||||
|
quote!(( #(#placeholders),* ))
|
||||||
|
}
|
||||||
|
Style::Unit => quote!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
match _serde::export::None {
|
||||||
|
_serde::export::Some((#(#placeholders,)*)) => {
|
||||||
|
let _ = #type_ident::#variant_ident #turbofish #pat;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
quote!(#(#cases)*)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn struct_pattern(fields: &[Field]) -> Tokens {
|
||||||
|
let names = fields.iter().map(|field| field.ident);
|
||||||
|
let placeholders = (0..fields.len())
|
||||||
|
.map(|i| Ident::new(&format!("__v{}", i), Span::call_site()));
|
||||||
|
quote!({ #(#names: ref #placeholders),* })
|
||||||
|
}
|
||||||
+18
-7
@@ -15,6 +15,8 @@ use bound;
|
|||||||
use fragment::{Fragment, Match, Stmts};
|
use fragment::{Fragment, Match, Stmts};
|
||||||
use internals::ast::{Container, Data, Field, Style, Variant};
|
use internals::ast::{Container, Data, Field, Style, Variant};
|
||||||
use internals::{attr, Ctxt};
|
use internals::{attr, Ctxt};
|
||||||
|
use pretend;
|
||||||
|
use try;
|
||||||
|
|
||||||
use std::u32;
|
use std::u32;
|
||||||
|
|
||||||
@@ -32,12 +34,13 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<Tokens, Strin
|
|||||||
|
|
||||||
let impl_block = if let Some(remote) = cont.attrs.remote() {
|
let impl_block = if let Some(remote) = cont.attrs.remote() {
|
||||||
let vis = &input.vis;
|
let vis = &input.vis;
|
||||||
let fun = quote_spanned!(Span::call_site()=> serialize);
|
let used = pretend::pretend_used(&cont);
|
||||||
quote! {
|
quote! {
|
||||||
impl #impl_generics #ident #ty_generics #where_clause {
|
impl #impl_generics #ident #ty_generics #where_clause {
|
||||||
#vis fn #fun<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
|
#vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
|
||||||
where __S: _serde::Serializer
|
where __S: _serde::Serializer
|
||||||
{
|
{
|
||||||
|
#used
|
||||||
#body
|
#body
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,10 +58,12 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<Tokens, Strin
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let try_replacement = try::replacement();
|
||||||
let generated = quote! {
|
let generated = quote! {
|
||||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||||
const #dummy_const: () = {
|
const #dummy_const: () = {
|
||||||
extern crate serde as _serde;
|
extern crate serde as _serde;
|
||||||
|
#try_replacement
|
||||||
#impl_block
|
#impl_block
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -594,9 +599,15 @@ fn serialize_adjacently_tagged_variant(
|
|||||||
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
|
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
quote_expr! {
|
return quote_block! {
|
||||||
_serde::Serialize::serialize(#field_expr, __serializer)
|
let mut __struct = try!(_serde::Serializer::serialize_struct(
|
||||||
}
|
__serializer, #type_name, 2));
|
||||||
|
try!(_serde::ser::SerializeStruct::serialize_field(
|
||||||
|
&mut __struct, #tag, #variant_name));
|
||||||
|
try!(_serde::ser::SerializeStruct::serialize_field(
|
||||||
|
&mut __struct, #content, #field_expr));
|
||||||
|
_serde::ser::SerializeStruct::end(__struct)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
Style::Tuple => {
|
Style::Tuple => {
|
||||||
serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields)
|
serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields)
|
||||||
@@ -1056,9 +1067,9 @@ fn mut_if(is_mut: bool) -> Option<Tokens> {
|
|||||||
fn get_member(params: &Parameters, field: &Field, member: &Member) -> Tokens {
|
fn get_member(params: &Parameters, field: &Field, member: &Member) -> Tokens {
|
||||||
let self_var = ¶ms.self_var;
|
let self_var = ¶ms.self_var;
|
||||||
match (params.is_remote, field.attrs.getter()) {
|
match (params.is_remote, field.attrs.getter()) {
|
||||||
(false, None) => quote_spanned!(Span::call_site()=> &#self_var.#member),
|
(false, None) => quote!(&#self_var.#member),
|
||||||
(true, None) => {
|
(true, None) => {
|
||||||
let inner = quote_spanned!(Span::call_site()=> &#self_var.#member);
|
let inner = quote!(&#self_var.#member);
|
||||||
let ty = field.ty;
|
let ty = field.ty;
|
||||||
quote!(_serde::private::ser::constrain::<#ty>(#inner))
|
quote!(_serde::private::ser::constrain::<#ty>(#inner))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
use proc_macro2::{Op, Spacing};
|
||||||
|
use quote::Tokens;
|
||||||
|
|
||||||
|
// None of our generated code requires the `From::from` error conversion
|
||||||
|
// performed by the standard library's `try!` macro. With this simplified macro
|
||||||
|
// we see a significant improvement in type checking and borrow checking time of
|
||||||
|
// the generated code and a slight improvement in binary size.
|
||||||
|
pub fn replacement() -> Tokens {
|
||||||
|
// Cannot pass `$expr` to `quote!` prior to Rust 1.17.0 so interpolate it.
|
||||||
|
let dollar = Op::new('$', Spacing::Alone);
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#[allow(unused_macros)]
|
||||||
|
macro_rules! try {
|
||||||
|
(#dollar __expr:expr) => {
|
||||||
|
match #dollar __expr {
|
||||||
|
_serde::export::Ok(__val) => __val,
|
||||||
|
_serde::export::Err(__err) => {
|
||||||
|
return _serde::export::Err(__err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_test"
|
name = "serde_test"
|
||||||
version = "1.0.41" # remember to update html_root_url
|
version = "1.0.45" # remember to update html_root_url
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "Token De/Serializer for testing De/Serialize implementations"
|
description = "Token De/Serializer for testing De/Serialize implementations"
|
||||||
|
|||||||
@@ -155,7 +155,7 @@
|
|||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.41")]
|
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.45")]
|
||||||
#![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))]
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
use serde::de::{Deserializer, Visitor, SeqAccess, Error};
|
use serde::de::{Deserializer, Error, SeqAccess, Visitor};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
|
||||||
where D: Deserializer<'de>
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
deserializer.deserialize_byte_buf(ByteBufVisitor)
|
deserializer.deserialize_byte_buf(ByteBufVisitor)
|
||||||
}
|
}
|
||||||
@@ -17,7 +18,8 @@ impl<'de> Visitor<'de> for ByteBufVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
|
fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
|
||||||
where V: SeqAccess<'de>
|
where
|
||||||
|
V: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
let mut values = Vec::new();
|
let mut values = Vec::new();
|
||||||
while let Some(value) = try!(visitor.next_element()) {
|
while let Some(value) = try!(visitor.next_element()) {
|
||||||
@@ -27,25 +29,29 @@ impl<'de> Visitor<'de> for ByteBufVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||||
where E: Error
|
where
|
||||||
|
E: Error,
|
||||||
{
|
{
|
||||||
Ok(v.to_vec())
|
Ok(v.to_vec())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
|
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
|
||||||
where E: Error
|
where
|
||||||
|
E: Error,
|
||||||
{
|
{
|
||||||
Ok(v)
|
Ok(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||||
where E: Error
|
where
|
||||||
|
E: Error,
|
||||||
{
|
{
|
||||||
Ok(v.as_bytes().to_vec())
|
Ok(v.as_bytes().to_vec())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||||
where E: Error
|
where
|
||||||
|
E: Error,
|
||||||
{
|
{
|
||||||
Ok(v.into_bytes())
|
Ok(v.into_bytes())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,9 @@
|
|||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
use std::collections::HashMap;
|
|
||||||
use self::serde::{Deserialize, Deserializer, Serialize, Serializer};
|
|
||||||
use self::serde::de::{self, Unexpected};
|
use self::serde::de::{self, Unexpected};
|
||||||
|
use self::serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
extern crate serde_test;
|
extern crate serde_test;
|
||||||
use self::serde_test::{assert_de_tokens, assert_de_tokens_error, assert_ser_tokens,
|
use self::serde_test::{assert_de_tokens, assert_de_tokens_error, assert_ser_tokens,
|
||||||
@@ -114,10 +114,7 @@ struct FlattenStructEnumWrapper {
|
|||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
enum FlattenStructEnum {
|
enum FlattenStructEnum {
|
||||||
InsertInteger {
|
InsertInteger { index: u32, value: u32 },
|
||||||
index: u32,
|
|
||||||
value: u32
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
@@ -133,10 +130,7 @@ struct FlattenStructTagContentEnumNewtype(pub FlattenStructTagContentEnum);
|
|||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "snake_case", tag = "type", content = "value")]
|
#[serde(rename_all = "snake_case", tag = "type", content = "value")]
|
||||||
enum FlattenStructTagContentEnum {
|
enum FlattenStructTagContentEnum {
|
||||||
InsertInteger {
|
InsertInteger { index: u32, value: u32 },
|
||||||
index: u32,
|
|
||||||
value: u32
|
|
||||||
},
|
|
||||||
NewtypeVariant(FlattenStructTagContentEnumNewtypeVariant),
|
NewtypeVariant(FlattenStructTagContentEnumNewtypeVariant),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -529,12 +523,10 @@ enum RenameEnumSerializeDeserialize<A> {
|
|||||||
fn test_rename_enum() {
|
fn test_rename_enum() {
|
||||||
assert_tokens(
|
assert_tokens(
|
||||||
&RenameEnum::Batman,
|
&RenameEnum::Batman,
|
||||||
&[
|
&[Token::UnitVariant {
|
||||||
Token::UnitVariant {
|
name: "Superhero",
|
||||||
name: "Superhero",
|
variant: "bruce_wayne",
|
||||||
variant: "bruce_wayne",
|
}],
|
||||||
},
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_tokens(
|
assert_tokens(
|
||||||
@@ -1221,12 +1213,7 @@ fn test_missing_renamed_field_enum() {
|
|||||||
#[derive(Debug, PartialEq, Deserialize)]
|
#[derive(Debug, PartialEq, Deserialize)]
|
||||||
enum InvalidLengthEnum {
|
enum InvalidLengthEnum {
|
||||||
A(i32, i32, i32),
|
A(i32, i32, i32),
|
||||||
B(
|
B(#[serde(skip_deserializing)] i32, i32, i32),
|
||||||
#[serde(skip_deserializing)]
|
|
||||||
i32,
|
|
||||||
i32,
|
|
||||||
i32,
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -1345,7 +1332,7 @@ fn test_flatten_struct_enum() {
|
|||||||
let change_request = FlattenStructEnumWrapper {
|
let change_request = FlattenStructEnumWrapper {
|
||||||
data: FlattenStructEnum::InsertInteger {
|
data: FlattenStructEnum::InsertInteger {
|
||||||
index: 0,
|
index: 0,
|
||||||
value: 42
|
value: 42,
|
||||||
},
|
},
|
||||||
extra,
|
extra,
|
||||||
};
|
};
|
||||||
@@ -1362,7 +1349,7 @@ fn test_flatten_struct_enum() {
|
|||||||
Token::MapEnd,
|
Token::MapEnd,
|
||||||
Token::Str("extra_key"),
|
Token::Str("extra_key"),
|
||||||
Token::Str("extra value"),
|
Token::Str("extra value"),
|
||||||
Token::MapEnd
|
Token::MapEnd,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
assert_ser_tokens(
|
assert_ser_tokens(
|
||||||
@@ -1370,7 +1357,10 @@ fn test_flatten_struct_enum() {
|
|||||||
&[
|
&[
|
||||||
Token::Map { len: None },
|
Token::Map { len: None },
|
||||||
Token::Str("insert_integer"),
|
Token::Str("insert_integer"),
|
||||||
Token::Struct { len: 2, name: "insert_integer" },
|
Token::Struct {
|
||||||
|
len: 2,
|
||||||
|
name: "insert_integer",
|
||||||
|
},
|
||||||
Token::Str("index"),
|
Token::Str("index"),
|
||||||
Token::U32(0),
|
Token::U32(0),
|
||||||
Token::Str("value"),
|
Token::Str("value"),
|
||||||
@@ -1378,7 +1368,7 @@ fn test_flatten_struct_enum() {
|
|||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
Token::Str("extra_key"),
|
Token::Str("extra_key"),
|
||||||
Token::Str("extra value"),
|
Token::Str("extra value"),
|
||||||
Token::MapEnd
|
Token::MapEnd,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1387,12 +1377,10 @@ fn test_flatten_struct_enum() {
|
|||||||
fn test_flatten_struct_tag_content_enum() {
|
fn test_flatten_struct_tag_content_enum() {
|
||||||
let change_request = FlattenStructTagContentEnumWrapper {
|
let change_request = FlattenStructTagContentEnumWrapper {
|
||||||
outer: 42,
|
outer: 42,
|
||||||
data: FlattenStructTagContentEnumNewtype(
|
data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::InsertInteger {
|
||||||
FlattenStructTagContentEnum::InsertInteger {
|
index: 0,
|
||||||
index: 0,
|
value: 42,
|
||||||
value: 42
|
}),
|
||||||
}
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&change_request,
|
&change_request,
|
||||||
@@ -1421,7 +1409,10 @@ fn test_flatten_struct_tag_content_enum() {
|
|||||||
Token::Str("type"),
|
Token::Str("type"),
|
||||||
Token::Str("insert_integer"),
|
Token::Str("insert_integer"),
|
||||||
Token::Str("value"),
|
Token::Str("value"),
|
||||||
Token::Struct { len: 2, name: "insert_integer" },
|
Token::Struct {
|
||||||
|
len: 2,
|
||||||
|
name: "insert_integer",
|
||||||
|
},
|
||||||
Token::Str("index"),
|
Token::Str("index"),
|
||||||
Token::U32(0),
|
Token::U32(0),
|
||||||
Token::Str("value"),
|
Token::Str("value"),
|
||||||
@@ -1436,13 +1427,9 @@ fn test_flatten_struct_tag_content_enum() {
|
|||||||
fn test_flatten_struct_tag_content_enum_newtype() {
|
fn test_flatten_struct_tag_content_enum_newtype() {
|
||||||
let change_request = FlattenStructTagContentEnumWrapper {
|
let change_request = FlattenStructTagContentEnumWrapper {
|
||||||
outer: 42,
|
outer: 42,
|
||||||
data: FlattenStructTagContentEnumNewtype(
|
data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::NewtypeVariant(
|
||||||
FlattenStructTagContentEnum::NewtypeVariant(
|
FlattenStructTagContentEnumNewtypeVariant { value: 23 },
|
||||||
FlattenStructTagContentEnumNewtypeVariant {
|
)),
|
||||||
value: 23
|
|
||||||
}
|
|
||||||
)
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&change_request,
|
&change_request,
|
||||||
@@ -1469,7 +1456,10 @@ fn test_flatten_struct_tag_content_enum_newtype() {
|
|||||||
Token::Str("type"),
|
Token::Str("type"),
|
||||||
Token::Str("newtype_variant"),
|
Token::Str("newtype_variant"),
|
||||||
Token::Str("value"),
|
Token::Str("value"),
|
||||||
Token::Struct { len: 1, name: "FlattenStructTagContentEnumNewtypeVariant" },
|
Token::Struct {
|
||||||
|
len: 1,
|
||||||
|
name: "FlattenStructTagContentEnumNewtypeVariant",
|
||||||
|
},
|
||||||
Token::Str("value"),
|
Token::Str("value"),
|
||||||
Token::U32(23),
|
Token::U32(23),
|
||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
@@ -1525,7 +1515,7 @@ fn test_complex_flatten() {
|
|||||||
first: First,
|
first: First,
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
second: Second,
|
second: Second,
|
||||||
z: u32
|
z: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
@@ -1552,10 +1542,8 @@ fn test_complex_flatten() {
|
|||||||
d: "c".into(),
|
d: "c".into(),
|
||||||
e: Some(2),
|
e: Some(2),
|
||||||
},
|
},
|
||||||
second: Second {
|
second: Second { f: 3 },
|
||||||
f: 3
|
z: 4,
|
||||||
},
|
|
||||||
z: 4
|
|
||||||
},
|
},
|
||||||
&[
|
&[
|
||||||
Token::Map { len: None },
|
Token::Map { len: None },
|
||||||
@@ -1592,10 +1580,8 @@ fn test_complex_flatten() {
|
|||||||
d: "c".into(),
|
d: "c".into(),
|
||||||
e: Some(2),
|
e: Some(2),
|
||||||
},
|
},
|
||||||
second: Second {
|
second: Second { f: 3 },
|
||||||
f: 3
|
z: 4,
|
||||||
},
|
|
||||||
z: 4
|
|
||||||
},
|
},
|
||||||
&[
|
&[
|
||||||
Token::Map { len: None },
|
Token::Map { len: None },
|
||||||
@@ -1652,7 +1638,7 @@ fn test_flatten_unsupported_type() {
|
|||||||
Token::Str("foo"),
|
Token::Str("foo"),
|
||||||
Token::Str("a"),
|
Token::Str("a"),
|
||||||
Token::Str("b"),
|
Token::Str("b"),
|
||||||
Token::MapEnd
|
Token::MapEnd,
|
||||||
],
|
],
|
||||||
"can only flatten structs and maps",
|
"can only flatten structs and maps",
|
||||||
);
|
);
|
||||||
@@ -1671,7 +1657,11 @@ fn test_non_string_keys() {
|
|||||||
let mut mapping = HashMap::new();
|
let mut mapping = HashMap::new();
|
||||||
mapping.insert(0, 42);
|
mapping.insert(0, 42);
|
||||||
assert_tokens(
|
assert_tokens(
|
||||||
&TestStruct { name: "peter".into(), age: 3, mapping },
|
&TestStruct {
|
||||||
|
name: "peter".into(),
|
||||||
|
age: 3,
|
||||||
|
mapping,
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Map { len: None },
|
Token::Map { len: None },
|
||||||
Token::Str("name"),
|
Token::Str("name"),
|
||||||
@@ -1720,7 +1710,9 @@ fn test_lifetime_propagation_for_flatten() {
|
|||||||
let mut borrowed_map = HashMap::new();
|
let mut borrowed_map = HashMap::new();
|
||||||
borrowed_map.insert("x", 42u32);
|
borrowed_map.insert("x", 42u32);
|
||||||
assert_ser_tokens(
|
assert_ser_tokens(
|
||||||
&B { t: borrowed_map.clone() },
|
&B {
|
||||||
|
t: borrowed_map.clone(),
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Map { len: None },
|
Token::Map { len: None },
|
||||||
Token::BorrowedStr("x"),
|
Token::BorrowedStr("x"),
|
||||||
@@ -1742,7 +1734,9 @@ fn test_lifetime_propagation_for_flatten() {
|
|||||||
let mut borrowed_map = HashMap::new();
|
let mut borrowed_map = HashMap::new();
|
||||||
borrowed_map.insert(&b"x"[..], 42u32);
|
borrowed_map.insert(&b"x"[..], 42u32);
|
||||||
assert_ser_tokens(
|
assert_ser_tokens(
|
||||||
&C { t: borrowed_map.clone() },
|
&C {
|
||||||
|
t: borrowed_map.clone(),
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Map { len: None },
|
Token::Map { len: None },
|
||||||
Token::Seq { len: Some(1) },
|
Token::Seq { len: Some(1) },
|
||||||
|
|||||||
@@ -12,14 +12,14 @@
|
|||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
||||||
use std::net;
|
|
||||||
use std::path::{Path, PathBuf};
|
|
||||||
use std::time::{Duration, UNIX_EPOCH};
|
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::ffi::{CString, OsString};
|
use std::ffi::{CString, OsString};
|
||||||
|
use std::net;
|
||||||
|
use std::num::Wrapping;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::num::Wrapping;
|
use std::time::{Duration, UNIX_EPOCH};
|
||||||
|
|
||||||
#[cfg(feature = "unstable")]
|
#[cfg(feature = "unstable")]
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
|||||||
@@ -17,8 +17,8 @@
|
|||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
use self::serde::ser::{Serialize, Serializer};
|
|
||||||
use self::serde::de::{DeserializeOwned, Deserializer};
|
use self::serde::de::{DeserializeOwned, Deserializer};
|
||||||
|
use self::serde::ser::{Serialize, Serializer};
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
@@ -92,14 +92,10 @@ 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,
|
||||||
@@ -122,17 +118,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>>();
|
||||||
|
|
||||||
@@ -191,12 +183,16 @@ fn test_gen() {
|
|||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(bound = "D: SerializeWith + DeserializeWith")]
|
#[serde(bound = "D: SerializeWith + DeserializeWith")]
|
||||||
struct WithTraits1<D, E> {
|
struct WithTraits1<D, E> {
|
||||||
#[serde(serialize_with = "SerializeWith::serialize_with",
|
#[serde(
|
||||||
deserialize_with = "DeserializeWith::deserialize_with")]
|
serialize_with = "SerializeWith::serialize_with",
|
||||||
|
deserialize_with = "DeserializeWith::deserialize_with"
|
||||||
|
)]
|
||||||
d: D,
|
d: D,
|
||||||
#[serde(serialize_with = "SerializeWith::serialize_with",
|
#[serde(
|
||||||
deserialize_with = "DeserializeWith::deserialize_with",
|
serialize_with = "SerializeWith::serialize_with",
|
||||||
bound = "E: SerializeWith + DeserializeWith")]
|
deserialize_with = "DeserializeWith::deserialize_with",
|
||||||
|
bound = "E: SerializeWith + DeserializeWith"
|
||||||
|
)]
|
||||||
e: E,
|
e: E,
|
||||||
}
|
}
|
||||||
assert::<WithTraits1<X, X>>();
|
assert::<WithTraits1<X, X>>();
|
||||||
@@ -204,13 +200,18 @@ fn test_gen() {
|
|||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(bound(serialize = "D: SerializeWith", deserialize = "D: DeserializeWith"))]
|
#[serde(bound(serialize = "D: SerializeWith", deserialize = "D: DeserializeWith"))]
|
||||||
struct WithTraits2<D, E> {
|
struct WithTraits2<D, E> {
|
||||||
#[serde(serialize_with = "SerializeWith::serialize_with",
|
#[serde(
|
||||||
deserialize_with = "DeserializeWith::deserialize_with")]
|
serialize_with = "SerializeWith::serialize_with",
|
||||||
|
deserialize_with = "DeserializeWith::deserialize_with"
|
||||||
|
)]
|
||||||
d: D,
|
d: D,
|
||||||
#[serde(serialize_with = "SerializeWith::serialize_with",
|
#[serde(
|
||||||
bound(serialize = "E: SerializeWith"))]
|
serialize_with = "SerializeWith::serialize_with", bound(serialize = "E: SerializeWith")
|
||||||
#[serde(deserialize_with = "DeserializeWith::deserialize_with",
|
)]
|
||||||
bound(deserialize = "E: DeserializeWith"))]
|
#[serde(
|
||||||
|
deserialize_with = "DeserializeWith::deserialize_with",
|
||||||
|
bound(deserialize = "E: DeserializeWith")
|
||||||
|
)]
|
||||||
e: E,
|
e: E,
|
||||||
}
|
}
|
||||||
assert::<WithTraits2<X, X>>();
|
assert::<WithTraits2<X, X>>();
|
||||||
@@ -270,17 +271,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 {}
|
||||||
@@ -305,10 +300,7 @@ fn test_gen() {
|
|||||||
#[serde(skip_deserializing)]
|
#[serde(skip_deserializing)]
|
||||||
f: u8,
|
f: u8,
|
||||||
},
|
},
|
||||||
TupleSkip(
|
TupleSkip(#[serde(skip_deserializing)] u8),
|
||||||
#[serde(skip_deserializing)]
|
|
||||||
u8,
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "unstable")]
|
#[cfg(feature = "unstable")]
|
||||||
@@ -321,10 +313,7 @@ fn test_gen() {
|
|||||||
#[serde(skip_deserializing)]
|
#[serde(skip_deserializing)]
|
||||||
f: u8,
|
f: u8,
|
||||||
},
|
},
|
||||||
TupleSkip(
|
TupleSkip(#[serde(skip_deserializing)] u8),
|
||||||
#[serde(skip_deserializing)]
|
|
||||||
u8,
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
@@ -344,9 +333,7 @@ fn test_gen() {
|
|||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(untagged, remote = "Or")]
|
#[serde(untagged, remote = "Or")]
|
||||||
enum OrDef<A, B> {
|
enum OrDef<A, B> {
|
||||||
#[allow(dead_code)]
|
|
||||||
A(A),
|
A(A),
|
||||||
#[allow(dead_code)]
|
|
||||||
B(B),
|
B(B),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,6 +490,13 @@ fn test_gen() {
|
|||||||
}
|
}
|
||||||
assert_ser::<UntaggedVariantWith>();
|
assert_ser::<UntaggedVariantWith>();
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct FlattenWith {
|
||||||
|
#[serde(flatten, serialize_with = "ser_x", deserialize_with = "de_x")]
|
||||||
|
x: X,
|
||||||
|
}
|
||||||
|
assert::<FlattenWith>();
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct StaticStrStruct<'a> {
|
struct StaticStrStruct<'a> {
|
||||||
a: &'a str,
|
a: &'a str,
|
||||||
@@ -531,7 +525,9 @@ fn test_gen() {
|
|||||||
assert::<SkippedStaticStr>();
|
assert::<SkippedStaticStr>();
|
||||||
|
|
||||||
macro_rules! T {
|
macro_rules! T {
|
||||||
() => { () }
|
() => {
|
||||||
|
()
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
@@ -559,7 +555,7 @@ fn test_gen() {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct AssocDerive<T: AssocSerde> {
|
struct AssocDerive<T: AssocSerde> {
|
||||||
assoc: T::Assoc
|
assoc: T::Assoc,
|
||||||
}
|
}
|
||||||
|
|
||||||
assert::<AssocDerive<NoSerdeImpl>>();
|
assert::<AssocDerive<NoSerdeImpl>>();
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#![deny(trivial_numeric_casts)]
|
#![deny(trivial_numeric_casts)]
|
||||||
|
|
||||||
#![cfg_attr(feature = "cargo-clippy", allow(redundant_field_names))]
|
#![cfg_attr(feature = "cargo-clippy", allow(redundant_field_names))]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@@ -226,12 +225,10 @@ fn test_de_named_map() {
|
|||||||
fn test_ser_enum_unit() {
|
fn test_ser_enum_unit() {
|
||||||
assert_ser_tokens(
|
assert_ser_tokens(
|
||||||
&SerEnum::Unit::<u32, u32, u32>,
|
&SerEnum::Unit::<u32, u32, u32>,
|
||||||
&[
|
&[Token::UnitVariant {
|
||||||
Token::UnitVariant {
|
name: "SerEnum",
|
||||||
name: "SerEnum",
|
variant: "Unit",
|
||||||
variant: "Unit",
|
}],
|
||||||
},
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,12 +293,10 @@ fn test_ser_enum_map() {
|
|||||||
fn test_de_enum_unit() {
|
fn test_de_enum_unit() {
|
||||||
assert_tokens(
|
assert_tokens(
|
||||||
&DeEnum::Unit::<u32, u32, u32>,
|
&DeEnum::Unit::<u32, u32, u32>,
|
||||||
&[
|
&[Token::UnitVariant {
|
||||||
Token::UnitVariant {
|
name: "DeEnum",
|
||||||
name: "DeEnum",
|
variant: "Unit",
|
||||||
variant: "Unit",
|
}],
|
||||||
},
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,6 +441,51 @@ fn test_generic_newtype_struct() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_untagged_newtype_struct() {
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
enum E {
|
||||||
|
Newtype(GenericNewTypeStruct<u32>),
|
||||||
|
Null,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_tokens(
|
||||||
|
&E::Newtype(GenericNewTypeStruct(5u32)),
|
||||||
|
&[
|
||||||
|
Token::NewtypeStruct {
|
||||||
|
name: "GenericNewTypeStruct",
|
||||||
|
},
|
||||||
|
Token::U32(5),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_adjacently_tagged_newtype_struct() {
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "t", content = "c")]
|
||||||
|
enum E {
|
||||||
|
Newtype(GenericNewTypeStruct<u32>),
|
||||||
|
Null,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_de_tokens(
|
||||||
|
&E::Newtype(GenericNewTypeStruct(5u32)),
|
||||||
|
&[
|
||||||
|
Token::Struct { name: "E", len: 2 },
|
||||||
|
Token::Str("c"),
|
||||||
|
Token::NewtypeStruct {
|
||||||
|
name: "GenericNewTypeStruct",
|
||||||
|
},
|
||||||
|
Token::U32(5),
|
||||||
|
Token::Str("t"),
|
||||||
|
Token::Str("Newtype"),
|
||||||
|
Token::StructEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_generic_tuple_struct() {
|
fn test_generic_tuple_struct() {
|
||||||
assert_tokens(
|
assert_tokens(
|
||||||
@@ -466,12 +506,10 @@ fn test_generic_tuple_struct() {
|
|||||||
fn test_generic_enum_unit() {
|
fn test_generic_enum_unit() {
|
||||||
assert_tokens(
|
assert_tokens(
|
||||||
&GenericEnum::Unit::<u32, u32>,
|
&GenericEnum::Unit::<u32, u32>,
|
||||||
&[
|
&[Token::UnitVariant {
|
||||||
Token::UnitVariant {
|
name: "GenericEnum",
|
||||||
name: "GenericEnum",
|
variant: "Unit",
|
||||||
variant: "Unit",
|
}],
|
||||||
},
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -798,7 +836,9 @@ fn test_internally_tagged_bytes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&InternallyTagged::String { string: "\0".to_owned() },
|
&InternallyTagged::String {
|
||||||
|
string: "\0".to_owned(),
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Struct {
|
Token::Struct {
|
||||||
name: "String",
|
name: "String",
|
||||||
@@ -813,7 +853,9 @@ fn test_internally_tagged_bytes() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&InternallyTagged::String { string: "\0".to_owned() },
|
&InternallyTagged::String {
|
||||||
|
string: "\0".to_owned(),
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Struct {
|
Token::Struct {
|
||||||
name: "String",
|
name: "String",
|
||||||
@@ -828,7 +870,9 @@ fn test_internally_tagged_bytes() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&InternallyTagged::String { string: "\0".to_owned() },
|
&InternallyTagged::String {
|
||||||
|
string: "\0".to_owned(),
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Struct {
|
Token::Struct {
|
||||||
name: "String",
|
name: "String",
|
||||||
@@ -843,7 +887,9 @@ fn test_internally_tagged_bytes() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&InternallyTagged::String { string: "\0".to_owned() },
|
&InternallyTagged::String {
|
||||||
|
string: "\0".to_owned(),
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Struct {
|
Token::Struct {
|
||||||
name: "String",
|
name: "String",
|
||||||
@@ -1354,12 +1400,10 @@ fn test_enum_in_untagged_enum() {
|
|||||||
|
|
||||||
assert_tokens(
|
assert_tokens(
|
||||||
&Outer::Inner(Inner::Unit),
|
&Outer::Inner(Inner::Unit),
|
||||||
&[
|
&[Token::UnitVariant {
|
||||||
Token::UnitVariant {
|
name: "Inner",
|
||||||
name: "Inner",
|
variant: "Unit",
|
||||||
variant: "Unit",
|
}],
|
||||||
},
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_tokens(
|
assert_tokens(
|
||||||
@@ -1417,7 +1461,9 @@ fn test_untagged_bytes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&Untagged::String { string: "\0".to_owned() },
|
&Untagged::String {
|
||||||
|
string: "\0".to_owned(),
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Struct {
|
Token::Struct {
|
||||||
name: "Untagged",
|
name: "Untagged",
|
||||||
@@ -1430,7 +1476,9 @@ fn test_untagged_bytes() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&Untagged::String { string: "\0".to_owned() },
|
&Untagged::String {
|
||||||
|
string: "\0".to_owned(),
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Struct {
|
Token::Struct {
|
||||||
name: "Untagged",
|
name: "Untagged",
|
||||||
@@ -1443,7 +1491,9 @@ fn test_untagged_bytes() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&Untagged::String { string: "\0".to_owned() },
|
&Untagged::String {
|
||||||
|
string: "\0".to_owned(),
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Struct {
|
Token::Struct {
|
||||||
name: "Untagged",
|
name: "Untagged",
|
||||||
@@ -1456,7 +1506,9 @@ fn test_untagged_bytes() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&Untagged::String { string: "\0".to_owned() },
|
&Untagged::String {
|
||||||
|
string: "\0".to_owned(),
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Struct {
|
Token::Struct {
|
||||||
name: "Untagged",
|
name: "Untagged",
|
||||||
|
|||||||
@@ -121,10 +121,7 @@ struct UnitDef;
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::PrimitivePriv")]
|
#[serde(remote = "remote::PrimitivePriv")]
|
||||||
struct PrimitivePrivDef(
|
struct PrimitivePrivDef(#[serde(getter = "remote::PrimitivePriv::get")] u8);
|
||||||
#[serde(getter = "remote::PrimitivePriv::get")]
|
|
||||||
u8,
|
|
||||||
);
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::PrimitivePub")]
|
#[serde(remote = "remote::PrimitivePub")]
|
||||||
@@ -132,34 +129,22 @@ 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")]
|
||||||
struct NewtypePubDef(
|
struct NewtypePubDef(#[serde(with = "UnitDef")] remote::Unit);
|
||||||
#[serde(with = "UnitDef")]
|
|
||||||
remote::Unit,
|
|
||||||
);
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::TuplePriv")]
|
#[serde(remote = "remote::TuplePriv")]
|
||||||
struct TuplePrivDef(
|
struct TuplePrivDef(
|
||||||
#[serde(getter = "remote::TuplePriv::first")]
|
#[serde(getter = "remote::TuplePriv::first")] u8,
|
||||||
u8,
|
#[serde(getter = "remote::TuplePriv::second", with = "UnitDef")] remote::Unit,
|
||||||
#[serde(getter = "remote::TuplePriv::second", with = "UnitDef")]
|
|
||||||
remote::Unit,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::TuplePub")]
|
#[serde(remote = "remote::TuplePub")]
|
||||||
struct TuplePubDef(
|
struct TuplePubDef(u8, #[serde(with = "UnitDef")] remote::Unit);
|
||||||
u8,
|
|
||||||
#[serde(with = "UnitDef")]
|
|
||||||
remote::Unit,
|
|
||||||
);
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::StructPriv")]
|
#[serde(remote = "remote::StructPriv")]
|
||||||
@@ -175,10 +160,8 @@ struct StructPrivDef {
|
|||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::StructPub")]
|
#[serde(remote = "remote::StructPub")]
|
||||||
struct StructPubDef {
|
struct StructPubDef {
|
||||||
#[allow(dead_code)]
|
|
||||||
a: u8,
|
a: u8,
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[serde(with = "UnitDef")]
|
#[serde(with = "UnitDef")]
|
||||||
b: remote::Unit,
|
b: remote::Unit,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,13 +10,13 @@
|
|||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
||||||
use std::net;
|
|
||||||
use std::path::{Path, PathBuf};
|
|
||||||
use std::time::{Duration, UNIX_EPOCH};
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
use std::net;
|
||||||
|
use std::num::Wrapping;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::num::Wrapping;
|
use std::time::{Duration, UNIX_EPOCH};
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
use serde::Deserialize;
|
|
||||||
use serde::de::{value, IntoDeserializer};
|
use serde::de::{value, IntoDeserializer};
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_u32_to_enum() {
|
fn test_u32_to_enum() {
|
||||||
|
|||||||
Reference in New Issue
Block a user