diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index 53d2ebaf..eb938816 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -286,7 +286,7 @@ fn serialize_struct_as_struct(params: &Parameters, fields: &[Field], cattrs: &at } } -fn serialize_struct_as_map(params: &Parameters, fields: &[Field], _cattrs: &attr::Container) -> Fragment { +fn serialize_struct_as_map(params: &Parameters, fields: &[Field], cattrs: &attr::Container) -> Fragment { let serialize_fields = serialize_struct_visitor( fields, params, @@ -301,11 +301,7 @@ fn serialize_struct_as_map(params: &Parameters, fields: &[Field], _cattrs: &attr let let_mut = mut_if(serialized_fields.peek().is_some()); - let has_flatten = fields - .iter() - .any(|field| field.attrs.flatten()); - - let len = if has_flatten { + let len = if cattrs.has_flatten() { quote!(None) } else { let len = serialized_fields diff --git a/serde_derive_internals/src/ast.rs b/serde_derive_internals/src/ast.rs index fcc7b924..916f647a 100644 --- a/serde_derive_internals/src/ast.rs +++ b/serde_derive_internals/src/ast.rs @@ -48,7 +48,7 @@ pub enum Style { impl<'a> Container<'a> { pub fn from_ast(cx: &Ctxt, item: &'a syn::DeriveInput) -> Container<'a> { - let attrs = attr::Container::from_ast(cx, item); + let mut attrs = attr::Container::from_ast(cx, item); let mut data = match item.data { syn::Data::Enum(ref data) => { @@ -85,6 +85,10 @@ impl<'a> Container<'a> { found #[serde(repr = \"{}\")]", attrs.repr())); } + if has_flatten { + attrs.mark_has_flatten(); + } + let item = Container { ident: item.ident, attrs: attrs, diff --git a/serde_derive_internals/src/attr.rs b/serde_derive_internals/src/attr.rs index ad291fc4..b62e4748 100644 --- a/serde_derive_internals/src/attr.rs +++ b/serde_derive_internals/src/attr.rs @@ -146,6 +146,7 @@ pub struct Container { remote: Option, identifier: Identifier, repr: ContainerRepr, + has_flatten: bool, } /// Styles of representing an enum. @@ -417,6 +418,7 @@ impl Container { remote: remote.get(), identifier: decide_identifier(cx, item, &field_identifier, &variant_identifier), repr: repr.get().unwrap_or(ContainerRepr::Auto), + has_flatten: false, } } @@ -467,6 +469,14 @@ impl Container { pub fn repr(&self) -> ContainerRepr { self.repr } + + pub fn has_flatten(&self) -> bool { + self.has_flatten + } + + pub fn mark_has_flatten(&mut self) { + self.has_flatten = true; + } } fn decide_tag(