{%- for sfield in m.fields %}

#[derive(::std::clone::Clone, ::std::cmp::PartialEq, ::std::fmt::Debug)]

{%- let maybe_gp %}
{%- if sfield.is_repeated %}
    {%- let maybe_gp = "<ScalarType, RepeatedType>" %}
{%- else %}
    {%- let maybe_gp = "<ScalarType>" %}
{%- endif %}

pub struct {{ m.single_field_ident }}{{ sfield.number }}{{ maybe_gp }}
{%- call single_field_bound(sfield) %}
{
    pub {{ sfield.ident }}: {{ sfield.single_field_type }},
}

impl{{ maybe_gp }} ::puroro::Message<super::{{ m.simple_ident }}>
for {{ m.single_field_ident }}{{ sfield.number }}{{ maybe_gp }}
{%- call single_field_bound(sfield) %}
{}

impl{{ maybe_gp }} super::_puroro_traits::{{ m.ident }}Trait
for {{ m.single_field_ident }}{{ sfield.number }}{{ maybe_gp }}
{%- call single_field_bound(sfield) %}
{
    {%- for field in m.fields %}
    {%- if field.number == sfield.number %}
    {%- call single_field_trait_impl_field(field) %}
    {%- else %}
    {%- call empty_trait_impl_field(field) %}
    {%- endif %}
    {%- endfor %}

    {%- for oneof in m.oneofs %}
    fn {{ oneof.field_ident }}<'this>(&'this self) ->
        ::std::option::Option<
            super::_puroro_nested::{{ m.submodule_ident }}::_puroro_oneofs::{{ oneof.enum_ident }}
            {%- if oneof.has_ld_field %}
            {%- if oneof.has_message_field %}
            <'this, ::puroro::internal::bool::False, Self>
            {%- else %}
            <'this, ::puroro::internal::bool::False>
            {%- endif %}
            {%- endif %}
        >
    {
        {%- if sfield.oneof_index == oneof.index %}
        use super::_puroro_nested::{{ m.submodule_ident }}::_puroro_oneofs::{{ oneof.enum_ident }} as E;
        ::std::option::Option::Some(
            E::{{ sfield.oneof_enum_value_ident }}(
                {%- if sfield.is_length_delimited %}
                {%- if sfield.is_message %}
                &self.{{ sfield.ident }}
                {%- else %}
                self.{{ sfield.ident }}.as_ref()
                {%- endif %}
                {%- else %}
                ::std::convert::Into::into(
                    ::std::clone::Clone::clone(&self.{{ sfield.ident }})
                )
                {%- endif %}
            )
        )
        {%- else %}
        ::std::option::Option::None
        {%- endif %}
    }
    {%- endfor %}
}


impl{{ maybe_gp }} ::puroro::internal::SerializableMessageToIoWrite
for {{ m.single_field_ident }}{{ sfield.number }}{{ maybe_gp }}
{%- call single_field_bound(sfield) %}
    Self: super::_puroro_traits::{{ m.ident }}Trait,
{%- if sfield.is_message %}
    for<'a> <Self as super::_puroro_traits::{{ m.ident }}Trait>::Field{{ sfield.number }}MessageType<'a> :
        ::puroro::internal::SerializableMessageToIoWrite,
{%- endif %}
{
    fn ser<W>(&self, out: &mut W) -> ::puroro::Result<()>
    where
        W: ::std::io::Write,
    {
        ::puroro::internal::se::SerFieldToIoWrite::<
            {{ sfield.trait_label_and_type_tags }}
        >::ser_field(
            {%- if sfield.is_repeated %}
            <Self as super::_puroro_traits::{{ m.ident }}Trait>::{{ sfield.ident }}(self),
            {%- else %}
            <Self as super::_puroro_traits::{{ m.ident }}Trait>::{{ sfield.ident_unesc }}_opt(self),
            {%- endif %}
            {{ sfield.number }},
            out
        )?;
        ::std::result::Result::Ok(())
    }
}

impl{{ maybe_gp }} ::std::convert::From<{{ sfield.single_field_type }}>
for {{ m.single_field_ident }}{{ sfield.number }}{{ maybe_gp }}
{%- call single_field_bound(sfield) %}
{
    fn from(value: {{ sfield.single_field_type }}) -> Self {
        Self {
            {{ sfield.ident }}: value,
        }
    }
}

{%- endfor %}