Take into account only not skipped flatten fields when choose serialization form

Consequence: `FlattenSkipSerializing`
- uses `serialize_struct` instead of `serialize_map`
This commit is contained in:
Mingun 2024-08-11 19:56:27 +05:00
parent 547d843cca
commit 77a6a9d4e1
3 changed files with 5 additions and 39 deletions

View File

@ -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,

View File

@ -216,23 +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,
/// True if container is a struct and has a field with `#[serde(flatten)]`,
/// or is an enum with a struct variant which has a field with
/// `#[serde(flatten)]`.
///
/// ```ignore
/// struct Container {
/// #[serde(flatten)]
/// some_field: (),
/// }
/// enum Container {
/// Variant {
/// #[serde(flatten)]
/// some_field: (),
/// },
/// }
/// ```
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
@ -603,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(),
@ -671,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()
} }

View File

@ -297,7 +297,10 @@ fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Contai
u32::MAX 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)