rkyv/impls/alloc/collections/
vec_deque.rs

1use core::cmp::Ordering;
2
3use rancor::{Fallible, ResultExt, Source};
4
5use crate::{
6    alloc::{alloc::alloc, boxed::Box, collections::VecDeque, vec::Vec},
7    ser::{Allocator, Writer},
8    traits::LayoutRaw,
9    vec::{ArchivedVec, VecResolver},
10    Archive, Deserialize, DeserializeUnsized, Place, Serialize,
11};
12
13impl<T: Archive> Archive for VecDeque<T> {
14    type Archived = ArchivedVec<T::Archived>;
15    type Resolver = VecResolver;
16
17    fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>) {
18        ArchivedVec::resolve_from_len(self.len(), resolver, out);
19    }
20}
21
22impl<T, S> Serialize<S> for VecDeque<T>
23where
24    T: Serialize<S>,
25    S: Fallible + Allocator + Writer + ?Sized,
26{
27    fn serialize(
28        &self,
29        serializer: &mut S,
30    ) -> Result<Self::Resolver, S::Error> {
31        let (a, b) = self.as_slices();
32        if b.is_empty() {
33            ArchivedVec::<T::Archived>::serialize_from_slice(a, serializer)
34        } else if a.is_empty() {
35            ArchivedVec::<T::Archived>::serialize_from_slice(b, serializer)
36        } else {
37            ArchivedVec::<T::Archived>::serialize_from_iter::<T, _, _>(
38                self.iter(),
39                serializer,
40            )
41        }
42    }
43}
44
45impl<T, D> Deserialize<VecDeque<T>, D> for ArchivedVec<T::Archived>
46where
47    T: Archive,
48    [T::Archived]: DeserializeUnsized<[T], D>,
49    D: Fallible + ?Sized,
50    D::Error: Source,
51{
52    fn deserialize(
53        &self,
54        deserializer: &mut D,
55    ) -> Result<VecDeque<T>, D::Error> {
56        let metadata = self.as_slice().deserialize_metadata();
57        let layout = <[T] as LayoutRaw>::layout_raw(metadata).into_error()?;
58        let data_address = if layout.size() > 0 {
59            unsafe { alloc(layout) }
60        } else {
61            crate::polyfill::dangling(&layout).as_ptr()
62        };
63        let out = ptr_meta::from_raw_parts_mut(data_address.cast(), metadata);
64        unsafe {
65            self.as_slice().deserialize_unsized(deserializer, out)?;
66        }
67        let boxed = unsafe { Box::<[T]>::from_raw(out) };
68        Ok(VecDeque::from(Vec::from(boxed)))
69    }
70}
71
72impl<T: PartialEq<U>, U> PartialEq<VecDeque<U>> for ArchivedVec<T> {
73    fn eq(&self, other: &VecDeque<U>) -> bool {
74        self.len() == other.len() && self.iter().eq(other.iter())
75    }
76}
77
78impl<T: PartialOrd> PartialOrd<VecDeque<T>> for ArchivedVec<T> {
79    fn partial_cmp(&self, other: &VecDeque<T>) -> Option<Ordering> {
80        self.iter().partial_cmp(other.iter())
81    }
82}
83
84#[cfg(test)]
85mod tests {
86    use crate::{
87        access_unchecked, alloc::collections::VecDeque, api::test::deserialize,
88        rancor::Error, to_bytes, vec::ArchivedVec, Archived,
89    };
90
91    #[test]
92    fn vecdeque() {
93        for n in 2..10 {
94            for k in 1..n {
95                let mut deque = VecDeque::with_capacity(n as usize + 1);
96                for x in k..n {
97                    deque.push_back(x);
98                }
99                for x in (0..k).rev() {
100                    deque.push_front(x);
101                }
102                assert!(deque.iter().copied().eq(0..n));
103
104                // Now serialize and deserialize and verify that the
105                // deserialized version contains `0..n`.
106                let bytes = to_bytes::<Error>(&deque).unwrap();
107                let archived = unsafe {
108                    access_unchecked::<ArchivedVec<Archived<i32>>>(&bytes)
109                };
110                assert!(archived.iter().copied().eq(0..n));
111
112                let deserialized = deserialize::<VecDeque<i32>>(archived);
113                assert_eq!(deque, deserialized);
114            }
115        }
116    }
117}