
{%- let maybe_gp %}
{%- if has_ld_field %}
{%- if has_message_field %}
{%- let maybe_gp = "<'msg, T>" %}
{%- else %}
{%- let maybe_gp = "<'msg>" %}
{%- endif %}
{%- else %}
{%- let maybe_gp = "" %}
{%- endif %}

pub enum {{ enum_ident }}{{ maybe_gp }}
{%- if has_ld_field %}
where
    {%- if has_message_field %}
    T: 'msg + ?Sized + {{ owner_message_trait_path }},
    {%- endif %}
{%- else %}
{%- endif %}
{
    {%- for field in fields %}
    {{ field.ident }}({{ field.field_type }}),
    {%- endfor %}
}

impl{{ maybe_gp }} {{ enum_ident }}{{ maybe_gp }}
{%- if has_ld_field %}
where
    {%- if has_message_field %}
    T: 'msg + ?Sized + {{ owner_message_trait_path }},
    {%- endif %}
{%- endif %}
{
    {%- for field in fields %}
    pub fn {{ field.getter_ident }}(self) -> ::std::option::Option<{{ field.field_type }}> {
        match self {
            Self::{{ field.ident }}(v) => ::std::option::Option::Some(v),
            #[allow(unreachable_patterns)]
            _ => None,
        }
    }
    {%- endfor %}
}


impl{{ maybe_gp }} ::std::fmt::Debug for {{ enum_ident }}{{ maybe_gp }}
where
    {%- for field in fields %}
    {{ field.field_type }}: ::std::fmt::Debug,
    {%- endfor %} {#- for field in fields #}
    {%- if has_ld_field %}
    {%- if has_message_field %}
    T: 'msg + ?Sized + {{ owner_message_trait_path }},
    {%- endif %}
    {%- endif %}
{
    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        match self {
            {%- for field in fields %}
            Self::{{ field.ident }}(v) => f
                .debug_tuple("{{ enum_ident }}::{{ field.ident }}")
                .field(&v)
                .finish(),
            {%- endfor %} {#- for field in fields #}
        }
    }
}

impl{{ maybe_gp }} ::std::clone::Clone for {{ enum_ident }}{{ maybe_gp }}
where
    {%- for field in fields %}
    {{ field.field_type }}: ::std::clone::Clone,
    {%- endfor %} {#- for field in fields #}
    {%- if has_ld_field %}
    {%- if has_message_field %}
    T: 'msg + ?Sized + {{ owner_message_trait_path }},
    {%- endif %}
    {%- endif %}
{
    fn clone(&self) -> Self {
        match self {
            {%- for field in fields %}
            Self::{{ field.ident }}(v) => Self::{{ field.ident }}(
                ::std::clone::Clone::clone(&v)
            ),
            {%- endfor %} {#- for field in fields #}
        }
    }
}

impl{{ maybe_gp }} ::std::cmp::PartialEq for {{ enum_ident }}{{ maybe_gp }}
where
    {%- for field in fields %}
    {{ field.field_type }}: ::std::cmp::PartialEq,
    {%- endfor %} {#- for field in fields #}
    {%- if has_ld_field %}
    {%- if has_message_field %}
    T: 'msg + ?Sized + {{ owner_message_trait_path }},
    {%- endif %}
    {%- endif %}
{
    fn eq(&self, rhs: &Self) -> bool {
        match (self, rhs) {
            {%- for field in fields %}
            (Self::{{ field.ident }}(left), Self::{{ field.ident }}(right)) => left == right,
            {%- endfor %} {#- for field in fields #}
            #[allow(unreachable_patterns)]
            _ => false,
        }
    }
}

{%- if has_message_field %}
impl{{ maybe_gp }} ::std::convert::From<{{ enum_ident }}{{ maybe_gp }}>
for {{ enum_ident }}<'msg, &'_ T>
where
    T: 'msg + {{ owner_message_trait_path }},
{
    fn from(value: {{ enum_ident }}{{ maybe_gp }}) -> Self {
        match value {
            {%- for field in fields %}
            {{ enum_ident }}::{{ field.ident }}(v) => {{ enum_ident }}::{{ field.ident }}(v),
            {%- endfor %}
        }
    }
}
{%- endif %}

{%- if has_message_field %}
impl{{ maybe_gp }} ::std::convert::From<{{ enum_ident }}{{ maybe_gp }}>
for {{ enum_ident }}<'msg, &'_ mut T>
where
    T: 'msg + {{ owner_message_trait_path }},
{
    fn from(value: {{ enum_ident }}{{ maybe_gp }}) -> Self {
        match value {
            {%- for field in fields %}
            {{ enum_ident }}::{{ field.ident }}(v) => {{ enum_ident }}::{{ field.ident }}(v),
            {%- endfor %}
        }
    }
}
{%- endif %}

{%- if has_message_field %}
impl{{ maybe_gp }} ::std::convert::From<{{ enum_ident }}{{ maybe_gp }}>
for {{ enum_ident }}<'msg, ::std::boxed::Box<T>>
where
    T: 'msg + {{ owner_message_trait_path }},
{
    fn from(value: {{ enum_ident }}{{ maybe_gp }}) -> Self {
        match value {
            {%- for field in fields %}
            {{ enum_ident }}::{{ field.ident }}(v) => {{ enum_ident }}::{{ field.ident }}(v),
            {%- endfor %}
        }
    }
}
{%- endif %}

{%- if has_message_field %}
impl<'msg, 'bump, T> ::std::convert::From<{{ enum_ident }}{{ maybe_gp }}>
for {{ enum_ident }}<'msg, ::puroro::bumpalo::boxed::Box<'bump, T>>
where
    T: 'msg + {{ owner_message_trait_path }},
{
    fn from(value: {{ enum_ident }}{{ maybe_gp }}) -> Self {
        match value {
            {%- for field in fields %}
            {{ enum_ident }}::{{ field.ident }}(v) => {{ enum_ident }}::{{ field.ident }}(v),
            {%- endfor %}
        }
    }
}
{%- endif %}

{%- if has_message_field %}
impl<'msg, 'bump, T> ::std::convert::From<{{ enum_ident }}{{ maybe_gp }}>
for {{ enum_ident }}<'msg, ::puroro::BumpaloOwned<T>>
where
    T: 'msg + {{ owner_message_trait_path }},
{
    fn from(value: {{ enum_ident }}{{ maybe_gp }}) -> Self {
        match value {
            {%- for field in fields %}
            {{ enum_ident }}::{{ field.ident }}(v) => {{ enum_ident }}::{{ field.ident }}(v),
            {%- endfor %}
        }
    }
}
{%- endif %}

