rkyv_test/impls/alloc/
rc.rs

1use crate::{
2    de::{SharedDeserializeRegistry, SharedPointer},
3    rc::{ArchivedRc, ArchivedRcWeak, RcResolver, RcWeakResolver},
4    ser::{Serializer, SharedSerializeRegistry},
5    Archive, ArchivePointee, ArchiveUnsized, Deserialize, DeserializeUnsized, Serialize,
6    SerializeUnsized,
7};
8#[cfg(all(not(feature = "std"), has_atomics))]
9use ::alloc::sync;
10#[cfg(not(feature = "std"))]
11use ::alloc::{alloc, boxed::Box, rc};
12use ::core::mem::forget;
13#[cfg(all(feature = "std", has_atomics))]
14use ::std::sync;
15#[cfg(feature = "std")]
16use ::std::{alloc, rc};
17
18// Rc
19
20/// The flavor type for `Rc`.
21pub struct RcFlavor;
22
23impl<T: ?Sized> SharedPointer for rc::Rc<T> {
24    #[inline]
25    fn data_address(&self) -> *const () {
26        rc::Rc::as_ptr(self) as *const ()
27    }
28}
29
30impl<T: ArchiveUnsized + ?Sized> Archive for rc::Rc<T> {
31    type Archived = ArchivedRc<T::Archived, RcFlavor>;
32    type Resolver = RcResolver<T::MetadataResolver>;
33
34    #[inline]
35    unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) {
36        ArchivedRc::resolve_from_ref(self.as_ref(), pos, resolver, out);
37    }
38}
39
40impl<T, S> Serialize<S> for rc::Rc<T>
41where
42    T: SerializeUnsized<S> + ?Sized + 'static,
43    S: Serializer + SharedSerializeRegistry + ?Sized,
44{
45    #[inline]
46    fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
47        ArchivedRc::<T::Archived, RcFlavor>::serialize_from_ref(self.as_ref(), serializer)
48    }
49}
50
51impl<T, D> Deserialize<rc::Rc<T>, D> for ArchivedRc<T::Archived, RcFlavor>
52where
53    T: ArchiveUnsized + ?Sized + 'static,
54    T::Archived: DeserializeUnsized<T, D>,
55    D: SharedDeserializeRegistry + ?Sized,
56{
57    #[inline]
58    fn deserialize(&self, deserializer: &mut D) -> Result<rc::Rc<T>, D::Error> {
59        let raw_shared_ptr = deserializer.deserialize_shared(
60            self.get(),
61            |ptr| rc::Rc::<T>::from(unsafe { Box::from_raw(ptr) }),
62            |layout| unsafe { alloc::alloc(layout) },
63        )?;
64        let shared_ptr = unsafe { rc::Rc::<T>::from_raw(raw_shared_ptr) };
65        forget(shared_ptr.clone());
66        Ok(shared_ptr)
67    }
68}
69
70impl<T: ArchivePointee + PartialEq<U> + ?Sized, U: ?Sized> PartialEq<rc::Rc<U>>
71    for ArchivedRc<T, RcFlavor>
72{
73    #[inline]
74    fn eq(&self, other: &rc::Rc<U>) -> bool {
75        self.get().eq(other.as_ref())
76    }
77}
78
79// rc::Weak
80
81impl<T: ArchiveUnsized + ?Sized> Archive for rc::Weak<T> {
82    type Archived = ArchivedRcWeak<T::Archived, RcFlavor>;
83    type Resolver = RcWeakResolver<T::MetadataResolver>;
84
85    #[inline]
86    unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) {
87        ArchivedRcWeak::resolve_from_ref(
88            self.upgrade().as_ref().map(|v| v.as_ref()),
89            pos,
90            resolver,
91            out,
92        );
93    }
94}
95
96impl<T, S> Serialize<S> for rc::Weak<T>
97where
98    T: SerializeUnsized<S> + ?Sized + 'static,
99    S: Serializer + SharedSerializeRegistry + ?Sized,
100{
101    #[inline]
102    fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
103        ArchivedRcWeak::<T::Archived, RcFlavor>::serialize_from_ref(
104            self.upgrade().as_ref().map(|v| v.as_ref()),
105            serializer,
106        )
107    }
108}
109
110// Deserialize can only be implemented for sized types because weak pointers don't have from/into
111// raw functions.
112impl<T, D> Deserialize<rc::Weak<T>, D> for ArchivedRcWeak<T::Archived, RcFlavor>
113where
114    T: Archive + 'static,
115    T::Archived: DeserializeUnsized<T, D>,
116    D: SharedDeserializeRegistry + ?Sized,
117{
118    #[inline]
119    fn deserialize(&self, deserializer: &mut D) -> Result<rc::Weak<T>, D::Error> {
120        Ok(match self {
121            ArchivedRcWeak::None => rc::Weak::new(),
122            ArchivedRcWeak::Some(r) => rc::Rc::downgrade(&r.deserialize(deserializer)?),
123        })
124    }
125}
126
127// Arc
128
129/// The flavor type for `Arc`.
130#[cfg(has_atomics)]
131pub struct ArcFlavor;
132
133#[cfg(has_atomics)]
134impl<T: ?Sized> SharedPointer for sync::Arc<T> {
135    #[inline]
136    fn data_address(&self) -> *const () {
137        sync::Arc::as_ptr(self) as *const ()
138    }
139}
140
141#[cfg(has_atomics)]
142impl<T: ArchiveUnsized + ?Sized> Archive for sync::Arc<T> {
143    type Archived = ArchivedRc<T::Archived, ArcFlavor>;
144    type Resolver = RcResolver<T::MetadataResolver>;
145
146    #[inline]
147    unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) {
148        ArchivedRc::resolve_from_ref(self.as_ref(), pos, resolver, out);
149    }
150}
151
152#[cfg(has_atomics)]
153impl<T, S> Serialize<S> for sync::Arc<T>
154where
155    T: SerializeUnsized<S> + ?Sized + 'static,
156    S: Serializer + SharedSerializeRegistry + ?Sized,
157{
158    #[inline]
159    fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
160        ArchivedRc::<T::Archived, ArcFlavor>::serialize_from_ref(self.as_ref(), serializer)
161    }
162}
163
164#[cfg(has_atomics)]
165impl<T: ArchiveUnsized + ?Sized + 'static, D: SharedDeserializeRegistry + ?Sized>
166    Deserialize<sync::Arc<T>, D> for ArchivedRc<T::Archived, ArcFlavor>
167where
168    T::Archived: DeserializeUnsized<T, D>,
169{
170    #[inline]
171    fn deserialize(&self, deserializer: &mut D) -> Result<sync::Arc<T>, D::Error> {
172        let raw_shared_ptr = deserializer.deserialize_shared(
173            self.get(),
174            |ptr| sync::Arc::<T>::from(unsafe { Box::from_raw(ptr) }),
175            |layout| unsafe { alloc::alloc(layout) },
176        )?;
177        let shared_ptr = unsafe { sync::Arc::<T>::from_raw(raw_shared_ptr) };
178        forget(shared_ptr.clone());
179        Ok(shared_ptr)
180    }
181}
182
183#[cfg(has_atomics)]
184impl<T, U> PartialEq<sync::Arc<U>> for ArchivedRc<T, ArcFlavor>
185where
186    T: ArchivePointee + PartialEq<U> + ?Sized,
187    U: ?Sized,
188{
189    #[inline]
190    fn eq(&self, other: &sync::Arc<U>) -> bool {
191        self.get().eq(other.as_ref())
192    }
193}
194
195// sync::Weak
196
197#[cfg(has_atomics)]
198impl<T: ArchiveUnsized + ?Sized> Archive for sync::Weak<T> {
199    type Archived = ArchivedRcWeak<T::Archived, ArcFlavor>;
200    type Resolver = RcWeakResolver<T::MetadataResolver>;
201
202    #[inline]
203    unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) {
204        ArchivedRcWeak::resolve_from_ref(
205            self.upgrade().as_ref().map(|v| v.as_ref()),
206            pos,
207            resolver,
208            out,
209        );
210    }
211}
212
213#[cfg(has_atomics)]
214impl<T, S> Serialize<S> for sync::Weak<T>
215where
216    T: SerializeUnsized<S> + ?Sized + 'static,
217    S: Serializer + SharedSerializeRegistry + ?Sized,
218{
219    #[inline]
220    fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
221        ArchivedRcWeak::<T::Archived, ArcFlavor>::serialize_from_ref(
222            self.upgrade().as_ref().map(|v| v.as_ref()),
223            serializer,
224        )
225    }
226}
227
228// Deserialize can only be implemented for sized types because weak pointers don't have from/into
229// raw functions.
230#[cfg(has_atomics)]
231impl<T, D> Deserialize<sync::Weak<T>, D> for ArchivedRcWeak<T::Archived, ArcFlavor>
232where
233    T: Archive + 'static,
234    T::Archived: DeserializeUnsized<T, D>,
235    D: SharedDeserializeRegistry + ?Sized,
236{
237    #[inline]
238    fn deserialize(&self, deserializer: &mut D) -> Result<sync::Weak<T>, D::Error> {
239        Ok(match self {
240            ArchivedRcWeak::None => sync::Weak::new(),
241            ArchivedRcWeak::Some(r) => sync::Arc::downgrade(&r.deserialize(deserializer)?),
242        })
243    }
244}