serde_derive/de/
enum_adjacently.rs

1//! Deserialization for adjacently tagged enums:
2//!
3//! ```ignore
4//! #[serde(tag = "...", content = "...")]
5//! enum Enum {}
6//! ```
7
8use 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
18/// Generates `Deserialize::deserialize` body for an `enum Enum {...}` with `#[serde(tag, content)]` attributes
19pub(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 = &params.this_type;
27    let this_value = &params.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    // If unknown fields are allowed, we pick the visitor that can step over
56    // those. Otherwise we pick the visitor that fails on unknown keys.
57    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    // Advance the map by one key, returning early in case of error.
106    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    // When allowing unknown fields, we want to transparently step through keys
122    // we don't care about until we find `tag`, `content`, or run out of keys.
123    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    // Step through remaining keys, looking for duplicates of previously-seen
150    // keys. When unknown fields are denied, any key that isn't a duplicate will
151    // at this point immediately produce an error.
152    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, looking for duplicates.
178            #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                // Visit the first relevant key.
227                match #next_relevant_key {
228                    // First key is the tag.
229                    _serde::#private::Some(_serde::#private::de::TagOrContentField::Tag) => {
230                        // Parse the tag.
231                        let __field = #variant_from_map;
232                        // Visit the second key.
233                        match #next_relevant_key {
234                            // Second key is a duplicate of the tag.
235                            _serde::#private::Some(_serde::#private::de::TagOrContentField::Tag) => {
236                                _serde::#private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#tag))
237                            }
238                            // Second key is the content.
239                            _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, looking for duplicates.
247                                #visit_remaining_keys
248                            }
249                            // There is no second key; might be okay if the we have a unit variant.
250                            _serde::#private::None => #missing_content
251                        }
252                    }
253                    // First key is the content.
254                    _serde::#private::Some(_serde::#private::de::TagOrContentField::Content) => {
255                        // Buffer up the content.
256                        let __content = _serde::de::MapAccess::next_value_seed(&mut __map, _serde::#private::de::ContentVisitor::new())?;
257                        // Visit the second key.
258                        match #next_relevant_key {
259                            // Second key is the tag.
260                            _serde::#private::Some(_serde::#private::de::TagOrContentField::Tag) => {
261                                #finish_content_then_tag
262                            }
263                            // Second key is a duplicate of the content.
264                            _serde::#private::Some(_serde::#private::de::TagOrContentField::Content) => {
265                                _serde::#private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#content))
266                            }
267                            // There is no second key.
268                            _serde::#private::None => {
269                                _serde::#private::Err(<__A::Error as _serde::de::Error>::missing_field(#tag))
270                            }
271                        }
272                    }
273                    // There is no first key.
274                    _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                // Visit the first element - the tag.
285                match _serde::de::SeqAccess::next_element(&mut __seq)? {
286                    _serde::#private::Some(__variant) => {
287                        // Visit the second element - the content.
288                        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                            // There is no second element.
298                            _serde::#private::None => {
299                                _serde::#private::Err(_serde::de::Error::invalid_length(1, &self))
300                            }
301                        }
302                    }
303                    // There is no first element.
304                    _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}