Skip to content

Commit 3bff326

Browse files
authored
Merge pull request #2555 from Mingun/field
Refactor code that generates `__Field` enums
2 parents aaadd93 + 070cce0 commit 3bff326

File tree

1 file changed

+39
-31
lines changed

1 file changed

+39
-31
lines changed

serde_derive/src/de.rs

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -965,12 +965,7 @@ fn deserialize_struct(
965965
)
966966
})
967967
.collect();
968-
let field_visitor = Stmts(deserialize_generated_identifier(
969-
&field_names_idents,
970-
cattrs,
971-
false,
972-
None,
973-
));
968+
let field_visitor = deserialize_field_identifier(&field_names_idents, cattrs);
974969

975970
// untagged struct variants do not get a visit_seq method. The same applies to
976971
// structs that only have a map representation.
@@ -1128,12 +1123,7 @@ fn deserialize_struct_in_place(
11281123
})
11291124
.collect();
11301125

1131-
let field_visitor = Stmts(deserialize_generated_identifier(
1132-
&field_names_idents,
1133-
cattrs,
1134-
false,
1135-
None,
1136-
));
1126+
let field_visitor = deserialize_field_identifier(&field_names_idents, cattrs);
11371127

11381128
let mut_seq = if field_names_idents.is_empty() {
11391129
quote!(_)
@@ -1247,7 +1237,12 @@ fn prepare_enum_variant_enum(
12471237
})
12481238
.collect();
12491239

1250-
let other_idx = deserialized_variants.position(|(_, variant)| variant.attrs.other());
1240+
let fallthrough = deserialized_variants
1241+
.position(|(_, variant)| variant.attrs.other())
1242+
.map(|other_idx| {
1243+
let ignore_variant = variant_names_idents[other_idx].1.clone();
1244+
quote!(_serde::__private::Ok(__Field::#ignore_variant))
1245+
});
12511246

12521247
let variants_stmt = {
12531248
let variant_names = variant_names_idents.iter().map(|(name, _, _)| name);
@@ -1261,7 +1256,8 @@ fn prepare_enum_variant_enum(
12611256
&variant_names_idents,
12621257
cattrs,
12631258
true,
1264-
other_idx,
1259+
None,
1260+
fallthrough,
12651261
));
12661262

12671263
(variants_stmt, variant_visitor)
@@ -1986,27 +1982,12 @@ fn deserialize_generated_identifier(
19861982
fields: &[(&str, Ident, &BTreeSet<String>)],
19871983
cattrs: &attr::Container,
19881984
is_variant: bool,
1989-
other_idx: Option<usize>,
1985+
ignore_variant: Option<TokenStream>,
1986+
fallthrough: Option<TokenStream>,
19901987
) -> Fragment {
19911988
let this_value = quote!(__Field);
19921989
let field_idents: &Vec<_> = &fields.iter().map(|(_, ident, _)| ident).collect();
19931990

1994-
let (ignore_variant, fallthrough) = if !is_variant && cattrs.has_flatten() {
1995-
let ignore_variant = quote!(__other(_serde::__private::de::Content<'de>),);
1996-
let fallthrough = quote!(_serde::__private::Ok(__Field::__other(__value)));
1997-
(Some(ignore_variant), Some(fallthrough))
1998-
} else if let Some(other_idx) = other_idx {
1999-
let ignore_variant = fields[other_idx].1.clone();
2000-
let fallthrough = quote!(_serde::__private::Ok(__Field::#ignore_variant));
2001-
(None, Some(fallthrough))
2002-
} else if is_variant || cattrs.deny_unknown_fields() {
2003-
(None, None)
2004-
} else {
2005-
let ignore_variant = quote!(__ignore,);
2006-
let fallthrough = quote!(_serde::__private::Ok(__Field::__ignore));
2007-
(Some(ignore_variant), Some(fallthrough))
2008-
};
2009-
20101991
let visitor_impl = Stmts(deserialize_identifier(
20111992
&this_value,
20121993
fields,
@@ -2052,6 +2033,33 @@ fn deserialize_generated_identifier(
20522033
}
20532034
}
20542035

2036+
/// Generates enum and its `Deserialize` implementation that represents each
2037+
/// non-skipped field of the struct
2038+
fn deserialize_field_identifier(
2039+
fields: &[(&str, Ident, &BTreeSet<String>)],
2040+
cattrs: &attr::Container,
2041+
) -> Stmts {
2042+
let (ignore_variant, fallthrough) = if cattrs.has_flatten() {
2043+
let ignore_variant = quote!(__other(_serde::__private::de::Content<'de>),);
2044+
let fallthrough = quote!(_serde::__private::Ok(__Field::__other(__value)));
2045+
(Some(ignore_variant), Some(fallthrough))
2046+
} else if cattrs.deny_unknown_fields() {
2047+
(None, None)
2048+
} else {
2049+
let ignore_variant = quote!(__ignore,);
2050+
let fallthrough = quote!(_serde::__private::Ok(__Field::__ignore));
2051+
(Some(ignore_variant), Some(fallthrough))
2052+
};
2053+
2054+
Stmts(deserialize_generated_identifier(
2055+
fields,
2056+
cattrs,
2057+
false,
2058+
ignore_variant,
2059+
fallthrough,
2060+
))
2061+
}
2062+
20552063
// Generates `Deserialize::deserialize` body for an enum with
20562064
// `serde(field_identifier)` or `serde(variant_identifier)` attribute.
20572065
fn deserialize_custom_identifier(

0 commit comments

Comments
 (0)