blob: fe96c8746809c78180b591f040ccdc652681bea7 [file] [log] [blame]
{{ self.doc_string(table.attributes) -}}
#[derive(PartialEq,
{% if !table.is_resource %}
Clone,
{% endif %}
{% if self.emit_debug_impls() %}
Debug,
{% endif %}
Default,
)]
pub struct {{ name }} {
{% for member in table.members %}
pub {{ member.name|snake }}: ::core::option::Option<{{ self.natural_type(member.ty) }}>,
{% endfor %}
}
impl {{ name }} {
fn __max_ordinal(&self) -> usize {
{% for member in table.members.iter().rev() %}
if self.{{ member.name|snake }}.is_some() { return {{ member.ordinal }}; }
{% endfor %}
0
}
}
impl ::fidl_next::Encodable for {{ name }} {
type Encoded = {{ wire_name }}<'static>;
}
unsafe impl<___E> ::fidl_next::Encode<___E> for {{ name }}
where
___E: ::fidl_next::Encoder + ?Sized,
{% if table.is_resource %}
___E: {{ self.encode_trait_path() }},
{% endif %}
{
#[inline]
fn encode(
mut self,
encoder: &mut ___E,
out: &mut ::core::mem::MaybeUninit<Self::Encoded>,
) -> ::core::result::Result<(), ::fidl_next::EncodeError> {
::fidl_next::munge!(let {{ wire_name }} { table } = out);
let max_ord = self.__max_ordinal();
let mut out = ::core::mem::MaybeUninit::<::fidl_next::WireEnvelope>::uninit();
::fidl_next::Wire::zero_padding(&mut out);
let mut preallocated = ::fidl_next::EncoderExt::preallocate::<::fidl_next::WireEnvelope>(encoder, max_ord);
for i in 1..=max_ord {
match i {
{% for member in table.members.iter().rev() %}
{% let member_name = filters::escape_snake(member.name) %}
{{ member.ordinal }} => if let Some(value) = self.{{ member_name }}.take() {
::fidl_next::WireEnvelope::encode_value(
value,
preallocated.encoder,
&mut out,
)?;
} else {
::fidl_next::WireEnvelope::encode_zero(&mut out)
}
{% endfor %}
_ => ::fidl_next::WireEnvelope::encode_zero(&mut out),
}
unsafe {
preallocated.write_next(out.assume_init_ref());
}
}
::fidl_next::WireTable::encode_len(table, max_ord);
Ok(())
}
}
{% if !table.is_resource %}
unsafe impl<___E> ::fidl_next::EncodeRef<___E> for {{ name }}
where
___E: ::fidl_next::Encoder + ?Sized,
{
#[inline]
fn encode_ref(
&self,
encoder: &mut ___E,
out: &mut ::core::mem::MaybeUninit<Self::Encoded>,
) -> ::core::result::Result<(), ::fidl_next::EncodeError> {
::fidl_next::munge!(let {{ wire_name }} { table } = out);
let max_ord = self.__max_ordinal();
let mut out = ::core::mem::MaybeUninit::<::fidl_next::WireEnvelope>::uninit();
::fidl_next::Wire::zero_padding(&mut out);
let mut preallocated = ::fidl_next::EncoderExt::preallocate::<::fidl_next::WireEnvelope>(encoder, max_ord);
for i in 1..=max_ord {
match i {
{% for member in table.members.iter().rev() %}
{% let member_name = filters::escape_snake(member.name) %}
{{ member.ordinal }} => if let Some(value) = &self.{{ member_name }} {
::fidl_next::WireEnvelope::encode_value(
value,
preallocated.encoder,
&mut out,
)?;
} else {
::fidl_next::WireEnvelope::encode_zero(&mut out)
}
{% endfor %}
_ => ::fidl_next::WireEnvelope::encode_zero(&mut out),
}
unsafe {
preallocated.write_next(out.assume_init_ref());
}
}
::fidl_next::WireTable::encode_len(table, max_ord);
Ok(())
}
}
{% endif %}
impl<'de> ::fidl_next::FromWire<{{ wire_name }}<'de>> for {{ name }} {
#[inline]
fn from_wire(wire_: {{ wire_name }}<'de>) -> Self {
let wire_ = ::core::mem::ManuallyDrop::new(wire_);
{% for member in table.members %}
let {{ member.name|snake }} = wire_.table.get({{ member.ordinal }});
{% endfor %}
Self {
{% for member in table.members %}
{% let member_name = filters::escape_snake(member.name) %}
{{ member_name }}: {{ member_name }}.map(|envelope| ::fidl_next::FromWire::from_wire(
unsafe { envelope.read_unchecked::<{{ self.wire_type(member.ty) }}>() }
)),
{% endfor %}
}
}
}
impl<'de> ::fidl_next::IntoNatural for {{ wire_name }}<'de> {
type Natural = {{ name }};
}
{% if !table.is_resource %}
impl<'de> ::fidl_next::FromWireRef<{{ wire_name }}<'de>> for {{ name }} {
#[inline]
fn from_wire_ref(wire: &{{ wire_name }}<'de>) -> Self {
Self {
{% for member in table.members %}
{% let member_name = filters::escape_snake(member.name) %}
{{ member_name }}: wire.table.get({{ member.ordinal }})
.map(|envelope| ::fidl_next::FromWireRef::from_wire_ref(
unsafe { envelope.deref_unchecked::<{{ self.wire_type(member.ty) }}>() }
)),
{% endfor %}
}
}
}
{% endif %}
/// The wire type corresponding to [`{{ name }}`].
#[repr(C)]
pub struct {{ wire_name }}<'de> {
table: ::fidl_next::WireTable<'de>,
}
impl<'de> Drop for {{ wire_name }}<'de> {
fn drop(&mut self) {
{% for member in table.members %}
let _ = self.table.get({{ member.ordinal }})
.map(|envelope| unsafe {
envelope.read_unchecked::<{{ self.wire_type(member.ty) }}>()
});
{% endfor %}
}
}
unsafe impl ::fidl_next::Wire for {{ wire_name }}<'static> {
type Decoded<'de> = {{ wire_name }}<'de>;
#[inline]
fn zero_padding(out: &mut ::core::mem::MaybeUninit<Self>) {
::fidl_next::munge!(let Self { table } = out);
::fidl_next::WireTable::zero_padding(table);
}
}
unsafe impl<___D> ::fidl_next::Decode<___D> for {{ wire_name }}<'static>
where
___D: ::fidl_next::Decoder + ?Sized,
{% if table.is_resource %}
___D: {{ self.decode_trait_path() }},
{% endif %}
{
fn decode(
slot: ::fidl_next::Slot<'_, Self>,
decoder: &mut ___D,
) -> ::core::result::Result<(), ::fidl_next::DecodeError> {
::fidl_next::munge!(let Self { table } = slot);
::fidl_next::WireTable::decode_with(
table,
decoder,
|ordinal, mut slot, decoder| match ordinal {
0 => unsafe { ::core::hint::unreachable_unchecked() },
{% for member in table.members %}
{{ member.ordinal }} => {
::fidl_next::WireEnvelope::decode_as::<
___D,
{{ self.static_wire_type(member.ty) }},
>(slot.as_mut(), decoder)?;
{# type check #}
{% match member.ty.kind -%}
{% when TypeKind::Array { element_count, element_type } %}
{% when TypeKind::Vector { element_count, element_type, nullable } -%}
{% if let Some(limit) = element_count -%}
let value = unsafe {
slot
.deref_unchecked()
.deref_unchecked::<
{{ self.anonymous_wire_type(member.ty) }}
>()
};
{% if nullable -%}
if let Some(value) = value.as_ref() {
{%- endif %}
if value.len() > {{ limit }} {
return Err(::fidl_next::DecodeError::VectorTooLong {
size: value.len() as u64,
limit: {{ limit }},
});
}
{% if nullable -%}
}
{%- endif %}
{%- endif %}
{% when TypeKind::String { element_count, nullable } %}
{% if let Some(limit) = element_count -%}
let value = unsafe {
slot
.deref_unchecked()
.deref_unchecked::<
{{ self.anonymous_wire_type(member.ty) }}
>()
};
{% if nullable -%}
if let Some(value) = value.as_ref() {
{%- endif %}
if value.len() > {{ limit }} {
return Err(::fidl_next::DecodeError::VectorTooLong {
size: value.len() as u64,
limit: {{ limit }},
});
}
{% if nullable -%}
}
{%- endif %}
{% endif %}
{% else %} {# todo #}
{%- endmatch %}
Ok(())
}
{% endfor %}
_ => ::fidl_next::WireEnvelope::decode_unknown(slot, decoder),
}
)
}
}
impl<'de> {{ wire_name }}<'de> {
{% for member in table.members %}
pub fn {{ member.name|snake }}(&self) -> ::core::option::Option<&{{ self.wire_type(member.ty) }}> {
unsafe {
Some(self.table.get({{ member.ordinal }})?.deref_unchecked())
}
}
{% endfor %}
}
{% if self.emit_debug_impls() %}
impl<'de> ::core::fmt::Debug for {{ wire_name }}<'de> {
fn fmt(
&self,
f: &mut ::core::fmt::Formatter<'_>,
) -> ::core::result::Result<(), ::core::fmt::Error> {
f.debug_struct("{{ name }}")
{% for member in table.members %}
{% let member_name = filters::escape_snake(member.name) %}
.field("{{ member_name }}", &self.{{ member_name }}())
{% endfor %}
.finish()
}
}
{% endif %}