1#[cfg(feature = "validation")]
4pub mod validation;
5
6use crate::{
7 ser::{Serializer, SharedSerializeRegistry},
8 ArchivePointee, ArchiveUnsized, MetadataResolver, RelPtr, SerializeUnsized,
9};
10use core::{borrow::Borrow, cmp, fmt, hash, marker::PhantomData, ops::Deref, pin::Pin, ptr};
11
12#[repr(transparent)]
18pub struct ArchivedRc<T: ArchivePointee + ?Sized, F>(RelPtr<T>, PhantomData<F>);
19
20impl<T: ArchivePointee + ?Sized, F> ArchivedRc<T, F> {
21 #[inline]
23 pub fn get(&self) -> &T {
24 unsafe { &*self.0.as_ptr() }
25 }
26
27 #[inline]
34 pub unsafe fn get_pin_mut_unchecked(self: Pin<&mut Self>) -> Pin<&mut T> {
35 self.map_unchecked_mut(|s| &mut *s.0.as_mut_ptr())
36 }
37
38 #[inline]
45 pub unsafe fn resolve_from_ref<U: ArchiveUnsized<Archived = T> + ?Sized>(
46 value: &U,
47 pos: usize,
48 resolver: RcResolver<MetadataResolver<U>>,
49 out: *mut Self,
50 ) {
51 let (fp, fo) = out_field!(out.0);
52 value.resolve_unsized(pos + fp, resolver.pos, resolver.metadata_resolver, fo);
53 }
54
55 #[inline]
57 pub fn serialize_from_ref<
58 U: SerializeUnsized<S> + ?Sized,
59 S: Serializer + SharedSerializeRegistry + ?Sized,
60 >(
61 value: &U,
62 serializer: &mut S,
63 ) -> Result<RcResolver<MetadataResolver<U>>, S::Error> {
64 Ok(RcResolver {
65 pos: serializer.serialize_shared(value)?,
66 metadata_resolver: value.serialize_metadata(serializer)?,
67 })
68 }
69}
70
71impl<T: ArchivePointee + ?Sized, F> AsRef<T> for ArchivedRc<T, F> {
72 #[inline]
73 fn as_ref(&self) -> &T {
74 self.get()
75 }
76}
77
78impl<T: ArchivePointee + ?Sized, F> Borrow<T> for ArchivedRc<T, F> {
79 #[inline]
80 fn borrow(&self) -> &T {
81 self.get()
82 }
83}
84
85impl<T: ArchivePointee + fmt::Debug + ?Sized, F> fmt::Debug for ArchivedRc<T, F> {
86 #[inline]
87 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88 self.get().fmt(f)
89 }
90}
91
92impl<T: ArchivePointee + ?Sized, F> Deref for ArchivedRc<T, F> {
93 type Target = T;
94
95 #[inline]
96 fn deref(&self) -> &Self::Target {
97 self.get()
98 }
99}
100
101impl<T: ArchivePointee + fmt::Display + ?Sized, F> fmt::Display for ArchivedRc<T, F> {
102 #[inline]
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 self.get().fmt(f)
105 }
106}
107
108impl<T: ArchivePointee + Eq + ?Sized, F> Eq for ArchivedRc<T, F> {}
109
110impl<T: ArchivePointee + hash::Hash + ?Sized, F> hash::Hash for ArchivedRc<T, F> {
111 fn hash<H: hash::Hasher>(&self, state: &mut H) {
112 self.get().hash(state)
113 }
114}
115
116impl<T: ArchivePointee + Ord + ?Sized, F> Ord for ArchivedRc<T, F> {
117 fn cmp(&self, other: &Self) -> cmp::Ordering {
118 self.get().cmp(other.get())
119 }
120}
121
122impl<T, TF, U, UF> PartialEq<ArchivedRc<U, UF>> for ArchivedRc<T, TF>
123where
124 T: ArchivePointee + PartialEq<U> + ?Sized,
125 U: ArchivePointee + ?Sized,
126{
127 fn eq(&self, other: &ArchivedRc<U, UF>) -> bool {
128 self.get().eq(other.get())
129 }
130}
131
132impl<T, TF, U, UF> PartialOrd<ArchivedRc<U, UF>> for ArchivedRc<T, TF>
133where
134 T: ArchivePointee + PartialOrd<U> + ?Sized,
135 U: ArchivePointee + ?Sized,
136{
137 fn partial_cmp(&self, other: &ArchivedRc<U, UF>) -> Option<cmp::Ordering> {
138 self.get().partial_cmp(other.get())
139 }
140}
141
142impl<T, F> fmt::Pointer for ArchivedRc<T, F> {
143 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144 fmt::Pointer::fmt(&self.0.base(), f)
145 }
146}
147
148pub struct RcResolver<T> {
150 pos: usize,
151 metadata_resolver: T,
152}
153
154#[repr(u8)]
158pub enum ArchivedRcWeak<T: ArchivePointee + ?Sized, F> {
159 None,
161 Some(ArchivedRc<T, F>),
163}
164
165impl<T: ArchivePointee + ?Sized, F> ArchivedRcWeak<T, F> {
166 #[inline]
170 pub fn upgrade(&self) -> Option<&ArchivedRc<T, F>> {
171 match self {
172 ArchivedRcWeak::None => None,
173 ArchivedRcWeak::Some(r) => Some(r),
174 }
175 }
176
177 #[inline]
179 pub fn upgrade_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut ArchivedRc<T, F>>> {
180 unsafe {
181 match self.get_unchecked_mut() {
182 ArchivedRcWeak::None => None,
183 ArchivedRcWeak::Some(r) => Some(Pin::new_unchecked(r)),
184 }
185 }
186 }
187
188 #[inline]
195 pub unsafe fn resolve_from_ref<U: ArchiveUnsized<Archived = T> + ?Sized>(
196 value: Option<&U>,
197 pos: usize,
198 resolver: RcWeakResolver<MetadataResolver<U>>,
199 out: *mut Self,
200 ) {
201 match resolver {
202 RcWeakResolver::None => {
203 let out = out.cast::<ArchivedRcWeakVariantNone>();
204 ptr::addr_of_mut!((*out).0).write(ArchivedRcWeakTag::None);
205 }
206 RcWeakResolver::Some(resolver) => {
207 let out = out.cast::<ArchivedRcWeakVariantSome<T, F>>();
208 ptr::addr_of_mut!((*out).0).write(ArchivedRcWeakTag::Some);
209
210 let (fp, fo) = out_field!(out.1);
211 ArchivedRc::resolve_from_ref(value.unwrap(), pos + fp, resolver, fo);
212 }
213 }
214 }
215
216 #[inline]
218 pub fn serialize_from_ref<U, S>(
219 value: Option<&U>,
220 serializer: &mut S,
221 ) -> Result<RcWeakResolver<MetadataResolver<U>>, S::Error>
222 where
223 U: SerializeUnsized<S, Archived = T> + ?Sized,
224 S: Serializer + SharedSerializeRegistry + ?Sized,
225 {
226 Ok(match value {
227 None => RcWeakResolver::None,
228 Some(r) => RcWeakResolver::Some(ArchivedRc::<T, F>::serialize_from_ref(r, serializer)?),
229 })
230 }
231}
232
233impl<T: ArchivePointee + fmt::Debug + ?Sized, F> fmt::Debug for ArchivedRcWeak<T, F> {
234 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
235 write!(f, "(Weak)")
236 }
237}
238
239pub enum RcWeakResolver<T> {
241 None,
243 Some(RcResolver<T>),
245}
246
247#[allow(dead_code)]
248#[repr(u8)]
249enum ArchivedRcWeakTag {
250 None,
251 Some,
252}
253
254#[repr(C)]
255struct ArchivedRcWeakVariantNone(ArchivedRcWeakTag);
256
257#[repr(C)]
258struct ArchivedRcWeakVariantSome<T: ArchivePointee + ?Sized, F>(
259 ArchivedRcWeakTag,
260 ArchivedRc<T, F>,
261);