Skip to main content

serde_derive/de/
enum_externally.rs

1//! Deserialization for externally tagged enums:
2//!
3//! ```ignore
4//! enum Enum {}
5//! ```
6
7use crate::de::enum_;
8use crate::de::struct_;
9use crate::de::tuple;
10use crate::de::{
11    expr_is_missing, field_i, unwrap_to_variant_closure, wrap_deserialize_field_with,
12    wrap_deserialize_with, Parameters, StructForm, TupleForm,
13};
14use crate::fragment::{Expr, Fragment, Match};
15use crate::internals::ast::{Field, Style, Variant};
16use crate::internals::attr;
17use crate::private;
18use proc_macro2::TokenStream;
19use quote::{quote, quote_spanned};
20use syn::spanned::Spanned;
21
22/// Generates `Deserialize::deserialize` body for an `enum Enum {...}` without additional attributes
23pub(super) fn deserialize(
24    params: &Parameters,
25    variants: &[Variant],
26    cattrs: &attr::Container,
27) -> Fragment {
28    let this_type = &params.this_type;
29    let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
30        params.generics_with_de_lifetime();
31    let delife = params.borrowed.de_lifetime();
32
33    let type_name = cattrs.name().deserialize_name();
34    let expecting = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("enum {0}", params.type_name()))
    })format!("enum {}", params.type_name());
