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| 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
79impl<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
110impl<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#[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#[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#[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}