Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show variant aliases in error message #2566

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
62 changes: 18 additions & 44 deletions serde_derive/src/de.rs
Expand Up @@ -957,13 +957,7 @@ fn deserialize_struct(
// Skip fields that shouldn't be deserialized or that were flattened,
// so they don't appear in the storage in their literal form
.filter(|&(_, field)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
.map(|(i, field)| {
(
field.attrs.name().deserialize_name(),
field_i(i),
field.attrs.aliases(),
)
})
.map(|(i, field)| (field_i(i), field.attrs.aliases()))
.collect();
let field_visitor = deserialize_field_identifier(&field_names_idents, cattrs);

Expand Down Expand Up @@ -1015,9 +1009,7 @@ fn deserialize_struct(
let fields_stmt = if cattrs.has_flatten() {
None
} else {
let field_names = field_names_idents
.iter()
.flat_map(|&(_, _, aliases)| aliases);
let field_names = field_names_idents.iter().flat_map(|&(_, aliases)| aliases);

Some(quote! {
#[doc(hidden)]
Expand Down Expand Up @@ -1114,13 +1106,7 @@ fn deserialize_struct_in_place(
.iter()
.enumerate()
.filter(|&(_, field)| !field.attrs.skip_deserializing())
.map(|(i, field)| {
(
field.attrs.name().deserialize_name(),
field_i(i),
field.attrs.aliases(),
)
})
.map(|(i, field)| (field_i(i), field.attrs.aliases()))
.collect();

let field_visitor = deserialize_field_identifier(&field_names_idents, cattrs);
Expand All @@ -1132,9 +1118,7 @@ fn deserialize_struct_in_place(
};
let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, expecting));
let visit_map = Stmts(deserialize_map_in_place(params, fields, cattrs));
let field_names = field_names_idents
.iter()
.flat_map(|&(_, _, aliases)| aliases);
let field_names = field_names_idents.iter().flat_map(|&(_, aliases)| aliases);
let type_name = cattrs.name().deserialize_name();

let in_place_impl_generics = de_impl_generics.in_place();
Expand Down Expand Up @@ -1228,24 +1212,20 @@ fn prepare_enum_variant_enum(

let variant_names_idents: Vec<_> = deserialized_variants
.clone()
.map(|(i, variant)| {
(
variant.attrs.name().deserialize_name(),
field_i(i),
variant.attrs.aliases(),
)
})
.map(|(i, variant)| (field_i(i), variant.attrs.aliases()))
.collect();

let fallthrough = deserialized_variants
.position(|(_, variant)| variant.attrs.other())
.map(|other_idx| {
let ignore_variant = variant_names_idents[other_idx].1.clone();
let ignore_variant = variant_names_idents[other_idx].0.clone();
quote!(_serde::__private::Ok(__Field::#ignore_variant))
});

let variants_stmt = {
let variant_names = variant_names_idents.iter().map(|(name, _, _)| name);
let variant_names = variant_names_idents
.iter()
.flat_map(|&(_, aliases)| aliases);
quote! {
#[doc(hidden)]
const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
Expand Down Expand Up @@ -1979,14 +1959,14 @@ fn deserialize_untagged_newtype_variant(
}

fn deserialize_generated_identifier(
fields: &[(&str, Ident, &BTreeSet<String>)],
fields: &[(Ident, &BTreeSet<String>)],
cattrs: &attr::Container,
is_variant: bool,
ignore_variant: Option<TokenStream>,
fallthrough: Option<TokenStream>,
) -> Fragment {
let this_value = quote!(__Field);
let field_idents: &Vec<_> = &fields.iter().map(|(_, ident, _)| ident).collect();
let field_idents: &Vec<_> = &fields.iter().map(|(ident, _)| ident).collect();

let visitor_impl = Stmts(deserialize_identifier(
&this_value,
Expand Down Expand Up @@ -2036,7 +2016,7 @@ fn deserialize_generated_identifier(
/// Generates enum and its `Deserialize` implementation that represents each
/// non-skipped field of the struct
fn deserialize_field_identifier(
fields: &[(&str, Ident, &BTreeSet<String>)],
fields: &[(Ident, &BTreeSet<String>)],
cattrs: &attr::Container,
) -> Stmts {
let (ignore_variant, fallthrough) = if cattrs.has_flatten() {
Expand Down Expand Up @@ -2112,16 +2092,10 @@ fn deserialize_custom_identifier(

let names_idents: Vec<_> = ordinary
.iter()
.map(|variant| {
(
variant.attrs.name().deserialize_name(),
variant.ident.clone(),
variant.attrs.aliases(),
)
})
.map(|variant| (variant.ident.clone(), variant.attrs.aliases()))
.collect();

let names = names_idents.iter().flat_map(|&(_, _, aliases)| aliases);
let names = names_idents.iter().flat_map(|&(_, aliases)| aliases);

let names_const = if fallthrough.is_some() {
None
Expand Down Expand Up @@ -2177,18 +2151,18 @@ fn deserialize_custom_identifier(

fn deserialize_identifier(
this_value: &TokenStream,
fields: &[(&str, Ident, &BTreeSet<String>)],
fields: &[(Ident, &BTreeSet<String>)],
is_variant: bool,
fallthrough: Option<TokenStream>,
fallthrough_borrowed: Option<TokenStream>,
collect_other_fields: bool,
expecting: Option<&str>,
) -> Fragment {
let str_mapping = fields.iter().map(|(_, ident, aliases)| {
let str_mapping = fields.iter().map(|(ident, aliases)| {
// `aliases` also contains a main name
quote!(#(#aliases)|* => _serde::__private::Ok(#this_value::#ident))
});
let bytes_mapping = fields.iter().map(|(_, ident, aliases)| {
let bytes_mapping = fields.iter().map(|(ident, aliases)| {
// `aliases` also contains a main name
let aliases = aliases
.iter()
Expand Down Expand Up @@ -2343,7 +2317,7 @@ fn deserialize_identifier(
}
}
} else {
let u64_mapping = fields.iter().enumerate().map(|(i, (_, ident, _))| {
let u64_mapping = fields.iter().enumerate().map(|(i, (ident, _))| {
let i = i as u64;
quote!(#i => _serde::__private::Ok(#this_value::#ident))
});
Expand Down
2 changes: 1 addition & 1 deletion test_suite/tests/test_annotations.rs
Expand Up @@ -782,7 +782,7 @@ fn test_unknown_field_rename_enum() {
variant: "SailorMoon",
len: 3,
}],
"unknown variant `SailorMoon`, expected `sailor_moon`",
"unknown variant `SailorMoon`, expected `sailor_moon` or `usagi_tsukino`",
);

assert_de_tokens_error::<AliasEnum>(
Expand Down