fidl_next_codec/wire/vec/
required.rs
1use core::mem::needs_drop;
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 unsafe fn zero_padding(ptr: *mut Self) {
27 unsafe {
28 RawWireVector::<T>::zero_padding(ptr.cast());
29 }
30 }
31}
32
33impl<T> Drop for WireVector<T> {
34 fn drop(&mut self) {
35 if needs_drop::<T>() {
36 unsafe {
37 self.raw.as_slice_ptr().drop_in_place();
38 }
39 }
40 }
41}
42
43impl<T> WireVector<T> {
44 pub fn encode_present(slot: Slot<'_, Self>, len: u64) {
46 munge!(let Self { raw } = slot);
47 RawWireVector::encode_present(raw, len);
48 }
49
50 pub fn len(&self) -> usize {
52 self.raw.len() as usize
53 }
54
55 pub fn is_empty(&self) -> bool {
57 self.len() == 0
58 }
59
60 fn as_slice_ptr(&self) -> NonNull<[T]> {
62 unsafe { NonNull::new_unchecked(self.raw.as_slice_ptr()) }
63 }
64
65 pub fn as_slice(&self) -> &[T] {
67 unsafe { self.as_slice_ptr().as_ref() }
68 }
69
70 pub unsafe fn decode_raw<D>(
77 mut slot: Slot<'_, Self>,
78 mut decoder: &mut D,
79 ) -> Result<(), DecodeError>
80 where
81 D: Decoder + ?Sized,
82 T: Decode<D>,
83 {
84 munge!(let Self { raw: RawWireVector { len, mut ptr } } = slot.as_mut());
85
86 if !WirePointer::is_encoded_present(ptr.as_mut())? {
87 return Err(DecodeError::RequiredValueAbsent);
88 }
89
90 let mut slice = decoder.take_slice_slot::<T>(**len as usize)?;
91 WirePointer::set_decoded(ptr, slice.as_mut_ptr().cast());
92
93 Ok(())
94 }
95}
96
97impl<T> Deref for WireVector<T> {
98 type Target = [T];
99
100 fn deref(&self) -> &Self::Target {
101 self.as_slice()
102 }
103}
104
105impl<T: fmt::Debug> fmt::Debug for WireVector<T> {
106 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107 self.as_slice().fmt(f)
108 }
109}
110
111unsafe impl<D: Decoder + ?Sized, T: Decode<D>> Decode<D> for WireVector<T> {
112 fn decode(mut slot: Slot<'_, Self>, mut decoder: &mut D) -> Result<(), DecodeError> {
113 munge!(let Self { raw: RawWireVector { len, mut ptr } } = slot.as_mut());
114
115 if !WirePointer::is_encoded_present(ptr.as_mut())? {
116 return Err(DecodeError::RequiredValueAbsent);
117 }
118
119 let slice = decoder.decode_next_slice::<T>(**len as usize)?;
120 WirePointer::set_decoded(ptr, slice.into_raw().cast());
121
122 Ok(())
123 }
124}
125
126impl<T: Encodable> Encodable for Vec<T> {
127 type Encoded = WireVector<T::Encoded>;
128}
129
130impl<E: Encoder + ?Sized, T: Encode<E>> Encode<E> for Vec<T> {
131 fn encode(
132 &mut self,
133 encoder: &mut E,
134 slot: Slot<'_, Self::Encoded>,
135 ) -> Result<(), EncodeError> {
136 if T::COPY_OPTIMIZATION.is_enabled() {
137 let bytes =
138 unsafe { slice::from_raw_parts(self.as_ptr().cast(), self.len() * size_of::<T>()) };
139 encoder.write(bytes);
140 } else {
141 encoder.encode_next_slice(self.as_mut_slice())?;
142 }
143 WireVector::encode_present(slot, self.len() as u64);
144 Ok(())
145 }
146}
147
148impl<T: TakeFrom<WT>, WT> TakeFrom<WireVector<WT>> for Vec<T> {
149 fn take_from(from: &WireVector<WT>) -> Self {
150 let mut result = Vec::<T>::with_capacity(from.len());
151 if T::COPY_OPTIMIZATION.is_enabled() {
152 unsafe {
153 copy_nonoverlapping(from.as_ptr().cast(), result.as_mut_ptr(), from.len());
154 }
155 unsafe {
156 result.set_len(from.len());
157 }
158 } else {
159 for item in from.as_slice() {
160 result.push(T::take_from(item));
161 }
162 }
163 result
164 }
165}