fidl_next_codec/wire/
union.rs1use core::mem::MaybeUninit;
6use core::ptr::addr_of_mut;
7
8use munge::munge;
9
10use crate::decoder::InternalHandleDecoder;
11use crate::encoder::InternalHandleEncoder;
12use crate::{
13 Constrained, Decode, DecodeError, Decoder, Encode, EncodeError, Encoder, Slot, ValidationError,
14 Wire, wire,
15};
16
17#[repr(C)]
19pub struct Union {
20 ordinal: wire::Uint64,
21 envelope: wire::Envelope,
22}
23
24impl Constrained for Union {
25 type Constraint = ();
26
27 fn validate(_: Slot<'_, Self>, _: Self::Constraint) -> Result<(), ValidationError> {
28 Ok(())
29 }
30}
31
32unsafe impl Wire for Union {
34 type Narrowed<'de> = Self;
35
36 #[inline]
37 fn zero_padding(_: &mut MaybeUninit<Self>) {
38 }
40}
41
42impl Union {
43 #[inline]
45 pub fn encode_absent(out: &mut MaybeUninit<Self>) {
46 munge!(let Self { ordinal, envelope } = out);
47
48 ordinal.write(wire::Uint64(0));
49 wire::Envelope::encode_zero(envelope);
50 }
51
52 #[inline]
54 pub fn encode_as_static<E: InternalHandleEncoder + ?Sized, W: Wire>(
55 value: impl Encode<W, E>,
56 ord: u64,
57 encoder: &mut E,
58 out: &mut MaybeUninit<Self>,
59 constraint: W::Constraint,
60 ) -> Result<(), EncodeError> {
61 munge!(let Self { ordinal, envelope } = out);
62
63 ordinal.write(wire::Uint64(ord));
64 wire::Envelope::encode_value_static(value, encoder, envelope, constraint)
65 }
66
67 #[inline]
69 pub fn encode_as<E: Encoder + ?Sized, W: Wire>(
70 value: impl Encode<W, E>,
71 ord: u64,
72 encoder: &mut E,
73 out: &mut MaybeUninit<Self>,
74 constraint: W::Constraint,
75 ) -> Result<(), EncodeError> {
76 munge!(let Self { ordinal, envelope } = out);
77
78 ordinal.write(wire::Uint64(ord));
79 wire::Envelope::encode_value(value, encoder, envelope, constraint)
80 }
81
82 #[inline]
84 pub fn encoded_ordinal(slot: Slot<'_, Self>) -> u64 {
85 munge!(let Self { ordinal, envelope: _ } = slot);
86 **ordinal
87 }
88
89 #[inline]
91 pub fn decode_absent(slot: Slot<'_, Self>) -> Result<(), DecodeError> {
92 munge!(let Self { ordinal: _, envelope } = slot);
93 if !wire::Envelope::is_encoded_zero(envelope) {
94 return Err(DecodeError::InvalidUnionEnvelope);
95 }
96 Ok(())
97 }
98
99 #[inline]
103 pub fn decode_unknown_static<D: InternalHandleDecoder + ?Sized>(
104 slot: Slot<'_, Self>,
105 decoder: &mut D,
106 ) -> Result<(), DecodeError> {
107 munge!(let Self { ordinal: _, envelope } = slot);
108 wire::Envelope::decode_unknown_static(envelope, decoder)
109 }
110
111 #[inline]
115 pub fn decode_unknown<'de, D: Decoder<'de> + ?Sized>(
116 slot: Slot<'_, Self>,
117 decoder: &mut D,
118 ) -> Result<(), DecodeError> {
119 munge!(let Self { ordinal: _, envelope } = slot);
120 wire::Envelope::decode_unknown(envelope, decoder)
121 }
122
123 #[inline]
125 pub fn decode_as_static<D: InternalHandleDecoder + ?Sized, T: Decode<D>>(
126 slot: Slot<'_, Self>,
127 decoder: &mut D,
128 constraint: T::Constraint,
129 ) -> Result<(), DecodeError> {
130 munge!(let Self { ordinal: _, envelope } = slot);
131 wire::Envelope::decode_as_static::<D, T>(envelope, decoder, constraint)
132 }
133
134 #[inline]
136 pub fn decode_as<'de, D: Decoder<'de> + ?Sized, T: Decode<D>>(
137 slot: Slot<'_, Self>,
138 decoder: &mut D,
139 constraint: T::Constraint,
140 ) -> Result<(), DecodeError> {
141 munge!(let Self { ordinal: _, envelope } = slot);
142 wire::Envelope::decode_as::<D, T>(envelope, decoder, constraint)
143 }
144
145 #[inline]
147 pub fn absent() -> Self {
148 Self { ordinal: wire::Uint64(0), envelope: wire::Envelope::zero() }
149 }
150
151 #[inline]
153 pub fn is_some(&self) -> bool {
154 *self.ordinal != 0
155 }
156
157 #[inline]
159 pub fn is_none(&self) -> bool {
160 !self.is_some()
161 }
162
163 #[inline]
165 pub fn ordinal(&self) -> u64 {
166 *self.ordinal
167 }
168
169 #[inline]
175 pub unsafe fn get_raw(this: *mut Self) -> *mut wire::Envelope {
176 unsafe { addr_of_mut!((*this).envelope) }
178 }
179
180 #[inline]
182 pub fn get(&self) -> &wire::Envelope {
183 &self.envelope
184 }
185
186 #[inline]
192 pub unsafe fn clone_inline_unchecked<T: Clone>(&self) -> Self {
193 Self {
194 ordinal: self.ordinal,
195 envelope: unsafe { self.envelope.clone_inline_unchecked::<T>() },
198 }
199 }
200}