From 77a6a9d4e193c82439aa0c35dfdbbb34fafdf38e Mon Sep 17 00:00:00 2001 From: Mingun Date: Sun, 11 Aug 2024 19:56:27 +0500 Subject: [PATCH] Take into account only not skipped flatten fields when choose serialization form Consequence: `FlattenSkipSerializing` - uses `serialize_struct` instead of `serialize_map` --- serde_derive/src/internals/ast.rs | 13 +------------ serde_derive/src/internals/attr.rs | 26 -------------------------- serde_derive/src/ser.rs | 5 ++++- 3 files changed, 5 insertions(+), 39 deletions(-) diff --git a/serde_derive/src/internals/ast.rs b/serde_derive/src/internals/ast.rs index a28d3ae7e..3293823a7 100644 --- a/serde_derive/src/internals/ast.rs +++ b/serde_derive/src/internals/ast.rs @@ -63,7 +63,7 @@ impl<'a> Container<'a> { item: &'a syn::DeriveInput, derive: Derive, ) -> Option> { - 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())), @@ -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 @@ -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, diff --git a/serde_derive/src/internals/attr.rs b/serde_derive/src/internals/attr.rs index 28ed54267..ac5f5d9a5 100644 --- a/serde_derive/src/internals/attr.rs +++ b/serde_derive/src/internals/attr.rs @@ -216,23 +216,6 @@ pub struct Container { type_into: Option, remote: Option, 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, is_packed: bool, /// Error message generated when type can't be deserialized @@ -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(), @@ -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() } diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index f745bf675..4f5e000d4 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -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)