{% for docstring in docstrings.iter_strings() %}
/// {{ docstring }}
{%- endfor %}
#[derive(Clone, Debug, PartialEq, PartialOrd,
{% if info.should_do_eq %}Eq, Ord, Hash,{% endif %}
::serde::Serialize, ::serde::Deserialize
)]
pub struct {{ info.owned_name }}{
{% for field in fields.declaration_order() -%}
{% for docstring in field.name_and_docs.docstrings.iter_strings() %}
/// {{ docstring }}
{%- endfor %}
pub {{ field.info.name }}: {{ field.info.owned_type }},
{%- endfor -%}
}
{% if info.should_do_default %}
#[allow(clippy::derivable_impls)]
impl ::core::default::Default for {{ info.owned_name }} {
fn default() -> Self {
Self {
{% for field in fields.declaration_order() -%}
{{ field.info.name }}: {{ field.info.impl_default_code }},
{% endfor %}
}
}
}
{% endif %}
impl {{info.owned_name}} {
/// Creates a [{{info.builder_name}}] for serializing an instance of this table.
#[inline]
pub fn builder() -> {{ info.builder_name}}<()> {
{{ info.builder_name }}(())
}
#[allow(clippy::too_many_arguments)]
pub fn create(
builder: &mut ::planus::Builder,
{% for field in fields.declaration_order() -%}
field_{{ field.info.create_name }}: impl ::planus::{{ field.info.create_trait }},
{% endfor %}
) -> ::planus::Offset<Self> {
{%- for field in fields.declaration_order() -%}
{%- match field.info.serialize_default -%}
{%- when Some with (serialize_default) -%}
let prepared_{{ field.info.create_name }} = field_{{ field.info.create_name }}.prepare(builder, {{ serialize_default }});
{%- when None -%}
let prepared_{{ field.info.create_name }} = field_{{ field.info.create_name }}.prepare(builder);
{%- endmatch -%}
{%- endfor %}
{% if fields.is_empty() -%}
let table_writer: ::planus::table_writer::TableWriter::<{{max_vtable_size}}> = ::core::default::Default::default();
unsafe {
table_writer.finish(builder, |_table_writer| {});
}
{%- else -%}
let mut table_writer: ::planus::table_writer::TableWriter::<{{max_vtable_size}}> = ::core::default::Default::default();
{% for field in fields.alignment_order() %}
{%- if field.info.read_type.starts_with("::core::option::Option<") || field.info.serialize_default.is_some() -%}
if prepared_{{field.info.create_name}}.is_some() {
{%- endif -%}
{%- if field.field_type == BackendTableFieldType::UnionKey -%}
table_writer.write_entry::<u8>({{field.vtable_index}});
{%- else if field.field_type == BackendTableFieldType::UnionKeyVector -%}
table_writer.write_entry::<::planus::Offset<[u8]>>({{field.vtable_index}});
{%- else -%}
table_writer.write_entry::<{{field.info.vtable_type}}>({{field.vtable_index}});
{%- endif -%}
{%- if field.info.read_type.starts_with("::core::option::Option<") || field.info.serialize_default.is_some() -%}
}
{%- endif -%}
{% endfor %}
unsafe {
table_writer.finish(builder, |object_writer| {
{%- if fields.is_empty() -%}
let _ = object_writer;
{%- else -%}
{% for field in fields.alignment_order() %}
{%- if field.info.read_type.starts_with("::core::option::Option<") || field.info.serialize_default.is_some() -%}
if let ::core::option::Option::Some(prepared_{{field.info.create_name}}) = prepared_{{field.info.create_name}} {
{%- endif -%}
{%- match field.field_type -%}
{%- when BackendTableFieldType::UnionKey -%} object_writer.write::<_, _, 1>(&prepared_{{field.info.create_name}}.tag());
{%- when BackendTableFieldType::UnionValue -%} object_writer.write::<_, _, {{field.info.primitive_size}}>(&prepared_{{field.info.create_name}}.offset());
{%- when BackendTableFieldType::UnionKeyVector -%} object_writer.write::<_, _, 4>(&prepared_{{field.info.create_name}}.tags_offset());
{%- when BackendTableFieldType::UnionValueVector -%} object_writer.write::<_, _, 4>(&prepared_{{field.info.create_name}}.values_offset());
{%- when BackendTableFieldType::Other -%} object_writer.write::<_, _, {{field.info.primitive_size}}>(&prepared_{{field.info.create_name}});
{%- endmatch -%}
{%- if field.info.read_type.starts_with("::core::option::Option<") || field.info.serialize_default.is_some() -%}
}
{%- endif -%}
{% endfor %}
{% endif %}
});
}
{%- endif -%}
builder.current_offset()
}
}
impl ::planus::WriteAs<::planus::Offset<{{info.owned_name}}>> for {{info.owned_name}} {
type Prepared = ::planus::Offset<Self>;
#[inline]
fn prepare(&self, builder: &mut ::planus::Builder) -> ::planus::Offset<{{info.owned_name}}> {
::planus::WriteAsOffset::prepare(self, builder)
}
}
impl ::planus::WriteAsOptional<::planus::Offset<{{info.owned_name}}>> for {{info.owned_name}} {
type Prepared = ::planus::Offset<Self>;
#[inline]
fn prepare(&self, builder: &mut ::planus::Builder) -> ::core::option::Option<::planus::Offset<{{info.owned_name}}>> {
::core::option::Option::Some(::planus::WriteAsOffset::prepare(self, builder))
}
}
impl ::planus::WriteAsOffset<{{info.owned_name}}> for {{info.owned_name}} {
#[inline]
fn prepare(&self, builder: &mut ::planus::Builder) -> ::planus::Offset<{{info.owned_name}}> {
{{info.owned_name}}::create(
builder,
{% for field in fields.declaration_order() %}
{% if field.info.is_copy %}
self.{{field.info.name}},
{% else %}
&self.{{field.info.name}},
{% endif %}
{% endfor %}
)
}
}
/// Builder for serializing an instance of the [{{info.owned_name}}] type.
///
/// Can be created using the [{{info.owned_name}}::builder] method.
#[derive(Debug)]
#[must_use]
pub struct {{ info.builder_name }}<State>(State);
{% for field in fields.declaration_order() -%}
impl<
{% for i in 0..loop.index0 %}
T{{i}},
{% endfor %}
> {{ info.builder_name}}
<
(
{% for i in 0..loop.index0 %}
T{{i}},
{% endfor %}
)
>
{
/// Setter for the [`{{field.name_and_docs.original_name}}` field]({{info.owned_name}}#structfield.{{field.info.name}}).
#[inline]
#[allow(clippy::type_complexity)]
pub fn {{ field.info.name }}<T{{loop.index0}}>(self, value: T{{loop.index0}}) -> {{ info.builder_name }}<(
{% for i in 0..=loop.index0 %}
T{{i}},
{% endfor %}
)>
where T{{loop.index0}}: ::planus::{{ field.info.create_trait }}
{
{% if !loop.first %}
let (
{% for i in 0..loop.index0 %}
v{{i}},
{% endfor %}
) = self.0;
{%- endif -%}
{{ info.builder_name}}((
{% for i in 0..loop.index0 %}
v{{i}},
{% endfor %}
value,
))
}
{% if field.info.has_default %}
/// Sets the [`{{field.name_and_docs.original_name}}` field]({{info.owned_name}}#structfield.{{field.info.name}}) to the default value.
#[inline]
#[allow(clippy::type_complexity)]
pub fn {{ field.info.name_with_as }}_default(self) -> {{ info.builder_name}}<(
{% for i in 0..loop.index0 %}
T{{i}},
{% endfor %}
::planus::DefaultValue,
)>
{
self.{{ field.info.name }}(::planus::DefaultValue)
}
{% endif %}
{% if field.info.optional %}
/// Sets the [`{{field.name_and_docs.original_name}}` field]({{info.owned_name}}#structfield.{{field.info.name}}) to null.
#[inline]
#[allow(clippy::type_complexity)]
pub fn {{ field.info.name_with_as }}_null(self) -> {{ info.builder_name}}<(
{% for i in 0..loop.index0 %}
T{{i}},
{% endfor %}
(),
)>
{
self.{{ field.info.name }}(())
}
{% endif %}
}
{% endfor %}
impl<
{% for field in fields.declaration_order() %}
T{{ loop.index0 }},
{% endfor %}
> {{ info.builder_name }}<(
{% for field in 0..fields.declaration_order().count() %}
T{{loop.index0}},
{% endfor %}
)> {
/// Finish writing the builder to get an [Offset](::planus::Offset) to a serialized [{{info.owned_name}}].
#[inline]
pub fn finish(self, builder: &mut ::planus::Builder) -> ::planus::Offset<{{ info.owned_name }}>
where Self: ::planus::WriteAsOffset<{{ info.owned_name }}>
{
::planus::WriteAsOffset::prepare(&self, builder)
}
}
impl<
{% for field in fields.declaration_order() %}
T{{ loop.index0 }}: ::planus::{{ field.info.create_trait }},
{% endfor %}
> ::planus::WriteAs<::planus::Offset<{{info.owned_name}}>> for {{ info.builder_name }}<(
{% for field in 0..fields.declaration_order().count() %}
T{{loop.index0}},
{% endfor %}
)> {
type Prepared = ::planus::Offset<{{ info.owned_name }}>;
#[inline]
fn prepare(&self, builder: &mut ::planus::Builder) -> ::planus::Offset<{{info.owned_name}}> {
::planus::WriteAsOffset::prepare(self, builder)
}
}
impl<
{% for field in fields.declaration_order() %}
T{{ loop.index0 }}: ::planus::{{ field.info.create_trait }},
{% endfor %}
> ::planus::WriteAsOptional<::planus::Offset<{{info.owned_name}}>> for {{ info.builder_name }}<(
{% for field in 0..fields.declaration_order().count() %}
T{{loop.index0}},
{% endfor %}
)> {
type Prepared = ::planus::Offset<{{ info.owned_name }}>;
#[inline]
fn prepare(&self, builder: &mut ::planus::Builder) -> ::core::option::Option<::planus::Offset<{{info.owned_name}}>> {
::core::option::Option::Some(::planus::WriteAsOffset::prepare(self, builder))
}
}
impl<
{% for field in fields.declaration_order() %}
T{{ loop.index0 }}: ::planus::{{ field.info.create_trait }},
{% endfor %}
> ::planus::WriteAsOffset<{{info.owned_name}}> for {{ info.builder_name }}<(
{% for field in 0..fields.declaration_order().count() %}
T{{loop.index0}},
{% endfor %}
)> {
#[inline]
fn prepare(&self, builder: &mut ::planus::Builder) -> ::planus::Offset<{{info.owned_name}}> {
{% if fields.declaration_order().count() != 0 %}
let (
{% for _ in fields.declaration_order() %}
v{{loop.index0}},
{% endfor %}
) = &self.0;
{%- endif -%}
{{ info.owned_name }}::create(
builder,
{% for _ in fields.declaration_order() %}
v{{loop.index0}},
{% endfor %}
)
}
}
/// Reference to a deserialized [{{info.owned_name}}].
#[derive(Copy, Clone)]
pub struct {{info.ref_name}}<'a>(
#[allow(dead_code)]
::planus::table_reader::Table<'a>
);
impl<'a> {{info.ref_name}}<'a> {
{% for field in fields.declaration_order() %}
/// Getter for the [`{{field.name_and_docs.original_name}}` field]({{info.owned_name}}#structfield.{{field.info.name}}).
#[inline]
pub fn {{field.info.name}}(&self) -> ::planus::Result<{{field.info.read_type}}> {
{% if field.info.deserialize_default.is_some() %} ::core::result::Result::Ok( {% endif %}
{% if field.field_type == BackendTableFieldType::UnionValue %}
{% if field.info.required %}
self.0.access_union_required({{field.vtable_index-1}}, "{{info.owned_name}}", "{{field.info.name}}")
{% else %}
self.0.access_union({{field.vtable_index-1}}, "{{info.owned_name}}", "{{field.info.name}}")
{% endif %}
{% else if field.field_type == BackendTableFieldType::UnionValueVector %}
{% if field.info.required %}
self.0.access_union_vector_required({{field.vtable_index-1}}, "{{info.owned_name}}", "{{field.info.name}}")
{% else %}
self.0.access_union_vector({{field.vtable_index-1}}, "{{info.owned_name}}", "{{field.info.name}}")
{% endif %}
{% else %}
{% if field.info.required %}
self.0.access_required({{field.vtable_index}}, "{{info.owned_name}}", "{{field.info.name}}")
{% else %}
self.0.access({{field.vtable_index}}, "{{info.owned_name}}", "{{field.info.name}}")
{% endif %}
{% endif %}
{% match field.info.deserialize_default %}
{% when Some with (deserialize_default) %}?.unwrap_or({{deserialize_default}}))
{% when None %}
{% endmatch %}
}
{% endfor %}
}
impl<'a> ::core::fmt::Debug for {{info.ref_name}}<'a> {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
let mut f = f.debug_struct("{{info.ref_name}}");
{% for field in fields.declaration_order() -%}
{%- if field.info.read_type.starts_with("::core::option::Option<") -%}
if let ::core::option::Option::Some(field_{{field.info.name}}) = self.{{field.info.name}}().transpose() {
f.field("{{field.info.name}}", &field_{{field.info.name}});
}
{%- else -%}
f.field("{{field.info.name}}", &self.{{field.info.name}}());
{%- endif -%}
{%- endfor %}
f.finish()
}
}
impl<'a> ::core::convert::TryFrom<{{info.ref_name}}<'a>> for {{info.owned_name}} {
type Error = ::planus::Error;
{% if fields.is_empty() %}
fn try_from(_value: {{info.ref_name}}<'a>) -> ::planus::Result<Self> {
{% else %}
#[allow(unreachable_code)]
fn try_from(value: {{info.ref_name}}<'a>) -> ::planus::Result<Self> {
{% endif %}
::core::result::Result::Ok(Self {
{% for field in fields.declaration_order() -%}
{{field.info.name}}: {{field.info.try_from_code}},
{%- endfor %}
})
}
}
impl<'a> ::planus::TableRead<'a> for {{info.ref_name}}<'a> {
#[inline]
fn from_buffer(buffer: ::planus::SliceWithStartOffset<'a>, offset: usize) -> ::core::result::Result<Self, ::planus::errors::ErrorKind> {
::core::result::Result::Ok(Self(::planus::table_reader::Table::from_buffer(buffer, offset)?))
}
}
impl<'a> ::planus::VectorReadInner<'a> for {{info.ref_name}}<'a> {
type Error = ::planus::Error;
const STRIDE: usize = 4;
unsafe fn from_buffer(buffer: ::planus::SliceWithStartOffset<'a>, offset: usize) -> ::planus::Result<Self> {
::planus::TableRead::from_buffer(buffer, offset).map_err(|error_kind| error_kind.with_error_location(
"[{{info.ref_name}}]",
"get",
buffer.offset_from_start,
))
}
}
/// # Safety
/// The planus compiler generates implementations that initialize
/// the bytes in `write_values`.
unsafe impl ::planus::VectorWrite<::planus::Offset<{{info.owned_name}}>> for {{info.owned_name}} {
type Value = ::planus::Offset<{{info.owned_name}}>;
const STRIDE: usize = 4;
#[inline]
fn prepare(&self, builder: &mut ::planus::Builder) -> Self::Value {
::planus::WriteAs::prepare(self, builder)
}
#[inline]
unsafe fn write_values(
values: &[::planus::Offset<{{info.owned_name}}>],
bytes: *mut ::core::mem::MaybeUninit<u8>,
buffer_position: u32,
) {
let bytes = bytes as *mut [::core::mem::MaybeUninit<u8>; 4];
for (i, v) in ::core::iter::Iterator::enumerate(values.iter()) {
::planus::WriteAsPrimitive::write(
v,
::planus::Cursor::new(unsafe { &mut *bytes.add(i) }),
buffer_position - (Self::STRIDE * i) as u32,
);
}
}
}
impl<'a> ::planus::ReadAsRoot<'a> for {{info.ref_name}}<'a> {
fn read_as_root(slice: &'a [u8]) -> ::planus::Result<Self> {
::planus::TableRead::from_buffer(::planus::SliceWithStartOffset {
buffer: slice,
offset_from_start: 0,
}, 0).map_err(|error_kind| error_kind.with_error_location(
"[{{info.ref_name}}]",
"read_as_root",
0,
))
}
}