fidl_next_codec/wire/
union.rs1use core::mem::MaybeUninit;
6
7use munge::munge;
8
9use crate::decoder::InternalHandleDecoder;
10use crate::encoder::InternalHandleEncoder;
11use crate::{
12    Constrained, Decode, DecodeError, Decoder, Encode, EncodeError, Encoder, Slot, Unconstrained,
13    Wire, WireEnvelope, WireU64,
14};
15
16#[repr(C)]
18pub struct RawWireUnion {
19    ordinal: WireU64,
20    envelope: WireEnvelope,
21}
22
23unsafe impl Wire for RawWireUnion {
24    type Owned<'de> = RawWireUnion;
25
26    #[inline]
27    fn zero_padding(_: &mut MaybeUninit<Self>) {
28        }
30}
31
32impl Unconstrained for RawWireUnion {}
33
34impl RawWireUnion {
35    #[inline]
37    pub fn encode_absent(out: &mut MaybeUninit<Self>) {
38        munge!(let Self { ordinal, envelope } = out);
39
40        ordinal.write(WireU64(0));
41        WireEnvelope::encode_zero(envelope);
42    }
43
44    #[inline]
46    pub fn encode_as_static<E: InternalHandleEncoder + ?Sized, W: Constrained + Wire>(
47        value: impl Encode<W, E>,
48        ord: u64,
49        encoder: &mut E,
50        out: &mut MaybeUninit<Self>,
51        constraint: W::Constraint,
52    ) -> Result<(), EncodeError> {
53        munge!(let Self { ordinal, envelope } = out);
54
55        ordinal.write(WireU64(ord));
56        WireEnvelope::encode_value_static(value, encoder, envelope, constraint)
57    }
58
59    #[inline]
61    pub fn encode_as<E: Encoder + ?Sized, W: Constrained + Wire>(
62        value: impl Encode<W, E>,
63        ord: u64,
64        encoder: &mut E,
65        out: &mut MaybeUninit<Self>,
66        constraint: W::Constraint,
67    ) -> Result<(), EncodeError> {
68        munge!(let Self { ordinal, envelope } = out);
69
70        ordinal.write(WireU64(ord));
71        WireEnvelope::encode_value(value, encoder, envelope, constraint)
72    }
73
74    #[inline]
76    pub fn encoded_ordinal(slot: Slot<'_, Self>) -> u64 {
77        munge!(let Self { ordinal, envelope: _ } = slot);
78        **ordinal
79    }
80
81    #[inline]
83    pub fn decode_absent(slot: Slot<'_, Self>) -> Result<(), DecodeError> {
84        munge!(let Self { ordinal: _, envelope } = slot);
85        if !WireEnvelope::is_encoded_zero(envelope) {
86            return Err(DecodeError::InvalidUnionEnvelope);
87        }
88        Ok(())
89    }
90
91    #[inline]
95    pub fn decode_unknown_static<D: InternalHandleDecoder + ?Sized>(
96        slot: Slot<'_, Self>,
97        decoder: &mut D,
98    ) -> Result<(), DecodeError> {
99        munge!(let Self { ordinal: _, envelope } = slot);
100        WireEnvelope::decode_unknown_static(envelope, decoder)
101    }
102
103    #[inline]
107    pub fn decode_unknown<D: Decoder + ?Sized>(
108        slot: Slot<'_, Self>,
109        decoder: &mut D,
110    ) -> Result<(), DecodeError> {
111        munge!(let Self { ordinal: _, envelope } = slot);
112        WireEnvelope::decode_unknown(envelope, decoder)
113    }
114
115    #[inline]
117    pub fn decode_as_static<D: InternalHandleDecoder + ?Sized, T: Decode<D>>(
118        slot: Slot<'_, Self>,
119        decoder: &mut D,
120        constraint: <T as Constrained>::Constraint,
121    ) -> Result<(), DecodeError> {
122        munge!(let Self { ordinal: _, envelope } = slot);
123        WireEnvelope::decode_as_static::<D, T>(envelope, decoder, constraint)
124    }
125
126    #[inline]
128    pub fn decode_as<D: Decoder + ?Sized, T: Decode<D>>(
129        slot: Slot<'_, Self>,
130        decoder: &mut D,
131        constraint: <T as Constrained>::Constraint,
132    ) -> Result<(), DecodeError> {
133        munge!(let Self { ordinal: _, envelope } = slot);
134        WireEnvelope::decode_as::<D, T>(envelope, decoder, constraint)
135    }
136
137    #[inline]
139    pub fn absent() -> Self {
140        Self { ordinal: WireU64(0), envelope: WireEnvelope::zero() }
141    }
142
143    #[inline]
145    pub fn is_some(&self) -> bool {
146        *self.ordinal != 0
147    }
148
149    #[inline]
151    pub fn is_none(&self) -> bool {
152        !self.is_some()
153    }
154
155    #[inline]
157    pub fn ordinal(&self) -> u64 {
158        *self.ordinal
159    }
160
161    #[inline]
163    pub fn get(&self) -> &WireEnvelope {
164        &self.envelope
165    }
166
167    #[inline]
173    pub unsafe fn clone_inline_unchecked<T: Clone>(&self) -> Self {
174        Self {
175            ordinal: self.ordinal,
176            envelope: unsafe { self.envelope.clone_inline_unchecked::<T>() },
177        }
178    }
179}