#[derive(::std::fmt::Debug, ::std::clone::Clone, ::std::marker::Copy, ::std::cmp::PartialEq)]
pub enum {{ ident }} {
    {%- for value in values %}
    {{ value.ident }},
    {%- endfor %}

    {%- if is_proto3 %}
    _Unknown(i32)
    {%- endif %}
}

{%- if is_proto3 %}

impl ::puroro::Enum3 for {{ ident }} {}
impl ::std::convert::From<i32> for {{ ident }} {
    fn from(value: i32) -> Self {
        match value {
            {%- for value in values %}
            {{ value.number }} => {{ ident }}::{{ value.ident }},
            {%- endfor %}
            _ => {{ ident }}::_Unknown(value),
        }
    }
}

{%- else %}

impl ::puroro::Enum2 for {{ ident }} {}
impl ::std::convert::TryFrom<i32> for {{ ident }} {
    type Error = i32;
    fn try_from(value: i32) -> ::std::result::Result<Self, i32> {
        ::std::result::Result::Ok(match value {
            {%- for value in values %}
            {{ value.number }} => {{ ident }}::{{ value.ident }},
            {%- endfor %}
            _ => Err(value)?,
        })
    }
}

{%- endif %}

impl ::std::convert::From<{{ ident }}> for i32 {
    fn from(value: {{ ident }}) -> i32 {
        match value {
            {%- for value in values %}
            {{ ident }}::{{ value.ident }} => {{ value.number }},
            {%- endfor %}

            {%- if is_proto3 %}
            {{ ident }}::_Unknown(ivalue) => ivalue,
            {%- endif %}
        }
    }
}

impl ::std::default::Default for {{ ident }} {
    fn default() -> Self {
        {{ ident }}::{{ first_value_ident }}
    }
}

impl<'bump> ::puroro::internal::BumpDefault<'bump> for {{ ident }} {
    fn default_in(_: &'bump ::puroro::bumpalo::Bump) -> Self {
        ::std::default::Default::default()
    }
}
