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