fidl_next_codec/wire/vec/
required.rs1use core::mem::{needs_drop, MaybeUninit};
6use core::ops::Deref;
7use core::ptr::{copy_nonoverlapping, NonNull};
8use core::{fmt, slice};
9
10use munge::munge;
11
12use super::raw::RawWireVector;
13use crate::{
14 Decode, DecodeError, Decoder, DecoderExt as _, Encodable, Encode, EncodeError, EncodeRef,
15 Encoder, EncoderExt as _, Slot, TakeFrom, WirePointer, ZeroPadding,
16};
17
18#[repr(transparent)]
20pub struct WireVector<T> {
21 raw: RawWireVector<T>,
22}
23
24unsafe impl<T> ZeroPadding for WireVector<T> {
25 #[inline]
26 fn zero_padding(out: &mut MaybeUninit<Self>) {
27 munge!(let Self { raw } = out);
28 RawWireVector::<T>::zero_padding(raw);
29 }
30}
31
32impl<T> Drop for WireVector<T> {
33 fn drop(&mut self) {
34 if needs_drop::<T>() {
35 unsafe {
36 self.raw.as_slice_ptr().drop_in_place();
37 }
38 }
39 }
40}
41
42impl<T> WireVector<T> {
43 pub fn encode_present(out: &mut MaybeUninit<Self>, len: u64) {
45 munge!(let Self { raw } = out);
46 RawWireVector::encode_present(raw, len);
47 }
48
49 pub fn len(&self) -> usize {
51 self.raw.len() as usize
52 }
53
54 pub fn is_empty(&self) -> bool {
56 self.len() == 0
57 }
58
59 fn as_slice_ptr(&self) -> NonNull<[T]> {
61 unsafe { NonNull::new_unchecked(self.raw.as_slice_ptr()) }
62 }
63
64 pub fn as_slice(&self) -> &[T] {
66 unsafe { self.as_slice_ptr().as_ref() }
67 }
68
69 pub unsafe fn decode_raw<D>(
76 mut slot: Slot<'_, Self>,
77 mut decoder: &mut D,
78 ) -> Result<(), DecodeError>
79 where
80 D: Decoder + ?Sized,
81 T: Decode<D>,
82 {
83 munge!(let Self { raw: RawWireVector { len, mut ptr } } = slot.as_mut());
84
85 if !WirePointer::is_encoded_present(ptr.as_mut())? {
86 return Err(DecodeError::RequiredValueAbsent);
87 }
88
89 let mut slice = decoder.take_slice_slot::<T>(**len as usize)?;
90 WirePointer::set_decoded(ptr, slice.as_mut_ptr().cast());
91
92 Ok(())
93 }
94}
95
96impl<T> Deref for WireVector<T> {
97 type Target = [T];
98
99 fn deref(&self) -> &Self::Target {
100 self.as_slice()
101 }
102}
103
104impl<T: fmt::Debug> fmt::Debug for WireVector<T> {
105 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106 self.as_slice().fmt(f)
107 }
108}
109
110unsafe impl<D: Decoder + ?Sized, T: Decode<D>> Decode<D> for WireVector<T> {
111 fn decode(mut slot: Slot<'_, Self>, mut decoder: &mut D) -> Result<(), DecodeError> {
112 munge!(let Self { raw: RawWireVector { len, mut ptr } } = slot.as_mut());
113
114 if !WirePointer::is_encoded_present(ptr.as_mut())? {
115 return Err(DecodeError::RequiredValueAbsent);
116 }
117
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
124 Ok(())
125 }
126}
127
128#[inline]
129fn encode_to_vector<V, E, T>(
130 value: V,
131 encoder: &mut E,
132 out: &mut MaybeUninit<WireVector<T::Encoded>>,
133) -> Result<(), EncodeError>
134where
135 V: AsRef<[T]> + IntoIterator,
136 V::IntoIter: ExactSizeIterator,
137 V::Item: Encode<E, Encoded = T::Encoded>,
138 E: Encoder + ?Sized,
139 T: Encode<E>,
140{
141 let len = value.as_ref().len();
142 if T::COPY_OPTIMIZATION.is_enabled() {
143 let slice = value.as_ref();
144 let bytes = unsafe { slice::from_raw_parts(slice.as_ptr().cast(), size_of_val(slice)) };
148 encoder.write(bytes);
149 } else {
150 encoder.encode_next_iter(value.into_iter())?;
151 }
152 WireVector::encode_present(out, len as u64);
153 Ok(())
154}
155
156impl<T: Encodable> Encodable for Vec<T> {
157 type Encoded = WireVector<T::Encoded>;
158}
159
160unsafe impl<E: Encoder + ?Sized, T: Encode<E>> Encode<E> for Vec<T> {
161 fn encode(
162 self,
163 encoder: &mut E,
164 out: &mut MaybeUninit<Self::Encoded>,
165 ) -> Result<(), EncodeError> {
166 encode_to_vector(self, encoder, out)
167 }
168}
169
170unsafe impl<E: Encoder + ?Sized, T: EncodeRef<E>> EncodeRef<E> for Vec<T> {
171 fn encode_ref(
172 &self,
173 encoder: &mut E,
174 out: &mut MaybeUninit<Self::Encoded>,
175 ) -> Result<(), EncodeError> {
176 encode_to_vector(self, encoder, out)
177 }
178}
179
180impl<T: Encodable> Encodable for &[T] {
181 type Encoded = WireVector<T::Encoded>;
182}
183
184unsafe impl<E: Encoder + ?Sized, T: EncodeRef<E>> Encode<E> for &[T] {
185 fn encode(
186 self,
187 encoder: &mut E,
188 out: &mut MaybeUninit<Self::Encoded>,
189 ) -> Result<(), EncodeError> {
190 encode_to_vector(self, encoder, out)
191 }
192}
193
194impl<T: TakeFrom<WT>, WT> TakeFrom<WireVector<WT>> for Vec<T> {
195 fn take_from(from: &WireVector<WT>) -> Self {
196 let mut result = Vec::<T>::with_capacity(from.len());
197 if T::COPY_OPTIMIZATION.is_enabled() {
198 unsafe {
199 copy_nonoverlapping(from.as_ptr().cast(), result.as_mut_ptr(), from.len());
200 }
201 unsafe {
202 result.set_len(from.len());
203 }
204 } else {
205 for item in from.as_slice() {
206 result.push(T::take_from(item));
207 }
208 }
209 result
210 }
211}