serde_derive/de/
identifier.rs

1//! Deserialization of struct field identifiers and enum variant identifiers by
2//! way of a Rust enum.
3
4use crate::de::{FieldWithAliases, Parameters};
5use crate::fragment::{Fragment, Stmts};
6use crate::internals::ast::{Style, Variant};
7use crate::internals::attr;
8use crate::private;
9use proc_macro2::{Literal, TokenStream};
10use quote::{quote, ToTokens};
11
12// Generates `Deserialize::deserialize` body for an enum with
13// `serde(field_identifier)` or `serde(variant_identifier)` attribute.
14pub(super) fn deserialize_custom(
15    params: &Parameters,
16    variants: &[Variant],
17    cattrs: &attr::Container,
18) -> Fragment {
19    let is_variant = match cattrs.identifier() {
20        attr::Identifier::Variant => true,
21        attr::Identifier::Field => false,
22        attr::Identifier::No => unreachable!(),
23    };
24
25    let this_type = params.this_type.to_token_stream();
26    let this_value = params.this_value.to_token_stream();
27
28    let (ordinary, fallthrough, fallthrough_borrowed) = if let Some(last) = variants.last() {
29        let last_ident = &last.ident;
30        if last.attrs.other() {
31            // Process `serde(other)` attribute. It would always be found on the
32            // last variant (checked in `check_identifier`), so all preceding
33            // are ordinary variants.
34            let ordinary = &variants[..variants.len() - 1];
35            let fallthrough = quote!(_serde::#private::Ok(#this_value::#last_ident));
36            (ordinary, Some(fallthrough), None)
37        } else if let Style::Newtype = last.style {
38            let ordinary = &variants[..variants.len() - 1];
39            let fallthrough = |value| {
40                quote! {
41                    _serde::#private::Result::map(
42                        _serde::Deserialize::deserialize(
43                            _serde::#private::de::IdentifierDeserializer::from(#value)
44                        ),
45                        #this_value::#last_ident)
46                }
47            };
48            (
49                ordinary,
50                Some(fallthrough(quote!(__value))),
51                Some(fallthrough(quote!(_serde::#private::de::Borrowed(
52                    __value
53                )))),
54            )
55        } else {
56            (variants, None, None)
57        }
58    } else {
59        (variants, None, None)
60    };
61
62    let idents_aliases: Vec<_> = ordinary
63        .iter()
64        .map(|variant| FieldWithAliases {
65            ident: variant.ident.clone(),
66            aliases: variant.attrs.aliases(),
67        })
68        .collect();
69
70    let names = idents_aliases.iter().flat_map(|variant| variant.aliases);
71
72    let names_const = if fallthrough.is_some() {
73        None
74    } else if is_variant {
75        let variants = quote! {
76            #[doc(hidden)]
77            const VARIANTS: &'static [&'static str] = &[ #(#names),* ];
78        };
79        Some(variants)
80    } else {
81        let fields = quote! {
82            #[doc(hidden)]
83            const FIELDS: &'static [&'static str] = &[ #(#names),* ];
84        };
85        Some(fields)
86    };
87
88    let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
89        params.generics_with_de_lifetime();
90    let delife = params.borrowed.de_lifetime();
91    let visitor_impl = Stmts(deserialize_identifier(
92        &this_value,
93        &idents_aliases,
94        is_variant,
95        fallthrough,
96        fallthrough_borrowed,
97        false,
98        cattrs.expecting(),
99    ));
100
101    quote_block! {
102        #names_const
103
104        #[doc(hidden)]
105        struct __FieldVisitor #de_impl_generics #where_clause {
106            marker: _serde::#private::PhantomData<#this_type #ty_generics>,
107            lifetime: _serde::#private::PhantomData<&#delife ()>,
108        }
109
110        #[automatically_derived]
111        impl #de_impl_generics _serde::de::Visitor<#delife> for __FieldVisitor #de_ty_generics #where_clause {
112            type Value = #this_type #ty_generics;
113
114            #visitor_impl
115        }
116
117        let __visitor = __FieldVisitor {
118            marker: _serde::#private::PhantomData::<#this_type #ty_generics>,
119            lifetime: _serde::#private::PhantomData,
120        };
121        _serde::Deserializer::deserialize_identifier(__deserializer, __visitor)
122    }
123}
124
125pub(super) fn deserialize_generated(
126    deserialized_fields: &[FieldWithAliases],
127    has_flatten: bool,
128    is_variant: bool,
129    ignore_variant: Option<TokenStream>,
130    fallthrough: Option<TokenStream>,
131) -> Fragment {
132    let this_value = quote!(__Field);
133    let field_idents: &Vec<_> = &deserialized_fields
134        .iter()
135        .map(|field| &field.ident)
136        .collect();
137
138    let visitor_impl = Stmts(deserialize_identifier(
139        &this_value,
140        deserialized_fields,
141        is_variant,
142        fallthrough,
143        None,
144        !is_variant && has_flatten,
145        None,
146    ));
147
148    let lifetime = if !is_variant && has_flatten {
149        Some(quote!(<'de>))
150    } else {
151        None
152    };
153
154    quote_block! {
155        #[allow(non_camel_case_types)]
156        #[doc(hidden)]
157        enum __Field #lifetime {
158            #(#field_idents,)*
159            #ignore_variant
160        }
161
162        #[doc(hidden)]
163        struct __FieldVisitor;
164
165        #[automatically_derived]
166        impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
167            type Value = __Field #lifetime;
168
169            #visitor_impl
170        }
171
172        #[automatically_derived]
173        impl<'de> _serde::Deserialize<'de> for __Field #lifetime {
174            #[inline]
175            fn deserialize<__D>(__deserializer: __D) -> _serde::#private::Result<Self, __D::Error>
176            where
177                __D: _serde::Deserializer<'de>,
178            {
179                _serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
180            }
181        }
182    }
183}
184
185fn deserialize_identifier(
186    this_value: &TokenStream,
187    deserialized_fields: &[FieldWithAliases],
188    is_variant: bool,
189    fallthrough: Option<TokenStream>,
190    fallthrough_borrowed: Option<TokenStream>,
191    collect_other_fields: bool,
192    expecting: Option<&str>,
193) -> Fragment {
194    let str_mapping = deserialized_fields.iter().map(|field| {
195        let ident = &field.ident;
196        let aliases = field.aliases;
197        let private2 = private;
198        // `aliases` also contains a main name
199        quote! {
200            #(
201                #aliases => _serde::#private2::Ok(#this_value::#ident),
202            )*
203        }
204    });
205    let bytes_mapping = deserialized_fields.iter().map(|field| {
206        let ident = &field.ident;
207        // `aliases` also contains a main name
208        let aliases = field
209            .aliases
210            .iter()
211            .map(|alias| Literal::byte_string(alias.value.as_bytes()));
212        let private2 = private;
213        quote! {
214            #(
215                #aliases => _serde::#private2::Ok(#this_value::#ident),
216            )*
217        }
218    });
219
220    let expecting = expecting.unwrap_or(if is_variant {
221        "variant identifier"
222    } else {
223        "field identifier"
224    });
225
226    let bytes_to_str = if fallthrough.is_some() || collect_other_fields {
227        None
228    } else {
229        Some(quote! {
230            let __value = &_serde::#private::from_utf8_lossy(__value);
231        })
232    };
233
234    let (
235        value_as_str_content,
236        value_as_borrowed_str_content,
237        value_as_bytes_content,
238        value_as_borrowed_bytes_content,
239    ) = if collect_other_fields {
240        (
241            Some(quote! {
242                let __value = _serde::#private::de::Content::String(_serde::#private::ToString::to_string(__value));
243            }),
244            Some(quote! {
245                let __value = _serde::#private::de::Content::Str(__value);
246            }),
247            Some(quote! {
248                let __value = _serde::#private::de::Content::ByteBuf(__value.to_vec());
249            }),
250            Some(quote! {
251                let __value = _serde::#private::de::Content::Bytes(__value);
252            }),
253        )
254    } else {
255        (None, None, None, None)
256    };
257
258    let fallthrough_arm_tokens;
259    let fallthrough_arm = if let Some(fallthrough) = &fallthrough {
260        fallthrough
261    } else if is_variant {
262        fallthrough_arm_tokens = quote! {
263            _serde::#private::Err(_serde::de::Error::unknown_variant(__value, VARIANTS))
264        };
265        &fallthrough_arm_tokens
266    } else {
267        fallthrough_arm_tokens = quote! {
268            _serde::#private::Err(_serde::de::Error::unknown_field(__value, FIELDS))
269        };
270        &fallthrough_arm_tokens
271    };
272
273    let visit_other = if collect_other_fields {
274        quote! {
275            fn visit_bool<__E>(self, __value: bool) -> _serde::#private::Result<Self::Value, __E>
276            where
277                __E: _serde::de::Error,
278            {
279                _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::Bool(__value)))
280            }
281
282            fn visit_i8<__E>(self, __value: i8) -> _serde::#private::Result<Self::Value, __E>
283            where
284                __E: _serde::de::Error,
285            {
286                _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::I8(__value)))
287            }
288
289            fn visit_i16<__E>(self, __value: i16) -> _serde::#private::Result<Self::Value, __E>
290            where
291                __E: _serde::de::Error,
292            {
293                _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::I16(__value)))
294            }
295
296            fn visit_i32<__E>(self, __value: i32) -> _serde::#private::Result<Self::Value, __E>
297            where
298                __E: _serde::de::Error,
299            {
300                _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::I32(__value)))
301            }
302
303            fn visit_i64<__E>(self, __value: i64) -> _serde::#private::Result<Self::Value, __E>
304            where
305                __E: _serde::de::Error,
306            {
307                _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::I64(__value)))
308            }
309
310            fn visit_u8<__E>(self, __value: u8) -> _serde::#private::Result<Self::Value, __E>
311            where
312                __E: _serde::de::Error,
313            {
314                _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::U8(__value)))
315            }
316
317            fn visit_u16<__E>(self, __value: u16) -> _serde::#private::Result<Self::Value, __E>
318            where
319                __E: _serde::de::Error,
320            {
321                _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::U16(__value)))
322            }
323
324            fn visit_u32<__E>(self, __value: u32) -> _serde::#private::Result<Self::Value, __E>
325            where
326                __E: _serde::de::Error,
327            {
328                _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::U32(__value)))
329            }
330
331            fn visit_u64<__E>(self, __value: u64) -> _serde::#private::Result<Self::Value, __E>
332            where
333                __E: _serde::de::Error,
334            {
335                _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::U64(__value)))
336            }
337
338            fn visit_f32<__E>(self, __value: f32) -> _serde::#private::Result<Self::Value, __E>
339            where
340                __E: _serde::de::Error,
341            {
342                _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::F32(__value)))
343            }
344
345            fn visit_f64<__E>(self, __value: f64) -> _serde::#private::Result<Self::Value, __E>
346            where
347                __E: _serde::de::Error,
348            {
349                _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::F64(__value)))
350            }
351
352            fn visit_char<__E>(self, __value: char) -> _serde::#private::Result<Self::Value, __E>
353            where
354                __E: _serde::de::Error,
355            {
356                _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::Char(__value)))
357            }
358
359            fn visit_unit<__E>(self) -> _serde::#private::Result<Self::Value, __E>
360            where
361                __E: _serde::de::Error,
362            {
363                _serde::#private::Ok(__Field::__other(_serde::#private::de::Content::Unit))
364            }
365        }
366    } else {
367        let u64_mapping = deserialized_fields.iter().enumerate().map(|(i, field)| {
368            let i = i as u64;
369            let ident = &field.ident;
370            quote!(#i => _serde::#private::Ok(#this_value::#ident))
371        });
372
373        let u64_fallthrough_arm_tokens;
374        let u64_fallthrough_arm = if let Some(fallthrough) = &fallthrough {
375            fallthrough
376        } else {
377            let index_expecting = if is_variant { "variant" } else { "field" };
378            let fallthrough_msg = format!(
379                "{} index 0 <= i < {}",
380                index_expecting,
381                deserialized_fields.len(),
382            );
383            u64_fallthrough_arm_tokens = quote! {
384                _serde::#private::Err(_serde::de::Error::invalid_value(
385                    _serde::de::Unexpected::Unsigned(__value),
386                    &#fallthrough_msg,
387                ))
388            };
389            &u64_fallthrough_arm_tokens
390        };
391
392        quote! {
393            fn visit_u64<__E>(self, __value: u64) -> _serde::#private::Result<Self::Value, __E>
394            where
395                __E: _serde::de::Error,
396            {
397                match __value {
398                    #(#u64_mapping,)*
399                    _ => #u64_fallthrough_arm,
400                }
401            }
402        }
403    };
404
405    let visit_borrowed = if fallthrough_borrowed.is_some() || collect_other_fields {
406        let str_mapping = str_mapping.clone();
407        let bytes_mapping = bytes_mapping.clone();
408        let fallthrough_borrowed_arm = fallthrough_borrowed.as_ref().unwrap_or(fallthrough_arm);
409        Some(quote! {
410            fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::#private::Result<Self::Value, __E>
411            where
412                __E: _serde::de::Error,
413            {
414                match __value {
415                    #(#str_mapping)*
416                    _ => {
417                        #value_as_borrowed_str_content
418                        #fallthrough_borrowed_arm
419                    }
420                }
421            }
422
423            fn visit_borrowed_bytes<__E>(self, __value: &'de [u8]) -> _serde::#private::Result<Self::Value, __E>
424            where
425                __E: _serde::de::Error,
426            {
427                match __value {
428                    #(#bytes_mapping)*
429                    _ => {
430                        #bytes_to_str
431                        #value_as_borrowed_bytes_content
432                        #fallthrough_borrowed_arm
433                    }
434                }
435            }
436        })
437    } else {
438        None
439    };
440
441    quote_block! {
442        fn expecting(&self, __formatter: &mut _serde::#private::Formatter) -> _serde::#private::fmt::Result {
443            _serde::#private::Formatter::write_str(__formatter, #expecting)
444        }
445
446        #visit_other
447
448        fn visit_str<__E>(self, __value: &str) -> _serde::#private::Result<Self::Value, __E>
449        where
450            __E: _serde::de::Error,
451        {
452            match __value {
453                #(#str_mapping)*
454                _ => {
455                    #value_as_str_content
456                    #fallthrough_arm
457                }
458            }
459        }
460
461        fn visit_bytes<__E>(self, __value: &[u8]) -> _serde::#private::Result<Self::Value, __E>
462        where
463            __E: _serde::de::Error,
464        {
465            match __value {
466                #(#bytes_mapping)*
467                _ => {
468                    #bytes_to_str
469                    #value_as_bytes_content
470                    #fallthrough_arm
471                }
472            }
473        }
474
475        #visit_borrowed
476    }
477}