1use core::alloc::LayoutError;
2
3use ptr_meta::{from_raw_parts_mut, Pointee};
4use rancor::{Fallible, Source};
5
6use crate::{
7 alloc::{
8 alloc::{alloc, handle_alloc_error},
9 boxed::Box,
10 sync,
11 },
12 de::{FromMetadata, Metadata, Pooling, PoolingExt as _, SharedPointer},
13 rc::{ArcFlavor, ArchivedRc, ArchivedRcWeak, RcResolver, RcWeakResolver},
14 ser::{Sharing, Writer},
15 traits::{ArchivePointee, LayoutRaw},
16 Archive, ArchiveUnsized, Deserialize, DeserializeUnsized, Place, Serialize,
17 SerializeUnsized,
18};
19
20impl<T: ArchiveUnsized + ?Sized> Archive for sync::Arc<T> {
23 type Archived = ArchivedRc<T::Archived, ArcFlavor>;
24 type Resolver = RcResolver;
25
26 fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>) {
27 ArchivedRc::resolve_from_ref(self.as_ref(), resolver, out);
28 }
29}
30
31impl<T, S> Serialize<S> for sync::Arc<T>
32where
33 T: SerializeUnsized<S> + ?Sized + 'static,
34 S: Fallible + Writer + Sharing + ?Sized,
35 S::Error: Source,
36{
37 fn serialize(
38 &self,
39 serializer: &mut S,
40 ) -> Result<Self::Resolver, S::Error> {
41 ArchivedRc::<T::Archived, ArcFlavor>::serialize_from_ref(
42 self.as_ref(),
43 serializer,
44 )
45 }
46}
47
48unsafe impl<T: LayoutRaw + Pointee + ?Sized> SharedPointer<T> for sync::Arc<T> {
49 fn alloc(metadata: T::Metadata) -> Result<*mut T, LayoutError> {
50 let layout = T::layout_raw(metadata)?;
51 let data_address = if layout.size() > 0 {
52 let ptr = unsafe { alloc(layout) };
53 if ptr.is_null() {
54 handle_alloc_error(layout);
55 }
56 ptr
57 } else {
58 crate::polyfill::dangling(&layout).as_ptr()
59 };
60 let ptr = from_raw_parts_mut(data_address.cast(), metadata);
61 Ok(ptr)
62 }
63
64 unsafe fn from_value(ptr: *mut T) -> *mut T {
65 let arc = sync::Arc::<T>::from(unsafe { Box::from_raw(ptr) });
66 sync::Arc::into_raw(arc).cast_mut()
67 }
68
69 unsafe fn drop(ptr: *mut T) {
70 drop(unsafe { sync::Arc::from_raw(ptr) });
71 }
72}
73
74impl<T, D> Deserialize<sync::Arc<T>, D> for ArchivedRc<T::Archived, ArcFlavor>
75where
76 T: ArchiveUnsized + LayoutRaw + Pointee + ?Sized + 'static,
77 T::Archived: DeserializeUnsized<T, D>,
78 T::Metadata: Into<Metadata> + FromMetadata,
79 D: Fallible + Pooling + ?Sized,
80 D::Error: Source,
81{
82 fn deserialize(
83 &self,
84 deserializer: &mut D,
85 ) -> Result<sync::Arc<T>, D::Error> {
86 let raw_shared_ptr =
87 deserializer.deserialize_shared::<_, sync::Arc<T>>(self.get())?;
88 unsafe {
89 sync::Arc::<T>::increment_strong_count(raw_shared_ptr);
90 }
91 unsafe { Ok(sync::Arc::<T>::from_raw(raw_shared_ptr)) }
92 }
93}
94
95impl<T, U> PartialEq<sync::Arc<U>> for ArchivedRc<T, ArcFlavor>
96where
97 T: ArchivePointee + PartialEq<U> + ?Sized,
98 U: ?Sized,
99{
100 fn eq(&self, other: &sync::Arc<U>) -> bool {
101 self.get().eq(other.as_ref())
102 }
103}
104
105impl<T: ArchiveUnsized + ?Sized> Archive for sync::Weak<T> {
108 type Archived = ArchivedRcWeak<T::Archived, ArcFlavor>;
109 type Resolver = RcWeakResolver;
110
111 fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>) {
112 ArchivedRcWeak::resolve_from_ref(
113 self.upgrade().as_ref().map(|v| v.as_ref()),
114 resolver,
115 out,
116 );
117 }
118}
119
120impl<T, S> Serialize<S> for sync::Weak<T>
121where
122 T: SerializeUnsized<S> + ?Sized + 'static,
123 S: Fallible + Writer + Sharing + ?Sized,
124 S::Error: Source,
125{
126 fn serialize(
127 &self,
128 serializer: &mut S,
129 ) -> Result<Self::Resolver, S::Error> {
130 ArchivedRcWeak::<T::Archived, ArcFlavor>::serialize_from_ref(
131 self.upgrade().as_ref().map(|v| v.as_ref()),
132 serializer,
133 )
134 }
135}
136
137impl<T, D> Deserialize<sync::Weak<T>, D>
140 for ArchivedRcWeak<T::Archived, ArcFlavor>
141where
142 T: ArchiveUnsized
145 + LayoutRaw
146 + Pointee + 'static,
148 T::Archived: DeserializeUnsized<T, D>,
149 T::Metadata: Into<Metadata> + FromMetadata,
150 D: Fallible + Pooling + ?Sized,
151 D::Error: Source,
152{
153 fn deserialize(
154 &self,
155 deserializer: &mut D,
156 ) -> Result<sync::Weak<T>, D::Error> {
157 Ok(match self.upgrade() {
158 None => sync::Weak::new(),
159 Some(r) => sync::Arc::downgrade(&r.deserialize(deserializer)?),
160 })
161 }
162}