fidl_next_codec/wire/
table.rs1use core::mem::MaybeUninit;
6
7use munge::munge;
8
9use crate::{
10 Constrained, DecodeError, Decoder, DecoderExt as _, Slot, ValidationError, Wire, wire,
11};
12
13#[repr(C)]
15pub struct Table<'de> {
16 len: wire::Uint64,
17 ptr: wire::Pointer<'de, wire::Envelope>,
18}
19
20impl Constrained for Table<'_> {
21 type Constraint = ();
22
23 fn validate(_: Slot<'_, Self>, _: Self::Constraint) -> Result<(), ValidationError> {
24 Ok(())
25 }
26}
27
28unsafe impl Wire for Table<'static> {
29 type Narrowed<'de> = Table<'de>;
30
31 #[inline]
32 fn zero_padding(_: &mut MaybeUninit<Self>) {
33 }
35}
36
37impl<'de> Table<'de> {
38 #[inline]
40 pub fn encode_len(out: &mut MaybeUninit<Self>, len: usize) {
41 munge!(let Self { len: table_len, ptr } = out);
42 table_len.write(wire::Uint64(len.try_into().unwrap()));
43 wire::Pointer::encode_present(ptr);
44 }
45
46 #[inline]
50 pub fn decode_with<D: Decoder<'de> + ?Sized>(
51 slot: Slot<'_, Self>,
52 decoder: &mut D,
53 f: impl Fn(i64, Slot<'_, wire::Envelope>, &mut D) -> Result<(), DecodeError>,
54 ) -> Result<(), DecodeError> {
55 munge!(let Self { len, mut ptr } = slot);
56
57 if wire::Pointer::is_encoded_present(ptr.as_mut())? {
58 let mut envelopes = decoder.take_slice_slot::<wire::Envelope>(**len as usize)?;
59
60 for i in 0..**len as usize {
61 let mut envelope = envelopes.index(i);
62 if !wire::Envelope::is_encoded_zero(envelope.as_mut()) {
63 f((i + 1) as i64, envelope, decoder)?;
64 }
65 }
66
67 wire::Pointer::set_decoded_slice(ptr, envelopes);
68 } else if **len != 0 {
69 return Err(DecodeError::InvalidOptionalSize(**len));
70 }
71
72 Ok(())
73 }
74}
75
76impl Table<'_> {
77 #[inline]
79 pub fn get(&self, ordinal: usize) -> Option<&wire::Envelope> {
80 if ordinal == 0 || ordinal > *self.len as usize {
81 return None;
82 }
83
84 let envelope = unsafe { &*self.ptr.as_ptr().add(ordinal - 1) };
85 (!envelope.is_zero()).then_some(envelope)
86 }
87}