rkyv/impls/alloc/
vec.rs

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