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 _, Slot, TakeFrom,
14 WirePointer, WireVector, ZeroPadding,
15};
16
17#[repr(transparent)]
19pub struct WireOptionalVector<T> {
20 raw: RawWireVector<T>,
21}
22
23unsafe impl<T> ZeroPadding for WireOptionalVector<T> {
24 #[inline]
25 fn zero_padding(out: &mut MaybeUninit<Self>) {
26 munge!(let Self { raw } = out);
27 RawWireVector::<T>::zero_padding(raw);
28 }
29}
30
31impl<T> Drop for WireOptionalVector<T> {
32 fn drop(&mut self) {
33 if needs_drop::<T>() && self.is_some() {
34 unsafe {
35 self.raw.as_slice_ptr().drop_in_place();
36 }
37 }
38 }
39}
40
41impl<T> WireOptionalVector<T> {
42 pub fn encode_present(out: &mut MaybeUninit<Self>, len: u64) {
44 munge!(let Self { raw } = out);
45 RawWireVector::encode_present(raw, len);
46 }
47
48 pub fn encode_absent(out: &mut MaybeUninit<Self>) {
50 munge!(let Self { raw } = out);
51 RawWireVector::encode_absent(raw);
52 }
53
54 pub fn is_some(&self) -> bool {
56 !self.raw.as_ptr().is_null()
57 }
58
59 pub fn is_none(&self) -> bool {
61 !self.is_some()
62 }
63
64 pub fn as_ref(&self) -> Option<&WireVector<T>> {
66 if self.is_some() {
67 Some(unsafe { &*(self as *const Self).cast() })
68 } else {
69 None
70 }
71 }
72
73 pub unsafe fn decode_raw<D>(
80 mut slot: Slot<'_, Self>,
81 mut decoder: &mut D,
82 ) -> Result<(), DecodeError>
83 where
84 D: Decoder + ?Sized,
85 T: Decode<D>,
86 {
87 munge!(let Self { raw: RawWireVector { len, mut ptr } } = slot.as_mut());
88
89 if WirePointer::is_encoded_present(ptr.as_mut())? {
90 let mut slice = decoder.take_slice_slot::<T>(**len as usize)?;
91 WirePointer::set_decoded(ptr, slice.as_mut_ptr().cast());
92 } else if *len != 0 {
93 return Err(DecodeError::InvalidOptionalSize(**len));
94 }
95
96 Ok(())
97 }
98}
99
100impl<T: fmt::Debug> fmt::Debug for WireOptionalVector<T> {
101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 self.as_ref().fmt(f)
103 }
104}
105
106unsafe impl<D: Decoder + ?Sized, T: Decode<D>> Decode<D> for WireOptionalVector<T> {
107 fn decode(mut slot: Slot<'_, Self>, mut decoder: &mut D) -> Result<(), DecodeError> {
108 munge!(let Self { raw: RawWireVector { len, mut ptr } } = slot.as_mut());
109
110 if WirePointer::is_encoded_present(ptr.as_mut())? {
111 let mut slice = decoder.take_slice_slot::<T>(**len as usize)?;
112 for i in 0..**len as usize {
113 T::decode(slice.index(i), decoder)?;
114 }
115 WirePointer::set_decoded(ptr, slice.as_mut_ptr().cast());
116 } else if *len != 0 {
117 return Err(DecodeError::InvalidOptionalSize(**len));
118 }
119
120 Ok(())
121 }
122}
123
124#[inline]
125fn encode_to_optional_vector<V, E, T>(
126 value: Option<V>,
127 encoder: &mut E,
128 out: &mut MaybeUninit<WireOptionalVector<T::Encoded>>,
129) -> Result<(), EncodeError>
130where
131 V: AsRef<[T]> + IntoIterator,
132 V::IntoIter: ExactSizeIterator,
133 V::Item: Encode<E, Encoded = T::Encoded>,
134 E: Encoder + ?Sized,
135 T: Encode<E>,
136{
137 if let Some(value) = value {
138 let len = value.as_ref().len();
139 if T::COPY_OPTIMIZATION.is_enabled() {
140 let slice = value.as_ref();
141 let bytes = unsafe { slice::from_raw_parts(slice.as_ptr().cast(), size_of_val(slice)) };
145 encoder.write(bytes);
146 } else {
147 encoder.encode_next_iter(value.into_iter())?;
148 }
149 WireOptionalVector::encode_present(out, len as u64);
150 } else {
151 WireOptionalVector::encode_absent(out);
152 }
153 Ok(())
154}
155
156impl<T: Encodable> EncodableOption for Vec<T> {
157 type EncodedOption = WireOptionalVector<T::Encoded>;
158}
159
160unsafe impl<E: Encoder + ?Sized, T: Encode<E>> EncodeOption<E> for Vec<T> {
161 fn encode_option(
162 this: Option<Self>,
163 encoder: &mut E,
164 out: &mut MaybeUninit<Self::EncodedOption>,
165 ) -> Result<(), EncodeError> {
166 encode_to_optional_vector(this, encoder, out)
167 }
168}
169
170unsafe impl<E: Encoder + ?Sized, T: EncodeRef<E>> EncodeOptionRef<E> for Vec<T> {
171 fn encode_option_ref(
172 this: Option<&Self>,
173 encoder: &mut E,
174 out: &mut MaybeUninit<Self::EncodedOption>,
175 ) -> Result<(), EncodeError> {
176 encode_to_optional_vector(this, encoder, out)
177 }
178}
179
180impl<T: Encodable> EncodableOption for &[T] {
181 type EncodedOption = WireOptionalVector<T::Encoded>;
182}
183
184unsafe impl<E: Encoder + ?Sized, T: EncodeRef<E>> EncodeOption<E> for &[T] {
185 fn encode_option(
186 this: Option<Self>,
187 encoder: &mut E,
188 out: &mut MaybeUninit<Self::EncodedOption>,
189 ) -> Result<(), EncodeError> {
190 encode_to_optional_vector(this, encoder, out)
191 }
192}
193
194impl<T: TakeFrom<WT>, WT> TakeFrom<WireOptionalVector<WT>> for Option<Vec<T>> {
195 fn take_from(from: &WireOptionalVector<WT>) -> Self {
196 from.as_ref().map(Vec::take_from)
197 }
198}