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