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, ValidationError,
13 Wire, wire,
14};
15
16#[repr(C)]
18pub struct Union {
19 ordinal: wire::Uint64,
20 envelope: wire::Envelope,
21}
22
23impl Constrained for Union {
24 type Constraint = ();
25
26 fn validate(_: Slot<'_, Self>, _: Self::Constraint) -> Result<(), ValidationError> {
27 Ok(())
28 }
29}
30
31unsafe impl Wire for Union {
32 type Narrowed<'de> = Self;
33
34 #[inline]
35 fn zero_padding(_: &mut MaybeUninit<Self>) {
36 }
38}
39
40impl Union {
41 #[inline]
43 pub fn encode_absent(out: &mut MaybeUninit<Self>) {
44 munge!(let Self { ordinal, envelope } = out);
45
46 ordinal.write(wire::Uint64(0));
47 wire::Envelope::encode_zero(envelope);
48 }
49
50 #[inline]
52 pub fn encode_as_static<E: InternalHandleEncoder + ?Sized, W: Wire>(
53 value: impl Encode<W, E>,
54 ord: u64,
55 encoder: &mut E,
56 out: &mut MaybeUninit<Self>,
57 constraint: W::Constraint,
58 ) -> Result<(), EncodeError> {
59 munge!(let Self { ordinal, envelope } = out);
60
61 ordinal.write(wire::Uint64(ord));
62 wire::Envelope::encode_value_static(value, encoder, envelope, constraint)
63 }
64
65 #[inline]
67 pub fn encode_as<E: Encoder + ?Sized, W: Wire>(
68 value: impl Encode<W, E>,
69 ord: u64,
70 encoder: &mut E,
71 out: &mut MaybeUninit<Self>,
72 constraint: W::Constraint,
73 ) -> Result<(), EncodeError> {
74 munge!(let Self { ordinal, envelope } = out);
75
76 ordinal.write(wire::Uint64(ord));
77 wire::Envelope::encode_value(value, encoder, envelope, constraint)
78 }
79
80 #[inline]
82 pub fn encoded_ordinal(slot: Slot<'_, Self>) -> u64 {
83 munge!(let Self { ordinal, envelope: _ } = slot);
84 **ordinal
85 }
86
87 #[inline]
89 pub fn decode_absent(slot: Slot<'_, Self>) -> Result<(), DecodeError> {
90 munge!(let Self { ordinal: _, envelope } = slot);
91 if !wire::Envelope::is_encoded_zero(envelope) {
92 return Err(DecodeError::InvalidUnionEnvelope);
93 }
94 Ok(())
95 }
96
97 #[inline]
101 pub fn decode_unknown_static<D: InternalHandleDecoder + ?Sized>(
102 slot: Slot<'_, Self>,
103 decoder: &mut D,
104 ) -> Result<(), DecodeError> {
105 munge!(let Self { ordinal: _, envelope } = slot);
106 wire::Envelope::decode_unknown_static(envelope, decoder)
107 }
108
109 #[inline]
113 pub fn decode_unknown<'de, D: Decoder<'de> + ?Sized>(
114 slot: Slot<'_, Self>,
115 decoder: &mut D,
116 ) -> Result<(), DecodeError> {
117 munge!(let Self { ordinal: _, envelope } = slot);
118 wire::Envelope::decode_unknown(envelope, decoder)
119 }
120
121 #[inline]
123 pub fn decode_as_static<D: InternalHandleDecoder + ?Sized, T: Decode<D>>(
124 slot: Slot<'_, Self>,
125 decoder: &mut D,
126 constraint: T::Constraint,
127 ) -> Result<(), DecodeError> {
128 munge!(let Self { ordinal: _, envelope } = slot);
129 wire::Envelope::decode_as_static::<D, T>(envelope, decoder, constraint)
130 }
131
132 #[inline]
134 pub fn decode_as<'de, D: Decoder<'de> + ?Sized, T: Decode<D>>(
135 slot: Slot<'_, Self>,
136 decoder: &mut D,
137 constraint: T::Constraint,
138 ) -> Result<(), DecodeError> {
139 munge!(let Self { ordinal: _, envelope } = slot);
140 wire::Envelope::decode_as::<D, T>(envelope, decoder, constraint)
141 }
142
143 #[inline]
145 pub fn absent() -> Self {
146 Self { ordinal: wire::Uint64(0), envelope: wire::Envelope::zero() }
147 }
148
149 #[inline]
151 pub fn is_some(&self) -> bool {
152 *self.ordinal != 0
153 }
154
155 #[inline]
157 pub fn is_none(&self) -> bool {
158 !self.is_some()
159 }
160
161 #[inline]
163 pub fn ordinal(&self) -> u64 {
164 *self.ordinal
165 }
166
167 #[inline]
169 pub fn get(&self) -> &wire::Envelope {
170 &self.envelope
171 }
172
173 #[inline]
179 pub unsafe fn clone_inline_unchecked<T: Clone>(&self) -> Self {
180 Self {
181 ordinal: self.ordinal,
182 envelope: unsafe { self.envelope.clone_inline_unchecked::<T>() },
183 }
184 }
185}