mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-23 00:08:01 +00:00
Move body generator for internally tagged enums to its own module
Cut-paste
This commit is contained in:
+2
-89
@@ -14,6 +14,7 @@ use syn::{parse_quote, Ident, Index, Member};
|
||||
|
||||
mod enum_adjacently;
|
||||
mod enum_externally;
|
||||
mod enum_internally;
|
||||
|
||||
pub fn expand_derive_deserialize(input: &mut syn::DeriveInput) -> syn::Result<TokenStream> {
|
||||
replace_receiver(input);
|
||||
@@ -1262,7 +1263,7 @@ fn deserialize_homogeneous_enum(
|
||||
match cattrs.tag() {
|
||||
attr::TagType::External => enum_externally::deserialize_externally_tagged_enum(params, variants, cattrs),
|
||||
attr::TagType::Internal { tag } => {
|
||||
deserialize_internally_tagged_enum(params, variants, cattrs, tag)
|
||||
enum_internally::deserialize_internally_tagged_enum(params, variants, cattrs, tag)
|
||||
}
|
||||
attr::TagType::Adjacent { tag, content } => {
|
||||
enum_adjacently::deserialize_adjacently_tagged_enum(params, variants, cattrs, tag, content)
|
||||
@@ -1313,51 +1314,6 @@ fn prepare_enum_variant_enum(variants: &[Variant]) -> (TokenStream, Stmts) {
|
||||
(variants_stmt, variant_visitor)
|
||||
}
|
||||
|
||||
/// Generates `Deserialize::deserialize` body for an `enum Enum {...}` with `#[serde(tag)]` attribute
|
||||
fn deserialize_internally_tagged_enum(
|
||||
params: &Parameters,
|
||||
variants: &[Variant],
|
||||
cattrs: &attr::Container,
|
||||
tag: &str,
|
||||
) -> Fragment {
|
||||
let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants);
|
||||
|
||||
// Match arms to extract a variant from a string
|
||||
let variant_arms = variants
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
|
||||
.map(|(i, variant)| {
|
||||
let variant_name = field_i(i);
|
||||
|
||||
let block = Match(deserialize_internally_tagged_variant(
|
||||
params, variant, cattrs,
|
||||
));
|
||||
|
||||
quote! {
|
||||
__Field::#variant_name => #block
|
||||
}
|
||||
});
|
||||
|
||||
let expecting = format!("internally tagged enum {}", params.type_name());
|
||||
let expecting = cattrs.expecting().unwrap_or(&expecting);
|
||||
|
||||
quote_block! {
|
||||
#variant_visitor
|
||||
|
||||
#variants_stmt
|
||||
|
||||
let (__tag, __content) = _serde::Deserializer::deserialize_any(
|
||||
__deserializer,
|
||||
_serde::#private::de::TaggedContentVisitor::<__Field>::new(#tag, #expecting))?;
|
||||
let __deserializer = _serde::#private::de::ContentDeserializer::<__D::Error>::new(__content);
|
||||
|
||||
match __tag {
|
||||
#(#variant_arms)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates `Deserialize::deserialize` body for an `enum Enum {...}` with `#[serde(untagged)]` attribute
|
||||
fn deserialize_untagged_enum(
|
||||
params: &Parameters,
|
||||
@@ -1398,49 +1354,6 @@ fn deserialize_untagged_enum(
|
||||
}
|
||||
}
|
||||
|
||||
// Generates significant part of the visit_seq and visit_map bodies of visitors
|
||||
// for the variants of internally tagged enum.
|
||||
fn deserialize_internally_tagged_variant(
|
||||
params: &Parameters,
|
||||
variant: &Variant,
|
||||
cattrs: &attr::Container,
|
||||
) -> Fragment {
|
||||
if let Some(path) = variant.attrs.deserialize_with() {
|
||||
let unwrap_fn = unwrap_to_variant_closure(params, variant, false);
|
||||
return quote_block! {
|
||||
_serde::#private::Result::map(#path(__deserializer), #unwrap_fn)
|
||||
};
|
||||
}
|
||||
|
||||
let variant_ident = &variant.ident;
|
||||
|
||||
match effective_style(variant) {
|
||||
Style::Unit => {
|
||||
let this_value = ¶ms.this_value;
|
||||
let type_name = params.type_name();
|
||||
let variant_name = variant.ident.to_string();
|
||||
let default = variant.fields.first().map(|field| {
|
||||
let default = Expr(expr_is_missing(field, cattrs));
|
||||
quote!((#default))
|
||||
});
|
||||
quote_block! {
|
||||
_serde::Deserializer::deserialize_any(__deserializer, _serde::#private::de::InternallyTaggedUnitVisitor::new(#type_name, #variant_name))?;
|
||||
_serde::#private::Ok(#this_value::#variant_ident #default)
|
||||
}
|
||||
}
|
||||
Style::Newtype => {
|
||||
deserialize_untagged_newtype_variant(variant_ident, params, &variant.fields[0])
|
||||
}
|
||||
Style::Struct => deserialize_struct(
|
||||
params,
|
||||
&variant.fields,
|
||||
cattrs,
|
||||
StructForm::InternallyTagged(variant_ident),
|
||||
),
|
||||
Style::Tuple => unreachable!("checked in serde_derive_internals"),
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_untagged_variant(
|
||||
params: &Parameters,
|
||||
variant: &Variant,
|
||||
|
||||
Reference in New Issue
Block a user