1use crate::{
4 ser::Serializer, ArchivePointee, ArchiveUnsized, Fallible, MetadataResolver, RelPtr, Serialize,
5 SerializeUnsized,
6};
7use core::{borrow::Borrow, cmp, fmt, hash, ops::Deref, pin::Pin};
8
9#[repr(transparent)]
13pub struct ArchivedBox<T: ArchivePointee + ?Sized>(RelPtr<T>);
14
15impl<T: ArchivePointee + ?Sized> ArchivedBox<T> {
16 #[inline]
18 pub fn get(&self) -> &T {
19 unsafe { &*self.0.as_ptr() }
20 }
21
22 #[inline]
24 pub fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> {
25 unsafe { self.map_unchecked_mut(|s| &mut *s.0.as_mut_ptr()) }
26 }
27
28 #[inline]
35 pub unsafe fn resolve_from_ref<U: ArchiveUnsized<Archived = T> + ?Sized>(
36 value: &U,
37 pos: usize,
38 resolver: BoxResolver<U::MetadataResolver>,
39 out: *mut Self,
40 ) {
41 let (fp, fo) = out_field!(out.0);
42 value.resolve_unsized(pos + fp, resolver.pos, resolver.metadata_resolver, fo);
43 }
44
45 #[inline]
47 pub fn serialize_from_ref<U, S>(
48 value: &U,
49 serializer: &mut S,
50 ) -> Result<BoxResolver<U::MetadataResolver>, S::Error>
51 where
52 U: SerializeUnsized<S, Archived = T> + ?Sized,
53 S: Fallible + ?Sized,
54 {
55 Ok(BoxResolver {
56 pos: value.serialize_unsized(serializer)?,
57 metadata_resolver: value.serialize_metadata(serializer)?,
58 })
59 }
60
61 pub unsafe fn resolve_from_raw_parts(
72 pos: usize,
73 resolver: BoxResolver<<T as ArchivePointee>::ArchivedMetadata>,
74 out: *mut Self,
75 ) {
76 let (fp, fo) = out_field!(out.0);
77 RelPtr::resolve_emplace_from_raw_parts(
78 pos + fp,
79 resolver.pos,
80 resolver.metadata_resolver,
81 fo,
82 );
83 }
84
85 #[doc(hidden)]
86 #[inline]
87 pub fn is_null(&self) -> bool {
88 self.0.is_null()
89 }
90}
91
92impl<T> ArchivedBox<[T]> {
93 #[inline]
102 pub unsafe fn serialize_copy_from_slice<U, S>(
103 slice: &[U],
104 serializer: &mut S,
105 ) -> Result<BoxResolver<MetadataResolver<[U]>>, S::Error>
106 where
107 U: Serialize<S, Archived = T>,
108 S: Serializer + ?Sized,
109 {
110 use ::core::{mem::size_of, slice::from_raw_parts};
111
112 let pos = serializer.align_for::<T>()?;
113
114 let bytes = from_raw_parts(slice.as_ptr().cast::<u8>(), size_of::<T>() * slice.len());
115 serializer.write(bytes)?;
116
117 Ok(BoxResolver {
118 pos,
119 metadata_resolver: (),
120 })
121 }
122}
123
124impl<T: ArchivePointee + ?Sized> ArchivedBox<T>
125where
126 T::ArchivedMetadata: Default,
127{
128 #[doc(hidden)]
129 #[inline]
130 pub unsafe fn emplace_null(pos: usize, out: *mut Self) {
131 let (fp, fo) = out_field!(out.0);
132 RelPtr::emplace_null(pos + fp, fo);
133 }
134}
135
136impl<T: ArchivePointee + ?Sized> AsRef<T> for ArchivedBox<T> {
137 #[inline]
138 fn as_ref(&self) -> &T {
139 self.get()
140 }
141}
142
143impl<T: ArchivePointee + ?Sized> Borrow<T> for ArchivedBox<T> {
144 #[inline]
145 fn borrow(&self) -> &T {
146 self.get()
147 }
148}
149
150impl<T: ArchivePointee + ?Sized> fmt::Debug for ArchivedBox<T>
151where
152 T::ArchivedMetadata: fmt::Debug,
153{
154 #[inline]
155 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
156 f.debug_tuple("ArchivedBox").field(&self.0).finish()
157 }
158}
159
160impl<T: ArchivePointee + ?Sized> Deref for ArchivedBox<T> {
161 type Target = T;
162
163 #[inline]
164 fn deref(&self) -> &Self::Target {
165 self.get()
166 }
167}
168
169impl<T: ArchivePointee + fmt::Display + ?Sized> fmt::Display for ArchivedBox<T> {
170 #[inline]
171 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172 self.get().fmt(f)
173 }
174}
175
176impl<T: ArchivePointee + Eq + ?Sized> Eq for ArchivedBox<T> {}
177
178impl<T: ArchivePointee + hash::Hash + ?Sized> hash::Hash for ArchivedBox<T> {
179 #[inline]
180 fn hash<H: hash::Hasher>(&self, state: &mut H) {
181 self.get().hash(state);
182 }
183}
184
185impl<T: ArchivePointee + Ord + ?Sized> Ord for ArchivedBox<T> {
186 #[inline]
187 fn cmp(&self, other: &Self) -> cmp::Ordering {
188 self.as_ref().cmp(other.as_ref())
189 }
190}
191
192impl<T: ArchivePointee + PartialEq<U> + ?Sized, U: ArchivePointee + ?Sized>
193 PartialEq<ArchivedBox<U>> for ArchivedBox<T>
194{
195 #[inline]
196 fn eq(&self, other: &ArchivedBox<U>) -> bool {
197 self.get().eq(other.get())
198 }
199}
200
201impl<T: ArchivePointee + PartialOrd + ?Sized> PartialOrd for ArchivedBox<T> {
202 #[inline]
203 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
204 self.get().partial_cmp(other.get())
205 }
206}
207
208impl<T: ArchivePointee + ?Sized> fmt::Pointer for ArchivedBox<T> {
209 #[inline]
210 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
211 let ptr = self.get() as *const T;
212 fmt::Pointer::fmt(&ptr, f)
213 }
214}
215
216pub struct BoxResolver<M> {
218 pos: usize,
219 metadata_resolver: M,
220}
221
222impl<M> BoxResolver<M> {
223 pub unsafe fn from_raw_parts(pos: usize, metadata_resolver: M) -> Self {
250 Self {
251 pos,
252 metadata_resolver,
253 }
254 }
255}
256
257#[cfg(feature = "validation")]
258const _: () = {
259 use crate::validation::{
260 owned::{CheckOwnedPointerError, OwnedPointerError},
261 ArchiveContext, LayoutRaw,
262 };
263 use bytecheck::{CheckBytes, Error};
264 use ptr_meta::Pointee;
265
266 impl<T, C> CheckBytes<C> for ArchivedBox<T>
267 where
268 T: ArchivePointee + CheckBytes<C> + LayoutRaw + Pointee + ?Sized,
269 C: ArchiveContext + ?Sized,
270 T::ArchivedMetadata: CheckBytes<C>,
271 C::Error: Error,
272 {
273 type Error = CheckOwnedPointerError<T, C>;
274
275 #[inline]
276 unsafe fn check_bytes<'a>(
277 value: *const Self,
278 context: &mut C,
279 ) -> Result<&'a Self, Self::Error> {
280 let rel_ptr = RelPtr::<T>::manual_check_bytes(value.cast(), context)
281 .map_err(OwnedPointerError::PointerCheckBytesError)?;
282 let ptr = context
283 .check_subtree_rel_ptr(rel_ptr)
284 .map_err(OwnedPointerError::ContextError)?;
285
286 let range = context
287 .push_prefix_subtree(ptr)
288 .map_err(OwnedPointerError::ContextError)?;
289 T::check_bytes(ptr, context).map_err(OwnedPointerError::ValueCheckBytesError)?;
290 context
291 .pop_prefix_range(range)
292 .map_err(OwnedPointerError::ContextError)?;
293
294 Ok(&*value)
295 }
296 }
297};