35    let expecting = cattrs.expecting().unwrap_or(&expecting);
36
37    let (variants_stmt, variant_visitor) = enum_::prepare_enum_variant_enum(variants);
38
39    // Match arms to extract a variant from a string
40    let variant_arms = variants
41        .iter()
42        .enumerate()
43        .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
44        .map(|(i, variant)| {
45            let variant_name = field_i(i);
46
47            let block = Match(deserialize_externally_tagged_variant(
48                params, variant, cattrs,
49            ));
50
51            {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "_serde");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::ToTokens::to_tokens(&private, &mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Ok");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__Field");
                    ::quote::__private::push_colon2(&mut _s);
                    ::quote::ToTokens::to_tokens(&variant_name, &mut _s);
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_ident(&mut _s, "__variant");
                    _s
                });
            _s
        });
    ::quote::__private::push_fat_arrow(&mut _s);
    ::quote::ToTokens::to_tokens(&block, &mut _s);
    _s
}quote! {
52                _serde::#private::Ok((__Field::#variant_name, __variant)) => #block
53            }
54        });
55
56    let all_skipped = variants
57        .iter()
58        .all(|variant| variant.attrs.skip_deserializing());
59    let match_variant = if all_skipped {
60        // This is an empty enum like `enum Impossible {}` or an enum in which
61        // all variants have `#[serde(skip_deserializing)]`.
62        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "_serde");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::ToTokens::to_tokens(&private, &mut _s);
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "Result");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "map");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "_serde");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "de");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "EnumAccess");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "variant");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_lt(&mut _s);
            ::quote::__private::push_ident(&mut _s, "__Field");
            ::quote::__private::push_gt(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__data");
                    _s
                });
            ::quote::__private::push_comma(&mut _s);
            ::quote::__private::push_or(&mut _s);
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__impossible");
                    ::quote::__private::push_comma(&mut _s);
                    ::quote::__private::push_underscore(&mut _s);
                    _s
                });
            ::quote::__private::push_or(&mut _s);
            ::quote::__private::push_ident(&mut _s, "match");
            ::quote::__private::push_ident(&mut _s, "__impossible");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Brace,
                ::quote::__private::TokenStream::new());
            _s
        });
    _s
}quote! {
63            // FIXME: Once feature(exhaustive_patterns) is stable:
64            // let _serde::#private::Err(__err) = _serde::de::EnumAccess::variant::<__Field>(__data);
65            // _serde::#private::Err(__err)
66            _serde::#private::Result::map(
67                _serde::de::EnumAccess::variant::<__Field>(__data),
68                |(__impossible, _)| match __impossible {})
69        }
70    } else {
71        {
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident(&mut _s, "match");
    ::quote::__private::push_ident(&mut _s, "_serde");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "de");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "EnumAccess");
    ::quote::__private::push_colon2(&mut _s);
    ::quote::__private::push_ident(&mut _s, "variant");
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            ::quote::__private::push_ident(&mut _s, "__data");
            _s
        });
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Brace,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            {
                use ::quote::__private::ext::*;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut variant_arms, i) = variant_arms.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let variant_arms =
                        match variant_arms.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    ::quote::ToTokens::to_tokens(&variant_arms, &mut _s);
                }
            }
            ::quote::__private::push_ident(&mut _s, "_serde");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::ToTokens::to_tokens(&private, &mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Err");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__err");
                    _s
                });
            ::quote::__private::push_fat_arrow(&mut _s);
            ::quote::__private::push_ident(&mut _s, "_serde");
            ::quote::__private::push_colon2(&mut _s);
            ::quote::ToTokens::to_tokens(&private, &mut _s);
            ::quote::__private::push_colon2(&mut _s);
            ::quote::__private::push_ident(&mut _s, "Err");
            ::quote::__private::push_group(&mut _s,
                ::quote::__private::Delimiter::Parenthesis,
                {
                    let mut _s = ::quote::__private::TokenStream::new();
                    ::quote::__private::push_ident(&mut _s, "__err");
                    _s
                });
            ::quote::__private::push_comma(&mut _s);
            _s
        });
    _s
}quote! {
72            match _serde::de::EnumAccess::variant(__data) {
73                #(#variant_arms)*
74                _serde::#private::Err(__err) => _serde::#private::Err(__err),
75            }
76        }
77    };
78
79    crate::fragment::Fragment::Block({
        let mut _s = ::quote::__private::TokenStream::new();
        ::quote::ToTokens::to_tokens(&variant_visitor, &mut _s);
        ::quote::__private::push_pound(&mut _s);
        ::quote::__private::push_group(&mut _s,
            ::quote::__private::Delimiter::Bracket,
            {
                let mut _s = ::quote::__private::TokenStream::new();
                ::quote::__private::push_ident(&mut _s, "doc");
                ::quote::__private::push_group(&mut _s,
                    ::quote::__private::Delimiter::Parenthesis,
                    {
                        let mut _s = ::quote::__private::TokenStream::new();
                        ::quote::__private::push_ident(&mut _s, "hidden");
                        _s
                    });
                _s
            });
        ::quote::__private::push_ident(&mut _s, "struct");
        ::quote::__private::push_ident(&mut _s, "__Visitor");
        ::quote::ToTokens::to_tokens(&de_impl_generics, &mut _s);
        ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
        ::quote::__private::push_group(&mut _s,
            ::quote::__private::Delimiter::Brace,
            {
                let mut _s = ::quote::__private::TokenStream::new();
                ::quote::__private::push_ident(&mut _s, "marker");
                ::quote::__private::push_colon(&mut _s);
                ::quote::__private::push_ident(&mut _s, "_serde");
                ::quote::__private::push_colon2(&mut _s);
                ::quote::ToTokens::to_tokens(&private, &mut _s);
                ::quote::__private::push_colon2(&mut _s);
                ::quote::__private::push_ident(&mut _s, "PhantomData");
                ::quote::__private::push_lt(&mut _s);
                ::quote::ToTokens::to_tokens(&this_type, &mut _s);
                ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
                ::quote::__private::push_gt(&mut _s);
                ::quote::__private::push_comma(&mut _s);
                ::quote::__private::push_ident(&mut _s, "lifetime");
                ::quote::__private::push_colon(&mut _s);
                ::quote::__private::push_ident(&mut _s, "_serde");
                ::quote::__private::push_colon2(&mut _s);
                ::quote::ToTokens::to_tokens(&private, &mut _s);
                ::quote::__private::push_colon2(&mut _s);
                ::quote::__private::push_ident(&mut _s, "PhantomData");
                ::quote::__private::push_lt(&mut _s);
                ::quote::__private::push_and(&mut _s);
                ::quote::ToTokens::to_tokens(&delife, &mut _s);
                ::quote::__private::push_group(&mut _s,
                    ::quote::__private::Delimiter::Parenthesis,
                    ::quote::__private::TokenStream::new());
                ::quote::__private::push_gt(&mut _s);
                ::quote::__private::push_comma(&mut _s);
                _s
            });
        ::quote::__private::push_pound(&mut _s);
        ::quote::__private::push_group(&mut _s,
            ::quote::__private::Delimiter::Bracket,
            {
                let mut _s = ::quote::__private::TokenStream::new();
                ::quote::__private::push_ident(&mut _s,
                    "automatically_derived");
                _s
            });
        ::quote::__private::push_ident(&mut _s, "impl");
        ::quote::ToTokens::to_tokens(&de_impl_generics, &mut _s);
        ::quote::__private::push_ident(&mut _s, "_serde");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "de");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "Visitor");
        ::quote::__private::push_lt(&mut _s);
        ::quote::ToTokens::to_tokens(&delife, &mut _s);
        ::quote::__private::push_gt(&mut _s);
        ::quote::__private::push_ident(&mut _s, "for");
        ::quote::__private::push_ident(&mut _s, "__Visitor");
        ::quote::ToTokens::to_tokens(&de_ty_generics, &mut _s);
        ::quote::ToTokens::to_tokens(&where_clause, &mut _s);
        ::quote::__private::push_group(&mut _s,
            ::quote::__private::Delimiter::Brace,
            {
                let mut _s = ::quote::__private::TokenStream::new();
                ::quote::__private::push_ident(&mut _s, "type");
                ::quote::__private::push_ident(&mut _s, "Value");
                ::quote::__private::push_eq(&mut _s);
                ::quote::ToTokens::to_tokens(&this_type, &mut _s);
                ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
                ::quote::__private::push_semi(&mut _s);
                ::quote::__private::push_ident(&mut _s, "fn");
                ::quote::__private::push_ident(&mut _s, "expecting");
                ::quote::__private::push_group(&mut _s,
                    ::quote::__private::Delimiter::Parenthesis,
                    {
                        let mut _s = ::quote::__private::TokenStream::new();
                        ::quote::__private::push_and(&mut _s);
                        ::quote::__private::push_ident(&mut _s, "self");
                        ::quote::__private::push_comma(&mut _s);
                        ::quote::__private::push_ident(&mut _s, "__formatter");
                        ::quote::__private::push_colon(&mut _s);
                        ::quote::__private::push_and(&mut _s);
                        ::quote::__private::push_ident(&mut _s, "mut");
                        ::quote::__private::push_ident(&mut _s, "_serde");
                        ::quote::__private::push_colon2(&mut _s);
                        ::quote::ToTokens::to_tokens(&private, &mut _s);
                        ::quote::__private::push_colon2(&mut _s);
                        ::quote::__private::push_ident(&mut _s, "Formatter");
                        _s
                    });
                ::quote::__private::push_rarrow(&mut _s);
                ::quote::__private::push_ident(&mut _s, "_serde");
                ::quote::__private::push_colon2(&mut _s);
                ::quote::ToTokens::to_tokens(&private, &mut _s);
                ::quote::__private::push_colon2(&mut _s);
                ::quote::__private::push_ident(&mut _s, "fmt");
                ::quote::__private::push_colon2(&mut _s);
                ::quote::__private::push_ident(&mut _s, "Result");
                ::quote::__private::push_group(&mut _s,
                    ::quote::__private::Delimiter::Brace,
                    {
                        let mut _s = ::quote::__private::TokenStream::new();
                        ::quote::__private::push_ident(&mut _s, "_serde");
                        ::quote::__private::push_colon2(&mut _s);
                        ::quote::ToTokens::to_tokens(&private, &mut _s);
                        ::quote::__private::push_colon2(&mut _s);
                        ::quote::__private::push_ident(&mut _s, "Formatter");
                        ::quote::__private::push_colon2(&mut _s);
                        ::quote::__private::push_ident(&mut _s, "write_str");
                        ::quote::__private::push_group(&mut _s,
                            ::quote::__private::Delimiter::Parenthesis,
                            {
                                let mut _s = ::quote::__private::TokenStream::new();
                                ::quote::__private::push_ident(&mut _s, "__formatter");
                                ::quote::__private::push_comma(&mut _s);
                                ::quote::ToTokens::to_tokens(&expecting, &mut _s);
                                _s
                            });
                        _s
                    });
                ::quote::__private::push_ident(&mut _s, "fn");
                ::quote::__private::push_ident(&mut _s, "visit_enum");
                ::quote::__private::push_lt(&mut _s);
                ::quote::__private::push_ident(&mut _s, "__A");
                ::quote::__private::push_gt(&mut _s);
                ::quote::__private::push_group(&mut _s,
                    ::quote::__private::Delimiter::Parenthesis,
                    {
                        let mut _s = ::quote::__private::TokenStream::new();
                        ::quote::__private::push_ident(&mut _s, "self");
                        ::quote::__private::push_comma(&mut _s);
                        ::quote::__private::push_ident(&mut _s, "__data");
                        ::quote::__private::push_colon(&mut _s);
                        ::quote::__private::push_ident(&mut _s, "__A");
                        _s
                    });
                ::quote::__private::push_rarrow(&mut _s);
                ::quote::__private::push_ident(&mut _s, "_serde");
                ::quote::__private::push_colon2(&mut _s);
                ::quote::ToTokens::to_tokens(&private, &mut _s);
                ::quote::__private::push_colon2(&mut _s);
                ::quote::__private::push_ident(&mut _s, "Result");
                ::quote::__private::push_lt(&mut _s);
                ::quote::__private::push_ident(&mut _s, "Self");
                ::quote::__private::push_colon2(&mut _s);
                ::quote::__private::push_ident(&mut _s, "Value");
                ::quote::__private::push_comma(&mut _s);
                ::quote::__private::push_ident(&mut _s, "__A");
                ::quote::__private::push_colon2(&mut _s);
                ::quote::__private::push_ident(&mut _s, "Error");
                ::quote::__private::push_gt(&mut _s);
                ::quote::__private::push_ident(&mut _s, "where");
                ::quote::__private::push_ident(&mut _s, "__A");
                ::quote::__private::push_colon(&mut _s);
                ::quote::__private::push_ident(&mut _s, "_serde");
                ::quote::__private::push_colon2(&mut _s);
                ::quote::__private::push_ident(&mut _s, "de");
                ::quote::__private::push_colon2(&mut _s);
                ::quote::__private::push_ident(&mut _s, "EnumAccess");
                ::quote::__private::push_lt(&mut _s);
                ::quote::ToTokens::to_tokens(&delife, &mut _s);
                ::quote::__private::push_gt(&mut _s);
                ::quote::__private::push_comma(&mut _s);
                ::quote::__private::push_group(&mut _s,
                    ::quote::__private::Delimiter::Brace,
                    {
                        let mut _s = ::quote::__private::TokenStream::new();
                        ::quote::ToTokens::to_tokens(&match_variant, &mut _s);
                        _s
                    });
                _s
            });
        ::quote::ToTokens::to_tokens(&variants_stmt, &mut _s);
        ::quote::__private::push_ident(&mut _s, "_serde");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "Deserializer");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "deserialize_enum");
        ::quote::__private::push_group(&mut _s,
            ::quote::__private::Delimiter::Parenthesis,
            {
                let mut _s = ::quote::__private::TokenStream::new();
                ::quote::__private::push_ident(&mut _s, "__deserializer");
                ::quote::__private::push_comma(&mut _s);
                ::quote::ToTokens::to_tokens(&type_name, &mut _s);
                ::quote::__private::push_comma(&mut _s);
                ::quote::__private::push_ident(&mut _s, "VARIANTS");
                ::quote::__private::push_comma(&mut _s);
                ::quote::__private::push_ident(&mut _s, "__Visitor");
                ::quote::__private::push_group(&mut _s,
                    ::quote::__private::Delimiter::Brace,
                    {
                        let mut _s = ::quote::__private::TokenStream::new();
                        ::quote::__private::push_ident(&mut _s, "marker");
                        ::quote::__private::push_colon(&mut _s);
                        ::quote::__private::push_ident(&mut _s, "_serde");
                        ::quote::__private::push_colon2(&mut _s);
                        ::quote::ToTokens::to_tokens(&private, &mut _s);
                        ::quote::__private::push_colon2(&mut _s);
                        ::quote::__private::push_ident(&mut _s, "PhantomData");
                        ::quote::__private::push_colon2(&mut _s);
                        ::quote::__private::push_lt(&mut _s);
                        ::quote::ToTokens::to_tokens(&this_type, &mut _s);
                        ::quote::ToTokens::to_tokens(&ty_generics, &mut _s);
                        ::quote::__private::push_gt(&mut _s);
                        ::quote::__private::push_comma(&mut _s);
                        ::quote::__private::push_ident(&mut _s, "lifetime");
                        ::quote::__private::push_colon(&mut _s);
                        ::quote::__private::push_ident(&mut _s, "_serde");
                        ::quote::__private::push_colon2(&mut _s);
                        ::quote::ToTokens::to_tokens(&private, &mut _s);
                        ::quote::__private::push_colon2(&mut _s);
                        ::quote::__private::push_ident(&mut _s, "PhantomData");
                        ::quote::__private::push_comma(&mut _s);
                        _s
                    });
                ::quote::__private::push_comma(&mut _s);
                _s
            });
        _s
    });quote_block! {
80        #variant_visitor
81
82        #[doc(hidden)]
83        struct __Visitor #de_impl_generics #where_clause {
84            marker: _serde::#private::PhantomData<#this_type #ty_generics>,
85            lifetime: _serde::#private::PhantomData<&#delife ()>,
86        }
87
88        #[automatically_derived]
89        impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
90            type Value = #this_type #ty_generics;
91
92            fn expecting(&self, __formatter: &mut _serde::#private::Formatter) -> _serde::#private::fmt::Result {
93                _serde::#private::Formatter::write_str(__formatter, #expecting)
94            }
95
96            fn visit_enum<__A>(self, __data: __A) -> _serde::#private::Result<Self::Value, __A::Error>
97            where
98                __A: _serde::de::EnumAccess<#delife>,
99            {
100                #match_variant
101            }
102        }
103
104        #variants_stmt
105
106        _serde::Deserializer::deserialize_enum(
107            __deserializer,
108            #type_name,
109            VARIANTS,
110            __Visitor {
111                marker: _serde::#private::PhantomData::<#this_type #ty_generics>,
112                lifetime: _serde::#private::PhantomData,
113            },
114        )
115    }
116}
117
118fn deserialize_externally_tagged_variant(
119    params: &Parameters,
120    variant: &Variant,
121    cattrs: &attr::Container,
122) -> Fragment {
123    if let Some(path) = variant.attrs.deserialize_with() {
124        let (wrapper, wrapper_ty, unwrap_fn) = wrap_deserialize_variant_with(params, variant, path);
125        return crate::fragment::Fragment::Block({
        let mut _s = ::quote::__private::TokenStream::new();
        ::quote::ToTokens::to_tokens(&wrapper, &mut _s);
        ::quote::__private::push_ident(&mut _s, "_serde");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::ToTokens::to_tokens(&private, &mut _s);
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "Result");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "map");
        ::quote::__private::push_group(&mut _s,
            ::quote::__private::Delimiter::Parenthesis,
            {
                let mut _s = ::quote::__private::TokenStream::new();
                ::quote::__private::push_ident(&mut _s, "_serde");
                ::quote::__private::push_colon2(&mut _s);
                ::quote::__private::push_ident(&mut _s, "de");
                ::quote::__private::push_colon2(&mut _s);
                ::quote::__private::push_ident(&mut _s, "VariantAccess");
                ::quote::__private::push_colon2(&mut _s);
                ::quote::__private::push_ident(&mut _s, "newtype_variant");
                ::quote::__private::push_colon2(&mut _s);
                ::quote::__private::push_lt(&mut _s);
                ::quote::ToTokens::to_tokens(&wrapper_ty, &mut _s);
                ::quote::__private::push_gt(&mut _s);
                ::quote::__private::push_group(&mut _s,
                    ::quote::__private::Delimiter::Parenthesis,
                    {
                        let mut _s = ::quote::__private::TokenStream::new();
                        ::quote::__private::push_ident(&mut _s, "__variant");
                        _s
                    });
                ::quote::__private::push_comma(&mut _s);
                ::quote::ToTokens::to_tokens(&unwrap_fn, &mut _s);
                _s
            });
        _s
    })quote_block! {
126            #wrapper
127            _serde::#private::Result::map(
128                _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant), #unwrap_fn)
129        };
130    }
131
132    let variant_ident = &variant.ident;
133
134    match variant.style {
135        Style::Unit => {
136            let this_value = &params.this_value;
137            crate::fragment::Fragment::Block({
        let mut _s = ::quote::__private::TokenStream::new();
        ::quote::__private::push_ident(&mut _s, "_serde");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "de");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "VariantAccess");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "unit_variant");
        ::quote::__private::push_group(&mut _s,
            ::quote::__private::Delimiter::Parenthesis,
            {
                let mut _s = ::quote::__private::TokenStream::new();
                ::quote::__private::push_ident(&mut _s, "__variant");
                _s
            });
        ::quote::__private::push_question(&mut _s);
        ::quote::__private::push_semi(&mut _s);
        ::quote::__private::push_ident(&mut _s, "_serde");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::ToTokens::to_tokens(&private, &mut _s);
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "Ok");
        ::quote::__private::push_group(&mut _s,
            ::quote::__private::Delimiter::Parenthesis,
            {
                let mut _s = ::quote::__private::TokenStream::new();
                ::quote::ToTokens::to_tokens(&this_value, &mut _s);
                ::quote::__private::push_colon2(&mut _s);
                ::quote::ToTokens::to_tokens(&variant_ident, &mut _s);
                _s
            });
        _s
    });quote_block! {
138                _serde::de::VariantAccess::unit_variant(__variant)?;
139                _serde::#private::Ok(#this_value::#variant_ident)
140            }
141        }
142        Style::Newtype => deserialize_externally_tagged_newtype_variant(
143            variant_ident,
144            params,
145            &variant.fields[0],
146            cattrs,
147        ),
148        Style::Tuple => tuple::deserialize(
149            params,
150            &variant.fields,
151            cattrs,
152            TupleForm::ExternallyTagged(variant_ident),
153        ),
154        Style::Struct => struct_::deserialize(
155            params,
156            &variant.fields,
157            cattrs,
158            StructForm::ExternallyTagged(variant_ident),
159        ),
160    }
161}
162
163fn wrap_deserialize_variant_with(
164    params: &Parameters,
165    variant: &Variant,
166    deserialize_with: &syn::ExprPath,
167) -> (TokenStream, TokenStream, TokenStream) {
168    let field_tys = variant.fields.iter().map(|field| field.ty);
169    let (wrapper, wrapper_ty) =
170        wrap_deserialize_with(params, &{
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_group(&mut _s,
        ::quote::__private::Delimiter::Parenthesis,
        {
            let mut _s = ::quote::__private::TokenStream::new();
            {
                use ::quote::__private::ext::*;
                let mut _first = true;
                let has_iter = ::quote::__private::HasIterator::<false>;
                #[allow(unused_mut)]
                let (mut field_tys, i) = field_tys.quote_into_iter();
                let has_iter = has_iter | i;
                <_ as
                        ::quote::__private::CheckHasIterator<true>>::check(has_iter);
                while true {
                    let field_tys =
                        match field_tys.next() {
                            Some(_x) => ::quote::__private::RepInterp(_x),
                            None => break,
                        };
                    if !_first { ::quote::__private::push_comma(&mut _s); }
                    _first = false;
                    ::quote::ToTokens::to_tokens(&field_tys, &mut _s);
                }
            }
            _s
        });
    _s
}quote!((#(#field_tys),*)), deserialize_with);
171
172    let unwrap_fn = unwrap_to_variant_closure(params, variant, true);
173
174    (wrapper, wrapper_ty, unwrap_fn)
175}
176
177fn deserialize_externally_tagged_newtype_variant(
178    variant_ident: &syn::Ident,
179    params: &Parameters,
180    field: &Field,
181    cattrs: &attr::Container,
182) -> Fragment {
183    let this_value = &params.this_value;
184
185    if field.attrs.skip_deserializing() {
186        let default = Expr(expr_is_missing(field, cattrs));
187        return crate::fragment::Fragment::Block({
        let mut _s = ::quote::__private::TokenStream::new();
        ::quote::__private::push_ident(&mut _s, "_serde");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "de");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "VariantAccess");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "unit_variant");
        ::quote::__private::push_group(&mut _s,
            ::quote::__private::Delimiter::Parenthesis,
            {
                let mut _s = ::quote::__private::TokenStream::new();
                ::quote::__private::push_ident(&mut _s, "__variant");
                _s
            });
        ::quote::__private::push_question(&mut _s);
        ::quote::__private::push_semi(&mut _s);
        ::quote::__private::push_ident(&mut _s, "_serde");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::ToTokens::to_tokens(&private, &mut _s);
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "Ok");
        ::quote::__private::push_group(&mut _s,
            ::quote::__private::Delimiter::Parenthesis,
            {
                let mut _s = ::quote::__private::TokenStream::new();
                ::quote::ToTokens::to_tokens(&this_value, &mut _s);
                ::quote::__private::push_colon2(&mut _s);
                ::quote::ToTokens::to_tokens(&variant_ident, &mut _s);
                ::quote::__private::push_group(&mut _s,
                    ::quote::__private::Delimiter::Parenthesis,
                    {
                        let mut _s = ::quote::__private::TokenStream::new();
                        ::quote::ToTokens::to_tokens(&default, &mut _s);
                        _s
                    });
                _s
            });
        _s
    })quote_block! {
188            _serde::de::VariantAccess::unit_variant(__variant)?;
189            _serde::#private::Ok(#this_value::#variant_ident(#default))
190        };
191    }
192
193    match field.attrs.deserialize_with() {
194        None => {
195            let field_ty = field.ty;
196            let span = field.original.span();
197            let func =
198                {
    let _span: ::quote::__private::Span =
        ::quote::__private::get_span(span).__into_span();
    let mut _s = ::quote::__private::TokenStream::new();
    ::quote::__private::push_ident_spanned(&mut _s, _span, "_serde");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "de");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "VariantAccess");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_ident_spanned(&mut _s, _span, "newtype_variant");
    ::quote::__private::push_colon2_spanned(&mut _s, _span);
    ::quote::__private::push_lt_spanned(&mut _s, _span);
    ::quote::ToTokens::to_tokens(&field_ty, &mut _s);
    ::quote::__private::push_gt_spanned(&mut _s, _span);
    _s
}quote_spanned!(span=> _serde::de::VariantAccess::newtype_variant::<#field_ty>);
199            crate::fragment::Fragment::Expr({
        let mut _s = ::quote::__private::TokenStream::new();
        ::quote::__private::push_ident(&mut _s, "_serde");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::ToTokens::to_tokens(&private, &mut _s);
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "Result");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "map");
        ::quote::__private::push_group(&mut _s,
            ::quote::__private::Delimiter::Parenthesis,
            {
                let mut _s = ::quote::__private::TokenStream::new();
                ::quote::ToTokens::to_tokens(&func, &mut _s);
                ::quote::__private::push_group(&mut _s,
                    ::quote::__private::Delimiter::Parenthesis,
                    {
                        let mut _s = ::quote::__private::TokenStream::new();
                        ::quote::__private::push_ident(&mut _s, "__variant");
                        _s
                    });
                ::quote::__private::push_comma(&mut _s);
                ::quote::ToTokens::to_tokens(&this_value, &mut _s);
                ::quote::__private::push_colon2(&mut _s);
                ::quote::ToTokens::to_tokens(&variant_ident, &mut _s);
                _s
            });
        _s
    });quote_expr! {
200                _serde::#private::Result::map(#func(__variant), #this_value::#variant_ident)
201            }
202        }
203        Some(path) => {
204            let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
205            crate::fragment::Fragment::Block({
        let mut _s = ::quote::__private::TokenStream::new();
        ::quote::ToTokens::to_tokens(&wrapper, &mut _s);
        ::quote::__private::push_ident(&mut _s, "_serde");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::ToTokens::to_tokens(&private, &mut _s);
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "Result");
        ::quote::__private::push_colon2(&mut _s);
        ::quote::__private::push_ident(&mut _s, "map");
        ::quote::__private::push_group(&mut _s,
            ::quote::__private::Delimiter::Parenthesis,
            {
                let mut _s = ::quote::__private::TokenStream::new();
                ::quote::__private::push_ident(&mut _s, "_serde");
                ::quote::__private::push_colon2(&mut _s);
                ::quote::__private::push_ident(&mut _s, "de");
                ::quote::__private::push_colon2(&mut _s);
                ::quote::__private::push_ident(&mut _s, "VariantAccess");
                ::quote::__private::push_colon2(&mut _s);
                ::quote::__private::push_ident(&mut _s, "newtype_variant");
                ::quote::__private::push_colon2(&mut _s);
                ::quote::__private::push_lt(&mut _s);
                ::quote::ToTokens::to_tokens(&wrapper_ty, &mut _s);
                ::quote::__private::push_gt(&mut _s);
                ::quote::__private::push_group(&mut _s,
                    ::quote::__private::Delimiter::Parenthesis,
                    {
                        let mut _s = ::quote::__private::TokenStream::new();
                        ::quote::__private::push_ident(&mut _s, "__variant");
                        _s
                    });
                ::quote::__private::push_comma(&mut _s);
                ::quote::__private::push_or(&mut _s);
                ::quote::__private::push_ident(&mut _s, "__wrapper");
                ::quote::__private::push_or(&mut _s);
                ::quote::ToTokens::to_tokens(&this_value, &mut _s);
                ::quote::__private::push_colon2(&mut _s);
                ::quote::ToTokens::to_tokens(&variant_ident, &mut _s);
                ::quote::__private::push_group(&mut _s,
                    ::quote::__private::Delimiter::Parenthesis,
                    {
                        let mut _s = ::quote::__private::TokenStream::new();
                        ::quote::__private::push_ident(&mut _s, "__wrapper");
                        ::quote::__private::push_dot(&mut _s);
                        ::quote::__private::push_ident(&mut _s, "value");
                        _s
                    });
                _s
            });
        _s
    });quote_block! {
206                #wrapper
207                _serde::#private::Result::map(
208                    _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant),
209                    |__wrapper| #this_value::#variant_ident(__wrapper.value))
210            }
211        }
212    }
213}