fidl_next_codec/wire/vec/
optional.rs1use core::mem::{needs_drop, MaybeUninit};
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() {
69 Some(unsafe { &*(self as *const Self).cast() })
70 } else {
71 None
72 }
73 }
74
75 pub fn to_option(self) -> Option<WireVector<'de, T>> {
77 if self.is_some() {
78 Some(unsafe { core::mem::transmute::<Self, WireVector<'de, T>>(self) })
79 } else {
80 None
81 }
82 }
83
84 pub unsafe fn decode_raw<D>(
91 mut slot: Slot<'_, Self>,
92 mut decoder: &mut D,
93 ) -> Result<(), DecodeError>
94 where
95 D: Decoder + ?Sized,
96 T: Decode<D>,
97 {
98 munge!(let Self { raw: RawWireVector { len, mut ptr } } = slot.as_mut());
99
100 if WirePointer::is_encoded_present(ptr.as_mut())? {
101 let mut slice = decoder.take_slice_slot::<T>(**len as usize)?;
102 WirePointer::set_decoded(ptr, slice.as_mut_ptr().cast());
103 } else if *len != 0 {
104 return Err(DecodeError::InvalidOptionalSize(**len));
105 }
106
107 Ok(())
108 }
109}
110
111impl<T: fmt::Debug> fmt::Debug for WireOptionalVector<'_, T> {
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 self.as_ref().fmt(f)
114 }
115}
116
117unsafe impl<D: Decoder + ?Sized, T: Decode<D>> Decode<D> for WireOptionalVector<'static, T> {
118 fn decode(mut slot: Slot<'_, Self>, mut decoder: &mut D) -> Result<(), DecodeError> {
119 munge!(let Self { raw: RawWireVector { len, mut ptr } } = slot.as_mut());
120
121 if WirePointer::is_encoded_present(ptr.as_mut())? {
122 let mut slice = decoder.take_slice_slot::<T>(**len as usize)?;
123 for i in 0..**len as usize {
124 T::decode(slice.index(i), decoder)?;
125 }
126 WirePointer::set_decoded(ptr, slice.as_mut_ptr().cast());
127 } else if *len != 0 {
128 return Err(DecodeError::InvalidOptionalSize(**len));
129 }
130
131 Ok(())
132 }
133}
134
135#[inline]
136fn encode_to_optional_vector<V, E, T>(
137 value: Option<V>,
138 encoder: &mut E,
139 out: &mut MaybeUninit<WireOptionalVector<'_, T::Encoded>>,
140) -> Result<(), EncodeError>
141where
142 V: AsRef<[T]> + IntoIterator,
143 V::IntoIter: ExactSizeIterator,
144 V::Item: Encode<E, Encoded = T::Encoded>,
145 E: Encoder + ?Sized,
146 T: Encode<E>,
147{
148 if let Some(value) = value {
149 let len = value.as_ref().len();
150 if T::COPY_OPTIMIZATION.is_enabled() {
151 let slice = value.as_ref();
152 let bytes = unsafe { slice::from_raw_parts(slice.as_ptr().cast(), size_of_val(slice)) };
156 encoder.write(bytes);
157 } else {
158 encoder.encode_next_iter(value.into_iter())?;
159 }
160 WireOptionalVector::encode_present(out, len as u64);
161 } else {
162 WireOptionalVector::encode_absent(out);
163 }
164 Ok(())
165}
166
167impl<T: Encodable> EncodableOption for Vec<T> {
168 type EncodedOption = WireOptionalVector<'static, T::Encoded>;
169}
170
171unsafe impl<E, T> EncodeOption<E> for Vec<T>
172where
173 E: Encoder + ?Sized,
174 T: Encode<E>,
175{
176 fn encode_option(
177 this: Option<Self>,
178 encoder: &mut E,
179 out: &mut MaybeUninit<Self::EncodedOption>,
180 ) -> Result<(), EncodeError> {
181 encode_to_optional_vector(this, encoder, out)
182 }
183}
184
185unsafe impl<E, T> EncodeOptionRef<E> for Vec<T>
186where
187 E: Encoder + ?Sized,
188 T: EncodeRef<E>,
189{
190 fn encode_option_ref(
191 this: Option<&Self>,
192 encoder: &mut E,
193 out: &mut MaybeUninit<Self::EncodedOption>,
194 ) -> Result<(), EncodeError> {
195 encode_to_optional_vector(this, encoder, out)
196 }
197}
198
199impl<T: Encodable> EncodableOption for &[T] {
200 type EncodedOption = WireOptionalVector<'static, T::Encoded>;
201}
202
203unsafe impl<E, T> EncodeOption<E> for &[T]
204where
205 E: Encoder + ?Sized,
206 T: EncodeRef<E>,
207{
208 fn encode_option(
209 this: Option<Self>,
210 encoder: &mut E,
211 out: &mut MaybeUninit<Self::EncodedOption>,
212 ) -> Result<(), EncodeError> {
213 encode_to_optional_vector(this, encoder, out)
214 }
215}
216
217impl<T: FromWire<W>, W> FromWireOption<WireOptionalVector<'_, W>> for Vec<T> {
218 fn from_wire_option(wire: WireOptionalVector<'_, W>) -> Option<Self> {
219 wire.to_option().map(Vec::from_wire)
220 }
221}
222
223impl<T: FromWireRef<W>, W> FromWireOptionRef<WireOptionalVector<'_, W>> for Vec<T> {
224 fn from_wire_option_ref(wire: &WireOptionalVector<'_, W>) -> Option<Self> {
225 wire.as_ref().map(Vec::from_wire_ref)
226 }
227}