Correctly process flatten fields in enum variants

- Fix incorrect deserialization of variants that doesn't contain flatten field when other contains
- Fix a panic when deriving `Deserialize` for an enum with tuple and struct with flatten field

Fixes (2):
    regression::issue2565::simple_variant
    regression::issue1904 (compilation)
This commit is contained in:
Mingun
2023-07-24 00:57:47 +05:00
parent c3ac7b675a
commit b4ec2595c9
3 changed files with 97 additions and 31 deletions
+1
View File
@@ -85,6 +85,7 @@ impl<'a> Container<'a> {
for field in &mut variant.fields {
if field.attrs.flatten() {
has_flatten = true;
variant.attrs.mark_has_flatten();
}
field.attrs.rename_by_rules(
variant
+37
View File
@@ -216,6 +216,22 @@ pub struct Container {
type_into: Option<syn::Type>,
remote: Option<syn::Path>,
identifier: Identifier,
/// `true` if container is a `struct` and it has a field with `#[serde(flatten)]`
/// attribute or it is an `enum` with a struct variant which has a field with
/// `#[serde(flatten)]` attribute. Examples:
///
/// ```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,
@@ -794,6 +810,18 @@ pub struct Variant {
rename_all_rules: RenameAllRules,
ser_bound: Option<Vec<syn::WherePredicate>>,
de_bound: Option<Vec<syn::WherePredicate>>,
/// `true` if variant is a struct variant which contains a field with `#[serde(flatten)]`
/// attribute. Examples:
///
/// ```ignore
/// enum Enum {
/// Variant {
/// #[serde(flatten)]
/// some_field: (),
/// },
/// }
/// ```
has_flatten: bool,
skip_deserializing: bool,
skip_serializing: bool,
other: bool,
@@ -963,6 +991,7 @@ impl Variant {
},
ser_bound: ser_bound.get(),
de_bound: de_bound.get(),
has_flatten: false,
skip_deserializing: skip_deserializing.get(),
skip_serializing: skip_serializing.get(),
other: other.get(),
@@ -1005,6 +1034,14 @@ impl Variant {
self.de_bound.as_ref().map(|vec| &vec[..])
}
pub fn has_flatten(&self) -> bool {
self.has_flatten
}
pub fn mark_has_flatten(&mut self) {
self.has_flatten = true;
}
pub fn skip_deserializing(&self) -> bool {
self.skip_deserializing
}