rkyv/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| {
63                let ptr = unsafe { alloc::alloc(layout) };
64                if ptr.is_null() {
65                    alloc::handle_alloc_error(layout);
66                }
67                ptr
68            },
69        )?;
70        let shared_ptr = unsafe { rc::Rc::<T>::from_raw(raw_shared_ptr) };
71        forget(shared_ptr.clone());
72        Ok(shared_ptr)
73    }
74}
75
76impl<T: ArchivePointee + PartialEq<U> + ?Sized, U: ?Sized> PartialEq<rc::Rc<U>>
77    for ArchivedRc<T, RcFlavor>
78{
79    #[inline]
80    fn eq(&self, other: &rc::Rc<U>) -> bool {
81        self.get().eq(other.as_ref())
82    }
83}
84
85// rc::Weak
86
87impl<T: ArchiveUnsized + ?Sized> Archive for rc::Weak<T> {
88    type Archived = ArchivedRcWeak<T::Archived, RcFlavor>;
89    type Resolver = RcWeakResolver<T::MetadataResolver>;
90
91    #[inline]
92    unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) {
93        ArchivedRcWeak::resolve_from_ref(
94            self.upgrade().as_ref().map(|v| v.as_ref()),
95            pos,
96            resolver,
97            out,
98        );
99    }
100}
101
102impl<T, S> Serialize<S> for rc::Weak<T>
103where
104    T: SerializeUnsized<S> + ?Sized + 'static,
105    S: Serializer + SharedSerializeRegistry + ?Sized,
106{
107    #[inline]
108    fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
109        ArchivedRcWeak::<T::Archived, RcFlavor>::serialize_from_ref(
110            self.upgrade().as_ref().map(|v| v.as_ref()),
111            serializer,
112        )
113    }
114}
115
116// Deserialize can only be implemented for sized types because weak pointers don't have from/into
117// raw functions.
118impl<T, D> Deserialize<rc::Weak<T>, D> for ArchivedRcWeak<T::Archived, RcFlavor>
119where
120    T: Archive + 'static,
121    T::Archived: DeserializeUnsized<T, D>,
122    D: SharedDeserializeRegistry + ?Sized,
123{
124    #[inline]
125    fn deserialize(&self, deserializer: &mut D) -> Result<rc::Weak<T>, D::Error> {
126        Ok(match self {
127            ArchivedRcWeak::None => rc::Weak::new(),
128            ArchivedRcWeak::Some(r) => rc::Rc::downgrade(&r.deserialize(deserializer)?),
129        })
130    }
131}
132
133// Arc
134
135/// The flavor type for `Arc`.
136#[cfg(has_atomics)]
137pub struct ArcFlavor;
138
139#[cfg(has_atomics)]
140impl<T: ?Sized> SharedPointer for sync::Arc<T> {
141    #[inline]
142    fn data_address(&self) -> *const () {
143        sync::Arc::as_ptr(self) as *const ()
144    }
145}
146
147#[cfg(has_atomics)]
148impl<T: ArchiveUnsized + ?Sized> Archive for sync::Arc<T> {
149    type Archived = ArchivedRc<T::Archived, ArcFlavor>;
150    type Resolver = RcResolver<T::MetadataResolver>;
151
152    #[inline]
153    unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) {
154        ArchivedRc::resolve_from_ref(self.as_ref(), pos, resolver, out);
155    }
156}
157
158#[cfg(has_atomics)]
159impl<T, S> Serialize<S> for sync::Arc<T>
160where
161    T: SerializeUnsized<S> + ?Sized + 'static,
162    S: Serializer + SharedSerializeRegistry + ?Sized,
163{
164    #[inline]
165    fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
166        ArchivedRc::<T::Archived, ArcFlavor>::serialize_from_ref(self.as_ref(), serializer)
167    }
168}
169
170#[cfg(has_atomics)]
171impl<T: ArchiveUnsized + ?Sized + 'static, D: SharedDeserializeRegistry + ?Sized>
172    Deserialize<sync::Arc<T>, D> for ArchivedRc<T::Archived, ArcFlavor>
173where
174    T::Archived: DeserializeUnsized<T, D>,
175{
176    #[inline]
177    fn deserialize(&self, deserializer: &mut D) -> Result<sync::Arc<T>, D::Error> {
178        let raw_shared_ptr = deserializer.deserialize_shared(
179            self.get(),
180            |ptr| sync::Arc::<T>::from(unsafe { Box::from_raw(ptr) }),
181            |layout| {
182                let ptr = unsafe { alloc::alloc(layout) };
183                if ptr.is_null() {
184                    alloc::handle_alloc_error(layout);
185                }
186                ptr
187            },
188        )?;
189        let shared_ptr = unsafe { sync::Arc::<T>::from_raw(raw_shared_ptr) };
190        forget(shared_ptr.clone());
191        Ok(shared_ptr)
192    }
193}
194
195#[cfg(has_atomics)]
196impl<T, U> PartialEq<sync::Arc<U>> for ArchivedRc<T, ArcFlavor>
197where
198    T: ArchivePointee + PartialEq<U> + ?Sized,
199    U: ?Sized,
200{
201    #[inline]
202    fn eq(&self, other: &sync::Arc<U>) -> bool {
203        self.get().eq(other.as_ref())
204    }
205}
206
207// sync::Weak
208
209#[cfg(has_atomics)]
210impl<T: ArchiveUnsized + ?Sized> Archive for sync::Weak<T> {
211    type Archived = ArchivedRcWeak<T::Archived, ArcFlavor>;
212    type Resolver = RcWeakResolver<T::MetadataResolver>;
213
214    #[inline]
215    unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) {
216        ArchivedRcWeak::resolve_from_ref(
217            self.upgrade().as_ref().map(|v| v.as_ref()),
218            pos,
219            resolver,
220            out,
221        );
222    }
223}
224
225#[cfg(has_atomics)]
226impl<T, S> Serialize<S> for sync::Weak<T>
227where
228    T: SerializeUnsized<S> + ?Sized + 'static,
229    S: Serializer + SharedSerializeRegistry + ?Sized,
230{
231    #[inline]
232    fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
233        ArchivedRcWeak::<T::Archived, ArcFlavor>::serialize_from_ref(
234            self.upgrade().as_ref().map(|v| v.as_ref()),
235            serializer,
236        )
237    }
238}
239
240// Deserialize can only be implemented for sized types because weak pointers don't have from/into
241// raw functions.
242#[cfg(has_atomics)]
243impl<T, D> Deserialize<sync::Weak<T>, D> for ArchivedRcWeak<T::Archived, ArcFlavor>
244where
245    T: Archive + 'static,
246    T::Archived: DeserializeUnsized<T, D>,
247    D: SharedDeserializeRegistry + ?Sized,
248{
249    #[inline]
250    fn deserialize(&self, deserializer: &mut D) -> Result<sync::Weak<T>, D::Error> {
251        Ok(match self {
252            ArchivedRcWeak::None => sync::Weak::new(),
253            ArchivedRcWeak::Some(r) => sync::Arc::downgrade(&r.deserialize(deserializer)?),
254        })
255    }
256}