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
18pub 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
85impl<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
116impl<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#[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#[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#[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}