
#[derive(Default)]
pub struct {{ ident_struct }} {
    {%- for field in fields %}
    // {{ "{:?}, {:?}"|format(field.rule,field.wire_type) }}
    {{ field.ident_struct_field }}: {{ field.rust_field_type }},
    {%- endfor %} {#- for field in fields #}

    {%- for oneof in oneofs %}
    // {{ "oneof {}"|format(oneof.ident_union) }}
    {{ oneof.ident_struct_field }}: {{ oneof.rust_field_type }},
    {%- endfor %} {#- for oneof in oneofs #}

    _bitfield: self::_puroro::bitvec::BitArray<{{ (bits_length + 7) / 8 }}>,
}

impl {{ ident_struct }} {
    {%- for field in fields %}
    {%- match field.rule %}
    {%- when FieldRule::Repeated %}

    {#- Repeated getter #}
    // {{ "{:?}, {:?}"|format(field.rule,field.wire_type) }}
    pub fn {{ field.ident_getter }}(&self) -> {{ field.rust_getter_type }} {
        use self::_puroro::internal::field_type::RepeatedFieldType;
        <{{ field.rust_field_type }} as RepeatedFieldType>::get_field(
            &self.{{ field.ident_struct_field }}, &self._bitfield, 
        )
    }
    pub fn {{ field.ident_getter_mut }}(&mut self) -> {{ field.rust_getter_mut_type }} {
        use self::_puroro::internal::field_type::RepeatedFieldType;
        <{{ field.rust_field_type }} as RepeatedFieldType>::mut_field(
            &mut self.{{ field.ident_struct_field }}, &mut self._bitfield, 
        )
    }
    pub fn {{ field.ident_clear }}(&mut self) {
        use self::_puroro::internal::field_type::RepeatedFieldType;
        <{{ field.rust_field_type }} as RepeatedFieldType>::clear(
            &mut self.{{ field.ident_struct_field }}, &mut self._bitfield, 
        )
    }
    
    {%- else %} {#- when FieldRule::Repeated #}

    {#- Singular getter #}
    // {{ "{:?}, {:?}"|format(field.rule,field.wire_type) }}
    pub fn {{ field.ident_getter }}(&self) -> {{ field.rust_getter_type }} {
        use self::_puroro::internal::field_type::NonRepeatedFieldType;
        <{{ field.rust_field_type }} as NonRepeatedFieldType>::get_field(
            &self.{{ field.ident_struct_field }}, &self._bitfield, ::std::default::Default::default,
        )
    }
    pub fn {{ field.ident_getter_opt }}(&self) -> {{ field.rust_getter_opt_type }} {
        use self::_puroro::internal::field_type::NonRepeatedFieldType;
        <{{ field.rust_field_type }} as NonRepeatedFieldType>::get_field_opt(
            &self.{{ field.ident_struct_field }}, &self._bitfield,
        )
    }
    pub fn {{ field.ident_has }}(&self) -> bool {
        use self::_puroro::internal::field_type::NonRepeatedFieldType;
        <{{ field.rust_field_type }} as NonRepeatedFieldType>::get_field_opt(
            &self.{{ field.ident_struct_field }}, &self._bitfield,
        ).is_some()
    }
    pub fn {{ field.ident_getter_mut }}(&mut self) -> {{ field.rust_getter_mut_type }} {
        use self::_puroro::internal::field_type::NonRepeatedFieldType;
        <{{ field.rust_field_type }} as NonRepeatedFieldType>::mut_field(
            &mut self.{{ field.ident_struct_field }}, &mut self._bitfield, ::std::default::Default::default,
        )
    }
    pub fn {{ field.ident_clear }}(&mut self) {
        use self::_puroro::internal::field_type::NonRepeatedFieldType;
        <{{ field.rust_field_type }} as NonRepeatedFieldType>::clear(
            &mut self.{{ field.ident_struct_field }}, &mut self._bitfield,
        )
    }

    {%- endmatch %} {#- match field.rule #}
    {%- endfor %} {#- for field in fields #}

    {%- for oneof in oneofs %}

    {#- oneof group getter #}
    pub fn {{ oneof.ident_getter }}(&self) -> {{ oneof.rust_getter_type }} {
        use self::_puroro::internal::oneof_type::OneofUnion;
        <{{ oneof.rust_union_type }} as OneofUnion>::case_ref(
            &self.{{ oneof.ident_struct_field }}, &self._bitfield
        )
    }

    pub fn {{ oneof.ident_clear }}(&mut self) {
        use self::_puroro::internal::oneof_type::OneofUnion;
        <{{ oneof.rust_field_type}} as OneofUnion>::clear(
            &mut self.{{ oneof.ident_struct_field }}, &mut self._bitfield
        );
    }

    {%- for field in oneof.fields %}

    {#- oneof item getter / setters #}
    pub fn {{ field.ident_getter }}(&self) -> {{ field.rust_getter_type }} {
        self.{{ oneof.ident_struct_field }}.{{ field.ident_getter }}(&self._bitfield)
    }

    pub fn {{ field.ident_getter_opt }}(&self) -> {{ field.rust_getter_opt_type }} {
        self.{{ oneof.ident_struct_field }}.{{ field.ident_getter_opt }}(&self._bitfield)
    }

    pub fn {{ field.ident_getter_mut }}(&mut self) -> {{ field.rust_getter_mut_type}} {
        self.{{ oneof.ident_struct_field }}.{{ field.ident_getter_mut }}(&mut self._bitfield)
    }

    pub fn {{ field.ident_has }}(&self) -> bool {
        self.{{ field.ident_getter_opt }}().is_some()
    }

    pub fn {{ field.ident_clear }}(&mut self) {
        #[allow(unused)]
        use ::std::option::Option::Some;
        #[allow(unused)]
        use self::_puroro::internal::oneof_type::OneofCase;
        match <{{ oneof.rust_case_type }} as OneofCase>::from_bitslice(&self._bitfield) {
            Some({{ oneof.rust_case_type  }}::{{ field.ident_enum_item }}) => {
                self.{{ oneof.ident_clear }}();
            }
            _ => ()
        }
    }

    {%- endfor %} {#- for field in oneof.fields #}

    {%- endfor %} {#- for oneof in oneofs #}
}

impl self::_puroro::Message for {{ ident_struct }} {
    fn from_bytes_iter<I: ::std::iter::Iterator<Item=::std::io::Result<u8>>>(iter: I) -> self::_puroro::Result<Self> {
        #[allow(unused)]
        use ::std::result::Result::Ok;
        let mut msg: Self = ::std::default::Default::default();
        msg.merge_from_bytes_iter(iter)?;
        Ok(msg)
    }

    fn merge_from_bytes_iter<I: ::std::iter::Iterator<Item =::std::io::Result<u8>>>(&mut self, mut iter: I) -> self::_puroro::Result<()> {
        #[allow(unused)]
        use ::std::result::Result::Ok;
        #[allow(unused)]
        use ::std::option::Option::Some;
        #[allow(unused)]
        use self::_puroro::internal::field_type::FieldType;
        #[allow(unused)]
        use self::_puroro::internal::oneof_type::OneofUnion;
        while let Some((number, field_data)) = self::_puroro::internal::ser::FieldData::from_bytes_iter(iter.by_ref())? {
            match number {
                {%- for field in fields %}
                {{ field.number }} => <{{ field.rust_field_type }} as FieldType>::deser_from_iter(
                    &mut self.{{ field.ident_struct_field }},
                    &mut self._bitfield,
                    field_data,
                )?,
                {%- endfor %} {#- for field in fields #}
                {%- for oneof in oneofs %}
                {%- for field in oneof.fields %}
                {{ field.number }} => <{{ oneof.rust_field_type }} as OneofUnion>::deser_from_iter(
                    &mut self.{{ oneof.ident_struct_field }},
                    &mut self._bitfield,
                    field_data,
                    {{ oneof.rust_case_type }}::{{ field.ident_enum_item }},
                )?,
                {%- endfor %} {#- for field in oneof.fields #}
                {%- endfor %} {#- for oneof in oneofs #}
                _ => todo!(), // Unknown field...
            }
        }
        Ok(())
    }

    fn to_bytes<W: ::std::io::Write>(&self, #[allow(unused)] out: &mut W) -> self::_puroro::Result<()> {
        #[allow(unused)]
        use ::std::result::Result::Ok;
        #[allow(unused)]
        use self::_puroro::internal::field_type::FieldType;
        #[allow(unused)]
        use self::_puroro::internal::oneof_type::OneofUnion;

        {%- for field in fields %}
        <{{ field.rust_field_type }} as FieldType>::ser_to_write(
            &self.{{ field.ident_struct_field }},
            &self._bitfield,
            {{ field.number }},
            out
        )?;
        {%- endfor %} {#- for field in fields #}
        {%- for oneof in oneofs %}
        <{{ oneof.rust_field_type }} as OneofUnion>::ser_to_write(
            &self.{{ oneof.ident_struct_field }},
            &self._bitfield,
            out
        )?;
        {%- endfor %} {#- for oneof in oneofs #}

        Ok(())
    }
}

impl ::std::clone::Clone for {{ ident_struct }} {
    fn clone(&self) -> Self {
        #[allow(unused)]
        use ::std::clone::Clone;
        #[allow(unused)]
        use self::_puroro::internal::oneof_type::OneofUnion;
        Self {
            {%- for field in fields %}
            {{ field.ident_struct_field }}: Clone::clone(&self.{{ field.ident_struct_field }}),
            {%- endfor %} {#- for field in fields #}

            {%- for oneof in oneofs %}
            {{ oneof.ident_struct_field }}: 
                <{{ oneof.rust_field_type}} as OneofUnion>::clone(
                    &self.{{ oneof.ident_struct_field }}, 
                    &self._bitfield),
            {%- endfor %} {#- for oneof in oneofs #}

            _bitfield: Clone::clone(&self._bitfield),
        }
    }
}

impl ::std::fmt::Debug for {{ ident_struct }} {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::result::Result<(), ::std::fmt::Error> {
        fmt.debug_struct("{{ ident_struct }}")
            {%- for field in fields %}
            .field("{{ field.ident_struct_field }}", &self.{{ field.ident_getter }}())
            {%- endfor %} {#- for field in fields #}
            {#- TODO: oneof fields? #}
            .finish()
    }
}

impl ::std::cmp::PartialEq for {{ ident_struct }} {
    fn eq(&self, rhs: &Self) -> bool {
        #[allow(unused)]
        use self::_puroro::internal::oneof_type::OneofUnion;

        true
            {%- for field in fields %}
            {%- match field.rule %}
            {%- when FieldRule::Repeated %}
            && self.{{ field.ident_getter }}() == rhs.{{ field.ident_getter }}()
            {%- else %}
            && self.{{ field.ident_getter_opt }}() == rhs.{{ field.ident_getter_opt }}()
            {%- endmatch %} {#- match field.rule #}
            {%- endfor %} {#- for field in fields #}

            {%- for oneof in oneofs %}
            && <{{ oneof.rust_union_type }} as OneofUnion>::case_ref(
                &self.{{ oneof.ident_struct_field }}, &self._bitfield
            ) == <{{ oneof.rust_union_type }} as OneofUnion>::case_ref(
                &rhs.{{ oneof.ident_struct_field }}, &rhs._bitfield
            )
            {%- endfor %} {#- for oneof in oneofs #}
    }
}

impl ::std::ops::Drop for {{ ident_struct }} {
    fn drop(&mut self) {
        #[allow(unused)]
        use self::_puroro::internal::oneof_type::OneofUnion;

        {#- We need to explicitly clear the oneof unions. #}
        {%- for oneof in oneofs %}
        <{{ oneof.rust_union_type}} as OneofUnion>::clear(
            &mut self.{{ oneof.ident_struct_field }}, 
            &mut self._bitfield
        );
        {%- endfor %} {#- for oneof in oneofs #}
    }
}
