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

Code before:

            #[inline]
            fn visit_map<__A>(self, mut __map: __A) -> _serde::__private::Result<Self::Value, __A::Error>
            where
                __A: _serde::de::MapAccess<#delife>,
            {
                #visit_map
            }
        }

        #fields_stmt

        #dispatch
    })
}

fn deserialize_enum(
    params: &Parameters,
    variants: &[Variant],
    cattrs: &attr::Container,
) -> Fragment {
    match variants
        .iter()
        .enumerate()
        .find(|(_, var)| var.attrs.untagged())
    {
        Some((variant_idx, _)) => {
            let (tagged, untagged) = variants.split_at(variant_idx);
            let tagged_frag = Expr(deserialize_homogenious_enum(params, tagged, cattrs));
            let tagged_frag = |deserializer| Expr(quote_block! {
                let __deserializer = #deserializer;
                #tagged_frag
            });
            deserialize_untagged_enum_after(params, untagged, cattrs, Some(tagged_frag))
        }
        None => deserialize_homogenious_enum(params, variants, cattrs),
    }
}

fn deserialize_homogenious_enum(
    params: &Parameters,
    variants: &[Variant],
    cattrs: &attr::Container,
) -> Fragment {
    match cattrs.tag() {
        attr::TagType::External => deserialize_externally_tagged_enum(params, variants, cattrs),
        attr::TagType::Internal { tag } => {
            deserialize_internally_tagged_enum(params, variants, cattrs, tag)
        }
        attr::TagType::Adjacent { tag, content } => {
            deserialize_adjacently_tagged_enum(params, variants, cattrs, tag, content)

Review comment (suggestion):
leave a comment here stating that this is correct because we check (elsewhere) that there are only untagged variants after the first untagged one

Code after:

            #[inline]
            fn visit_map<__A>(self, mut __map: __A) -> _serde::__private::Result<Self::Value, __A::Error>
            where
                __A: _serde::de::MapAccess<#delife>,
            {
                #visit_map
            }
        }

        #fields_stmt

        #dispatch
    })
}

fn deserialize_enum(
    params: &Parameters,
    variants: &[Variant],
    cattrs: &attr::Container,
) -> Fragment {
    // The variants have already been checked (in ast.rs) that all untagged variants appear at the end
    match variants
        .iter()
        .enumerate()
        .find(|(_, var)| var.attrs.untagged())
    {
        Some((variant_idx, _)) => {
            let (tagged, untagged) = variants.split_at(variant_idx);
            let tagged_frag = Expr(deserialize_homogeneous_enum(params, tagged, cattrs));
            let tagged_frag = |deserializer| {
                Some(Expr(quote_block! {
                    let __deserializer = #deserializer;
                    #tagged_frag
                }))
            };
            deserialize_untagged_enum_after(params, untagged, cattrs, tagged_frag)
        }
        None => deserialize_homogeneous_enum(params, variants, cattrs),
    }
}

fn deserialize_homogeneous_enum(
    params: &Parameters,
    variants: &[Variant],
    cattrs: &attr::Container,
) -> Fragment {
    match cattrs.tag() {
        attr::TagType::External => deserialize_externally_tagged_enum(params, variants, cattrs),
        attr::TagType::Internal { tag } => {
            deserialize_internally_tagged_enum(params, variants, cattrs, tag)