fidl_next_codec/wire/vec/
optional.rs1use core::mem::{MaybeUninit, needs_drop};
6use core::{fmt, slice};
7
8use munge::munge;
9
10use super::raw::RawWireVector;
11use crate::{
12 Decode, DecodeError, Decoder, DecoderExt as _, Encodable, EncodableOption, Encode, EncodeError,
13 EncodeOption, EncodeOptionRef, EncodeRef, Encoder, EncoderExt as _, FromWire, FromWireOption,
14 FromWireOptionRef, FromWireRef, Slot, Wire, WirePointer, WireVector,
15};
16
17#[repr(transparent)]
19pub struct WireOptionalVector<'de, T> {
20 raw: RawWireVector<'de, T>,
21}
22
23unsafe impl<T: Wire> Wire for WireOptionalVector<'static, T> {
24 type Decoded<'de> = WireOptionalVector<'de, T::Decoded<'de>>;
25
26 #[inline]
27 fn zero_padding(out: &mut MaybeUninit<Self>) {
28 munge!(let Self { raw } = out);
29 RawWireVector::<T>::zero_padding(raw);
30 }
31}
32
33impl<T> Drop for WireOptionalVector<'_, T> {
34 fn drop(&mut self) {
35 if needs_drop::<T>() && self.is_some() {
36 unsafe {
37 self.raw.as_slice_ptr().drop_in_place();
38 }
39 }
40 }
41}
42
43impl<'de, T> WireOptionalVector<'de, T> {
44 pub fn encode_present(out: &mut MaybeUninit<Self>, len: u64) {
46 munge!(let Self { raw } = out);
47 RawWireVector::encode_present(raw, len);
48 }
49
50 pub fn encode_absent(out: &mut MaybeUninit<Self>) {
52 munge!(let Self { raw } = out);
53 RawWireVector::encode_absent(raw);
54 }
55
56 pub fn is_some(&self) -> bool {
58 !self.raw.as_ptr().is_null()
59 }
60
61 pub fn is_none(&self) -> bool {
63 !self.is_some()
64 }
65
66 pub fn as_ref(&self) -> Option<&WireVector<'_, T>> {
68 if self.is_some() { Some(unsafe { &*(self as *const Self).cast() }) } else { None }
69 }
70
71 pub fn to_option(self) -> Option<WireVector<'de, T>> {
73 if self.is_some() {
74 Some(unsafe { core::mem::transmute::<Self, WireVector<'de, T>>(self) })
75 } else {
76 None
77 }
78 }
79
80 pub unsafe fn decode_raw<D>(
87 mut slot: Slot<'_, Self>,
88 mut decoder: &mut D,
89 ) -> Result<(), DecodeError>
90 where
91 D: Decoder + ?Sized,
92 T: Decode<D>,
93 {
94 munge!(let Self { raw: RawWireVector { len, mut ptr } } = slot.as_mut());
95
96 if WirePointer::is_encoded_present(ptr.as_mut())? {
97 let mut slice = decoder.take_slice_slot::<T>(**len as usize)?;
98 WirePointer::set_decoded(ptr, slice.as_mut_ptr().cast());
99 } else if *len != 0 {
100 return Err(DecodeError::InvalidOptionalSize(**len));
101 }
102
103 Ok(())
104 }
105}
106
107impl<T: fmt::Debug> fmt::Debug for WireOptionalVector<'_, T> {
108 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109 self.as_ref().fmt(f)
110 }
111}
112
113unsafe impl<D: Decoder + ?Sized, T: Decode<D>> Decode<D> for WireOptionalVector<'static, T> {
114 fn decode(mut slot: Slot<'_, Self>, mut decoder: &mut D) -> Result<(), DecodeError> {
115 munge!(let Self { raw: RawWireVector { len, mut ptr } } = slot.as_mut());
116
117 if WirePointer::is_encoded_present(ptr.as_mut())? {
118 let mut slice = decoder.take_slice_slot::<T>(**len as usize)?;
119 for i in 0..**len as usize {
120 T::decode(slice.index(i), decoder)?;
121 }
122 WirePointer::set_decoded(ptr, slice.as_mut_ptr().cast());
123 } else if *len != 0 {
124 return Err(DecodeError::InvalidOptionalSize(**len));
125 }
126
127 Ok(())
128 }
129}
130
131#[inline]
132fn encode_to_optional_vector<V, E, T>(
133 value: Option<V>,
134 encoder: &mut E,
135 out: &mut MaybeUninit<WireOptionalVector<'_, T::Encoded>>,
136) -> Result<(), EncodeError>
137where
138 V: AsRef<[T]> + IntoIterator,
139 V::IntoIter: ExactSizeIterator,
140 V::Item: Encode<E, Encoded = T::Encoded>,
141 E: Encoder + ?Sized,
142 T: Encode<E>,
143{
144 if let Some(value) = value {
145 let len = value.as_ref().len();
146 if T::COPY_OPTIMIZATION.is_enabled() {
147 let slice = value.as_ref();
148 let bytes = unsafe { slice::from_raw_parts(slice.as_ptr().cast(), size_of_val(slice)) };
152 encoder.write(bytes);
153 } else {
154 encoder.encode_next_iter(value.into_iter())?;
155 }
156 WireOptionalVector::encode_present(out, len as u64);
157 } else {
158 WireOptionalVector::encode_absent(out);
159 }
160 Ok(())
161}
162
163impl<T: Encodable> EncodableOption for Vec<T> {
164 type EncodedOption = WireOptionalVector<'static, T::Encoded>;
165}
166
167unsafe impl<E, T> EncodeOption<E> for Vec<T>
168where
169 E: Encoder + ?Sized,
170 T: Encode<E>,
171{
172 fn encode_option(
173 this: Option<Self>,
174 encoder: &mut E,
175 out: &mut MaybeUninit<Self::EncodedOption>,
176 ) -> Result<(), EncodeError> {
177 encode_to_optional_vector(this, encoder, out)
178 }
179}
180
181unsafe impl<E, T> EncodeOptionRef<E> for Vec<T>
182where
183 E: Encoder + ?Sized,
184 T: EncodeRef<E>,
185{
186 fn encode_option_ref(
187 this: Option<&Self>,
188 encoder: &mut E,
189 out: &mut MaybeUninit<Self::EncodedOption>,
190 ) -> Result<(), EncodeError> {
191 encode_to_optional_vector(this, encoder, out)
192 }
193}
194
195impl<T: Encodable> EncodableOption for &[T] {
196 type EncodedOption = WireOptionalVector<'static, T::Encoded>;
197}
198
199unsafe impl<E, T> EncodeOption<E> for &[T]
200where
201 E: Encoder + ?Sized,
202 T: EncodeRef<E>,
203{
204 fn encode_option(
205 this: Option<Self>,
206 encoder: &mut E,
207 out: &mut MaybeUninit<Self::EncodedOption>,
208 ) -> Result<(), EncodeError> {
209 encode_to_optional_vector(this, encoder, out)
210 }
211}
212
213impl<T: FromWire<W>, W> FromWireOption<WireOptionalVector<'_, W>> for Vec<T> {
214 fn from_wire_option(wire: WireOptionalVector<'_, W>) -> Option<Self> {
215 wire.to_option().map(Vec::from_wire)
216 }
217}
218
219impl<T: FromWireRef<W>, W> FromWireOptionRef<WireOptionalVector<'_, W>> for Vec<T> {
220 fn from_wire_option_ref(wire: &WireOptionalVector<'_, W>) -> Option<Self> {
221 wire.as_ref().map(Vec::from_wire_ref)
222 }
223}