rkyv/impls/alloc/
vec.rs

1use rancor::{Fallible, ResultExt as _, Source};
2
3use crate::{
4    alloc::{alloc::alloc, boxed::Box, vec::Vec},
5    ser::{Allocator, Writer},
6    traits::LayoutRaw,
7    vec::{ArchivedVec, VecResolver},
8    Archive, Deserialize, DeserializeUnsized, Place, Serialize,
9};
10
11impl<T: Archive> Archive for Vec<T> {
12    type Archived = ArchivedVec<T::Archived>;
13    type Resolver = VecResolver;
14
15    fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>) {
16        ArchivedVec::resolve_from_slice(self.as_slice(), resolver, out);
17    }
18}
19
20impl<T: Serialize<S>, S: Fallible + Allocator + Writer + ?Sized> Serialize<S>
21    for Vec<T>
22{
23    fn serialize(
24        &self,
25        serializer: &mut S,
26    ) -> Result<Self::Resolver, S::Error> {
27        ArchivedVec::<T::Archived>::serialize_from_slice(
28            self.as_slice(),
29            serializer,
30        )
31    }
32}
33
34impl<T, D> Deserialize<Vec<T>, D> for ArchivedVec<T::Archived>
35where
36    T: Archive,
37    [T::Archived]: DeserializeUnsized<[T], D>,
38    D: Fallible + ?Sized,
39    D::Error: Source,
40{
41    fn deserialize(&self, deserializer: &mut D) -> Result<Vec<T>, D::Error> {
42        let metadata = self.as_slice().deserialize_metadata();
43        let layout = <[T] as LayoutRaw>::layout_raw(metadata).into_error()?;
44        let data_address = if layout.size() > 0 {
45            unsafe { alloc(layout) }
46        } else {
47            crate::polyfill::dangling(&layout).as_ptr()
48        };
49        let out = ptr_meta::from_raw_parts_mut(data_address.cast(), metadata);
50        unsafe {
51            self.as_slice().deserialize_unsized(deserializer, out)?;
52        }
53        unsafe { Ok(Box::<[T]>::from_raw(out).into()) }
54    }
55}
56
57impl<T: PartialEq<U>, U> PartialEq<Vec<U>> for ArchivedVec<T> {
58    fn eq(&self, other: &Vec<U>) -> bool {
59        self.as_slice().eq(other.as_slice())
60    }
61}
62
63impl<T: PartialOrd<U>, U> PartialOrd<Vec<U>> for ArchivedVec<T> {
64    fn partial_cmp(&self, other: &Vec<U>) -> Option<::core::cmp::Ordering> {
65        crate::impls::lexicographical_partial_ord(
66            self.as_slice(),
67            other.as_slice(),
68        )
69    }
70}
71
72#[cfg(test)]
73mod tests {
74    use crate::{
75        alloc::{vec, vec::Vec},
76        api::test::roundtrip,
77    };
78
79    #[test]
80    fn roundtrip_vec() {
81        roundtrip(&Vec::<i32>::new());
82        roundtrip(&vec![1, 2, 3, 4]);
83    }
84
85    #[test]
86    fn roundtrip_vec_zst() {
87        roundtrip(&Vec::<()>::new());
88        roundtrip(&vec![(), (), (), ()]);
89    }
90
91    #[test]
92    fn roundtrip_option_vec() {
93        roundtrip(&Some(Vec::<i32>::new()));
94        roundtrip(&Some(vec![1, 2, 3, 4]));
95    }
96
97    #[test]
98    fn roundtrip_result_vec() {
99        roundtrip(&Ok::<_, ()>(Vec::<i32>::new()));
100        roundtrip(&Ok::<_, ()>(vec![1, 2, 3, 4]));
101
102        roundtrip(&Err::<(), _>(Vec::<i32>::new()));
103        roundtrip(&Err::<(), _>(vec![1, 2, 3, 4]));
104    }
105}