mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-27 21:37:55 +00:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1b4da41f97 | |||
| f61d452814 | |||
| f9866097a0 | |||
| 77a6a9d4e1 | |||
| 547d843cca | |||
| 005cb84593 | |||
| fd5b5e9aa5 | |||
| 0647a7c1fe | |||
| 85c73ef8de | |||
| 5ba1796a7e | |||
| e52b7b380f | |||
| 84c7419652 | |||
| 536221b1f9 | |||
| fc55ac70d3 | |||
| 2afe5b4ef9 | |||
| b4ec2595c9 | |||
| c3ac7b675a | |||
| 24614e44bf | |||
| 9b868ef831 | |||
| c3eaf76430 | |||
| 32958dec3b | |||
| d64a97ba1e | |||
| c3df3372a1 | |||
| 8764353fe2 | |||
| e08c5de5dd | |||
| bc5af506bd | |||
| 28a092261b |
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.204"
|
version = "1.0.207"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
categories = ["encoding", "no-std", "no-std::no-alloc"]
|
categories = ["encoding", "no-std", "no-std::no-alloc"]
|
||||||
@@ -37,7 +37,7 @@ rustdoc-args = ["--generate-link-to-definition"]
|
|||||||
# is compatible with exactly one serde release because the generated code
|
# is compatible with exactly one serde release because the generated code
|
||||||
# involves nonpublic APIs which are not bound by semver.
|
# involves nonpublic APIs which are not bound by semver.
|
||||||
[target.'cfg(any())'.dependencies]
|
[target.'cfg(any())'.dependencies]
|
||||||
serde_derive = { version = "=1.0.204", path = "../serde_derive" }
|
serde_derive = { version = "=1.0.207", path = "../serde_derive" }
|
||||||
|
|
||||||
|
|
||||||
### FEATURES #################################################################
|
### FEATURES #################################################################
|
||||||
|
|||||||
+1
-1
@@ -95,7 +95,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.204")]
|
#![doc(html_root_url = "https://docs.rs/serde/1.0.207")]
|
||||||
// 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)]
|
||||||
// Show which crate feature enables conditionally compiled APIs in documentation.
|
// Show which crate feature enables conditionally compiled APIs in documentation.
|
||||||
|
|||||||
@@ -1125,8 +1125,7 @@ where
|
|||||||
where
|
where
|
||||||
T: ?Sized + Serialize,
|
T: ?Sized + Serialize,
|
||||||
{
|
{
|
||||||
tri!(self.0.serialize_key(variant));
|
self.0.serialize_entry(variant, value)
|
||||||
self.0.serialize_value(value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
|
fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.204"
|
version = "1.0.207"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||||
categories = ["no-std", "no-std::no-alloc"]
|
categories = ["no-std", "no-std::no-alloc"]
|
||||||
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
||||||
|
|||||||
+52
-28
@@ -461,7 +461,10 @@ fn deserialize_tuple(
|
|||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
form: TupleForm,
|
form: TupleForm,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
assert!(!cattrs.has_flatten());
|
assert!(
|
||||||
|
!has_flatten(fields),
|
||||||
|
"tuples and tuple variants cannot have flatten fields"
|
||||||
|
);
|
||||||
|
|
||||||
let field_count = fields
|
let field_count = fields
|
||||||
.iter()
|
.iter()
|
||||||
@@ -579,7 +582,10 @@ fn deserialize_tuple_in_place(
|
|||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
assert!(!cattrs.has_flatten());
|
assert!(
|
||||||
|
!has_flatten(fields),
|
||||||
|
"tuples and tuple variants cannot have flatten fields"
|
||||||
|
);
|
||||||
|
|
||||||
let field_count = fields
|
let field_count = fields
|
||||||
.iter()
|
.iter()
|
||||||
@@ -958,13 +964,15 @@ fn deserialize_struct(
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let field_visitor = deserialize_field_identifier(&field_names_idents, cattrs);
|
|
||||||
|
let has_flatten = has_flatten(fields);
|
||||||
|
let field_visitor = deserialize_field_identifier(&field_names_idents, cattrs, has_flatten);
|
||||||
|
|
||||||
// untagged struct variants do not get a visit_seq method. The same applies to
|
// untagged struct variants do not get a visit_seq method. The same applies to
|
||||||
// structs that only have a map representation.
|
// structs that only have a map representation.
|
||||||
let visit_seq = match form {
|
let visit_seq = match form {
|
||||||
StructForm::Untagged(..) => None,
|
StructForm::Untagged(..) => None,
|
||||||
_ if cattrs.has_flatten() => None,
|
_ if has_flatten => None,
|
||||||
_ => {
|
_ => {
|
||||||
let mut_seq = if field_names_idents.is_empty() {
|
let mut_seq = if field_names_idents.is_empty() {
|
||||||
quote!(_)
|
quote!(_)
|
||||||
@@ -987,10 +995,16 @@ fn deserialize_struct(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let visit_map = Stmts(deserialize_map(&type_path, params, fields, cattrs));
|
let visit_map = Stmts(deserialize_map(
|
||||||
|
&type_path,
|
||||||
|
params,
|
||||||
|
fields,
|
||||||
|
cattrs,
|
||||||
|
has_flatten,
|
||||||
|
));
|
||||||
|
|
||||||
let visitor_seed = match form {
|
let visitor_seed = match form {
|
||||||
StructForm::ExternallyTagged(..) if cattrs.has_flatten() => Some(quote! {
|
StructForm::ExternallyTagged(..) if has_flatten => Some(quote! {
|
||||||
impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Visitor #de_ty_generics #where_clause {
|
impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Visitor #de_ty_generics #where_clause {
|
||||||
type Value = #this_type #ty_generics;
|
type Value = #this_type #ty_generics;
|
||||||
|
|
||||||
@@ -1005,7 +1019,7 @@ fn deserialize_struct(
|
|||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let fields_stmt = if cattrs.has_flatten() {
|
let fields_stmt = if has_flatten {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let field_names = field_names_idents
|
let field_names = field_names_idents
|
||||||
@@ -1025,7 +1039,7 @@ fn deserialize_struct(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
let dispatch = match form {
|
let dispatch = match form {
|
||||||
StructForm::Struct if cattrs.has_flatten() => quote! {
|
StructForm::Struct if has_flatten => quote! {
|
||||||
_serde::Deserializer::deserialize_map(__deserializer, #visitor_expr)
|
_serde::Deserializer::deserialize_map(__deserializer, #visitor_expr)
|
||||||
},
|
},
|
||||||
StructForm::Struct => {
|
StructForm::Struct => {
|
||||||
@@ -1034,7 +1048,7 @@ fn deserialize_struct(
|
|||||||
_serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr)
|
_serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StructForm::ExternallyTagged(_) if cattrs.has_flatten() => quote! {
|
StructForm::ExternallyTagged(_) if has_flatten => quote! {
|
||||||
_serde::de::VariantAccess::newtype_variant_seed(__variant, #visitor_expr)
|
_serde::de::VariantAccess::newtype_variant_seed(__variant, #visitor_expr)
|
||||||
},
|
},
|
||||||
StructForm::ExternallyTagged(_) => quote! {
|
StructForm::ExternallyTagged(_) => quote! {
|
||||||
@@ -1091,7 +1105,7 @@ fn deserialize_struct_in_place(
|
|||||||
) -> Option<Fragment> {
|
) -> Option<Fragment> {
|
||||||
// for now we do not support in_place deserialization for structs that
|
// for now we do not support in_place deserialization for structs that
|
||||||
// are represented as map.
|
// are represented as map.
|
||||||
if cattrs.has_flatten() {
|
if has_flatten(fields) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1116,7 +1130,7 @@ fn deserialize_struct_in_place(
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let field_visitor = deserialize_field_identifier(&field_names_idents, cattrs);
|
let field_visitor = deserialize_field_identifier(&field_names_idents, cattrs, false);
|
||||||
|
|
||||||
let mut_seq = if field_names_idents.is_empty() {
|
let mut_seq = if field_names_idents.is_empty() {
|
||||||
quote!(_)
|
quote!(_)
|
||||||
@@ -1210,10 +1224,7 @@ fn deserialize_homogeneous_enum(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_enum_variant_enum(
|
fn prepare_enum_variant_enum(variants: &[Variant]) -> (TokenStream, Stmts) {
|
||||||
variants: &[Variant],
|
|
||||||
cattrs: &attr::Container,
|
|
||||||
) -> (TokenStream, Stmts) {
|
|
||||||
let mut deserialized_variants = variants
|
let mut deserialized_variants = variants
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
@@ -1247,7 +1258,7 @@ fn prepare_enum_variant_enum(
|
|||||||
|
|
||||||
let variant_visitor = Stmts(deserialize_generated_identifier(
|
let variant_visitor = Stmts(deserialize_generated_identifier(
|
||||||
&variant_names_idents,
|
&variant_names_idents,
|
||||||
cattrs,
|
false, // variant identifiers do not depend on the presence of flatten fields
|
||||||
true,
|
true,
|
||||||
None,
|
None,
|
||||||
fallthrough,
|
fallthrough,
|
||||||
@@ -1270,7 +1281,7 @@ fn deserialize_externally_tagged_enum(
|
|||||||
let expecting = format!("enum {}", params.type_name());
|
let expecting = format!("enum {}", params.type_name());
|
||||||
let expecting = cattrs.expecting().unwrap_or(&expecting);
|
let expecting = cattrs.expecting().unwrap_or(&expecting);
|
||||||
|
|
||||||
let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs);
|
let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants);
|
||||||
|
|
||||||
// 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
|
||||||
@@ -1355,7 +1366,7 @@ fn deserialize_internally_tagged_enum(
|
|||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
tag: &str,
|
tag: &str,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs);
|
let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants);
|
||||||
|
|
||||||
// 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
|
||||||
@@ -1409,7 +1420,7 @@ fn deserialize_adjacently_tagged_enum(
|
|||||||
split_with_de_lifetime(params);
|
split_with_de_lifetime(params);
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
|
|
||||||
let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs);
|
let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants);
|
||||||
|
|
||||||
let variant_arms: &Vec<_> = &variants
|
let variant_arms: &Vec<_> = &variants
|
||||||
.iter()
|
.iter()
|
||||||
@@ -1985,7 +1996,7 @@ fn deserialize_untagged_newtype_variant(
|
|||||||
|
|
||||||
fn deserialize_generated_identifier(
|
fn deserialize_generated_identifier(
|
||||||
fields: &[(&str, Ident, &BTreeSet<String>)],
|
fields: &[(&str, Ident, &BTreeSet<String>)],
|
||||||
cattrs: &attr::Container,
|
has_flatten: bool,
|
||||||
is_variant: bool,
|
is_variant: bool,
|
||||||
ignore_variant: Option<TokenStream>,
|
ignore_variant: Option<TokenStream>,
|
||||||
fallthrough: Option<TokenStream>,
|
fallthrough: Option<TokenStream>,
|
||||||
@@ -1999,11 +2010,11 @@ fn deserialize_generated_identifier(
|
|||||||
is_variant,
|
is_variant,
|
||||||
fallthrough,
|
fallthrough,
|
||||||
None,
|
None,
|
||||||
!is_variant && cattrs.has_flatten(),
|
!is_variant && has_flatten,
|
||||||
None,
|
None,
|
||||||
));
|
));
|
||||||
|
|
||||||
let lifetime = if !is_variant && cattrs.has_flatten() {
|
let lifetime = if !is_variant && has_flatten {
|
||||||
Some(quote!(<'de>))
|
Some(quote!(<'de>))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -2043,8 +2054,9 @@ fn deserialize_generated_identifier(
|
|||||||
fn deserialize_field_identifier(
|
fn deserialize_field_identifier(
|
||||||
fields: &[(&str, Ident, &BTreeSet<String>)],
|
fields: &[(&str, Ident, &BTreeSet<String>)],
|
||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
|
has_flatten: bool,
|
||||||
) -> Stmts {
|
) -> Stmts {
|
||||||
let (ignore_variant, fallthrough) = if cattrs.has_flatten() {
|
let (ignore_variant, fallthrough) = if has_flatten {
|
||||||
let ignore_variant = quote!(__other(_serde::__private::de::Content<'de>),);
|
let ignore_variant = quote!(__other(_serde::__private::de::Content<'de>),);
|
||||||
let fallthrough = quote!(_serde::__private::Ok(__Field::__other(__value)));
|
let fallthrough = quote!(_serde::__private::Ok(__Field::__other(__value)));
|
||||||
(Some(ignore_variant), Some(fallthrough))
|
(Some(ignore_variant), Some(fallthrough))
|
||||||
@@ -2058,7 +2070,7 @@ fn deserialize_field_identifier(
|
|||||||
|
|
||||||
Stmts(deserialize_generated_identifier(
|
Stmts(deserialize_generated_identifier(
|
||||||
fields,
|
fields,
|
||||||
cattrs,
|
has_flatten,
|
||||||
false,
|
false,
|
||||||
ignore_variant,
|
ignore_variant,
|
||||||
fallthrough,
|
fallthrough,
|
||||||
@@ -2460,6 +2472,7 @@ fn deserialize_map(
|
|||||||
params: &Parameters,
|
params: &Parameters,
|
||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
|
has_flatten: bool,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
// Create the field names for the fields.
|
// Create the field names for the fields.
|
||||||
let fields_names: Vec<_> = fields
|
let fields_names: Vec<_> = fields
|
||||||
@@ -2480,7 +2493,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 has_flatten {
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
let mut __collect = _serde::__private::Vec::<_serde::__private::Option<(
|
let mut __collect = _serde::__private::Vec::<_serde::__private::Option<(
|
||||||
_serde::__private::de::Content,
|
_serde::__private::de::Content,
|
||||||
@@ -2532,7 +2545,7 @@ fn deserialize_map(
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Visit ignored values to consume them
|
// Visit ignored values to consume them
|
||||||
let ignored_arm = if cattrs.has_flatten() {
|
let ignored_arm = if has_flatten {
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
__Field::__other(__name) => {
|
__Field::__other(__name) => {
|
||||||
__collect.push(_serde::__private::Some((
|
__collect.push(_serde::__private::Some((
|
||||||
@@ -2602,7 +2615,7 @@ fn deserialize_map(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let collected_deny_unknown_fields = if cattrs.has_flatten() && cattrs.deny_unknown_fields() {
|
let collected_deny_unknown_fields = if has_flatten && cattrs.deny_unknown_fields() {
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
if let _serde::__private::Some(_serde::__private::Some((__key, _))) =
|
if let _serde::__private::Some(_serde::__private::Some((__key, _))) =
|
||||||
__collect.into_iter().filter(_serde::__private::Option::is_some).next()
|
__collect.into_iter().filter(_serde::__private::Option::is_some).next()
|
||||||
@@ -2678,7 +2691,10 @@ fn deserialize_map_in_place(
|
|||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
assert!(!cattrs.has_flatten());
|
assert!(
|
||||||
|
!has_flatten(fields),
|
||||||
|
"inplace deserialization of maps does not support flatten fields"
|
||||||
|
);
|
||||||
|
|
||||||
// Create the field names for the fields.
|
// Create the field names for the fields.
|
||||||
let fields_names: Vec<_> = fields
|
let fields_names: Vec<_> = fields
|
||||||
@@ -3011,6 +3027,14 @@ fn effective_style(variant: &Variant) -> Style {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// True if there is any field with a `#[serde(flatten)]` attribute, other than
|
||||||
|
/// fields which are skipped.
|
||||||
|
fn has_flatten(fields: &[Field]) -> bool {
|
||||||
|
fields
|
||||||
|
.iter()
|
||||||
|
.any(|field| field.attrs.flatten() && !field.attrs.skip_deserializing())
|
||||||
|
}
|
||||||
|
|
||||||
struct DeImplGenerics<'a>(&'a Parameters);
|
struct DeImplGenerics<'a>(&'a Parameters);
|
||||||
#[cfg(feature = "deserialize_in_place")]
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
struct InPlaceImplGenerics<'a>(&'a Parameters);
|
struct InPlaceImplGenerics<'a>(&'a Parameters);
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ impl<'a> Container<'a> {
|
|||||||
item: &'a syn::DeriveInput,
|
item: &'a syn::DeriveInput,
|
||||||
derive: Derive,
|
derive: Derive,
|
||||||
) -> Option<Container<'a>> {
|
) -> Option<Container<'a>> {
|
||||||
let mut attrs = attr::Container::from_ast(cx, item);
|
let attrs = attr::Container::from_ast(cx, item);
|
||||||
|
|
||||||
let mut data = match &item.data {
|
let mut data = match &item.data {
|
||||||
syn::Data::Enum(data) => Data::Enum(enum_from_ast(cx, &data.variants, attrs.default())),
|
syn::Data::Enum(data) => Data::Enum(enum_from_ast(cx, &data.variants, attrs.default())),
|
||||||
@@ -77,15 +77,11 @@ impl<'a> Container<'a> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut has_flatten = false;
|
|
||||||
match &mut data {
|
match &mut data {
|
||||||
Data::Enum(variants) => {
|
Data::Enum(variants) => {
|
||||||
for variant in variants {
|
for variant in variants {
|
||||||
variant.attrs.rename_by_rules(attrs.rename_all_rules());
|
variant.attrs.rename_by_rules(attrs.rename_all_rules());
|
||||||
for field in &mut variant.fields {
|
for field in &mut variant.fields {
|
||||||
if field.attrs.flatten() {
|
|
||||||
has_flatten = true;
|
|
||||||
}
|
|
||||||
field.attrs.rename_by_rules(
|
field.attrs.rename_by_rules(
|
||||||
variant
|
variant
|
||||||
.attrs
|
.attrs
|
||||||
@@ -97,18 +93,11 @@ impl<'a> Container<'a> {
|
|||||||
}
|
}
|
||||||
Data::Struct(_, fields) => {
|
Data::Struct(_, fields) => {
|
||||||
for field in fields {
|
for field in fields {
|
||||||
if field.attrs.flatten() {
|
|
||||||
has_flatten = true;
|
|
||||||
}
|
|
||||||
field.attrs.rename_by_rules(attrs.rename_all_rules());
|
field.attrs.rename_by_rules(attrs.rename_all_rules());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if has_flatten {
|
|
||||||
attrs.mark_has_flatten();
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut item = Container {
|
let mut item = Container {
|
||||||
ident: item.ident.clone(),
|
ident: item.ident.clone(),
|
||||||
attrs,
|
attrs,
|
||||||
|
|||||||
@@ -216,7 +216,6 @@ pub struct Container {
|
|||||||
type_into: Option<syn::Type>,
|
type_into: Option<syn::Type>,
|
||||||
remote: Option<syn::Path>,
|
remote: Option<syn::Path>,
|
||||||
identifier: Identifier,
|
identifier: Identifier,
|
||||||
has_flatten: bool,
|
|
||||||
serde_path: Option<syn::Path>,
|
serde_path: Option<syn::Path>,
|
||||||
is_packed: bool,
|
is_packed: bool,
|
||||||
/// Error message generated when type can't be deserialized
|
/// Error message generated when type can't be deserialized
|
||||||
@@ -587,7 +586,6 @@ impl Container {
|
|||||||
type_into: type_into.get(),
|
type_into: type_into.get(),
|
||||||
remote: remote.get(),
|
remote: remote.get(),
|
||||||
identifier: decide_identifier(cx, item, field_identifier, variant_identifier),
|
identifier: decide_identifier(cx, item, field_identifier, variant_identifier),
|
||||||
has_flatten: false,
|
|
||||||
serde_path: serde_path.get(),
|
serde_path: serde_path.get(),
|
||||||
is_packed,
|
is_packed,
|
||||||
expecting: expecting.get(),
|
expecting: expecting.get(),
|
||||||
@@ -655,14 +653,6 @@ impl Container {
|
|||||||
self.identifier
|
self.identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_flatten(&self) -> bool {
|
|
||||||
self.has_flatten
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mark_has_flatten(&mut self) {
|
|
||||||
self.has_flatten = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn custom_serde_path(&self) -> Option<&syn::Path> {
|
pub fn custom_serde_path(&self) -> Option<&syn::Path> {
|
||||||
self.serde_path.as_ref()
|
self.serde_path.as_ref()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,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.204")]
|
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.207")]
|
||||||
#![cfg_attr(not(check_cfg), allow(unexpected_cfgs))]
|
#![cfg_attr(not(check_cfg), allow(unexpected_cfgs))]
|
||||||
// Ignored clippy lints
|
// Ignored clippy lints
|
||||||
#![allow(
|
#![allow(
|
||||||
|
|||||||
+12
-21
@@ -289,9 +289,18 @@ fn serialize_tuple_struct(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Container) -> Fragment {
|
fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Container) -> Fragment {
|
||||||
assert!(fields.len() as u64 <= u64::from(u32::MAX));
|
assert!(
|
||||||
|
fields.len() as u64 <= u64::from(u32::MAX),
|
||||||
|
"too many fields in {}: {}, maximum supported count is {}",
|
||||||
|
cattrs.name().serialize_name(),
|
||||||
|
fields.len(),
|
||||||
|
u32::MAX,
|
||||||
|
);
|
||||||
|
|
||||||
if cattrs.has_flatten() {
|
let has_non_skipped_flatten = fields
|
||||||
|
.iter()
|
||||||
|
.any(|field| field.attrs.flatten() && !field.attrs.skip_serializing());
|
||||||
|
if has_non_skipped_flatten {
|
||||||
serialize_struct_as_map(params, fields, cattrs)
|
serialize_struct_as_map(params, fields, cattrs)
|
||||||
} else {
|
} else {
|
||||||
serialize_struct_as_struct(params, fields, cattrs)
|
serialize_struct_as_struct(params, fields, cattrs)
|
||||||
@@ -370,26 +379,8 @@ fn serialize_struct_as_map(
|
|||||||
|
|
||||||
let let_mut = mut_if(serialized_fields.peek().is_some() || tag_field_exists);
|
let let_mut = mut_if(serialized_fields.peek().is_some() || tag_field_exists);
|
||||||
|
|
||||||
let len = if cattrs.has_flatten() {
|
|
||||||
quote!(_serde::__private::None)
|
|
||||||
} else {
|
|
||||||
let len = serialized_fields
|
|
||||||
.map(|field| match field.attrs.skip_serializing_if() {
|
|
||||||
None => quote!(1),
|
|
||||||
Some(path) => {
|
|
||||||
let field_expr = get_member(params, field, &field.member);
|
|
||||||
quote!(if #path(#field_expr) { 0 } else { 1 })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.fold(
|
|
||||||
quote!(#tag_field_exists as usize),
|
|
||||||
|sum, expr| quote!(#sum + #expr),
|
|
||||||
);
|
|
||||||
quote!(_serde::__private::Some(#len))
|
|
||||||
};
|
|
||||||
|
|
||||||
quote_block! {
|
quote_block! {
|
||||||
let #let_mut __serde_state = _serde::Serializer::serialize_map(__serializer, #len)?;
|
let #let_mut __serde_state = _serde::Serializer::serialize_map(__serializer, _serde::__private::None)?;
|
||||||
#tag_field
|
#tag_field
|
||||||
#(#serialize_fields)*
|
#(#serialize_fields)*
|
||||||
_serde::ser::SerializeMap::end(__serde_state)
|
_serde::ser::SerializeMap::end(__serde_state)
|
||||||
|
|||||||
@@ -23,21 +23,21 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
|
|||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct Unit;
|
pub struct Unit;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct Newtype(u8);
|
pub struct Newtype(u8);
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct Tuple(u8, u8);
|
pub struct Tuple(u8, u8);
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct Struct {
|
pub struct Struct {
|
||||||
f: u8,
|
f: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
enum Enum {
|
pub enum Enum {
|
||||||
Unit,
|
Unit,
|
||||||
Newtype(u8),
|
Newtype(u8),
|
||||||
Tuple(u8, u8),
|
Tuple(u8, u8),
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#![allow(dead_code)] // we do not read enum fields
|
||||||
|
|
||||||
|
use serde_derive::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct Nested;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub enum ExternallyTagged1 {
|
||||||
|
Tuple(f64, String),
|
||||||
|
Flatten {
|
||||||
|
#[serde(flatten)]
|
||||||
|
nested: Nested,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub enum ExternallyTagged2 {
|
||||||
|
Flatten {
|
||||||
|
#[serde(flatten)]
|
||||||
|
nested: Nested,
|
||||||
|
},
|
||||||
|
Tuple(f64, String),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internally tagged enums cannot contain tuple variants so not tested here
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(tag = "tag", content = "content")]
|
||||||
|
pub enum AdjacentlyTagged1 {
|
||||||
|
Tuple(f64, String),
|
||||||
|
Flatten {
|
||||||
|
#[serde(flatten)]
|
||||||
|
nested: Nested,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(tag = "tag", content = "content")]
|
||||||
|
pub enum AdjacentlyTagged2 {
|
||||||
|
Flatten {
|
||||||
|
#[serde(flatten)]
|
||||||
|
nested: Nested,
|
||||||
|
},
|
||||||
|
Tuple(f64, String),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum Untagged1 {
|
||||||
|
Tuple(f64, String),
|
||||||
|
Flatten {
|
||||||
|
#[serde(flatten)]
|
||||||
|
nested: Nested,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum Untagged2 {
|
||||||
|
Flatten {
|
||||||
|
#[serde(flatten)]
|
||||||
|
nested: Nested,
|
||||||
|
},
|
||||||
|
Tuple(f64, String),
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
use serde_derive::{Serialize, Deserialize};
|
||||||
|
use serde_test::{assert_tokens, Token};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
||||||
|
enum Enum {
|
||||||
|
Simple {
|
||||||
|
a: i32,
|
||||||
|
},
|
||||||
|
Flatten {
|
||||||
|
#[serde(flatten)]
|
||||||
|
flatten: (),
|
||||||
|
a: i32,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn simple_variant() {
|
||||||
|
assert_tokens(
|
||||||
|
&Enum::Simple { a: 42 },
|
||||||
|
&[
|
||||||
|
Token::StructVariant { name: "Enum", variant: "Simple", len: 1 },
|
||||||
|
Token::Str("a"),
|
||||||
|
Token::I32(42),
|
||||||
|
Token::StructVariantEnd,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn flatten_variant() {
|
||||||
|
assert_tokens(
|
||||||
|
&Enum::Flatten { flatten: (), a: 42 },
|
||||||
|
&[
|
||||||
|
Token::NewtypeVariant { name: "Enum", variant: "Flatten" },
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::Str("a"),
|
||||||
|
Token::I32(42),
|
||||||
|
Token::MapEnd,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#![allow(dead_code)] // we do not read enum fields
|
||||||
|
|
||||||
|
use serde_derive::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
pub enum A {
|
||||||
|
B {
|
||||||
|
c: String,
|
||||||
|
},
|
||||||
|
D {
|
||||||
|
#[serde(flatten)]
|
||||||
|
e: E,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct E {}
|
||||||
@@ -2380,6 +2380,56 @@ fn test_partially_untagged_enum_desugared() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Regression test for https://github.com/serde-rs/serde/issues/1904
|
||||||
|
#[test]
|
||||||
|
fn test_enum_tuple_and_struct_with_flatten() {
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
enum Outer {
|
||||||
|
Tuple(f64, i32),
|
||||||
|
Flatten {
|
||||||
|
#[serde(flatten)]
|
||||||
|
nested: Nested,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
struct Nested {
|
||||||
|
a: i32,
|
||||||
|
b: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_tokens(
|
||||||
|
&Outer::Tuple(1.2, 3),
|
||||||
|
&[
|
||||||
|
Token::TupleVariant {
|
||||||
|
name: "Outer",
|
||||||
|
variant: "Tuple",
|
||||||
|
len: 2,
|
||||||
|
},
|
||||||
|
Token::F64(1.2),
|
||||||
|
Token::I32(3),
|
||||||
|
Token::TupleVariantEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
assert_tokens(
|
||||||
|
&Outer::Flatten {
|
||||||
|
nested: Nested { a: 1, b: 2 },
|
||||||
|
},
|
||||||
|
&[
|
||||||
|
Token::NewtypeVariant {
|
||||||
|
name: "Outer",
|
||||||
|
variant: "Flatten",
|
||||||
|
},
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::Str("a"),
|
||||||
|
Token::I32(1),
|
||||||
|
Token::Str("b"),
|
||||||
|
Token::I32(2),
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_partially_untagged_internally_tagged_enum() {
|
fn test_partially_untagged_internally_tagged_enum() {
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ fn test_cow() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_lifetimes() {
|
fn test_lifetimes() {
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Cows<'a, 'b> {
|
pub struct Cows<'a, 'b> {
|
||||||
_copied: Cow<'a, str>,
|
_copied: Cow<'a, str>,
|
||||||
|
|
||||||
#[serde(borrow)]
|
#[serde(borrow)]
|
||||||
@@ -178,7 +178,7 @@ fn test_lifetimes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Wrap<'a, 'b> {
|
pub struct Wrap<'a, 'b> {
|
||||||
#[serde(borrow = "'b")]
|
#[serde(borrow = "'b")]
|
||||||
_cows: Cows<'a, 'b>,
|
_cows: Cows<'a, 'b>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ struct StructSkipDefault {
|
|||||||
|
|
||||||
#[derive(PartialEq, Debug, Deserialize)]
|
#[derive(PartialEq, Debug, Deserialize)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
struct StructSkipDefaultGeneric<T> {
|
pub struct StructSkipDefaultGeneric<T> {
|
||||||
#[serde(skip_deserializing)]
|
#[serde(skip_deserializing)]
|
||||||
t: T,
|
t: T,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#![deny(warnings)]
|
#![deny(warnings)]
|
||||||
#![allow(
|
#![allow(
|
||||||
|
confusable_idents,
|
||||||
unknown_lints,
|
unknown_lints,
|
||||||
mixed_script_confusables,
|
mixed_script_confusables,
|
||||||
clippy::derive_partial_eq_without_eq,
|
clippy::derive_partial_eq_without_eq,
|
||||||
@@ -19,6 +20,7 @@
|
|||||||
clippy::trivially_copy_pass_by_ref,
|
clippy::trivially_copy_pass_by_ref,
|
||||||
clippy::type_repetition_in_bounds
|
clippy::type_repetition_in_bounds
|
||||||
)]
|
)]
|
||||||
|
#![deny(clippy::collection_is_never_read)]
|
||||||
|
|
||||||
use serde::de::{Deserialize, DeserializeOwned, Deserializer};
|
use serde::de::{Deserialize, DeserializeOwned, Deserializer};
|
||||||
use serde::ser::{Serialize, Serializer};
|
use serde::ser::{Serialize, Serializer};
|
||||||
@@ -287,60 +289,60 @@ fn test_gen() {
|
|||||||
assert::<EmptyEnumVariant>();
|
assert::<EmptyEnumVariant>();
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct NonAsciiIdents {
|
pub struct NonAsciiIdents {
|
||||||
σ: f64,
|
σ: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct EmptyBraced {}
|
pub struct EmptyBraced {}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct EmptyBracedDenyUnknown {}
|
pub struct EmptyBracedDenyUnknown {}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct BracedSkipAll {
|
pub 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 {
|
pub struct BracedSkipAllDenyUnknown {
|
||||||
#[serde(skip_deserializing)]
|
#[serde(skip_deserializing)]
|
||||||
f: u8,
|
f: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct EmptyTuple();
|
pub struct EmptyTuple();
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct EmptyTupleDenyUnknown();
|
pub struct EmptyTupleDenyUnknown();
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct TupleSkipAll(#[serde(skip_deserializing)] u8);
|
pub struct TupleSkipAll(#[serde(skip_deserializing)] u8);
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct TupleSkipAllDenyUnknown(#[serde(skip_deserializing)] u8);
|
pub struct TupleSkipAllDenyUnknown(#[serde(skip_deserializing)] u8);
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
enum EmptyEnum {}
|
pub enum EmptyEnum {}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
enum EmptyEnumDenyUnknown {}
|
pub enum EmptyEnumDenyUnknown {}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
enum EnumSkipAll {
|
pub enum EnumSkipAll {
|
||||||
#[serde(skip_deserializing)]
|
#[serde(skip_deserializing)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
Variant,
|
Variant,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
enum EmptyVariants {
|
pub enum EmptyVariants {
|
||||||
Braced {},
|
Braced {},
|
||||||
Tuple(),
|
Tuple(),
|
||||||
BracedSkip {
|
BracedSkip {
|
||||||
@@ -352,7 +354,7 @@ fn test_gen() {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
enum EmptyVariantsDenyUnknown {
|
pub enum EmptyVariantsDenyUnknown {
|
||||||
Braced {},
|
Braced {},
|
||||||
Tuple(),
|
Tuple(),
|
||||||
BracedSkip {
|
BracedSkip {
|
||||||
@@ -364,21 +366,21 @@ fn test_gen() {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct UnitDenyUnknown;
|
pub struct UnitDenyUnknown;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct EmptyArray {
|
pub struct EmptyArray {
|
||||||
empty: [X; 0],
|
empty: [X; 0],
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Or<A, B> {
|
pub enum Or<A, B> {
|
||||||
A(A),
|
A(A),
|
||||||
B(B),
|
B(B),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(untagged, remote = "Or")]
|
#[serde(untagged, remote = "Or")]
|
||||||
enum OrDef<A, B> {
|
pub enum OrDef<A, B> {
|
||||||
A(A),
|
A(A),
|
||||||
B(B),
|
B(B),
|
||||||
}
|
}
|
||||||
@@ -390,7 +392,7 @@ fn test_gen() {
|
|||||||
struct StrDef<'a>(&'a str);
|
struct StrDef<'a>(&'a str);
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct Remote<'a> {
|
pub struct Remote<'a> {
|
||||||
#[serde(with = "OrDef")]
|
#[serde(with = "OrDef")]
|
||||||
or: Or<u8, bool>,
|
or: Or<u8, bool>,
|
||||||
#[serde(borrow, with = "StrDef")]
|
#[serde(borrow, with = "StrDef")]
|
||||||
@@ -398,7 +400,7 @@ fn test_gen() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
enum BorrowVariant<'a> {
|
pub enum BorrowVariant<'a> {
|
||||||
#[serde(borrow, with = "StrDef")]
|
#[serde(borrow, with = "StrDef")]
|
||||||
S(Str<'a>),
|
S(Str<'a>),
|
||||||
}
|
}
|
||||||
@@ -415,15 +417,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 {
|
pub struct RemoteVisibility {
|
||||||
#[serde(with = "vis::SDef")]
|
#[serde(with = "vis::SDef")]
|
||||||
s: vis::S,
|
s: vis::S,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "Self")]
|
#[serde(remote = "Self")]
|
||||||
#[allow(dead_code)]
|
pub struct RemoteSelf;
|
||||||
struct RemoteSelf;
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
enum ExternallyTaggedVariantWith {
|
enum ExternallyTaggedVariantWith {
|
||||||
@@ -547,26 +548,45 @@ fn test_gen() {
|
|||||||
assert::<FlattenWith>();
|
assert::<FlattenWith>();
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
pub struct Flatten<T> {
|
||||||
struct FlattenDenyUnknown<T> {
|
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
t: T,
|
t: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct StaticStrStruct<'a> {
|
#[serde(deny_unknown_fields)]
|
||||||
|
pub struct FlattenDenyUnknown<T> {
|
||||||
|
#[serde(flatten)]
|
||||||
|
t: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct SkipDeserializing<T> {
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
flat: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
pub struct SkipDeserializingDenyUnknown<T> {
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
flat: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct StaticStrStruct<'a> {
|
||||||
a: &'a str,
|
a: &'a str,
|
||||||
b: &'static str,
|
b: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct StaticStrTupleStruct<'a>(&'a str, &'static str);
|
pub struct StaticStrTupleStruct<'a>(&'a str, &'static str);
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct StaticStrNewtypeStruct(&'static str);
|
pub struct StaticStrNewtypeStruct(&'static str);
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
enum StaticStrEnum<'a> {
|
pub enum StaticStrEnum<'a> {
|
||||||
Struct { a: &'a str, b: &'static str },
|
Struct { a: &'a str, b: &'static str },
|
||||||
Tuple(&'a str, &'static str),
|
Tuple(&'a str, &'static str),
|
||||||
Newtype(&'static str),
|
Newtype(&'static str),
|
||||||
@@ -640,6 +660,7 @@ fn test_gen() {
|
|||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[allow(dead_code)]
|
||||||
struct Restricted {
|
struct Restricted {
|
||||||
pub(super) a: usize,
|
pub(super) a: usize,
|
||||||
pub(in super::inner) b: usize,
|
pub(in super::inner) b: usize,
|
||||||
@@ -649,7 +670,7 @@ fn test_gen() {
|
|||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
#[serde(tag = "t", content = "c")]
|
#[serde(tag = "t", content = "c")]
|
||||||
enum AdjacentlyTaggedVoid {}
|
pub enum AdjacentlyTaggedVoid {}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
enum SkippedVariant<T> {
|
enum SkippedVariant<T> {
|
||||||
@@ -662,14 +683,13 @@ fn test_gen() {
|
|||||||
assert::<SkippedVariant<X>>();
|
assert::<SkippedVariant<X>>();
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct ImplicitlyBorrowedOption<'a> {
|
pub struct ImplicitlyBorrowedOption<'a> {
|
||||||
#[allow(dead_code)]
|
|
||||||
option: std::option::Option<&'a str>,
|
option: std::option::Option<&'a str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
enum UntaggedNewtypeVariantWith {
|
pub enum UntaggedNewtypeVariantWith {
|
||||||
Newtype(
|
Newtype(
|
||||||
#[serde(serialize_with = "ser_x")]
|
#[serde(serialize_with = "ser_x")]
|
||||||
#[serde(deserialize_with = "de_x")]
|
#[serde(deserialize_with = "de_x")]
|
||||||
@@ -679,7 +699,7 @@ fn test_gen() {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(transparent)]
|
#[serde(transparent)]
|
||||||
struct TransparentWith {
|
pub struct TransparentWith {
|
||||||
#[serde(serialize_with = "ser_x")]
|
#[serde(serialize_with = "ser_x")]
|
||||||
#[serde(deserialize_with = "de_x")]
|
#[serde(deserialize_with = "de_x")]
|
||||||
x: X,
|
x: X,
|
||||||
@@ -701,35 +721,46 @@ fn test_gen() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct RelObject<'a> {
|
pub struct RelObject<'a> {
|
||||||
#[allow(dead_code)]
|
|
||||||
ty: &'a str,
|
ty: &'a str,
|
||||||
#[allow(dead_code)]
|
|
||||||
id: String,
|
id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct FlattenSkipSerializing<T> {
|
pub struct FlattenSkipSerializing<T> {
|
||||||
#[serde(flatten, skip_serializing)]
|
#[serde(flatten, skip_serializing)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
flat: T,
|
flat: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct FlattenSkipSerializingIf<T> {
|
pub struct FlattenSkipSerializingIf<T> {
|
||||||
#[serde(flatten, skip_serializing_if = "StdOption::is_none")]
|
#[serde(flatten, skip_serializing_if = "StdOption::is_none")]
|
||||||
flat: StdOption<T>,
|
flat: StdOption<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct FlattenSkipDeserializing<T> {
|
pub struct FlattenSkipDeserializing<T> {
|
||||||
#[serde(flatten, skip_deserializing)]
|
#[serde(flatten, skip_deserializing)]
|
||||||
flat: T,
|
flat: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum Inner<T> {
|
||||||
|
Builder {
|
||||||
|
s: T,
|
||||||
|
#[serde(flatten)]
|
||||||
|
o: T,
|
||||||
|
},
|
||||||
|
Default {
|
||||||
|
s: T,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// https://github.com/serde-rs/serde/issues/1804
|
// https://github.com/serde-rs/serde/issues/1804
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
enum Message {
|
pub enum Message {
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
String(String),
|
String(String),
|
||||||
@@ -748,8 +779,7 @@ fn test_gen() {
|
|||||||
macro_rules! deriving {
|
macro_rules! deriving {
|
||||||
($field:ty) => {
|
($field:ty) => {
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct MacroRules<'a> {
|
pub struct MacroRules<'a> {
|
||||||
#[allow(dead_code)]
|
|
||||||
field: $field,
|
field: $field,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -764,22 +794,20 @@ fn test_gen() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct BorrowLifetimeInsideMacro<'a> {
|
pub struct BorrowLifetimeInsideMacro<'a> {
|
||||||
#[serde(borrow = "'a")]
|
#[serde(borrow = "'a")]
|
||||||
#[allow(dead_code)]
|
pub f: mac!(Cow<'a, str>),
|
||||||
f: mac!(Cow<'a, str>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
#[allow(dead_code)]
|
pub struct Struct {
|
||||||
struct Struct {
|
|
||||||
#[serde(serialize_with = "vec_first_element")]
|
#[serde(serialize_with = "vec_first_element")]
|
||||||
vec: Vec<Self>,
|
pub vec: Vec<Self>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
#[serde(bound(deserialize = "[&'de str; N]: Copy"))]
|
#[serde(bound(deserialize = "[&'de str; N]: Copy"))]
|
||||||
struct GenericUnitStruct<const N: usize>;
|
pub struct GenericUnitStruct<const N: usize>;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@@ -866,7 +894,7 @@ where
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq, Deserialize)]
|
#[derive(Debug, PartialEq, Deserialize)]
|
||||||
#[serde(tag = "tag")]
|
#[serde(tag = "tag")]
|
||||||
enum InternallyTagged {
|
pub enum InternallyTagged {
|
||||||
#[serde(deserialize_with = "deserialize_generic")]
|
#[serde(deserialize_with = "deserialize_generic")]
|
||||||
Unit,
|
Unit,
|
||||||
|
|
||||||
|
|||||||
@@ -7,14 +7,17 @@ mod remote {
|
|||||||
|
|
||||||
pub struct PrimitivePriv(u8);
|
pub struct PrimitivePriv(u8);
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub struct PrimitivePub(pub u8);
|
pub struct PrimitivePub(pub u8);
|
||||||
|
|
||||||
pub struct NewtypePriv(Unit);
|
pub struct NewtypePriv(Unit);
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub struct NewtypePub(pub Unit);
|
pub struct NewtypePub(pub Unit);
|
||||||
|
|
||||||
pub struct TuplePriv(u8, Unit);
|
pub struct TuplePriv(u8, Unit);
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub struct TuplePub(pub u8, pub Unit);
|
pub struct TuplePub(pub u8, pub Unit);
|
||||||
|
|
||||||
pub struct StructPriv {
|
pub struct StructPriv {
|
||||||
@@ -22,6 +25,7 @@ mod remote {
|
|||||||
b: Unit,
|
b: Unit,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub struct StructPub {
|
pub struct StructPub {
|
||||||
pub a: u8,
|
pub a: u8,
|
||||||
pub b: Unit,
|
pub b: Unit,
|
||||||
@@ -86,12 +90,14 @@ mod remote {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub enum EnumGeneric<T> {
|
pub enum EnumGeneric<T> {
|
||||||
Variant(T),
|
Variant(T),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[allow(dead_code)]
|
||||||
struct Test {
|
struct Test {
|
||||||
#[serde(with = "UnitDef")]
|
#[serde(with = "UnitDef")]
|
||||||
unit: remote::Unit,
|
unit: remote::Unit,
|
||||||
@@ -132,6 +138,7 @@ struct Test {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::Unit")]
|
#[serde(remote = "remote::Unit")]
|
||||||
|
#[allow(dead_code)]
|
||||||
struct UnitDef;
|
struct UnitDef;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
@@ -140,6 +147,7 @@ struct PrimitivePrivDef(#[serde(getter = "remote::PrimitivePriv::get")] u8);
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::PrimitivePub")]
|
#[serde(remote = "remote::PrimitivePub")]
|
||||||
|
#[allow(dead_code)]
|
||||||
struct PrimitivePubDef(u8);
|
struct PrimitivePubDef(u8);
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
@@ -148,6 +156,7 @@ struct NewtypePrivDef(#[serde(getter = "remote::NewtypePriv::get", with = "UnitD
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::NewtypePub")]
|
#[serde(remote = "remote::NewtypePub")]
|
||||||
|
#[allow(dead_code)]
|
||||||
struct NewtypePubDef(#[serde(with = "UnitDef")] remote::Unit);
|
struct NewtypePubDef(#[serde(with = "UnitDef")] remote::Unit);
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
@@ -159,6 +168,7 @@ struct TuplePrivDef(
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::TuplePub")]
|
#[serde(remote = "remote::TuplePub")]
|
||||||
|
#[allow(dead_code)]
|
||||||
struct TuplePubDef(u8, #[serde(with = "UnitDef")] remote::Unit);
|
struct TuplePubDef(u8, #[serde(with = "UnitDef")] remote::Unit);
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
@@ -174,6 +184,7 @@ struct StructPrivDef {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::StructPub")]
|
#[serde(remote = "remote::StructPub")]
|
||||||
|
#[allow(dead_code)]
|
||||||
struct StructPubDef {
|
struct StructPubDef {
|
||||||
a: u8,
|
a: u8,
|
||||||
|
|
||||||
@@ -190,17 +201,20 @@ struct StructGenericWithGetterDef<T> {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::StructGeneric<u8>")]
|
#[serde(remote = "remote::StructGeneric<u8>")]
|
||||||
|
#[allow(dead_code)]
|
||||||
struct StructConcrete {
|
struct StructConcrete {
|
||||||
value: u8,
|
value: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::EnumGeneric<u8>")]
|
#[serde(remote = "remote::EnumGeneric<u8>")]
|
||||||
|
#[allow(dead_code)]
|
||||||
enum EnumConcrete {
|
enum EnumConcrete {
|
||||||
Variant(u8),
|
Variant(u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[allow(dead_code)]
|
||||||
enum ErrorKind {
|
enum ErrorKind {
|
||||||
NotFound,
|
NotFound,
|
||||||
PermissionDenied,
|
PermissionDenied,
|
||||||
@@ -211,6 +225,7 @@ enum ErrorKind {
|
|||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "ErrorKind")]
|
#[serde(remote = "ErrorKind")]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
|
#[allow(dead_code)]
|
||||||
enum ErrorKindDef {
|
enum ErrorKindDef {
|
||||||
NotFound,
|
NotFound,
|
||||||
PermissionDenied,
|
PermissionDenied,
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ fn test_self() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
struct Tuple(
|
pub struct Tuple(
|
||||||
Box<Self>,
|
Box<Self>,
|
||||||
Box<<Self as Trait>::Assoc>,
|
Box<<Self as Trait>::Assoc>,
|
||||||
[(); Self::ASSOC],
|
[(); Self::ASSOC],
|
||||||
@@ -60,7 +60,7 @@ fn test_self() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
enum Enum {
|
pub enum Enum {
|
||||||
Struct {
|
Struct {
|
||||||
_f1: Box<Self>,
|
_f1: Box<Self>,
|
||||||
_f2: Box<<Self as Trait>::Assoc>,
|
_f2: Box<<Self as Trait>::Assoc>,
|
||||||
|
|||||||
Reference in New Issue
Block a user