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, Encoder,
15 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 slice = decoder.decode_next_slice::<T>(**len as usize)?;
119 WirePointer::set_decoded(ptr, slice.into_raw().cast());
120
121 Ok(())
122 }
123}
124
125impl<T: Encodable> Encodable for Vec<T> {
126 type Encoded = WireVector<T::Encoded>;
127}
128
129unsafe impl<E: Encoder + ?Sized, T: Encode<E>> Encode<E> for Vec<T> {
130 fn encode(
131 &mut self,
132 encoder: &mut E,
133 out: &mut MaybeUninit<Self::Encoded>,
134 ) -> Result<(), EncodeError> {
135 if T::COPY_OPTIMIZATION.is_enabled() {
136 let bytes =
137 unsafe { slice::from_raw_parts(self.as_ptr().cast(), self.len() * size_of::<T>()) };
138 encoder.write(bytes);
139 } else {
140 encoder.encode_next_slice(self.as_mut_slice())?;
141 }
142 WireVector::encode_present(out, self.len() as u64);
143 Ok(())
144 }
145}
146
147impl<T: TakeFrom<WT>, WT> TakeFrom<WireVector<WT>> for Vec<T> {
148 fn take_from(from: &WireVector<WT>) -> Self {
149 let mut result = Vec::<T>::with_capacity(from.len());
150 if T::COPY_OPTIMIZATION.is_enabled() {
151 unsafe {
152 copy_nonoverlapping(from.as_ptr().cast(), result.as_mut_ptr(), from.len());
153 }
154 unsafe {
155 result.set_len(from.len());
156 }
157 } else {
158 for item in from.as_slice() {
159 result.push(T::take_from(item));
160 }
161 }
162 result
163 }
164}