1use core::{
2 alloc::{Layout, LayoutError},
3 marker::{PhantomData, PhantomPinned},
4 mem::{ManuallyDrop, MaybeUninit},
5 ptr::{self, addr_of_mut},
6 str,
7};
8
9use ptr_meta::Pointee;
10use rancor::Fallible;
11
12use crate::{
13 primitive::ArchivedUsize,
14 ser::{Allocator, Writer, WriterExt as _},
15 traits::{ArchivePointee, CopyOptimization, LayoutRaw, NoUndef},
16 tuple::*,
17 Archive, ArchiveUnsized, ArchivedMetadata, Deserialize, DeserializeUnsized,
18 Place, Portable, Serialize, SerializeUnsized,
19};
20
21mod ffi;
22mod net;
23mod ops;
24mod option;
25mod primitive;
26mod result;
27mod time;
28pub(crate) mod with;
29
30impl<T> LayoutRaw for T {
31 fn layout_raw(
32 _: <Self as Pointee>::Metadata,
33 ) -> Result<Layout, LayoutError> {
34 Ok(Layout::new::<T>())
35 }
36}
37
38impl<T> LayoutRaw for [T] {
39 fn layout_raw(
40 metadata: <Self as Pointee>::Metadata,
41 ) -> Result<Layout, LayoutError> {
42 Layout::array::<T>(metadata)
43 }
44}
45
46impl LayoutRaw for str {
47 #[inline]
48 fn layout_raw(
49 metadata: <Self as Pointee>::Metadata,
50 ) -> Result<Layout, LayoutError> {
51 Layout::array::<u8>(metadata)
52 }
53}
54
55impl<T> ArchivePointee for T {
56 type ArchivedMetadata = ();
57
58 fn pointer_metadata(
59 _: &Self::ArchivedMetadata,
60 ) -> <Self as Pointee>::Metadata {
61 }
62}
63
64impl<T: Archive> ArchiveUnsized for T {
65 type Archived = T::Archived;
66
67 fn archived_metadata(&self) -> ArchivedMetadata<Self> {}
68}
69
70impl<T, S> SerializeUnsized<S> for T
71where
72 T: Serialize<S>,
73 S: Fallible + Writer + ?Sized,
74{
75 fn serialize_unsized(&self, serializer: &mut S) -> Result<usize, S::Error> {
76 let resolver = self.serialize(serializer)?;
77 serializer.align_for::<T::Archived>()?;
78 unsafe { serializer.resolve_aligned(self, resolver) }
79 }
80}
81
82impl<T, D> DeserializeUnsized<T, D> for T::Archived
83where
84 T: Archive,
85 D: Fallible + ?Sized,
86 T::Archived: Deserialize<T, D>,
87{
88 unsafe fn deserialize_unsized(
89 &self,
90 deserializer: &mut D,
91 out: *mut T,
92 ) -> Result<(), D::Error> {
93 unsafe {
97 out.write(self.deserialize(deserializer)?);
98 }
99 Ok(())
100 }
101
102 fn deserialize_metadata(&self) -> <T as Pointee>::Metadata {}
103}
104
105macro_rules! impl_tuple {
106 ($name:ident, $($type:ident $index:tt),*) => {
107 impl<$($type),*> Archive for ($($type,)*)
108 where
109 $($type: Archive,)*
110 {
111 type Archived = $name<$($type::Archived,)*>;
112 type Resolver = ($($type::Resolver,)*);
113
114 fn resolve(
115 &self,
116 resolver: Self::Resolver,
117 out: Place<Self::Archived>,
118 ) {
119 let out_ptr = unsafe { out.ptr() };
122 $(
123 let ptr = unsafe { addr_of_mut!((*out_ptr).$index) };
126 let out_field = unsafe {
131 Place::from_field_unchecked(out, ptr)
132 };
133 self.$index.resolve(resolver.$index, out_field);
134 )*
135 }
136 }
137
138 impl<$($type,)* S> Serialize<S> for ($($type,)*)
139 where
140 $($type: Serialize<S>,)*
141 S: Fallible + ?Sized,
142 {
143 fn serialize(
144 &self,
145 serializer: &mut S,
146 ) -> Result<Self::Resolver, S::Error> {
147 Ok((
148 $(self.$index.serialize(serializer)?,)*
149 ))
150 }
151 }
152
153 impl<$($type,)* D> Deserialize<($($type,)*), D>
154 for $name<$($type::Archived,)*>
155 where
156 D: Fallible + ?Sized,
157 $($type: Archive,)*
158 $($type::Archived: Deserialize<$type, D>,)*
159 {
160 fn deserialize(
161 &self,
162 deserializer: &mut D,
163 ) -> Result<($($type,)*), D::Error> {
164 Ok((
165 $(self.$index.deserialize(deserializer)?,)*
166 ))
167 }
168 }
169 };
170}
171
172impl_tuple!(ArchivedTuple1, T0 0);
173impl_tuple!(ArchivedTuple2, T0 0, T1 1);
174impl_tuple!(ArchivedTuple3, T0 0, T1 1, T2 2);
175impl_tuple!(ArchivedTuple4, T0 0, T1 1, T2 2, T3 3);
176impl_tuple!(ArchivedTuple5, T0 0, T1 1, T2 2, T3 3, T4 4);
177impl_tuple!(ArchivedTuple6, T0 0, T1 1, T2 2, T3 3, T4 4, T5 5);
178impl_tuple!(ArchivedTuple7, T0 0, T1 1, T2 2, T3 3, T4 4, T5 5, T6 6);
179impl_tuple!(ArchivedTuple8, T0 0, T1 1, T2 2, T3 3, T4 4, T5 5, T6 6, T7 7);
180impl_tuple!(
181 ArchivedTuple9, T0 0, T1 1, T2 2, T3 3, T4 4, T5 5, T6 6, T7 7, T8 8
182);
183impl_tuple!(
184 ArchivedTuple10, T0 0, T1 1, T2 2, T3 3, T4 4, T5 5, T6 6, T7 7, T8 8, T9 9
185);
186impl_tuple!(
187 ArchivedTuple11, T0 0, T1 1, T2 2, T3 3, T4 4, T5 5, T6 6, T7 7, T8 8, T9 9,
188 T10 10
189);
190impl_tuple!(
191 ArchivedTuple12, T0 0, T1 1, T2 2, T3 3, T4 4, T5 5, T6 6, T7 7, T8 8, T9 9,
192 T10 10, T11 11
193);
194impl_tuple!(
195 ArchivedTuple13, T0 0, T1 1, T2 2, T3 3, T4 4, T5 5, T6 6, T7 7, T8 8, T9 9,
196 T10 10, T11 11, T12 12
197);
198
199unsafe impl<T: Portable, const N: usize> Portable for [T; N] {}
204
205impl<T: Archive, const N: usize> Archive for [T; N] {
206 const COPY_OPTIMIZATION: CopyOptimization<Self> = unsafe {
207 CopyOptimization::enable_if(T::COPY_OPTIMIZATION.is_enabled())
208 };
209
210 type Archived = [T::Archived; N];
211 type Resolver = [T::Resolver; N];
212
213 fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>) {
214 for (i, (value, resolver)) in self.iter().zip(resolver).enumerate() {
215 let out_i = unsafe { out.index(i) };
216 value.resolve(resolver, out_i);
217 }
218 }
219}
220
221impl<T, S, const N: usize> Serialize<S> for [T; N]
222where
223 T: Serialize<S>,
224 S: Fallible + ?Sized,
225{
226 fn serialize(
227 &self,
228 serializer: &mut S,
229 ) -> Result<Self::Resolver, S::Error> {
230 let mut result = core::mem::MaybeUninit::<Self::Resolver>::uninit();
231 let result_ptr = result.as_mut_ptr().cast::<T::Resolver>();
232 for (i, value) in self.iter().enumerate() {
233 unsafe {
234 result_ptr.add(i).write(value.serialize(serializer)?);
235 }
236 }
237 unsafe { Ok(result.assume_init()) }
238 }
239}
240
241impl<T, D, const N: usize> Deserialize<[T; N], D> for [T::Archived; N]
242where
243 T: Archive,
244 T::Archived: Deserialize<T, D>,
245 D: Fallible + ?Sized,
246{
247 fn deserialize(&self, deserializer: &mut D) -> Result<[T; N], D::Error> {
248 let mut result = core::mem::MaybeUninit::<[T; N]>::uninit();
249 let result_ptr = result.as_mut_ptr().cast::<T>();
250 for (i, value) in self.iter().enumerate() {
251 unsafe {
252 result_ptr.add(i).write(value.deserialize(deserializer)?);
253 }
254 }
255 unsafe { Ok(result.assume_init()) }
256 }
257}
258
259unsafe impl<T: Portable> Portable for [T] {}
264
265impl<T: Archive> ArchiveUnsized for [T] {
266 type Archived = [T::Archived];
267
268 fn archived_metadata(&self) -> ArchivedMetadata<Self> {
269 ArchivedUsize::from_native(ptr_meta::metadata(self) as _)
270 }
271}
272
273impl<T> ArchivePointee for [T] {
274 type ArchivedMetadata = ArchivedUsize;
275
276 fn pointer_metadata(
277 archived: &Self::ArchivedMetadata,
278 ) -> <Self as Pointee>::Metadata {
279 archived.to_native() as usize
280 }
281}
282
283impl<T, S> SerializeUnsized<S> for [T]
284where
285 T: Serialize<S>,
286 S: Fallible + Allocator + Writer + ?Sized,
287{
288 fn serialize_unsized(&self, serializer: &mut S) -> Result<usize, S::Error> {
289 if T::COPY_OPTIMIZATION.is_enabled() {
290 let result = serializer.align_for::<T::Archived>()?;
291 let as_bytes = unsafe {
292 core::slice::from_raw_parts(
293 self.as_ptr().cast::<u8>(),
294 core::mem::size_of_val(self),
295 )
296 };
297 serializer.write(as_bytes)?;
298
299 Ok(result)
300 } else {
301 use crate::util::SerVec;
302
303 SerVec::with_capacity(
304 serializer,
305 self.len(),
306 |resolvers, serializer| {
307 for value in self.iter() {
308 unsafe {
309 resolvers
310 .push_unchecked(value.serialize(serializer)?);
311 }
312 }
313
314 let result = serializer.align_for::<T::Archived>()?;
315
316 for (value, resolver) in self.iter().zip(resolvers.drain())
317 {
318 unsafe {
319 serializer.resolve_aligned(value, resolver)?;
320 }
321 }
322
323 Ok(result)
324 },
325 )?
326 }
327 }
328}
329
330impl<T, U, D> DeserializeUnsized<[U], D> for [T]
331where
332 T: Deserialize<U, D>,
333 D: Fallible + ?Sized,
334{
335 unsafe fn deserialize_unsized(
336 &self,
337 deserializer: &mut D,
338 out: *mut [U],
339 ) -> Result<(), D::Error> {
340 for (i, item) in self.iter().enumerate() {
341 let out_ptr = unsafe { out.cast::<U>().add(i) };
346 unsafe {
350 out_ptr.write(item.deserialize(deserializer)?);
351 }
352 }
353 Ok(())
354 }
355
356 fn deserialize_metadata(&self) -> <[U] as Pointee>::Metadata {
357 ptr_meta::metadata(self)
358 }
359}
360
361unsafe impl Portable for str {}
366
367unsafe impl NoUndef for str {}
369
370impl ArchiveUnsized for str {
371 type Archived = str;
372
373 #[inline]
374 fn archived_metadata(&self) -> ArchivedMetadata<Self> {
375 ArchivedUsize::from_native(ptr_meta::metadata(self) as _)
376 }
377}
378
379impl ArchivePointee for str {
380 type ArchivedMetadata = ArchivedUsize;
381
382 #[inline]
383 fn pointer_metadata(
384 archived: &Self::ArchivedMetadata,
385 ) -> <Self as Pointee>::Metadata {
386 <[u8]>::pointer_metadata(archived)
387 }
388}
389
390impl<S: Fallible + Writer + ?Sized> SerializeUnsized<S> for str {
391 fn serialize_unsized(&self, serializer: &mut S) -> Result<usize, S::Error> {
392 let result = serializer.pos();
393 serializer.write(self.as_bytes())?;
394 Ok(result)
395 }
396}
397
398impl<D: Fallible + ?Sized> DeserializeUnsized<str, D> for str {
399 unsafe fn deserialize_unsized(
400 &self,
401 _: &mut D,
402 out: *mut str,
403 ) -> Result<(), D::Error> {
404 unsafe {
411 ptr::copy_nonoverlapping(
412 self.as_ptr(),
413 out.cast::<u8>(),
414 self.len(),
415 );
416 }
417 Ok(())
418 }
419
420 fn deserialize_metadata(&self) -> <str as Pointee>::Metadata {
421 ptr_meta::metadata(self)
422 }
423}
424
425unsafe impl<T: ?Sized> Portable for PhantomData<T> {}
430
431impl<T: ?Sized> Archive for PhantomData<T> {
432 const COPY_OPTIMIZATION: CopyOptimization<Self> =
433 unsafe { CopyOptimization::enable() };
434
435 type Archived = PhantomData<T>;
436 type Resolver = ();
437
438 fn resolve(&self, _: Self::Resolver, _: Place<Self::Archived>) {}
439}
440
441impl<T: ?Sized, S: Fallible + ?Sized> Serialize<S> for PhantomData<T> {
442 fn serialize(&self, _: &mut S) -> Result<Self::Resolver, S::Error> {
443 Ok(())
444 }
445}
446
447impl<T: ?Sized, D: Fallible + ?Sized> Deserialize<PhantomData<T>, D>
448 for PhantomData<T>
449{
450 fn deserialize(&self, _: &mut D) -> Result<PhantomData<T>, D::Error> {
451 Ok(PhantomData)
452 }
453}
454
455unsafe impl Portable for PhantomPinned {}
460
461impl Archive for PhantomPinned {
462 const COPY_OPTIMIZATION: CopyOptimization<Self> =
463 unsafe { CopyOptimization::enable() };
464
465 type Archived = PhantomPinned;
466 type Resolver = ();
467
468 #[inline]
469 fn resolve(&self, _: Self::Resolver, _: Place<Self::Archived>) {}
470}
471
472impl<S: Fallible + ?Sized> Serialize<S> for PhantomPinned {
473 fn serialize(&self, _: &mut S) -> Result<Self::Resolver, S::Error> {
474 Ok(())
475 }
476}
477
478impl<D: Fallible + ?Sized> Deserialize<PhantomPinned, D> for PhantomPinned {
479 fn deserialize(&self, _: &mut D) -> Result<PhantomPinned, D::Error> {
480 Ok(PhantomPinned)
481 }
482}
483
484unsafe impl<T: Portable> Portable for ManuallyDrop<T> {}
489
490impl<T: Archive> Archive for ManuallyDrop<T> {
491 const COPY_OPTIMIZATION: CopyOptimization<Self> = unsafe {
492 CopyOptimization::enable_if(T::COPY_OPTIMIZATION.is_enabled())
493 };
494
495 type Archived = ManuallyDrop<T::Archived>;
496 type Resolver = T::Resolver;
497
498 fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>) {
499 let out_inner = unsafe { out.cast_unchecked::<T::Archived>() };
500 T::resolve(self, resolver, out_inner)
501 }
502}
503
504impl<T: Serialize<S>, S: Fallible + ?Sized> Serialize<S> for ManuallyDrop<T> {
505 fn serialize(
506 &self,
507 serializer: &mut S,
508 ) -> Result<Self::Resolver, S::Error> {
509 T::serialize(self, serializer)
510 }
511}
512
513impl<T, D> Deserialize<ManuallyDrop<T>, D> for ManuallyDrop<T::Archived>
514where
515 T: Archive,
516 T::Archived: Deserialize<T, D>,
517 D: Fallible + ?Sized,
518{
519 fn deserialize(
520 &self,
521 deserializer: &mut D,
522 ) -> Result<ManuallyDrop<T>, D::Error> {
523 T::Archived::deserialize(self, deserializer).map(ManuallyDrop::new)
524 }
525}
526
527unsafe impl<T: Portable> Portable for MaybeUninit<T> {}
532
533#[cfg(test)]
534mod tests {
535 use core::{
536 marker::{PhantomData, PhantomPinned},
537 mem::ManuallyDrop,
538 };
539
540 use crate::{
541 api::test::{roundtrip, roundtrip_with},
542 tuple::ArchivedTuple3,
543 };
544
545 #[test]
546 fn roundtrip_tuple() {
547 roundtrip_with(
548 &(24, true, 16f32),
549 |(a, b, c), ArchivedTuple3(d, e, f)| {
550 assert_eq!(a, d);
551 assert_eq!(b, e);
552 assert_eq!(c, f);
553 },
554 );
555 }
556
557 #[test]
558 fn roundtrip_array() {
559 roundtrip(&[1, 2, 3, 4, 5, 6]);
560 roundtrip(&[(); 0]);
561 roundtrip(&[(), (), (), ()]);
562 }
563
564 #[test]
565 fn roundtrip_phantoms() {
566 roundtrip(&PhantomData::<&'static u8>);
567 roundtrip(&PhantomPinned);
568 }
569
570 #[test]
571 fn roundtrip_manually_drop() {
572 roundtrip(&ManuallyDrop::new(123i8));
573 }
574}