fidl_next_codec/wire/vec/
optional.rs
1use core::mem::needs_drop;
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, Encoder, EncoderExt as _, Slot, TakeFrom, WirePointer, WireVector, ZeroPadding,
14};
15
16#[repr(transparent)]
18pub struct WireOptionalVector<T> {
19 raw: RawWireVector<T>,
20}
21
22unsafe impl<T> ZeroPadding for WireOptionalVector<T> {
23 #[inline]
24 unsafe fn zero_padding(ptr: *mut Self) {
25 unsafe {
26 RawWireVector::<T>::zero_padding(ptr.cast());
27 }
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(slot: Slot<'_, Self>, len: u64) {
44 munge!(let Self { raw } = slot);
45 RawWireVector::encode_present(raw, len);
46 }
47
48 pub fn encode_absent(slot: Slot<'_, Self>) {
50 munge!(let Self { raw } = slot);
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 slice = decoder.decode_next_slice::<T>(**len as usize)?;
112 WirePointer::set_decoded(ptr, slice.into_raw().cast());
113 } else if *len != 0 {
114 return Err(DecodeError::InvalidOptionalSize(**len));
115 }
116
117 Ok(())
118 }
119}
120
121impl<T: Encodable> EncodableOption for Vec<T> {
122 type EncodedOption = WireOptionalVector<T::Encoded>;
123}
124
125impl<E: Encoder + ?Sized, T: Encode<E>> EncodeOption<E> for Vec<T> {
126 fn encode_option(
127 this: Option<&mut Self>,
128 encoder: &mut E,
129 slot: Slot<'_, Self::EncodedOption>,
130 ) -> Result<(), EncodeError> {
131 if let Some(vec) = this {
132 if T::COPY_OPTIMIZATION.is_enabled() {
133 let bytes = unsafe {
134 slice::from_raw_parts(vec.as_ptr().cast(), vec.len() * size_of::<T>())
135 };
136 encoder.write(bytes);
137 } else {
138 encoder.encode_next_slice(vec.as_mut_slice())?;
139 }
140 WireOptionalVector::encode_present(slot, vec.len() as u64);
141 } else {
142 WireOptionalVector::encode_absent(slot);
143 }
144
145 Ok(())
146 }
147}
148
149impl<T: TakeFrom<WT>, WT> TakeFrom<WireOptionalVector<WT>> for Option<Vec<T>> {
150 fn take_from(from: &WireOptionalVector<WT>) -> Self {
151 from.as_ref().map(Vec::take_from)
152 }
153}