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