rkyv/
vec.rs

1//! An archived version of `Vec`.
2
3use core::{
4    borrow::Borrow,
5    cmp, fmt, hash,
6    ops::{Deref, Index},
7    slice::SliceIndex,
8};
9
10use munge::munge;
11use rancor::Fallible;
12
13use crate::{
14    primitive::{ArchivedUsize, FixedUsize},
15    seal::Seal,
16    ser::{Allocator, Writer, WriterExt as _},
17    Archive, Place, Portable, RelPtr, Serialize, SerializeUnsized,
18};
19
20/// An archived [`Vec`].
21///
22/// This uses a [`RelPtr`] to a `[T]` under the hood. Unlike
23/// [`ArchivedString`](crate::string::ArchivedString), it does not have an
24/// inline representation.
25#[derive(Portable)]
26#[cfg_attr(
27    feature = "bytecheck",
28    derive(bytecheck::CheckBytes),
29    bytecheck(verify)
30)]
31#[rkyv(crate)]
32#[repr(C)]
33pub struct ArchivedVec<T> {
34    ptr: RelPtr<T>,
35    len: ArchivedUsize,
36}
37
38impl<T> ArchivedVec<T> {
39    /// Returns a pointer to the first element of the archived vec.
40    pub fn as_ptr(&self) -> *const T {
41        unsafe { self.ptr.as_ptr() }
42    }
43
44    /// Returns the number of elements in the archived vec.
45    pub fn len(&self) -> usize {
46        self.len.to_native() as usize
47    }
48
49    /// Returns whether the archived vec is empty.
50    pub fn is_empty(&self) -> bool {
51        self.len() == 0
52    }
53
54    /// Gets the elements of the archived vec as a slice.
55    pub fn as_slice(&self) -> &[T] {
56        unsafe { core::slice::from_raw_parts(self.as_ptr(), self.len()) }
57    }
58
59    /// Gets the elements of the archived vec as a sealed mutable slice.
60    pub fn as_slice_seal(this: Seal<'_, Self>) -> Seal<'_, [T]> {
61        let len = this.len();
62        munge!(let Self { ptr, .. } = this);
63        let slice = unsafe {
64            core::slice::from_raw_parts_mut(RelPtr::as_mut_ptr(ptr), len)
65        };
66        Seal::new(slice)
67    }
68
69    /// Resolves an archived `Vec` from a given slice.
70    pub fn resolve_from_slice<U: Archive<Archived = T>>(
71        slice: &[U],
72        resolver: VecResolver,
73        out: Place<Self>,
74    ) {
75        Self::resolve_from_len(slice.len(), resolver, out);
76    }
77
78    /// Resolves an archived `Vec` from a given length.
79    pub fn resolve_from_len(
80        len: usize,
81        resolver: VecResolver,
82        out: Place<Self>,
83    ) {
84        munge!(let ArchivedVec { ptr, len: out_len } = out);
85        RelPtr::emplace(resolver.pos as usize, ptr);
86        usize::resolve(&len, (), out_len);
87    }
88
89    /// Serializes an archived `Vec` from a given slice.
90    pub fn serialize_from_slice<
91        U: Serialize<S, Archived = T>,
92        S: Fallible + Allocator + Writer + ?Sized,
93    >(
94        slice: &[U],
95        serializer: &mut S,
96    ) -> Result<VecResolver, S::Error> {
97        Ok(VecResolver {
98            pos: slice.serialize_unsized(serializer)? as FixedUsize,
99        })
100    }
101
102    /// Serializes an archived `Vec` from a given iterator.
103    ///
104    /// This method is unable to perform copy optimizations; prefer
105    /// [`serialize_from_slice`](ArchivedVec::serialize_from_slice) when
106    /// possible.
107    pub fn serialize_from_iter<U, I, S>(
108        iter: I,
109        serializer: &mut S,
110    ) -> Result<VecResolver, S::Error>
111    where
112        U: Serialize<S, Archived = T>,
113        I: ExactSizeIterator + Clone,
114        I::Item: Borrow<U>,
115        S: Fallible + Allocator + Writer + ?Sized,
116    {
117        use crate::util::SerVec;
118
119        SerVec::with_capacity(
120            serializer,
121            iter.len(),
122            |resolvers, serializer| {
123                for value in iter.clone() {
124                    let resolver = value.borrow().serialize(serializer)?;
125                    resolvers.push(resolver);
126                }
127
128                let pos = serializer.align_for::<T>()?;
129                for (value, resolver) in iter.zip(resolvers.drain()) {
130                    unsafe {
131                        serializer.resolve_aligned(value.borrow(), resolver)?;
132                    }
133                }
134
135                Ok(VecResolver {
136                    pos: pos as FixedUsize,
137                })
138            },
139        )?
140    }
141
142    /// Serializes an archived `Vec` from a given iterator. Compared to
143    /// `serialize_from_iter()`, this function:
144    /// - supports iterators whose length is not known in advance, and
145    /// - does not collect the data in memory before serializing.
146    ///
147    /// This method will panic if any item writes during `serialize` (i.e no
148    /// additional data written per item).
149    pub fn serialize_from_unknown_length_iter<B, I, S>(
150        iter: &mut I,
151        serializer: &mut S,
152    ) -> Result<VecResolver, S::Error>
153    where
154        B: Serialize<S, Archived = T>,
155        I: Iterator<Item = B>,
156        S: Fallible + Allocator + Writer + ?Sized,
157    {
158        unsafe {
159            let pos = serializer.align_for::<T>()?;
160
161            for value in iter {
162                let pos_cached = serializer.pos();
163                let resolver = value.serialize(serializer)?;
164                assert!(serializer.pos() == pos_cached);
165                serializer.resolve_aligned(value.borrow(), resolver)?;
166            }
167
168            Ok(VecResolver {
169                pos: pos as FixedUsize,
170            })
171        }
172    }
173}
174
175impl<T> AsRef<[T]> for ArchivedVec<T> {
176    fn as_ref(&self) -> &[T] {
177        self.as_slice()
178    }
179}
180
181impl<T> Borrow<[T]> for ArchivedVec<T> {
182    fn borrow(&self) -> &[T] {
183        self.as_slice()
184    }
185}
186
187impl<T: fmt::Debug> fmt::Debug for ArchivedVec<T> {
188    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
189        f.debug_list().entries(self.as_slice()).finish()
190    }
191}
192
193impl<T> Deref for ArchivedVec<T> {
194    type Target = [T];
195
196    fn deref(&self) -> &Self::Target {
197        self.as_slice()
198    }
199}
200
201impl<T: Eq> Eq for ArchivedVec<T> {}
202
203impl<T: hash::Hash> hash::Hash for ArchivedVec<T> {
204    fn hash<H: hash::Hasher>(&self, state: &mut H) {
205        self.as_slice().hash(state)
206    }
207}
208
209impl<T, I: SliceIndex<[T]>> Index<I> for ArchivedVec<T> {
210    type Output = <[T] as Index<I>>::Output;
211
212    fn index(&self, index: I) -> &Self::Output {
213        self.as_slice().index(index)
214    }
215}
216
217impl<T: Ord> Ord for ArchivedVec<T> {
218    fn cmp(&self, other: &Self) -> cmp::Ordering {
219        self.as_slice().cmp(other.as_slice())
220    }
221}
222
223impl<T: PartialEq<U>, U> PartialEq<ArchivedVec<U>> for ArchivedVec<T> {
224    fn eq(&self, other: &ArchivedVec<U>) -> bool {
225        self.as_slice().eq(other.as_slice())
226    }
227}
228
229impl<T: PartialEq<U>, U, const N: usize> PartialEq<[U; N]> for ArchivedVec<T> {
230    fn eq(&self, other: &[U; N]) -> bool {
231        self.as_slice().eq(&other[..])
232    }
233}
234
235impl<T: PartialEq<U>, U, const N: usize> PartialEq<ArchivedVec<T>> for [U; N] {
236    fn eq(&self, other: &ArchivedVec<T>) -> bool {
237        other.eq(self)
238    }
239}
240
241impl<T: PartialEq<U>, U> PartialEq<[U]> for ArchivedVec<T> {
242    fn eq(&self, other: &[U]) -> bool {
243        self.as_slice().eq(other)
244    }
245}
246
247impl<T: PartialEq<U>, U> PartialEq<ArchivedVec<U>> for [T] {
248    fn eq(&self, other: &ArchivedVec<U>) -> bool {
249        self.eq(other.as_slice())
250    }
251}
252
253impl<T: PartialOrd> PartialOrd<ArchivedVec<T>> for ArchivedVec<T> {
254    fn partial_cmp(&self, other: &ArchivedVec<T>) -> Option<cmp::Ordering> {
255        self.as_slice().partial_cmp(other.as_slice())
256    }
257}
258
259impl<T: PartialOrd> PartialOrd<[T]> for ArchivedVec<T> {
260    fn partial_cmp(&self, other: &[T]) -> Option<cmp::Ordering> {
261        self.as_slice().partial_cmp(other)
262    }
263}
264
265impl<T: PartialOrd> PartialOrd<ArchivedVec<T>> for [T] {
266    fn partial_cmp(&self, other: &ArchivedVec<T>) -> Option<cmp::Ordering> {
267        self.partial_cmp(other.as_slice())
268    }
269}
270
271/// The resolver for [`ArchivedVec`].
272pub struct VecResolver {
273    pos: FixedUsize,
274}
275
276impl VecResolver {
277    /// Creates a new `VecResolver` from a position in the output buffer where
278    /// the elements of the archived vector are stored.
279    pub fn from_pos(pos: usize) -> Self {
280        Self {
281            pos: pos as FixedUsize,
282        }
283    }
284}
285
286#[cfg(feature = "bytecheck")]
287mod verify {
288    use bytecheck::{
289        rancor::{Fallible, Source},
290        CheckBytes, Verify,
291    };
292
293    use crate::{
294        validation::{ArchiveContext, ArchiveContextExt},
295        vec::ArchivedVec,
296    };
297
298    unsafe impl<T, C> Verify<C> for ArchivedVec<T>
299    where
300        T: CheckBytes<C>,
301        C: Fallible + ArchiveContext + ?Sized,
302        C::Error: Source,
303    {
304        fn verify(&self, context: &mut C) -> Result<(), C::Error> {
305            let ptr = core::ptr::slice_from_raw_parts(
306                self.ptr.as_ptr_wrapping(),
307                self.len.to_native() as usize,
308            );
309
310            context.in_subtree(ptr, |context| unsafe {
311                <[T]>::check_bytes(ptr, context)
312            })
313        }
314    }
315}