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}