fidl_next_codec/wire/vec/
required.rs1use core::marker::PhantomData;
6use core::mem::{MaybeUninit, forget, needs_drop};
7use core::ops::Deref;
8use core::ptr::{NonNull, copy_nonoverlapping};
9use core::{fmt, slice};
10
11use munge::munge;
12
13use super::raw::RawWireVector;
14use crate::{
15 Chunk, Decode, DecodeError, Decoder, DecoderExt as _, Encodable, Encode, EncodeError,
16 EncodeRef, Encoder, EncoderExt as _, FromWire, FromWireRef, IntoNatural, Slot, Wire,
17 WirePointer,
18};
19
20#[repr(transparent)]
22pub struct WireVector<'de, T> {
23 pub(crate) raw: RawWireVector<'de, T>,
24}
25
26unsafe impl<T: Wire> Wire for WireVector<'static, T> {
27 type Decoded<'de> = WireVector<'de, T::Decoded<'de>>;
28
29 #[inline]
30 fn zero_padding(out: &mut MaybeUninit<Self>) {
31 munge!(let Self { raw } = out);
32 RawWireVector::<T>::zero_padding(raw);
33 }
34}
35
36impl<T> Drop for WireVector<'_, T> {
37 fn drop(&mut self) {
38 if needs_drop::<T>() {
39 unsafe {
40 self.raw.as_slice_ptr().drop_in_place();
41 }
42 }
43 }
44}
45
46impl<T> WireVector<'_, T> {
47 pub fn encode_present(out: &mut MaybeUninit<Self>, len: u64) {
49 munge!(let Self { raw } = out);
50 RawWireVector::encode_present(raw, len);
51 }
52
53 pub fn len(&self) -> usize {
55 self.raw.len() as usize
56 }
57
58 pub fn is_empty(&self) -> bool {
60 self.len() == 0
61 }
62
63 fn as_slice_ptr(&self) -> NonNull<[T]> {
65 unsafe { NonNull::new_unchecked(self.raw.as_slice_ptr()) }
66 }
67
68 pub fn as_slice(&self) -> &[T] {
70 unsafe { self.as_slice_ptr().as_ref() }
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 return Err(DecodeError::RequiredValueAbsent);
91 }
92
93 let mut slice = decoder.take_slice_slot::<T>(**len as usize)?;
94 WirePointer::set_decoded(ptr, slice.as_mut_ptr().cast());
95
96 Ok(())
97 }
98}
99
100pub struct IntoIter<'de, T> {
102 current: *mut T,
103 remaining: usize,
104 _phantom: PhantomData<&'de mut [Chunk]>,
105}
106
107impl<T> Drop for IntoIter<'_, T> {
108 fn drop(&mut self) {
109 for i in 0..self.remaining {
110 unsafe {
111 self.current.add(i).drop_in_place();
112 }
113 }
114 }
115}
116
117impl<T> Iterator for IntoIter<'_, T> {
118 type Item = T;
119
120 fn next(&mut self) -> Option<Self::Item> {
121 if self.remaining == 0 {
122 None
123 } else {
124 let result = unsafe { self.current.read() };
125 self.current = unsafe { self.current.add(1) };
126 self.remaining -= 1;
127 Some(result)
128 }
129 }
130}
131
132impl<'de, T> IntoIterator for WireVector<'de, T> {
133 type IntoIter = IntoIter<'de, T>;
134 type Item = T;
135
136 fn into_iter(self) -> Self::IntoIter {
137 let current = self.raw.as_ptr();
138 let remaining = self.len();
139 forget(self);
140
141 IntoIter { current, remaining, _phantom: PhantomData }
142 }
143}
144
145impl<T> Deref for WireVector<'_, T> {
146 type Target = [T];
147
148 fn deref(&self) -> &Self::Target {
149 self.as_slice()
150 }
151}
152
153impl<T: fmt::Debug> fmt::Debug for WireVector<'_, T> {
154 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
155 self.as_slice().fmt(f)
156 }
157}
158
159unsafe impl<D: Decoder + ?Sized, T: Decode<D>> Decode<D> for WireVector<'static, T> {
160 fn decode(mut slot: Slot<'_, Self>, mut decoder: &mut D) -> Result<(), DecodeError> {
161 munge!(let Self { raw: RawWireVector { len, mut ptr } } = slot.as_mut());
162
163 if !WirePointer::is_encoded_present(ptr.as_mut())? {
164 return Err(DecodeError::RequiredValueAbsent);
165 }
166
167 let mut slice = decoder.take_slice_slot::<T>(**len as usize)?;
168 for i in 0..**len as usize {
169 T::decode(slice.index(i), decoder)?;
170 }
171 WirePointer::set_decoded(ptr, slice.as_mut_ptr().cast());
172
173 Ok(())
174 }
175}
176
177#[inline]
178fn encode_to_vector<V, E, T>(
179 value: V,
180 encoder: &mut E,
181 out: &mut MaybeUninit<WireVector<'_, T::Encoded>>,
182) -> Result<(), EncodeError>
183where
184 V: AsRef<[T]> + IntoIterator,
185 V::IntoIter: ExactSizeIterator,
186 V::Item: Encode<E, Encoded = T::Encoded>,
187 E: Encoder + ?Sized,
188 T: Encode<E>,
189{
190 let len = value.as_ref().len();
191 if T::COPY_OPTIMIZATION.is_enabled() {
192 let slice = value.as_ref();
193 let bytes = unsafe { slice::from_raw_parts(slice.as_ptr().cast(), size_of_val(slice)) };
197 encoder.write(bytes);
198 } else {
199 encoder.encode_next_iter(value.into_iter())?;
200 }
201 WireVector::encode_present(out, len as u64);
202 Ok(())
203}
204
205impl<T: Encodable> Encodable for Vec<T> {
206 type Encoded = WireVector<'static, T::Encoded>;
207}
208
209unsafe impl<E, T> Encode<E> for Vec<T>
210where
211 E: Encoder + ?Sized,
212 T: Encode<E>,
213{
214 fn encode(
215 self,
216 encoder: &mut E,
217 out: &mut MaybeUninit<Self::Encoded>,
218 ) -> Result<(), EncodeError> {
219 encode_to_vector(self, encoder, out)
220 }
221}
222
223unsafe impl<E, T> EncodeRef<E> for Vec<T>
224where
225 E: Encoder + ?Sized,
226 T: EncodeRef<E>,
227{
228 fn encode_ref(
229 &self,
230 encoder: &mut E,
231 out: &mut MaybeUninit<Self::Encoded>,
232 ) -> Result<(), EncodeError> {
233 encode_to_vector(self, encoder, out)
234 }
235}
236
237impl<T: Encodable> Encodable for &[T] {
238 type Encoded = WireVector<'static, T::Encoded>;
239}
240
241unsafe impl<E, T> Encode<E> for &[T]
242where
243 E: Encoder + ?Sized,
244 T: EncodeRef<E>,
245{
246 fn encode(
247 self,
248 encoder: &mut E,
249 out: &mut MaybeUninit<Self::Encoded>,
250 ) -> Result<(), EncodeError> {
251 encode_to_vector(self, encoder, out)
252 }
253}
254
255impl<T: FromWire<W>, W> FromWire<WireVector<'_, W>> for Vec<T> {
256 fn from_wire(wire: WireVector<'_, W>) -> Self {
257 let mut result = Vec::<T>::with_capacity(wire.len());
258 if T::COPY_OPTIMIZATION.is_enabled() {
259 unsafe {
260 copy_nonoverlapping(wire.as_ptr().cast(), result.as_mut_ptr(), wire.len());
261 }
262 unsafe {
263 result.set_len(wire.len());
264 }
265 forget(wire);
266 } else {
267 for item in wire.into_iter() {
268 result.push(T::from_wire(item));
269 }
270 }
271 result
272 }
273}
274
275impl<T: IntoNatural> IntoNatural for WireVector<'_, T> {
276 type Natural = Vec<T::Natural>;
277}
278
279impl<T: FromWireRef<W>, W> FromWireRef<WireVector<'_, W>> for Vec<T> {
280 fn from_wire_ref(wire: &WireVector<'_, W>) -> Self {
281 let mut result = Vec::<T>::with_capacity(wire.len());
282 if T::COPY_OPTIMIZATION.is_enabled() {
283 unsafe {
284 copy_nonoverlapping(wire.as_ptr().cast(), result.as_mut_ptr(), wire.len());
285 }
286 unsafe {
287 result.set_len(wire.len());
288 }
289 } else {
290 for item in wire.iter() {
291 result.push(T::from_wire_ref(item));
292 }
293 }
294 result
295 }
296}