Skip to content

Commit

Permalink
Take into account only not skipped flatten fields when choose seriali…
Browse files Browse the repository at this point in the history
…zation form

Consequence: `FlattenSkipSerializing`
- uses `serialize_struct` instead of `serialize_map`
  • Loading branch information
Mingun committed Aug 11, 2024
1 parent 547d843 commit 77a6a9d
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 39 deletions.
13 changes: 1 addition & 12 deletions serde_derive/src/internals/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl<'a> Container<'a> {
item: &'a syn::DeriveInput,
derive: Derive,
) -> 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 {
syn::Data::Enum(data) => Data::Enum(enum_from_ast(cx, &data.variants, attrs.default())),
Expand All @@ -77,15 +77,11 @@ impl<'a> Container<'a> {
}
};

let mut has_flatten = false;
match &mut data {
Data::Enum(variants) => {
for variant in variants {
variant.attrs.rename_by_rules(attrs.rename_all_rules());
for field in &mut variant.fields {
if field.attrs.flatten() {
has_flatten = true;
}
field.attrs.rename_by_rules(
variant
.attrs
Expand All @@ -97,18 +93,11 @@ impl<'a> Container<'a> {
}
Data::Struct(_, fields) => {
for field in fields {
if field.attrs.flatten() {
has_flatten = true;
}
field.attrs.rename_by_rules(attrs.rename_all_rules());
}
}
}

if has_flatten {
attrs.mark_has_flatten();
}

let mut item = Container {
ident: item.ident.clone(),
attrs,
Expand Down
26 changes: 0 additions & 26 deletions serde_derive/src/internals/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,23 +216,6 @@ pub struct Container {
type_into: Option<syn::Type>,
remote: Option<syn::Path>,
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>,
is_packed: bool,
/// Error message generated when type can't be deserialized
Expand Down Expand Up @@ -603,7 +586,6 @@ impl Container {
type_into: type_into.get(),
remote: remote.get(),
identifier: decide_identifier(cx, item, field_identifier, variant_identifier),
has_flatten: false,
serde_path: serde_path.get(),
is_packed,
expecting: expecting.get(),
Expand Down Expand Up @@ -671,14 +653,6 @@ impl Container {
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> {
self.serde_path.as_ref()
}
Expand Down
5 changes: 4 additions & 1 deletion serde_derive/src/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,10 @@ fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Contai
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)
} else {
serialize_struct_as_struct(params, fields, cattrs)
Expand Down

0 comments on commit 77a6a9d

Please sign in to comment.