1use crate::de::enum_;
9use crate::de::enum_untagged;
10use crate::de::struct_;
11use crate::de::{
12 effective_style, expr_is_missing, field_i, unwrap_to_variant_closure, Parameters, StructForm,
13};
14use crate::fragment::{Expr, Fragment, Match};
15use crate::internals::ast::{Style, Variant};
16use crate::internals::attr;
17use crate::private;
18use quote::quote;
19
20pub(super) fn deserialize(
22 params: &Parameters,
23 variants: &[Variant],
24 cattrs: &attr::Container,
25 tag: &str,
26) -> Fragment {
27 let (variants_stmt, variant_visitor) = enum_::prepare_enum_variant_enum(variants);
28
29 let variant_arms = variants
31 .iter()
32 .enumerate()
33 .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
34 .map(|(i, variant)| {
35 let variant_name = field_i(i);
36
37 let block = Match(deserialize_internally_tagged_variant(
38 params, variant, cattrs,
39 ));
40
41 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "__Field");
::quote::__private::push_colon2(&mut _s);
::quote::ToTokens::to_tokens(&variant_name, &mut _s);
::quote::__private::push_fat_arrow(&mut _s);
::quote::ToTokens::to_tokens(&block, &mut _s);
_s
}quote! {
42 __Field::#variant_name => #block
43 }
44 });
45
46 let expecting = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("internally tagged enum {0}",
params.type_name()))
})format!("internally tagged enum {}", params.type_name());
47 let expecting = cattrs.expecting().unwrap_or(&expecting);
48
49 crate::fragment::Fragment::Block({
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&variant_visitor, &mut _s);
::quote::ToTokens::to_tokens(&variants_stmt, &mut _s);
::quote::__private::push_ident(&mut _s, "let");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "__tag");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "__content");
_s
});
::quote::__private::push_eq(&mut _s);
::quote::__private::push_ident(&mut _s, "_serde");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Deserializer");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "deserialize_any");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "__deserializer");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "_serde");
::quote::__private::push_colon2(&mut _s);
::quote::ToTokens::to_tokens(&private, &mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "de");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s,
"TaggedContentVisitor");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::__private::push_ident(&mut _s, "__Field");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "new");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&tag, &mut _s);
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&expecting, &mut _s);
_s
});
_s
});
::quote::__private::push_question(&mut _s);
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "let");
::quote::__private::push_ident(&mut _s, "__deserializer");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_ident(&mut _s, "_serde");
::quote::__private::push_colon2(&mut _s);
::quote::ToTokens::to_tokens(&private, &mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "de");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "ContentDeserializer");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::__private::push_ident(&mut _s, "__D");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Error");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "new");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "__content");
_s
});
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "match");
::quote::__private::push_ident(&mut _s, "__tag");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut variant_arms, i) = variant_arms.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let variant_arms =
match variant_arms.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&variant_arms, &mut _s);
}
}
_s
});
_s
});quote_block! {
50 #variant_visitor
51
52 #variants_stmt
53
54 let (__tag, __content) = _serde::Deserializer::deserialize_any(
55 __deserializer,
56 _serde::#private::de::TaggedContentVisitor::<__Field>::new(#tag, #expecting))?;
57 let __deserializer = _serde::#private::de::ContentDeserializer::<__D::Error>::new(__content);
58
59 match __tag {
60 #(#variant_arms)*
61 }
62 }
63}
64
65fn deserialize_internally_tagged_variant(
68 params: &Parameters,
69 variant: &Variant,
70 cattrs: &attr::Container,
71) -> Fragment {
72 if let Some(path) = variant.attrs.deserialize_with() {
73 let unwrap_fn = unwrap_to_variant_closure(params, variant, false);
74 return crate::fragment::Fragment::Block({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "_serde");
::quote::__private::push_colon2(&mut _s);
::quote::ToTokens::to_tokens(&private, &mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Result");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "map");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&path, &mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "__deserializer");
_s
});
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&unwrap_fn, &mut _s);
_s
});
_s
})quote_block! {
75 _serde::#private::Result::map(#path(__deserializer), #unwrap_fn)
76 };
77 }
78
79 let variant_ident = &variant.ident;
80
81 match effective_style(variant) {
82 Style::Unit => {
83 let this_value = ¶ms.this_value;
84 let type_name = params.type_name();
85 let variant_name = variant.ident.to_string();
86 let default = variant.fields.first().map(|field| {
87 let default = Expr(expr_is_missing(field, cattrs));
88 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&default, &mut _s);
_s
});
_s
}quote!((#default))
89 });
90 crate::fragment::Fragment::Block({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "_serde");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Deserializer");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "deserialize_any");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "__deserializer");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "_serde");
::quote::__private::push_colon2(&mut _s);
::quote::ToTokens::to_tokens(&private, &mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "de");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s,
"InternallyTaggedUnitVisitor");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "new");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&type_name, &mut _s);
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&variant_name, &mut _s);
_s
});
_s
});
::quote::__private::push_question(&mut _s);
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "_serde");
::quote::__private::push_colon2(&mut _s);
::quote::ToTokens::to_tokens(&private, &mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Ok");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&this_value, &mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::ToTokens::to_tokens(&variant_ident, &mut _s);
::quote::ToTokens::to_tokens(&default, &mut _s);
_s
});
_s
});quote_block! {
91 _serde::Deserializer::deserialize_any(__deserializer, _serde::#private::de::InternallyTaggedUnitVisitor::new(#type_name, #variant_name))?;
92 _serde::#private::Ok(#this_value::#variant_ident #default)
93 }
94 }
95 Style::Newtype => {
96 enum_untagged::deserialize_newtype_variant(variant_ident, params, &variant.fields[0])
97 }
98 Style::Struct => struct_::deserialize(
99 params,
100 &variant.fields,
101 cattrs,
102 StructForm::InternallyTagged(variant_ident),
103 ),
104 Style::Tuple => {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("checked in serde_derive_internals")));
}unreachable!("checked in serde_derive_internals"),
105 }
106}