serde_derive/de/
enum_untagged.rs1use crate::de::struct_;
9use crate::de::tuple;
10use crate::de::{
11 effective_style, expr_is_missing, unwrap_to_variant_closure, Parameters, StructForm, TupleForm,
12};
13use crate::fragment::{Expr, Fragment};
14use crate::internals::ast::{Field, Style, Variant};
15use crate::internals::attr;
16use crate::private;
17use proc_macro2::TokenStream;
18use quote::{quote, quote_spanned};
19use syn::spanned::Spanned;
20
21pub(super) fn deserialize(
23 params: &Parameters,
24 variants: &[Variant],
25 cattrs: &attr::Container,
26 first_attempt: Option<TokenStream>,
27) -> Fragment {
28 let attempts = variants
29 .iter()
30 .filter(|variant| !variant.attrs.skip_deserializing())
31 .map(|variant| Expr(deserialize_variant(params, variant, cattrs)));
32 let fallthrough_msg = format!(
39 "data did not match any variant of untagged enum {}",
40 params.type_name()
41 );
42 let fallthrough_msg = cattrs.expecting().unwrap_or(&fallthrough_msg);
43
44 let private2 = private;
45 quote_block! {
46 let __content = _serde::de::DeserializeSeed::deserialize(_serde::#private::de::ContentVisitor::new(), __deserializer)?;
47 let __deserializer = _serde::#private::de::ContentRefDeserializer::<__D::Error>::new(&__content);
48
49 #first_attempt
50
51 #(
52 if let _serde::#private2::Ok(__ok) = #attempts {
53 return _serde::#private2::Ok(__ok);
54 }
55 )*
56
57 _serde::#private::Err(_serde::de::Error::custom(#fallthrough_msg))
58 }
59}
60
61pub(super) fn deserialize_variant(
63 params: &Parameters,
64 variant: &Variant,
65 cattrs: &attr::Container,
66) -> Fragment {
67 if let Some(path) = variant.attrs.deserialize_with() {
68 let unwrap_fn = unwrap_to_variant_closure(params, variant, false);
69 return quote_block! {
70 _serde::#private::Result::map(#path(__deserializer), #unwrap_fn)
71 };
72 }
73
74 let variant_ident = &variant.ident;
75
76 match effective_style(variant) {
77 Style::Unit => {
78 let this_value = ¶ms.this_value;
79 let type_name = params.type_name();
80 let variant_name = variant.ident.to_string();
81 let default = variant.fields.first().map(|field| {
82 let default = Expr(expr_is_missing(field, cattrs));
83 quote!((#default))
84 });
85 quote_expr! {
86 match _serde::Deserializer::deserialize_any(
87 __deserializer,
88 _serde::#private::de::UntaggedUnitVisitor::new(#type_name, #variant_name)
89 ) {
90 _serde::#private::Ok(()) => _serde::#private::Ok(#this_value::#variant_ident #default),
91 _serde::#private::Err(__err) => _serde::#private::Err(__err),
92 }
93 }
94 }
95 Style::Newtype => deserialize_newtype_variant(variant_ident, params, &variant.fields[0]),
96 Style::Tuple => tuple::deserialize(
97 params,
98 &variant.fields,
99 cattrs,
100 TupleForm::Untagged(variant_ident),
101 ),
102 Style::Struct => struct_::deserialize(
103 params,
104 &variant.fields,
105 cattrs,
106 StructForm::Untagged(variant_ident),
107 ),
108 }
109}
110
111pub(super) fn deserialize_newtype_variant(
114 variant_ident: &syn::Ident,
115 params: &Parameters,
116 field: &Field,
117) -> Fragment {
118 let this_value = ¶ms.this_value;
119 let field_ty = field.ty;
120 match field.attrs.deserialize_with() {
121 None => {
122 let span = field.original.span();
123 let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize);
124 quote_expr! {
125 _serde::#private::Result::map(#func(__deserializer), #this_value::#variant_ident)
126 }
127 }
128 Some(path) => {
129 quote_block! {
130 let __value: _serde::#private::Result<#field_ty, _> = #path(__deserializer);
131 _serde::#private::Result::map(__value, #this_value::#variant_ident)
132 }
133 }
134 }
135}