Repository: serde-rs/serde
File: serde_derive/src/de.rs (Rust)

Code before:

    let other_idx = deserialized_variants.position(|(_, variant)| variant.attrs.other());

    let variants_stmt = {
        let variant_names = variant_names_idents.iter().map(|(name, _, _)| name);
        quote! {
            #[doc(hidden)]
            const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
        }
    };

    let variant_visitor = Stmts(deserialize_generated_identifier(
        &variant_names_idents,
        cattrs,
        true,
        other_idx,
    ));

    (variants_stmt, variant_visitor)
}

fn prepare_adjacently_tagged_enum_variant_enum(tag: &str) -> Fragment {
    let expecting = format!("enum {}", tag);
    quote_block! {
        #[doc(hidden)]
        struct __FieldVariant(pub __Field);

        #[doc(hidden)]
        struct __FieldVariantVisitor;

        impl<'de> _serde::de::Visitor<'de> for __FieldVariantVisitor {
            type Value = __FieldVariant;

            fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result {
                _serde::__private::Formatter::write_str(__formatter, #expecting)
            }

            fn visit_enum<__A>(
                self,
                __data: __A,
            ) -> _serde::__private::Result<Self::Value, __A::Error>
            where
                __A: _serde::de::EnumAccess<'de>,
            {
                let (__field, __variant) = match _serde::de::EnumAccess::variant(__data) {
                    _serde::__private::Ok(__val) => __val,
                    _serde::__private::Err(__err) => {
                        return _serde::__private::Err(__err);
                    }
                };
                match _serde::de::VariantAccess::unit_variant(__variant) {

Review comment (suggestion):
I would expect this whole type to go in `serde::__private::de` instead of emitting a whole new type and set of trait impls into every single use of adjacently tagged enums.

```rust
pub struct AdjacentlyTaggedEnumVariant<F> {
    tag: &'static str,
    variants: &'static [&'static str],
    fields_enum: PhantomData<F>,
}

impl<'de, F> DeserializeSeed<'de> for AdjacentlyTaggedEnumVariant<F>
where
    F: Deserialize<'de>,
{
    type Value = F;
    ...
}
```

Code after:
        })
        .collect();

    let other_idx = deserialized_variants.position(|(_, variant)| variant.attrs.other());

    let variants_stmt = {
        let variant_names = variant_names_idents.iter().map(|(name, _, _)| name);
        quote! {
            #[doc(hidden)]
            const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
        }
    };

    let variant_visitor = Stmts(deserialize_generated_identifier(
        &variant_names_idents,
        cattrs,
        true,
        other_idx,
    ));

    (variants_stmt, variant_visitor)
}

fn deserialize_externally_tagged_enum(
    params: &Parameters,
    variants: &[Variant],
    cattrs: &attr::Container,
) -> Fragment {
    let this_type = &params.this_type;
    let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
        split_with_de_lifetime(params);
    let delife = params.borrowed.de_lifetime();

    let type_name = cattrs.name().deserialize_name();
    let expecting = format!("enum {}", params.type_name());
    let expecting = cattrs.expecting().unwrap_or(&expecting);

    let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs);

    // Match arms to extract a variant from a string
    let variant_arms = variants
        .iter()
        .enumerate()
        .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
        .map(|(i, variant)| {
            let variant_name = field_i(i);

            let block = Match(deserialize_externally_tagged_variant(
                params, variant, cattrs,
            ));