fidl_next_codec/wire/vec/
required.rs

1// Copyright 2024 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use 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/// A FIDL vector
19#[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    /// Encodes that a vector is present in a slot.
45    pub fn encode_present(slot: Slot<'_, Self>, len: u64) {
46        munge!(let Self { raw } = slot);
47        RawWireVector::encode_present(raw, len);
48    }
49
50    /// Returns the length of the vector in elements.
51    pub fn len(&self) -> usize {
52        self.raw.len() as usize
53    }
54
55    /// Returns whether the vector is empty.
56    pub fn is_empty(&self) -> bool {
57        self.len() == 0
58    }
59
60    /// Returns a pointer to the elements of the vector.
61    fn as_slice_ptr(&self) -> NonNull<[T]> {
62        unsafe { NonNull::new_unchecked(self.raw.as_slice_ptr()) }
63    }
64
65    /// Returns a slice of the elements of the vector.
66    pub fn as_slice(&self) -> &[T] {
67        unsafe { self.as_slice_ptr().as_ref() }
68    }
69
70    /// Decodes a wire vector which contains raw data.
71    ///
72    /// # Safety
73    ///
74    /// The elements of the wire vecot rmust not need to be individually decoded, and must always be
75    /// valid.
76    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}