{% 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 %}
);
}
}
}