serde_derive/de/
struct_.rs

1use crate::de::identifier;
2use crate::de::{
3    deserialize_seq, expr_is_missing, field_i, has_flatten, wrap_deserialize_field_with,
4    FieldWithAliases, Parameters, StructForm,
5};
6#[cfg(feature = "deserialize_in_place")]
7use crate::de::{deserialize_seq_in_place, place_lifetime};
8use crate::fragment::{Expr, Fragment, Match, Stmts};
9use crate::internals::ast::Field;
10use crate::internals::attr;
11use crate::private;
12use proc_macro2::TokenStream;
13use quote::{quote, quote_spanned};
14use syn::spanned::Spanned;
15
16/// Generates `Deserialize::deserialize` body for a `struct Struct {...}`
17pub(super) fn deserialize(
18    params: &Parameters,
19    fields: &[Field],
20    cattrs: &attr::Container,
21    form: StructForm,
22) -> Fragment {
23    let this_type = &params.this_type;
24    let this_value = &params.this_value;
25    let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
26        params.generics_with_de_lifetime();
27    let delife = params.borrowed.de_lifetime();
28
29    // If there are getters (implying private fields), construct the local type
30    // and use an `Into` conversion to get the remote type. If there are no
31    // getters then construct the target type directly.
32    let construct = if params.has_getter {
33        let local = &params.local;
34        quote!(#local)
35    } else {
36        quote!(#this_value)
37    };
38
39    let type_path = match form {
40        StructForm::Struct => construct,
41        StructForm::ExternallyTagged(variant_ident)
42        | StructForm::InternallyTagged(variant_ident)
43        | StructForm::Untagged(variant_ident) => quote!(#construct::#variant_ident),
44    };
45    let expecting = match form {
46        StructForm::Struct => format!("struct {}", params.type_name()),
47        StructForm::ExternallyTagged(variant_ident)
48        | StructForm::InternallyTagged(variant_ident)
49        | StructForm::Untagged(variant_ident) => {
50            format!("struct variant {}::{}", params.type_name(), variant_ident)
51        }
52    };
53    let expecting = cattrs.expecting().unwrap_or(&expecting);
54
55    let deserialized_fields: Vec<_> = fields
56        .iter()
57        .enumerate()
58        // Skip fields that shouldn't be deserialized or that were flattened,
59        // so they don't appear in the storage in their literal form
60        .filter(|&(_, field)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
61        .map(|(i, field)| FieldWithAliases {
62            ident: field_i(i),
63            aliases: field.attrs.aliases(),
64        })
65        .collect();
66
67    let has_flatten = has_flatten(fields);
68    let field_visitor = deserialize_field_identifier(&deserialized_fields, cattrs, has_flatten);
69
70    // untagged struct variants do not get a visit_seq method. The same applies to
71    // structs that only have a map representation.
72    let visit_seq = match form {
73        StructForm::Untagged(_) => None,
74        _ if has_flatten => None,
75        _ => {
76            let mut_seq = if deserialized_fields.is_empty() {
77                quote!(_)
78            } else {
79                quote!(mut __seq)
80            };
81
82            let visit_seq = Stmts(deserialize_seq(
83                &type_path, params, fields, true, cattrs, expecting,
84            ));
85
86            Some(quote! {
87                #[inline]
88                fn visit_seq<__A>(self, #mut_seq: __A) -> _serde::#private::Result<Self::Value, __A::Error>
89                where
90                    __A: _serde::de::SeqAccess<#delife>,
91                {
92                    #visit_seq
93                }
94            })
95        }
96    };
97    let visit_map = Stmts(deserialize_map(
98        &type_path,
99        params,
100        fields,
101        cattrs,
102        has_flatten,
103    ));
104
105    let visitor_seed = match form {
106        StructForm::ExternallyTagged(..) if has_flatten => Some(quote! {
107            #[automatically_derived]
108            impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Visitor #de_ty_generics #where_clause {
109                type Value = #this_type #ty_generics;
110
111                fn deserialize<__D>(self, __deserializer: __D) -> _serde::#private::Result<Self::Value, __D::Error>
112                where
113                    __D: _serde::Deserializer<#delife>,
114                {
115                    _serde::Deserializer::deserialize_map(__deserializer, self)
116                }
117            }
118        }),
119        _ => None,
120    };
121
122    let fields_stmt = if has_flatten {
123        None
124    } else {
125        let field_names = deserialized_fields.iter().flat_map(|field| field.aliases);
126
127        Some(quote! {
128            #[doc(hidden)]
129            const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
130        })
131    };
132
133    let visitor_expr = quote! {
134        __Visitor {
135            marker: _serde::#private::PhantomData::<#this_type #ty_generics>,
136            lifetime: _serde::#private::PhantomData,
137        }
138    };
139    let dispatch = match form {
140        StructForm::Struct if has_flatten => quote! {
141            _serde::Deserializer::deserialize_map(__deserializer, #visitor_expr)
142        },
143        StructForm::Struct => {
144            let type_name = cattrs.name().deserialize_name();
145            quote! {
146                _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr)
147            }
148        }
149        StructForm::ExternallyTagged(_) if has_flatten => quote! {
150            _serde::de::VariantAccess::newtype_variant_seed(__variant, #visitor_expr)
151        },
152        StructForm::ExternallyTagged(_) => quote! {
153            _serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr)
154        },
155        StructForm::InternallyTagged(_) => quote! {
156            _serde::Deserializer::deserialize_any(__deserializer, #visitor_expr)
157        },
158        StructForm::Untagged(_) => quote! {
159            _serde::Deserializer::deserialize_any(__deserializer, #visitor_expr)
160        },
161    };
162
163    quote_block! {
164        #field_visitor
165
166        #[doc(hidden)]
167        struct __Visitor #de_impl_generics #where_clause {
168            marker: _serde::#private::PhantomData<#this_type #ty_generics>,
169            lifetime: _serde::#private::PhantomData<&#delife ()>,
170        }
171
172        #[automatically_derived]
173        impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
174            type Value = #this_type #ty_generics;
175
176            fn expecting(&self, __formatter: &mut _serde::#private::Formatter) -> _serde::#private::fmt::Result {
177                _serde::#private::Formatter::write_str(__formatter, #expecting)
178            }
179
180            #visit_seq
181
182            #[inline]
183            fn visit_map<__A>(self, mut __map: __A) -> _serde::#private::Result<Self::Value, __A::Error>
184            where
185                __A: _serde::de::MapAccess<#delife>,
186            {
187                #visit_map
188            }
189        }
190
191        #visitor_seed
192
193        #fields_stmt
194
195        #dispatch
196    }
197}
198
199fn deserialize_map(
200    struct_path: &TokenStream,
201    params: &Parameters,
202    fields: &[Field],
203    cattrs: &attr::Container,
204    has_flatten: bool,
205) -> Fragment {
206    // Create the field names for the fields.
207    let fields_names: Vec<_> = fields
208        .iter()
209        .enumerate()
210        .map(|(i, field)| (field, field_i(i)))
211        .collect();
212
213    // Declare each field that will be deserialized.
214    let let_values = fields_names
215        .iter()
216        .filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
217        .map(|(field, name)| {
218            let field_ty = field.ty;
219            quote! {
220                let mut #name: _serde::#private::Option<#field_ty> = _serde::#private::None;
221            }
222        });
223
224    // Collect contents for flatten fields into a buffer
225    let let_collect = if has_flatten {
226        Some(quote! {
227            let mut __collect = _serde::#private::Vec::<_serde::#private::Option<(
228                _serde::#private::de::Content,
229                _serde::#private::de::Content
230            )>>::new();
231        })
232    } else {
233        None
234    };
235
236    // Match arms to extract a value for a field.
237    let value_arms = fields_names
238        .iter()
239        .filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
240        .map(|(field, name)| {
241            let deser_name = field.attrs.name().deserialize_name();
242
243            let visit = match field.attrs.deserialize_with() {
244                None => {
245                    let field_ty = field.ty;
246                    let span = field.original.span();
247                    let func =
248                        quote_spanned!(span=> _serde::de::MapAccess::next_value::<#field_ty>);
249                    quote! {
250                        #func(&mut __map)?
251                    }
252                }
253                Some(path) => {
254                    let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
255                    quote!({
256                        #wrapper
257                        match _serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map) {
258                            _serde::#private::Ok(__wrapper) => __wrapper.value,
259                            _serde::#private::Err(__err) => {
260                                return _serde::#private::Err(__err);
261                            }
262                        }
263                    })
264                }
265            };
266            quote! {
267                __Field::#name => {
268                    if _serde::#private::Option::is_some(&#name) {
269                        return _serde::#private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#deser_name));
270                    }
271                    #name = _serde::#private::Some(#visit);
272                }
273            }
274        });
275
276    // Visit ignored values to consume them
277    let ignored_arm = if has_flatten {
278        Some(quote! {
279            __Field::__other(__name) => {
280                __collect.push(_serde::#private::Some((
281                    __name,
282                    _serde::de::MapAccess::next_value_seed(&mut __map, _serde::#private::de::ContentVisitor::new())?)));
283            }
284        })
285    } else if cattrs.deny_unknown_fields() {
286        None
287    } else {
288        Some(quote! {
289            _ => { let _ = _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?; }
290        })
291    };
292
293    let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
294    let match_keys = if cattrs.deny_unknown_fields() && all_skipped {
295        quote! {
296            // FIXME: Once feature(exhaustive_patterns) is stable:
297            // let _serde::#private::None::<__Field> = _serde::de::MapAccess::next_key(&mut __map)?;
298            _serde::#private::Option::map(
299                _serde::de::MapAccess::next_key::<__Field>(&mut __map)?,
300                |__impossible| match __impossible {});
301        }
302    } else {
303        quote! {
304            while let _serde::#private::Some(__key) = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
305                match __key {
306                    #(#value_arms)*
307                    #ignored_arm
308                }
309            }
310        }
311    };
312
313    let extract_values = fields_names
314        .iter()
315        .filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
316        .map(|(field, name)| {
317            let missing_expr = Match(expr_is_missing(field, cattrs));
318
319            quote! {
320                let #name = match #name {
321                    _serde::#private::Some(#name) => #name,
322                    _serde::#private::None => #missing_expr
323                };
324            }
325        });
326
327    let extract_collected = fields_names
328        .iter()
329        .filter(|&&(field, _)| field.attrs.flatten() && !field.attrs.skip_deserializing())
330        .map(|(field, name)| {
331            let field_ty = field.ty;
332            let func = match field.attrs.deserialize_with() {
333                None => {
334                    let span = field.original.span();
335                    quote_spanned!(span=> _serde::de::Deserialize::deserialize)
336                }
337                Some(path) => quote!(#path),
338            };
339            quote! {
340                let #name: #field_ty = #func(
341                    _serde::#private::de::FlatMapDeserializer(
342                        &mut __collect,
343                        _serde::#private::PhantomData))?;
344            }
345        });
346
347    let collected_deny_unknown_fields = if has_flatten && cattrs.deny_unknown_fields() {
348        Some(quote! {
349            if let _serde::#private::Some(_serde::#private::Some((__key, _))) =
350                __collect.into_iter().filter(_serde::#private::Option::is_some).next()
351            {
352                if let _serde::#private::Some(__key) = _serde::#private::de::content_as_str(&__key) {
353                    return _serde::#private::Err(
354                        _serde::de::Error::custom(format_args!("unknown field `{}`", &__key)));
355                } else {
356                    return _serde::#private::Err(
357                        _serde::de::Error::custom(format_args!("unexpected map key")));
358                }
359            }
360        })
361    } else {
362        None
363    };
364
365    let result = fields_names.iter().map(|(field, name)| {
366        let member = &field.member;
367        if field.attrs.skip_deserializing() {
368            let value = Expr(expr_is_missing(field, cattrs));
369            quote!(#member: #value)
370        } else {
371            quote!(#member: #name)
372        }
373    });
374
375    let let_default = match cattrs.default() {
376        attr::Default::Default => Some(quote!(
377            let __default: Self::Value = _serde::#private::Default::default();
378        )),
379        // If #path returns wrong type, error will be reported here (^^^^^).
380        // We attach span of the path to the function so it will be reported
381        // on the #[serde(default = "...")]
382        //                          ^^^^^
383        attr::Default::Path(path) => Some(quote_spanned!(path.span()=>
384            let __default: Self::Value = #path();
385        )),
386        attr::Default::None => {
387            // We don't need the default value, to prevent an unused variable warning
388            // we'll leave the line empty.
389            None
390        }
391    };
392
393    let mut result = quote!(#struct_path { #(#result),* });
394    if params.has_getter {
395        let this_type = &params.this_type;
396        let (_, ty_generics, _) = params.generics.split_for_impl();
397        result = quote! {
398            _serde::#private::Into::<#this_type #ty_generics>::into(#result)
399        };
400    }
401
402    quote_block! {
403        #(#let_values)*
404
405        #let_collect
406
407        #match_keys
408
409        #let_default
410
411        #(#extract_values)*
412
413        #(#extract_collected)*
414
415        #collected_deny_unknown_fields
416
417        _serde::#private::Ok(#result)
418    }
419}
420
421/// Generates `Deserialize::deserialize_in_place` body for a `struct Struct {...}`
422#[cfg(feature = "deserialize_in_place")]
423pub(super) fn deserialize_in_place(
424    params: &Parameters,
425    fields: &[Field],
426    cattrs: &attr::Container,
427) -> Option<Fragment> {
428    // for now we do not support in_place deserialization for structs that
429    // are represented as map.
430    if has_flatten(fields) {
431        return None;
432    }
433
434    let this_type = &params.this_type;
435    let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
436        params.generics_with_de_lifetime();
437    let delife = params.borrowed.de_lifetime();
438
439    let expecting = format!("struct {}", params.type_name());
440    let expecting = cattrs.expecting().unwrap_or(&expecting);
441
442    let deserialized_fields: Vec<_> = fields
443        .iter()
444        .enumerate()
445        .filter(|&(_, field)| !field.attrs.skip_deserializing())
446        .map(|(i, field)| FieldWithAliases {
447            ident: field_i(i),
448            aliases: field.attrs.aliases(),
449        })
450        .collect();
451
452    let field_visitor = deserialize_field_identifier(&deserialized_fields, cattrs, false);
453
454    let mut_seq = if deserialized_fields.is_empty() {
455        quote!(_)
456    } else {
457        quote!(mut __seq)
458    };
459    let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, expecting));
460    let visit_map = Stmts(deserialize_map_in_place(params, fields, cattrs));
461    let field_names = deserialized_fields.iter().flat_map(|field| field.aliases);
462    let type_name = cattrs.name().deserialize_name();
463
464    let in_place_impl_generics = de_impl_generics.in_place();
465    let in_place_ty_generics = de_ty_generics.in_place();
466    let place_life = place_lifetime();
467
468    Some(quote_block! {
469        #field_visitor
470
471        #[doc(hidden)]
472        struct __Visitor #in_place_impl_generics #where_clause {
473            place: &#place_life mut #this_type #ty_generics,
474            lifetime: _serde::#private::PhantomData<&#delife ()>,
475        }
476
477        #[automatically_derived]
478        impl #in_place_impl_generics _serde::de::Visitor<#delife> for __Visitor #in_place_ty_generics #where_clause {
479            type Value = ();
480
481            fn expecting(&self, __formatter: &mut _serde::#private::Formatter) -> _serde::#private::fmt::Result {
482                _serde::#private::Formatter::write_str(__formatter, #expecting)
483            }
484
485            #[inline]
486            fn visit_seq<__A>(self, #mut_seq: __A) -> _serde::#private::Result<Self::Value, __A::Error>
487            where
488                __A: _serde::de::SeqAccess<#delife>,
489            {
490                #visit_seq
491            }
492
493            #[inline]
494            fn visit_map<__A>(self, mut __map: __A) -> _serde::#private::Result<Self::Value, __A::Error>
495            where
496                __A: _serde::de::MapAccess<#delife>,
497            {
498                #visit_map
499            }
500        }
501
502        #[doc(hidden)]
503        const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
504
505        _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, __Visitor {
506            place: __place,
507            lifetime: _serde::#private::PhantomData,
508        })
509    })
510}
511
512#[cfg(feature = "deserialize_in_place")]
513fn deserialize_map_in_place(
514    params: &Parameters,
515    fields: &[Field],
516    cattrs: &attr::Container,
517) -> Fragment {
518    assert!(
519        !has_flatten(fields),
520        "inplace deserialization of maps does not support flatten fields"
521    );
522
523    // Create the field names for the fields.
524    let fields_names: Vec<_> = fields
525        .iter()
526        .enumerate()
527        .map(|(i, field)| (field, field_i(i)))
528        .collect();
529
530    // For deserialize_in_place, declare booleans for each field that will be
531    // deserialized.
532    let let_flags = fields_names
533        .iter()
534        .filter(|&&(field, _)| !field.attrs.skip_deserializing())
535        .map(|(_, name)| {
536            quote! {
537                let mut #name: bool = false;
538            }
539        });
540
541    // Match arms to extract a value for a field.
542    let value_arms_from = fields_names
543        .iter()
544        .filter(|&&(field, _)| !field.attrs.skip_deserializing())
545        .map(|(field, name)| {
546            let deser_name = field.attrs.name().deserialize_name();
547            let member = &field.member;
548
549            let visit = match field.attrs.deserialize_with() {
550                None => {
551                    quote! {
552                        _serde::de::MapAccess::next_value_seed(&mut __map, _serde::#private::de::InPlaceSeed(&mut self.place.#member))?
553                    }
554                }
555                Some(path) => {
556                    let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
557                    quote!({
558                        #wrapper
559                        self.place.#member = match _serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map) {
560                            _serde::#private::Ok(__wrapper) => __wrapper.value,
561                            _serde::#private::Err(__err) => {
562                                return _serde::#private::Err(__err);
563                            }
564                        };
565                    })
566                }
567            };
568            quote! {
569                __Field::#name => {
570                    if #name {
571                        return _serde::#private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#deser_name));
572                    }
573                    #visit;
574                    #name = true;
575                }
576            }
577        });
578
579    // Visit ignored values to consume them
580    let ignored_arm = if cattrs.deny_unknown_fields() {
581        None
582    } else {
583        Some(quote! {
584            _ => { let _ = _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?; }
585        })
586    };
587
588    let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
589
590    let match_keys = if cattrs.deny_unknown_fields() && all_skipped {
591        quote! {
592            // FIXME: Once feature(exhaustive_patterns) is stable:
593            // let _serde::#private::None::<__Field> = _serde::de::MapAccess::next_key(&mut __map)?;
594            _serde::#private::Option::map(
595                _serde::de::MapAccess::next_key::<__Field>(&mut __map)?,
596                |__impossible| match __impossible {});
597        }
598    } else {
599        quote! {
600            while let _serde::#private::Some(__key) = _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
601                match __key {
602                    #(#value_arms_from)*
603                    #ignored_arm
604                }
605            }
606        }
607    };
608
609    let check_flags = fields_names
610        .iter()
611        .filter(|&&(field, _)| !field.attrs.skip_deserializing())
612        .map(|(field, name)| {
613            let missing_expr = expr_is_missing(field, cattrs);
614            // If missing_expr unconditionally returns an error, don't try
615            // to assign its value to self.place.
616            if field.attrs.default().is_none()
617                && cattrs.default().is_none()
618                && field.attrs.deserialize_with().is_some()
619            {
620                let missing_expr = Stmts(missing_expr);
621                quote! {
622                    if !#name {
623                        #missing_expr;
624                    }
625                }
626            } else {
627                let member = &field.member;
628                let missing_expr = Expr(missing_expr);
629                quote! {
630                    if !#name {
631                        self.place.#member = #missing_expr;
632                    };
633                }
634            }
635        });
636
637    let this_type = &params.this_type;
638    let (_, ty_generics, _) = params.generics.split_for_impl();
639
640    let let_default = match cattrs.default() {
641        attr::Default::Default => Some(quote!(
642            let __default: #this_type #ty_generics = _serde::#private::Default::default();
643        )),
644        // If #path returns wrong type, error will be reported here (^^^^^).
645        // We attach span of the path to the function so it will be reported
646        // on the #[serde(default = "...")]
647        //                          ^^^^^
648        attr::Default::Path(path) => Some(quote_spanned!(path.span()=>
649            let __default: #this_type #ty_generics = #path();
650        )),
651        attr::Default::None => {
652            // We don't need the default value, to prevent an unused variable warning
653            // we'll leave the line empty.
654            None
655        }
656    };
657
658    quote_block! {
659        #(#let_flags)*
660
661        #match_keys
662
663        #let_default
664
665        #(#check_flags)*
666
667        _serde::#private::Ok(())
668    }
669}
670
671/// Generates enum and its `Deserialize` implementation that represents each
672/// non-skipped field of the struct
673fn deserialize_field_identifier(
674    deserialized_fields: &[FieldWithAliases],
675    cattrs: &attr::Container,
676    has_flatten: bool,
677) -> Stmts {
678    let (ignore_variant, fallthrough) = if has_flatten {
679        let ignore_variant = quote!(__other(_serde::#private::de::Content<'de>),);
680        let fallthrough = quote!(_serde::#private::Ok(__Field::__other(__value)));
681        (Some(ignore_variant), Some(fallthrough))
682    } else if cattrs.deny_unknown_fields() {
683        (None, None)
684    } else {
685        let ignore_variant = quote!(__ignore,);
686        let fallthrough = quote!(_serde::#private::Ok(__Field::__ignore));
687        (Some(ignore_variant), Some(fallthrough))
688    };
689
690    Stmts(identifier::deserialize_generated(
691        deserialized_fields,
692        has_flatten,
693        false,
694        ignore_variant,
695        fallthrough,
696    ))
697}