serde_derive/de/
enum_adjacently.rs1use crate::de::enum_;
9use crate::de::enum_untagged;
10use crate::de::{field_i, Parameters};
11use crate::fragment::{Fragment, Match};
12use crate::internals::ast::{Style, Variant};
13use crate::internals::attr;
14use crate::private;
15use quote::{quote, quote_spanned};
16use syn::spanned::Spanned;
17
18pub(super) fn deserialize(
20 params: &Parameters,
21 variants: &[Variant],
22 cattrs: &attr::Container,
23 tag: &str,
24 content: &str,
25) -> Fragment {
26 let this_type = ¶ms.this_type;
27 let this_value = ¶ms.this_value;
28 let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
29 params.generics_with_de_lifetime();
30 let delife = params.borrowed.de_lifetime();
31
32 let (variants_stmt, variant_visitor) = enum_::prepare_enum_variant_enum(variants);
33
34 let variant_arms: &Vec<_> = &variants
35 .iter()
36 .enumerate()
37 .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
38 .map(|(i, variant)| {
39 let variant_index = field_i(i);
40
41 let block = Match(enum_untagged::deserialize_variant(params, variant, cattrs));
42
43 quote! {
44 __Field::#variant_index => #block
45 }
46 })
47 .collect();
48
49 let rust_name = params.type_name();
50 let expecting = format!("adjacently tagged enum {}", rust_name);
51 let expecting = cattrs.expecting().unwrap_or(&expecting);
52 let type_name = cattrs.name().deserialize_name();
53 let deny_unknown_fields = cattrs.deny_unknown_fields();
54
55 let field_visitor_ty = if deny_unknown_fields {
58 quote! { _serde::#private::de::TagOrContentFieldVisitor }
59 } else {
60 quote! { _serde::#private::de::TagContentOtherFieldVisitor }
61 };
62
63 let mut missing_content = quote! {
64 _serde::#private::Err(<__A::Error as _serde::de::Error>::missing_field(#content))
65 };
66 let mut missing_content_fallthrough = quote!();
67 let missing_content_arms = variants
68 .iter()
69 .enumerate()
70 .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
71 .filter_map(|(i, variant)| {
72 let variant_index = field_i(i);
73 let variant_ident = &variant.ident;
74
75 let arm = match variant.style {
76 Style::Unit => quote! {
77 _serde::#private::Ok(#this_value::#variant_ident)
78 },
79 Style::Newtype if variant.attrs.deserialize_with().is_none() => {
80 let span = variant.original.span();
81 let func = quote_spanned!(span=> _serde::#private::de::missing_field);
82 quote! {
83 #func(#content).map(#this_value::#variant_ident)
84 }
85 }
86 _ => {
87 missing_content_fallthrough = quote!(_ => #missing_content);
88 return None;
89 }
90 };
91 Some(quote! {
92 __Field::#variant_index => #arm,
93 })
94 })
95 .collect::<Vec<_>>();
96 if !missing_content_arms.is_empty() {
97 missing_content = quote! {
98 match __field {
99 #(#missing_content_arms)*
100 #missing_content_fallthrough
101 }
102 };
103 }
104
105 let next_key = quote! {
107 _serde::de::MapAccess::next_key_seed(&mut __map, #field_visitor_ty {
108 tag: #tag,
109 content: #content,
110 })?
111 };
112
113 let variant_from_map = quote! {
114 _serde::de::MapAccess::next_value_seed(&mut __map, _serde::#private::de::AdjacentlyTaggedEnumVariantSeed::<__Field> {
115 enum_name: #rust_name,
116 variants: VARIANTS,
117 fields_enum: _serde::#private::PhantomData
118 })?
119 };
120
121 let next_relevant_key = if deny_unknown_fields {
124 next_key
125 } else {
126 quote!({
127 let mut __rk : _serde::#private::Option<_serde::#private::de::TagOrContentField> = _serde::#private::None;
128 while let _serde::#private::Some(__k) = #next_key {
129 match __k {
130 _serde::#private::de::TagContentOtherField::Other => {
131 let _ = _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
132 continue;
133 },
134 _serde::#private::de::TagContentOtherField::Tag => {
135 __rk = _serde::#private::Some(_serde::#private::de::TagOrContentField::Tag);
136 break;
137 }
138 _serde::#private::de::TagContentOtherField::Content => {
139 __rk = _serde::#private::Some(_serde::#private::de::TagOrContentField::Content);
140 break;
141 }
142 }
143 }
144
145 __rk
146 })
147 };
148
149 let visit_remaining_keys = quote! {
153 match #next_relevant_key {
154 _serde::#private::Some(_serde::#private::de::TagOrContentField::Tag) => {
155 _serde::#private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#tag))
156 }
157 _serde::#private::Some(_serde::#private::de::TagOrContentField::Content) => {
158 _serde::#private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#content))
159 }
160 _serde::#private::None => _serde::#private::Ok(__ret),
161 }
162 };
163
164 let finish_content_then_tag = if variant_arms.is_empty() {
165 quote! {
166 match #variant_from_map {}
167 }
168 } else {
169 quote! {
170 let __seed = __Seed {
171 variant: #variant_from_map,
172 marker: _serde::#private::PhantomData,
173 lifetime: _serde::#private::PhantomData,
174 };
175 let __deserializer = _serde::#private::de::ContentDeserializer::<__A::Error>::new(__content);
176 let __ret = _serde::de::DeserializeSeed::deserialize(__seed, __deserializer)?;
177 #visit_remaining_keys
179 }
180 };
181
182 quote_block! {
183 #variant_visitor
184
185 #variants_stmt
186
187 #[doc(hidden)]
188 struct __Seed #de_impl_generics #where_clause {
189 variant: __Field,
190 marker: _serde::#private::PhantomData<#this_type #ty_generics>,
191 lifetime: _serde::#private::PhantomData<&#delife ()>,
192 }
193
194 #[automatically_derived]
195 impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Seed #de_ty_generics #where_clause {
196 type Value = #this_type #ty_generics;
197
198 fn deserialize<__D>(self, __deserializer: __D) -> _serde::#private::Result<Self::Value, __D::Error>
199 where
200 __D: _serde::Deserializer<#delife>,
201 {
202 match self.variant {
203 #(#variant_arms)*
204 }
205 }
206 }
207
208 #[doc(hidden)]
209 struct __Visitor #de_impl_generics #where_clause {
210 marker: _serde::#private::PhantomData<#this_type #ty_generics>,
211 lifetime: _serde::#private::PhantomData<&#delife ()>,
212 }
213
214 #[automatically_derived]
215 impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
216 type Value = #this_type #ty_generics;
217
218 fn expecting(&self, __formatter: &mut _serde::#private::Formatter) -> _serde::#private::fmt::Result {
219 _serde::#private::Formatter::write_str(__formatter, #expecting)
220 }
221
222 fn visit_map<__A>(self, mut __map: __A) -> _serde::#private::Result<Self::Value, __A::Error>
223 where
224 __A: _serde::de::MapAccess<#delife>,
225 {
226 match #next_relevant_key {
228 _serde::#private::Some(_serde::#private::de::TagOrContentField::Tag) => {
230 let __field = #variant_from_map;
232 match #next_relevant_key {
234 _serde::#private::Some(_serde::#private::de::TagOrContentField::Tag) => {
236 _serde::#private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#tag))
237 }
238 _serde::#private::Some(_serde::#private::de::TagOrContentField::Content) => {
240 let __ret = _serde::de::MapAccess::next_value_seed(&mut __map,
241 __Seed {
242 variant: __field,
243 marker: _serde::#private::PhantomData,
244 lifetime: _serde::#private::PhantomData,
245 })?;
246 #visit_remaining_keys
248 }
249 _serde::#private::None => #missing_content
251 }
252 }
253 _serde::#private::Some(_serde::#private::de::TagOrContentField::Content) => {
255 let __content = _serde::de::MapAccess::next_value_seed(&mut __map, _serde::#private::de::ContentVisitor::new())?;
257 match #next_relevant_key {
259 _serde::#private::Some(_serde::#private::de::TagOrContentField::Tag) => {
261 #finish_content_then_tag
262 }
263 _serde::#private::Some(_serde::#private::de::TagOrContentField::Content) => {
265 _serde::#private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#content))
266 }
267 _serde::#private::None => {
269 _serde::#private::Err(<__A::Error as _serde::de::Error>::missing_field(#tag))
270 }
271 }
272 }
273 _serde::#private::None => {
275 _serde::#private::Err(<__A::Error as _serde::de::Error>::missing_field(#tag))
276 }
277 }
278 }
279
280 fn visit_seq<__A>(self, mut __seq: __A) -> _serde::#private::Result<Self::Value, __A::Error>
281 where
282 __A: _serde::de::SeqAccess<#delife>,
283 {
284 match _serde::de::SeqAccess::next_element(&mut __seq)? {
286 _serde::#private::Some(__variant) => {
287 match _serde::de::SeqAccess::next_element_seed(
289 &mut __seq,
290 __Seed {
291 variant: __variant,
292 marker: _serde::#private::PhantomData,
293 lifetime: _serde::#private::PhantomData,
294 },
295 )? {
296 _serde::#private::Some(__ret) => _serde::#private::Ok(__ret),
297 _serde::#private::None => {
299 _serde::#private::Err(_serde::de::Error::invalid_length(1, &self))
300 }
301 }
302 }
303 _serde::#private::None => {
305 _serde::#private::Err(_serde::de::Error::invalid_length(0, &self))
306 }
307 }
308 }
309 }
310
311 #[doc(hidden)]
312 const FIELDS: &'static [&'static str] = &[#tag, #content];
313 _serde::Deserializer::deserialize_struct(
314 __deserializer,
315 #type_name,
316 FIELDS,
317 __Visitor {
318 marker: _serde::#private::PhantomData::<#this_type #ty_generics>,
319 lifetime: _serde::#private::PhantomData,
320 },
321 )
322 }
323}