planus-codegen 1.3.0

Internal codegen library for planus.
Documentation
{% for docstring in docstrings.iter_strings() %}
/// {{ docstring }}
{%- endfor %}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, ::serde::Serialize, ::serde::Deserialize)]
{%- if !variants.is_empty() -%}
#[repr({{info.repr_type}})]
{%- endif -%}
pub enum {{ info.name }} {
    {% for variant in variants -%}
        {% for docstring in variant.name_and_docs.docstrings.iter_strings() %}
        /// {{ docstring }}
        {%- endfor %}
        {{ variant.name }} = {{ variant.value }},
    {% endfor %}
}

impl {{ info.name }} {
    /// Array containing all valid variants of {{ info.name }}
    pub const ENUM_VALUES: [Self; {{ variants.len() }}] = [
        {%- for variant in variants -%} Self::{{ variant.name }}, {%- endfor -%}
    ];
}

impl ::core::convert::TryFrom<{{info.repr_type}}> for {{info.name}} {
    type Error = ::planus::errors::UnknownEnumTagKind;
    #[inline]
    fn try_from(value: {{info.repr_type}}) -> ::core::result::Result<Self, ::planus::errors::UnknownEnumTagKind> {
        #[allow(clippy::match_single_binding)]
        match value {
            {% for variant in variants -%}
                {{ variant.value }} => ::core::result::Result::Ok({{info.name}}::{{ variant.name }}),
            {% endfor %}

            _ => ::core::result::Result::Err(::planus::errors::UnknownEnumTagKind { tag: value as i128 }),
        }
    }
}

impl ::core::convert::From<{{info.name}}> for {{info.repr_type}} {
    #[inline]
    fn from(value: {{info.name}}) -> Self {
        value as {{info.repr_type}}
    }
}

/// # Safety
/// The Planus compiler correctly calculates `ALIGNMENT` and `SIZE`.
unsafe impl ::planus::Primitive for {{ info.name }} {
    const ALIGNMENT: usize = {{ size }};
    const SIZE: usize = {{ size }};
}

impl ::planus::WriteAsPrimitive<{{ info.name }}> for {{ info.name }} {
    #[inline]
    fn write<const N: usize>(&self, cursor: ::planus::Cursor<'_, N>, buffer_position: u32) {
        (*self as {{ info.repr_type }}).write(cursor, buffer_position);
    }
}

impl ::planus::WriteAs<{{ info.name }}> for {{ info.name }} {
    type Prepared = Self;

    #[inline]
    fn prepare(&self, _builder: &mut ::planus::Builder) -> {{ info.name }} {
        *self
    }
}

impl ::planus::WriteAsDefault<{{ info.name }}, {{ info.name }}> for {{ info.name }} {
    type Prepared = Self;

    #[inline]
    fn prepare(&self, _builder: &mut ::planus::Builder, default: &{{ info.name }}) -> ::core::option::Option<{{ info.name }}> {
        if self == default {
            ::core::option::Option::None
        } else {
            ::core::option::Option::Some(*self)
        }
    }
}

impl ::planus::WriteAsOptional<{{ info.name }}> for {{ info.name }} {
    type Prepared = Self;

    #[inline]
    fn prepare(&self, _builder: &mut ::planus::Builder) -> ::core::option::Option<{{ info.name }}> {
        ::core::option::Option::Some(*self)
    }
}

impl<'buf> ::planus::TableRead<'buf> for {{ info.name }} {
    #[inline]
    fn from_buffer(buffer: ::planus::SliceWithStartOffset<'buf>, offset: usize) -> ::core::result::Result<Self, ::planus::errors::ErrorKind> {
        let n: {{ info.repr_type }} = ::planus::TableRead::from_buffer(buffer, offset)?;
        ::core::result::Result::Ok(::core::convert::TryInto::try_into(n)?)
    }
}

impl<'buf> ::planus::VectorReadInner<'buf> for {{info.name}} {
    type Error = ::planus::errors::UnknownEnumTag;
    const STRIDE: usize = {{ size }};
    #[inline]
    unsafe fn from_buffer(
        buffer: ::planus::SliceWithStartOffset<'buf>,
        offset: usize,
    ) -> ::core::result::Result<Self, ::planus::errors::UnknownEnumTag> {
        {%- if info.repr_type == "u8" -%}
        let value = unsafe { *buffer.buffer.get_unchecked(offset) };
        {%- else if info.repr_type == "i8" -%}
        let value = unsafe { *buffer.buffer.get_unchecked(offset) as i8 };
        {%- else -%}
        let value = unsafe { <{{info.repr_type}} as ::planus::VectorRead>::from_buffer(buffer, offset) };
        {%- endif -%}
        let value: ::core::result::Result<Self, _> = ::core::convert::TryInto::try_into(value);
        value.map_err(|error_kind| error_kind.with_error_location(
            "{{info.name}}",
            "VectorRead::from_buffer",
            buffer.offset_from_start,
        ))
    }
}

/// # Safety
/// The planus compiler generates implementations that initialize
/// the bytes in `write_values`.
unsafe impl ::planus::VectorWrite<{{info.name}}> for {{ info.name }} {
    const STRIDE: usize = {{ size }};

    type Value = Self;

    #[inline]
    fn prepare(&self, _builder: &mut ::planus::Builder) -> Self {
        *self
    }

    #[inline]
    unsafe fn write_values(
        values: &[Self],
        bytes: *mut ::core::mem::MaybeUninit<u8>,
        buffer_position: u32,
    ) {
        let bytes = bytes as *mut [::core::mem::MaybeUninit<u8>; {{ size }}];
        for (i, v) in ::core::iter::Iterator::enumerate(values.iter()) {
            ::planus::WriteAsPrimitive::write(
                v,
                ::planus::Cursor::new(unsafe { &mut *bytes.add(i) }),
                {% if size == 1 %}
                buffer_position - i as u32,
                {% else %}
                buffer_position - ({{ size }} * i) as u32,
                {% endif %}
            );
        }
    }
}