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 #[doc(hidden)]
62 #[inline]
63 pub fn is_null(&self) -> bool {
64 self.0.is_null()
65 }
66}
67
68impl<T> ArchivedBox<[T]> {
69 #[inline]
78 pub unsafe fn serialize_copy_from_slice<U, S>(
79 slice: &[U],
80 serializer: &mut S,
81 ) -> Result<BoxResolver<MetadataResolver<[U]>>, S::Error>
82 where
83 U: Serialize<S, Archived = T>,
84 S: Serializer + ?Sized,
85 {
86 use ::core::{mem::size_of, slice::from_raw_parts};
87
88 let pos = serializer.align_for::<T>()?;
89
90 let bytes = from_raw_parts(slice.as_ptr().cast::<u8>(), size_of::<T>() * slice.len());
91 serializer.write(bytes)?;
92
93 Ok(BoxResolver {
94 pos,
95 metadata_resolver: (),
96 })
97 }
98}
99
100impl<T: ArchivePointee + ?Sized> ArchivedBox<T>
101where
102 T::ArchivedMetadata: Default,
103{
104 #[doc(hidden)]
105 #[inline]
106 pub unsafe fn emplace_null(pos: usize, out: *mut Self) {
107 let (fp, fo) = out_field!(out.0);
108 RelPtr::emplace_null(pos + fp, fo);
109 }
110}
111
112impl<T: ArchivePointee + ?Sized> AsRef<T> for ArchivedBox<T> {
113 #[inline]
114 fn as_ref(&self) -> &T {
115 self.get()
116 }
117}
118
119impl<T: ArchivePointee + ?Sized> Borrow<T> for ArchivedBox<T> {
120 #[inline]
121 fn borrow(&self) -> &T {
122 self.get()
123 }
124}
125
126impl<T: ArchivePointee + ?Sized> fmt::Debug for ArchivedBox<T>
127where
128 T::ArchivedMetadata: fmt::Debug,
129{
130 #[inline]
131 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132 f.debug_tuple("ArchivedBox").field(&self.0).finish()
133 }
134}
135
136impl<T: ArchivePointee + ?Sized> Deref for ArchivedBox<T> {
137 type Target = T;
138
139 #[inline]
140 fn deref(&self) -> &Self::Target {
141 self.get()
142 }
143}
144
145impl<T: ArchivePointee + fmt::Display + ?Sized> fmt::Display for ArchivedBox<T> {
146 #[inline]
147 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
148 self.get().fmt(f)
149 }
150}
151
152impl<T: ArchivePointee + Eq + ?Sized> Eq for ArchivedBox<T> {}
153
154impl<T: ArchivePointee + hash::Hash + ?Sized> hash::Hash for ArchivedBox<T> {
155 #[inline]
156 fn hash<H: hash::Hasher>(&self, state: &mut H) {
157 self.get().hash(state);
158 }
159}
160
161impl<T: ArchivePointee + Ord + ?Sized> Ord for ArchivedBox<T> {
162 #[inline]
163 fn cmp(&self, other: &Self) -> cmp::Ordering {
164 self.as_ref().cmp(other.as_ref())
165 }
166}
167
168impl<T: ArchivePointee + PartialEq<U> + ?Sized, U: ArchivePointee + ?Sized>
169 PartialEq<ArchivedBox<U>> for ArchivedBox<T>
170{
171 #[inline]
172 fn eq(&self, other: &ArchivedBox<U>) -> bool {
173 self.get().eq(other.get())
174 }
175}
176
177impl<T: ArchivePointee + PartialOrd + ?Sized> PartialOrd for ArchivedBox<T> {
178 #[inline]
179 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
180 self.get().partial_cmp(other.get())
181 }
182}
183
184impl<T: ArchivePointee + ?Sized> fmt::Pointer for ArchivedBox<T> {
185 #[inline]
186 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
187 let ptr = self.get() as *const T;
188 fmt::Pointer::fmt(&ptr, f)
189 }
190}
191
192pub struct BoxResolver<T> {
194 pos: usize,
195 metadata_resolver: T,
196}
197
198#[cfg(feature = "validation")]
199const _: () = {
200 use crate::validation::{
201 owned::{CheckOwnedPointerError, OwnedPointerError},
202 ArchiveContext, LayoutRaw,
203 };
204 use bytecheck::{CheckBytes, Error};
205 use ptr_meta::Pointee;
206
207 impl<T, C> CheckBytes<C> for ArchivedBox<T>
208 where
209 T: ArchivePointee + CheckBytes<C> + LayoutRaw + Pointee + ?Sized,
210 C: ArchiveContext + ?Sized,
211 T::ArchivedMetadata: CheckBytes<C>,
212 C::Error: Error,
213 {
214 type Error = CheckOwnedPointerError<T, C>;
215
216 #[inline]
217 unsafe fn check_bytes<'a>(
218 value: *const Self,
219 context: &mut C,
220 ) -> Result<&'a Self, Self::Error> {
221 let rel_ptr = RelPtr::<T>::manual_check_bytes(value.cast(), context)
222 .map_err(OwnedPointerError::PointerCheckBytesError)?;
223 let ptr = context
224 .check_subtree_rel_ptr(rel_ptr)
225 .map_err(OwnedPointerError::ContextError)?;
226
227 let range = context
228 .push_prefix_subtree(ptr)
229 .map_err(OwnedPointerError::ContextError)?;
230 T::check_bytes(ptr, context).map_err(OwnedPointerError::ValueCheckBytesError)?;
231 context
232 .pop_prefix_range(range)
233 .map_err(OwnedPointerError::ContextError)?;
234
235 Ok(&*value)
236 }
237 }
238};