1#[cfg(any(
2 target_has_atomic = "8",
3 target_has_atomic = "16",
4 target_has_atomic = "32",
5 target_has_atomic = "64",
6))]
7mod atomic;
8mod niching;
9
10use core::{
11 cell::{Cell, UnsafeCell},
12 hash::{Hash, Hasher},
13 hint::unreachable_unchecked,
14 marker::PhantomData,
15 num::{
16 NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8,
17 NonZeroIsize, NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64,
18 NonZeroU8, NonZeroUsize,
19 },
20};
21
22use munge::munge;
23use rancor::{Fallible, Source};
24
25use crate::{
26 boxed::{ArchivedBox, BoxResolver},
27 niche::{
28 niched_option::NichedOption,
29 niching::{DefaultNiche, Niching},
30 option_nonzero::{
31 ArchivedOptionNonZeroI128, ArchivedOptionNonZeroI16,
32 ArchivedOptionNonZeroI32, ArchivedOptionNonZeroI64,
33 ArchivedOptionNonZeroI8, ArchivedOptionNonZeroIsize,
34 ArchivedOptionNonZeroU128, ArchivedOptionNonZeroU16,
35 ArchivedOptionNonZeroU32, ArchivedOptionNonZeroU64,
36 ArchivedOptionNonZeroU8, ArchivedOptionNonZeroUsize,
37 },
38 },
39 option::ArchivedOption,
40 primitive::{FixedNonZeroIsize, FixedNonZeroUsize},
41 ser::{Allocator, Writer},
42 string::{ArchivedString, StringResolver},
43 traits::NoUndef,
44 vec::{ArchivedVec, VecResolver},
45 with::{
46 ArchiveWith, AsBox, AsString, AsVec, DeserializeWith, Identity, Inline,
47 InlineAsBox, Map, MapNiche, Niche, NicheInto, SerializeWith, Skip,
48 Unsafe,
49 },
50 Archive, ArchiveUnsized, Deserialize, Place, Serialize, SerializeUnsized,
51};
52
53#[allow(dead_code)]
58pub struct RefWrapper<'o, A, O>(pub &'o O, pub PhantomData<A>);
62
63impl<A: ArchiveWith<O>, O> Archive for RefWrapper<'_, A, O> {
64 type Archived = <A as ArchiveWith<O>>::Archived;
65 type Resolver = <A as ArchiveWith<O>>::Resolver;
66
67 fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>) {
68 A::resolve_with(self.0, resolver, out)
69 }
70}
71
72impl<A, O, S> Serialize<S> for RefWrapper<'_, A, O>
73where
74 A: ArchiveWith<O> + SerializeWith<O, S>,
75 S: Fallible + ?Sized,
76{
77 fn serialize(&self, s: &mut S) -> Result<Self::Resolver, S::Error> {
78 A::serialize_with(self.0, s)
79 }
80}
81
82impl<A, O: Hash> Hash for RefWrapper<'_, A, O> {
83 fn hash<H: Hasher>(&self, state: &mut H) {
84 self.0.hash(state)
85 }
86}
87
88impl<A, O: PartialEq> PartialEq for RefWrapper<'_, A, O> {
89 fn eq(&self, other: &Self) -> bool {
90 self.0 == other.0
91 }
92}
93
94impl<A, O: Eq> Eq for RefWrapper<'_, A, O> {}
95
96impl<F: ArchiveUnsized + ?Sized> ArchiveWith<&F> for InlineAsBox {
99 type Archived = ArchivedBox<F::Archived>;
100 type Resolver = BoxResolver;
101
102 fn resolve_with(
103 field: &&F,
104 resolver: Self::Resolver,
105 out: Place<Self::Archived>,
106 ) {
107 ArchivedBox::resolve_from_ref(*field, resolver, out);
108 }
109}
110
111impl<F, S> SerializeWith<&F, S> for InlineAsBox
112where
113 F: SerializeUnsized<S> + ?Sized,
114 S: Fallible + ?Sized,
115{
116 fn serialize_with(
117 field: &&F,
118 serializer: &mut S,
119 ) -> Result<Self::Resolver, S::Error> {
120 ArchivedBox::serialize_from_ref(*field, serializer)
121 }
122}
123
124impl ArchiveWith<&str> for AsString {
127 type Archived = ArchivedString;
128 type Resolver = StringResolver;
129
130 fn resolve_with(
131 field: &&str,
132 resolver: Self::Resolver,
133 out: Place<Self::Archived>,
134 ) {
135 ArchivedString::resolve_from_str(field, resolver, out);
136 }
137}
138
139impl<S> SerializeWith<&str, S> for AsString
140where
141 str: SerializeUnsized<S>,
142 S: Fallible + ?Sized,
143 S::Error: Source,
144{
145 fn serialize_with(
146 field: &&str,
147 serializer: &mut S,
148 ) -> Result<Self::Resolver, S::Error> {
149 ArchivedString::serialize_from_str(field, serializer)
150 }
151}
152
153impl<T: Archive> ArchiveWith<&[T]> for AsVec {
156 type Archived = ArchivedVec<T::Archived>;
157 type Resolver = VecResolver;
158
159 fn resolve_with(
160 field: &&[T],
161 resolver: Self::Resolver,
162 out: Place<Self::Archived>,
163 ) {
164 ArchivedVec::resolve_from_len(field.len(), resolver, out);
165 }
166}
167
168impl<T, S> SerializeWith<&[T], S> for AsVec
169where
170 T: Serialize<S>,
171 S: Fallible + Allocator + Writer + ?Sized,
172{
173 fn serialize_with(
174 field: &&[T],
175 serializer: &mut S,
176 ) -> Result<Self::Resolver, S::Error> {
177 ArchivedVec::serialize_from_slice(field, serializer)
178 }
179}
180
181impl<F: ArchiveUnsized + ?Sized> ArchiveWith<F> for AsBox {
184 type Archived = ArchivedBox<F::Archived>;
185 type Resolver = BoxResolver;
186
187 fn resolve_with(
188 field: &F,
189 resolver: Self::Resolver,
190 out: Place<Self::Archived>,
191 ) {
192 ArchivedBox::resolve_from_ref(field, resolver, out);
193 }
194}
195
196impl<F, S> SerializeWith<F, S> for AsBox
197where
198 F: SerializeUnsized<S> + ?Sized,
199 S: Fallible + ?Sized,
200{
201 fn serialize_with(
202 field: &F,
203 serializer: &mut S,
204 ) -> Result<Self::Resolver, S::Error> {
205 ArchivedBox::serialize_from_ref(field, serializer)
206 }
207}
208
209impl<F, D> DeserializeWith<ArchivedBox<F::Archived>, F, D> for AsBox
210where
211 F: Archive,
212 F::Archived: Deserialize<F, D>,
213 D: Fallible + ?Sized,
214{
215 fn deserialize_with(
216 field: &ArchivedBox<F::Archived>,
217 deserializer: &mut D,
218 ) -> Result<F, D::Error> {
219 field.get().deserialize(deserializer)
220 }
221}
222
223impl<A, O> ArchiveWith<Option<O>> for Map<A>
227where
228 A: ArchiveWith<O>,
229{
230 type Archived = ArchivedOption<<A as ArchiveWith<O>>::Archived>;
231 type Resolver = Option<<A as ArchiveWith<O>>::Resolver>;
232
233 fn resolve_with(
234 field: &Option<O>,
235 resolver: Self::Resolver,
236 out: Place<Self::Archived>,
237 ) {
238 match resolver {
239 None => {
240 let out = unsafe {
241 out.cast_unchecked::<ArchivedOptionVariantNone>()
242 };
243 munge!(let ArchivedOptionVariantNone(tag) = out);
244 tag.write(ArchivedOptionTag::None);
245 }
246 Some(resolver) => {
247 let out = unsafe {
248 out.cast_unchecked::<ArchivedOptionVariantSome<
249 <A as ArchiveWith<O>>::Archived,
250 >>()
251 };
252 munge!(let ArchivedOptionVariantSome(tag, out_value) = out);
253 tag.write(ArchivedOptionTag::Some);
254
255 let value = if let Some(value) = field.as_ref() {
256 value
257 } else {
258 unsafe {
259 unreachable_unchecked();
260 }
261 };
262
263 A::resolve_with(value, resolver, out_value);
264 }
265 }
266 }
267}
268
269impl<A, O, S> SerializeWith<Option<O>, S> for Map<A>
270where
271 S: Fallible + ?Sized,
272 A: ArchiveWith<O> + SerializeWith<O, S>,
273{
274 fn serialize_with(
275 field: &Option<O>,
276 s: &mut S,
277 ) -> Result<Self::Resolver, S::Error> {
278 field
279 .as_ref()
280 .map(|value| A::serialize_with(value, s))
281 .transpose()
282 }
283}
284
285impl<A, O, D>
286 DeserializeWith<
287 ArchivedOption<<A as ArchiveWith<O>>::Archived>,
288 Option<O>,
289 D,
290 > for Map<A>
291where
292 D: Fallible + ?Sized,
293 A: ArchiveWith<O> + DeserializeWith<<A as ArchiveWith<O>>::Archived, O, D>,
294{
295 fn deserialize_with(
296 field: &ArchivedOption<<A as ArchiveWith<O>>::Archived>,
297 d: &mut D,
298 ) -> Result<Option<O>, D::Error> {
299 match field {
300 ArchivedOption::Some(value) => {
301 Ok(Some(A::deserialize_with(value, d)?))
302 }
303 ArchivedOption::None => Ok(None),
304 }
305 }
306}
307
308#[repr(u8)]
309enum ArchivedOptionTag {
310 None,
311 Some,
312}
313
314unsafe impl NoUndef for ArchivedOptionTag {}
317
318#[repr(C)]
319struct ArchivedOptionVariantNone(ArchivedOptionTag);
320
321#[repr(C)]
322struct ArchivedOptionVariantSome<T>(ArchivedOptionTag, T);
323
324impl<A, O, const N: usize> ArchiveWith<[O; N]> for Map<A>
327where
328 A: ArchiveWith<O>,
329{
330 type Archived = [A::Archived; N];
331 type Resolver = [A::Resolver; N];
332
333 fn resolve_with(
334 field: &[O; N],
335 resolver: Self::Resolver,
336 out: Place<Self::Archived>,
337 ) {
338 for (i, (value, resolver)) in field.iter().zip(resolver).enumerate() {
339 A::resolve_with(value, resolver, unsafe { out.index(i) })
340 }
341 }
342}
343
344impl<A, O, S, const N: usize> SerializeWith<[O; N], S> for Map<A>
345where
346 S: Fallible + ?Sized,
347 A: ArchiveWith<O> + SerializeWith<O, S>,
348{
349 fn serialize_with(
350 field: &[O; N],
351 serializer: &mut S,
352 ) -> Result<Self::Resolver, S::Error> {
353 let mut result = core::mem::MaybeUninit::<Self::Resolver>::uninit();
354 let result_ptr = result.as_mut_ptr().cast::<A::Resolver>();
355 for (i, value) in field.iter().enumerate() {
356 let serialized = A::serialize_with(value, serializer)?;
357 unsafe { result_ptr.add(i).write(serialized) };
358 }
359 Ok(unsafe { result.assume_init() })
360 }
361}
362
363impl<O, A, D, const N: usize> DeserializeWith<[A::Archived; N], [O; N], D>
364 for Map<A>
365where
366 D: Fallible + ?Sized,
367 A: ArchiveWith<O> + DeserializeWith<A::Archived, O, D>,
368{
369 fn deserialize_with(
370 field: &[A::Archived; N],
371 deserializer: &mut D,
372 ) -> Result<[O; N], <D as Fallible>::Error> {
373 let mut result = core::mem::MaybeUninit::<[O; N]>::uninit();
374 let result_ptr = result.as_mut_ptr().cast::<O>();
375 for (i, value) in field.iter().enumerate() {
376 let deserialized = A::deserialize_with(value, deserializer)?;
377 unsafe { result_ptr.add(i).write(deserialized) };
378 }
379 Ok(unsafe { result.assume_init() })
380 }
381}
382
383macro_rules! impl_nonzero_niche {
386 ($ar:ty, $nz:ty, $ne:ty) => {
387 impl ArchiveWith<Option<$nz>> for Niche {
388 type Archived = $ar;
389 type Resolver = ();
390
391 #[inline]
392 fn resolve_with(
393 field: &Option<$nz>,
394 _: Self::Resolver,
395 out: Place<Self::Archived>,
396 ) {
397 <$ar>::resolve_from_option(*field, out);
398 }
399 }
400
401 impl<S: Fallible + ?Sized> SerializeWith<Option<$nz>, S> for Niche {
402 fn serialize_with(
403 _: &Option<$nz>,
404 _: &mut S,
405 ) -> Result<Self::Resolver, S::Error> {
406 Ok(())
407 }
408 }
409
410 impl<D> DeserializeWith<$ar, Option<$nz>, D> for Niche
411 where
412 D: Fallible + ?Sized,
413 {
414 fn deserialize_with(
415 field: &$ar,
416 _: &mut D,
417 ) -> Result<Option<$nz>, D::Error> {
418 Ok(field.as_ref().map(|x| (*x).into()))
419 }
420 }
421 };
422}
423
424impl_nonzero_niche!(ArchivedOptionNonZeroI8, NonZeroI8, i8);
425impl_nonzero_niche!(ArchivedOptionNonZeroI16, NonZeroI16, i16);
426impl_nonzero_niche!(ArchivedOptionNonZeroI32, NonZeroI32, i32);
427impl_nonzero_niche!(ArchivedOptionNonZeroI64, NonZeroI64, i64);
428impl_nonzero_niche!(ArchivedOptionNonZeroI128, NonZeroI128, i128);
429
430impl_nonzero_niche!(ArchivedOptionNonZeroU8, NonZeroU8, u8);
431impl_nonzero_niche!(ArchivedOptionNonZeroU16, NonZeroU16, u16);
432impl_nonzero_niche!(ArchivedOptionNonZeroU32, NonZeroU32, u32);
433impl_nonzero_niche!(ArchivedOptionNonZeroU64, NonZeroU64, u64);
434impl_nonzero_niche!(ArchivedOptionNonZeroU128, NonZeroU128, u128);
435
436impl ArchiveWith<Option<NonZeroIsize>> for Niche {
437 type Archived = ArchivedOptionNonZeroIsize;
438 type Resolver = ();
439
440 #[inline]
441 fn resolve_with(
442 field: &Option<NonZeroIsize>,
443 _: Self::Resolver,
444 out: Place<Self::Archived>,
445 ) {
446 let f = field.as_ref().map(|&x| x.try_into().unwrap());
447 ArchivedOptionNonZeroIsize::resolve_from_option(f, out);
448 }
449}
450
451impl<S: Fallible + ?Sized> SerializeWith<Option<NonZeroIsize>, S> for Niche {
452 fn serialize_with(
453 _: &Option<NonZeroIsize>,
454 _: &mut S,
455 ) -> Result<Self::Resolver, S::Error> {
456 Ok(())
457 }
458}
459
460impl<D> DeserializeWith<ArchivedOptionNonZeroIsize, Option<NonZeroIsize>, D>
461 for Niche
462where
463 D: Fallible + ?Sized,
464{
465 fn deserialize_with(
466 field: &ArchivedOptionNonZeroIsize,
467 _: &mut D,
468 ) -> Result<Option<NonZeroIsize>, D::Error> {
469 #[allow(clippy::useless_conversion)]
471 Ok(field
472 .as_ref()
473 .map(|x| FixedNonZeroIsize::from(*x).try_into().unwrap()))
474 }
475}
476
477impl ArchiveWith<Option<NonZeroUsize>> for Niche {
478 type Archived = ArchivedOptionNonZeroUsize;
479 type Resolver = ();
480
481 #[inline]
482 fn resolve_with(
483 field: &Option<NonZeroUsize>,
484 _: Self::Resolver,
485 out: Place<Self::Archived>,
486 ) {
487 let f = field.as_ref().map(|&x| x.try_into().unwrap());
488 ArchivedOptionNonZeroUsize::resolve_from_option(f, out);
489 }
490}
491
492impl<S: Fallible + ?Sized> SerializeWith<Option<NonZeroUsize>, S> for Niche {
493 fn serialize_with(
494 _: &Option<NonZeroUsize>,
495 _: &mut S,
496 ) -> Result<Self::Resolver, S::Error> {
497 Ok(())
498 }
499}
500
501impl<D> DeserializeWith<ArchivedOptionNonZeroUsize, Option<NonZeroUsize>, D>
502 for Niche
503where
504 D: Fallible + ?Sized,
505{
506 fn deserialize_with(
507 field: &ArchivedOptionNonZeroUsize,
508 _: &mut D,
509 ) -> Result<Option<NonZeroUsize>, D::Error> {
510 #[allow(clippy::useless_conversion)]
512 Ok(field
513 .as_ref()
514 .map(|x| FixedNonZeroUsize::from(*x).try_into().unwrap()))
515 }
516}
517
518impl<T, N> ArchiveWith<Option<T>> for NicheInto<N>
521where
522 T: Archive,
523 N: Niching<T::Archived> + ?Sized,
524{
525 type Archived = NichedOption<T::Archived, N>;
526 type Resolver = Option<T::Resolver>;
527
528 fn resolve_with(
529 field: &Option<T>,
530 resolver: Self::Resolver,
531 out: Place<Self::Archived>,
532 ) {
533 NichedOption::<T::Archived, N>::resolve_from_option(
534 field.as_ref(),
535 resolver,
536 out,
537 );
538 }
539}
540
541impl<T, N, S> SerializeWith<Option<T>, S> for NicheInto<N>
542where
543 T: Serialize<S>,
544 N: Niching<T::Archived> + ?Sized,
545 S: Fallible + ?Sized,
546{
547 fn serialize_with(
548 field: &Option<T>,
549 serializer: &mut S,
550 ) -> Result<Self::Resolver, S::Error> {
551 NichedOption::<T::Archived, N>::serialize_from_option(
552 field.as_ref(),
553 serializer,
554 )
555 }
556}
557
558impl<T, N, D> DeserializeWith<NichedOption<T::Archived, N>, Option<T>, D>
559 for NicheInto<N>
560where
561 T: Archive<Archived: Deserialize<T, D>>,
562 N: Niching<T::Archived> + ?Sized,
563 D: Fallible + ?Sized,
564{
565 fn deserialize_with(
566 field: &NichedOption<T::Archived, N>,
567 deserializer: &mut D,
568 ) -> Result<Option<T>, D::Error> {
569 Deserialize::deserialize(field, deserializer)
570 }
571}
572
573impl<T, N, D> Deserialize<Option<T>, D> for NichedOption<T::Archived, N>
574where
575 T: Archive<Archived: Deserialize<T, D>>,
576 N: Niching<T::Archived> + ?Sized,
577 D: Fallible + ?Sized,
578{
579 fn deserialize(&self, deserializer: &mut D) -> Result<Option<T>, D::Error> {
580 match self.as_ref() {
581 Some(value) => value.deserialize(deserializer).map(Some),
582 None => Ok(None),
583 }
584 }
585}
586
587impl<T, W, N> ArchiveWith<Option<T>> for MapNiche<W, N>
590where
591 W: ArchiveWith<T> + ?Sized,
592 N: Niching<<W as ArchiveWith<T>>::Archived> + ?Sized,
593{
594 type Archived = NichedOption<<W as ArchiveWith<T>>::Archived, N>;
595 type Resolver = Option<<W as ArchiveWith<T>>::Resolver>;
596
597 fn resolve_with(
598 field: &Option<T>,
599 resolver: Self::Resolver,
600 out: Place<Self::Archived>,
601 ) {
602 let out = NichedOption::munge_place(out);
603 match field {
604 Some(value) => {
605 let resolver = resolver.expect("non-niched resolver");
606 W::resolve_with(value, resolver, out);
607 }
608 None => N::resolve_niched(out),
609 }
610 }
611}
612
613impl<T, W, N, S> SerializeWith<Option<T>, S> for MapNiche<W, N>
614where
615 W: SerializeWith<T, S> + ?Sized,
616 N: Niching<<W as ArchiveWith<T>>::Archived> + ?Sized,
617 S: Fallible + ?Sized,
618{
619 fn serialize_with(
620 field: &Option<T>,
621 serializer: &mut S,
622 ) -> Result<Self::Resolver, S::Error> {
623 match field {
624 Some(value) => W::serialize_with(value, serializer).map(Some),
625 None => Ok(None),
626 }
627 }
628}
629
630impl<T, W, N, D>
631 DeserializeWith<
632 NichedOption<<W as ArchiveWith<T>>::Archived, N>,
633 Option<T>,
634 D,
635 > for MapNiche<W, N>
636where
637 W: ArchiveWith<T> + DeserializeWith<<W as ArchiveWith<T>>::Archived, T, D>,
638 N: Niching<<W as ArchiveWith<T>>::Archived> + ?Sized,
639 D: Fallible + ?Sized,
640{
641 fn deserialize_with(
642 field: &NichedOption<<W as ArchiveWith<T>>::Archived, N>,
643 deserializer: &mut D,
644 ) -> Result<Option<T>, D::Error> {
645 field
646 .as_ref()
647 .map(|value| W::deserialize_with(value, deserializer))
648 .transpose()
649 }
650}
651
652impl<T> ArchiveWith<Option<T>> for DefaultNiche
655where
656 T: Archive,
657 Self: Niching<T::Archived>,
658{
659 type Archived = NichedOption<T::Archived, Self>;
660 type Resolver = Option<T::Resolver>;
661
662 fn resolve_with(
663 field: &Option<T>,
664 resolver: Self::Resolver,
665 out: Place<Self::Archived>,
666 ) {
667 NicheInto::<Self>::resolve_with(field, resolver, out);
668 }
669}
670
671impl<T, S> SerializeWith<Option<T>, S> for DefaultNiche
672where
673 T: Serialize<S>,
674 Self: Niching<T::Archived>,
675 S: Fallible + ?Sized,
676{
677 fn serialize_with(
678 field: &Option<T>,
679 serializer: &mut S,
680 ) -> Result<Self::Resolver, S::Error> {
681 NicheInto::<Self>::serialize_with(field, serializer)
682 }
683}
684
685impl<T, D> DeserializeWith<NichedOption<T::Archived, Self>, Option<T>, D>
686 for DefaultNiche
687where
688 T: Archive<Archived: Deserialize<T, D>>,
689 Self: Niching<T::Archived>,
690 D: Fallible + ?Sized,
691{
692 fn deserialize_with(
693 field: &NichedOption<T::Archived, Self>,
694 deserializer: &mut D,
695 ) -> Result<Option<T>, D::Error> {
696 NicheInto::<Self>::deserialize_with(field, deserializer)
697 }
698}
699
700impl<F: Archive> ArchiveWith<&F> for Inline {
703 type Archived = F::Archived;
704 type Resolver = F::Resolver;
705
706 fn resolve_with(
707 field: &&F,
708 resolver: Self::Resolver,
709 out: Place<Self::Archived>,
710 ) {
711 field.resolve(resolver, out);
712 }
713}
714
715impl<F: Serialize<S>, S: Fallible + ?Sized> SerializeWith<&F, S> for Inline {
716 fn serialize_with(
717 field: &&F,
718 serializer: &mut S,
719 ) -> Result<Self::Resolver, S::Error> {
720 field.serialize(serializer)
721 }
722}
723
724impl<F: Archive> ArchiveWith<UnsafeCell<F>> for Unsafe {
727 type Archived = F::Archived;
728 type Resolver = F::Resolver;
729
730 fn resolve_with(
731 field: &UnsafeCell<F>,
732 resolver: Self::Resolver,
733 out: Place<Self::Archived>,
734 ) {
735 let value = unsafe { &*field.get() };
736 F::resolve(value, resolver, out);
737 }
738}
739
740impl<F, S> SerializeWith<UnsafeCell<F>, S> for Unsafe
741where
742 F: Serialize<S>,
743 S: Fallible + ?Sized,
744{
745 fn serialize_with(
746 field: &UnsafeCell<F>,
747 serializer: &mut S,
748 ) -> Result<Self::Resolver, S::Error> {
749 unsafe { (*field.get()).serialize(serializer) }
750 }
751}
752
753impl<F, D> DeserializeWith<F::Archived, UnsafeCell<F>, D> for Unsafe
754where
755 F: Archive,
756 F::Archived: Deserialize<F, D>,
757 D: Fallible + ?Sized,
758{
759 fn deserialize_with(
760 field: &F::Archived,
761 deserializer: &mut D,
762 ) -> Result<UnsafeCell<F>, D::Error> {
763 field.deserialize(deserializer).map(|x| UnsafeCell::new(x))
764 }
765}
766
767impl<F: Archive> ArchiveWith<Cell<F>> for Unsafe {
768 type Archived = F::Archived;
769 type Resolver = F::Resolver;
770
771 fn resolve_with(
772 field: &Cell<F>,
773 resolver: Self::Resolver,
774 out: Place<Self::Archived>,
775 ) {
776 let value = unsafe { &*field.as_ptr() };
777 F::resolve(value, resolver, out);
778 }
779}
780
781impl<F, S> SerializeWith<Cell<F>, S> for Unsafe
782where
783 F: Serialize<S>,
784 S: Fallible + ?Sized,
785{
786 fn serialize_with(
787 field: &Cell<F>,
788 serializer: &mut S,
789 ) -> Result<Self::Resolver, S::Error> {
790 unsafe { (*field.as_ptr()).serialize(serializer) }
791 }
792}
793
794impl<F, D> DeserializeWith<F::Archived, Cell<F>, D> for Unsafe
795where
796 F: Archive,
797 F::Archived: Deserialize<F, D>,
798 D: Fallible + ?Sized,
799{
800 fn deserialize_with(
801 field: &F::Archived,
802 deserializer: &mut D,
803 ) -> Result<Cell<F>, D::Error> {
804 field.deserialize(deserializer).map(|x| Cell::new(x))
805 }
806}
807
808impl<F> ArchiveWith<F> for Skip {
811 type Archived = ();
812 type Resolver = ();
813
814 fn resolve_with(_: &F, _: Self::Resolver, _: Place<Self::Archived>) {}
815}
816
817impl<F, S: Fallible + ?Sized> SerializeWith<F, S> for Skip {
818 fn serialize_with(_: &F, _: &mut S) -> Result<(), S::Error> {
819 Ok(())
820 }
821}
822
823impl<F: Default, D: Fallible + ?Sized> DeserializeWith<(), F, D> for Skip {
824 fn deserialize_with(_: &(), _: &mut D) -> Result<F, D::Error> {
825 Ok(Default::default())
826 }
827}
828
829impl<F: Archive> ArchiveWith<F> for Identity {
832 type Archived = F::Archived;
833 type Resolver = F::Resolver;
834
835 fn resolve_with(
836 field: &F,
837 resolver: Self::Resolver,
838 out: Place<Self::Archived>,
839 ) {
840 field.resolve(resolver, out)
841 }
842}
843
844impl<F: Serialize<S>, S: Fallible + ?Sized> SerializeWith<F, S> for Identity {
845 fn serialize_with(
846 field: &F,
847 serializer: &mut S,
848 ) -> Result<Self::Resolver, S::Error> {
849 field.serialize(serializer)
850 }
851}
852
853impl<F, T, D> DeserializeWith<F, T, D> for Identity
854where
855 F: Deserialize<T, D>,
856 D: Fallible + ?Sized,
857{
858 fn deserialize_with(
859 field: &F,
860 deserializer: &mut D,
861 ) -> Result<T, <D as Fallible>::Error> {
862 field.deserialize(deserializer)
863 }
864}
865
866#[cfg(test)]
867mod tests {
868 use core::f32;
869
870 use crate::{
871 api::test::{deserialize, roundtrip, roundtrip_with, to_archived},
872 niche::niching::{NaN, Zero},
873 rancor::Fallible,
874 ser::Writer,
875 with::{
876 ArchiveWith, AsBox, AsString, AsVec, DeserializeWith, Identity,
877 Inline, InlineAsBox, Map, Niche, NicheInto, SerializeWith, Unsafe,
878 With,
879 },
880 Archive, Archived, Deserialize, Place, Serialize,
881 };
882
883 struct AsFloat;
884
885 impl ArchiveWith<i32> for AsFloat {
886 type Archived = Archived<f32>;
887 type Resolver = ();
888
889 fn resolve_with(
890 value: &i32,
891 _: Self::Resolver,
892 out: Place<Self::Archived>,
893 ) {
894 out.write(Archived::<f32>::from_native(*value as f32));
895 }
896 }
897
898 impl<S> SerializeWith<i32, S> for AsFloat
899 where
900 S: Fallible + Writer + ?Sized,
901 {
902 fn serialize_with(
903 _: &i32,
904 _: &mut S,
905 ) -> Result<Self::Resolver, S::Error> {
906 Ok(())
907 }
908 }
909
910 impl<D> DeserializeWith<Archived<f32>, i32, D> for AsFloat
911 where
912 D: Fallible + ?Sized,
913 {
914 fn deserialize_with(
915 value: &Archived<f32>,
916 _: &mut D,
917 ) -> Result<i32, D::Error> {
918 Ok(value.to_native() as i32)
919 }
920 }
921
922 #[test]
923 fn with_struct() {
924 #[derive(Archive, Serialize, Deserialize, Debug, PartialEq)]
925 #[rkyv(crate, derive(Debug))]
926 struct Test {
927 #[rkyv(with = AsFloat)]
928 value: i32,
929 other: i32,
930 }
931
932 let value = Test {
933 value: 10,
934 other: 10,
935 };
936 roundtrip_with(&value, |_, archived| {
937 assert_eq!(archived.value, 10.0);
938 assert_eq!(archived.other, 10);
939 });
940 }
941
942 #[test]
943 fn with_tuple_struct() {
944 #[derive(Archive, Serialize, Deserialize, Debug, PartialEq)]
945 #[rkyv(crate, derive(Debug))]
946 struct Test(#[rkyv(with = AsFloat)] i32, i32);
947
948 let value = Test(10, 10);
949 roundtrip_with(&value, |_, archived| {
950 assert_eq!(archived.0, 10.0);
951 assert_eq!(archived.1, 10);
952 });
953 }
954
955 #[test]
956 fn with_enum() {
957 #[derive(Archive, Serialize, Deserialize, Debug, PartialEq)]
958 #[rkyv(crate, derive(Debug))]
959 enum Test {
960 A {
961 #[rkyv(with = AsFloat)]
962 value: i32,
963 other: i32,
964 },
965 B(#[rkyv(with = AsFloat)] i32, i32),
966 }
967
968 let value = Test::A {
969 value: 10,
970 other: 10,
971 };
972 roundtrip_with(&value, |_, archived| {
973 if let ArchivedTest::A { value, other } = archived {
974 assert_eq!(*value, 10.0);
975 assert_eq!(*other, 10);
976 } else {
977 panic!("expected variant A");
978 }
979 });
980
981 let value = Test::B(10, 10);
982 roundtrip_with(&value, |_, archived| {
983 if let ArchivedTest::B(value, other) = archived {
984 assert_eq!(*value, 10.0);
985 assert_eq!(*other, 10);
986 } else {
987 panic!("expected variant B");
988 }
989 });
990 }
991
992 #[test]
993 fn with_wrapper() {
994 to_archived(With::<_, AsFloat>::cast(&10), |archived| {
995 assert_eq!(archived.to_native(), 10.0);
996 let original = deserialize(With::<_, AsFloat>::cast(&*archived));
997 assert_eq!(original, 10);
998 });
999 }
1000
1001 #[test]
1002 fn with_inline() {
1003 #[derive(Archive, Serialize, Deserialize)]
1004 #[rkyv(crate)]
1005 struct Test<'a> {
1006 #[rkyv(with = Inline)]
1007 value: &'a i32,
1008 }
1009
1010 let a = 42;
1011 let value = Test { value: &a };
1012 to_archived(&value, |archived| {
1013 assert_eq!(archived.value, 42);
1014 });
1015 }
1016
1017 #[test]
1018 fn with_boxed() {
1019 #[derive(Archive, Serialize, Deserialize)]
1020 #[rkyv(crate)]
1021 struct Test {
1022 #[rkyv(with = AsBox)]
1023 value: i32,
1024 }
1025
1026 let value = Test { value: 42 };
1027 to_archived(&value, |archived| {
1028 assert_eq!(archived.value.get(), &42);
1029 });
1030 }
1031
1032 #[test]
1033 fn with_boxed_inline() {
1034 #[derive(Archive, Serialize, Deserialize)]
1035 #[rkyv(crate)]
1036 struct Test<'a> {
1037 #[rkyv(with = InlineAsBox)]
1038 value: &'a str,
1039 }
1040
1041 let a = "hello world";
1042 let value = Test { value: &a };
1043 to_archived(&value, |archived| {
1044 assert_eq!(archived.value.as_ref(), "hello world");
1045 });
1046 }
1047
1048 #[test]
1049 fn with_str() {
1050 #[derive(Archive, Serialize, Deserialize)]
1051 #[rkyv(crate)]
1052 struct Test<'a> {
1053 #[rkyv(with = AsString)]
1054 value: &'a str,
1055 }
1056
1057 let a = "hello world";
1058 let value = Test { value: a };
1059 to_archived(&value, |archived| {
1060 assert_eq!(archived.value.as_str(), "hello world");
1061 });
1062 }
1063
1064 #[test]
1065 fn with_slice() {
1066 #[derive(Archive, Serialize, Deserialize)]
1067 #[rkyv(crate)]
1068 struct Test<'a> {
1069 #[rkyv(with = AsVec)]
1070 value: &'a [bool],
1071 }
1072
1073 let a: &[bool] = &[true, true, false, true];
1074 let value = Test { value: a };
1075 to_archived(&value, |archived| {
1076 assert_eq!(archived.value.as_slice(), &[true, true, false, true]);
1077 });
1078 }
1079
1080 #[test]
1081 fn with_niche_nonzero() {
1082 use core::{
1083 mem::size_of,
1084 num::{
1085 NonZeroI32, NonZeroI8, NonZeroIsize, NonZeroU32, NonZeroU8,
1086 NonZeroUsize,
1087 },
1088 };
1089
1090 #[derive(Archive, Serialize, Deserialize)]
1091 #[rkyv(crate)]
1092 struct TestNiche {
1093 #[rkyv(with = Niche)]
1094 a: Option<NonZeroI8>,
1095 #[rkyv(with = Niche)]
1096 b: Option<NonZeroI32>,
1097 #[rkyv(with = Niche)]
1098 c: Option<NonZeroIsize>,
1099 #[rkyv(with = Niche)]
1100 d: Option<NonZeroU8>,
1101 #[rkyv(with = Niche)]
1102 e: Option<NonZeroU32>,
1103 #[rkyv(with = Niche)]
1104 f: Option<NonZeroUsize>,
1105 }
1106
1107 #[derive(Archive, Serialize, Deserialize)]
1108 #[rkyv(crate)]
1109 struct TestZeroNiche {
1110 #[rkyv(with = NicheInto<Zero>)]
1111 a: Option<NonZeroI8>,
1112 #[rkyv(with = NicheInto<Zero>)]
1113 b: Option<NonZeroI32>,
1114 #[rkyv(with = NicheInto<Zero>)]
1115 c: Option<NonZeroIsize>,
1116 #[rkyv(with = NicheInto<Zero>)]
1117 d: Option<NonZeroU8>,
1118 #[rkyv(with = NicheInto<Zero>)]
1119 e: Option<NonZeroU32>,
1120 #[rkyv(with = NicheInto<Zero>)]
1121 f: Option<NonZeroUsize>,
1122 }
1123
1124 #[derive(Archive, Serialize, Deserialize)]
1125 #[rkyv(crate)]
1126 struct TestNoNiching {
1127 a: Option<NonZeroI8>,
1128 b: Option<NonZeroI32>,
1129 c: Option<NonZeroIsize>,
1130 d: Option<NonZeroU8>,
1131 e: Option<NonZeroU32>,
1132 f: Option<NonZeroUsize>,
1133 }
1134
1135 let value = TestNiche {
1136 a: Some(NonZeroI8::new(10).unwrap()),
1137 b: Some(NonZeroI32::new(10).unwrap()),
1138 c: Some(NonZeroIsize::new(10).unwrap()),
1139 d: Some(NonZeroU8::new(10).unwrap()),
1140 e: Some(NonZeroU32::new(10).unwrap()),
1141 f: Some(NonZeroUsize::new(10).unwrap()),
1142 };
1143 to_archived(&value, |archived| {
1144 assert!(archived.a.is_some());
1145 assert_eq!(archived.a.as_ref().unwrap().get(), 10);
1146 assert!(archived.b.is_some());
1147 assert_eq!(archived.b.as_ref().unwrap().get(), 10);
1148 assert!(archived.c.is_some());
1149 assert_eq!(archived.c.as_ref().unwrap().get(), 10);
1150 assert!(archived.d.is_some());
1151 assert_eq!(archived.d.as_ref().unwrap().get(), 10);
1152 assert!(archived.e.is_some());
1153 assert_eq!(archived.e.as_ref().unwrap().get(), 10);
1154 assert!(archived.f.is_some());
1155 assert_eq!(archived.f.as_ref().unwrap().get(), 10);
1156 });
1157
1158 let value = TestNiche {
1159 a: None,
1160 b: None,
1161 c: None,
1162 d: None,
1163 e: None,
1164 f: None,
1165 };
1166 to_archived(&value, |archived| {
1167 assert!(archived.a.is_none());
1168 assert!(archived.b.is_none());
1169 assert!(archived.c.is_none());
1170 assert!(archived.d.is_none());
1171 assert!(archived.e.is_none());
1172 assert!(archived.f.is_none());
1173 });
1174
1175 assert!(
1176 size_of::<Archived<TestNiche>>()
1177 < size_of::<Archived<TestNoNiching>>()
1178 );
1179
1180 let value = TestZeroNiche {
1181 a: Some(NonZeroI8::new(10).unwrap()),
1182 b: Some(NonZeroI32::new(10).unwrap()),
1183 c: Some(NonZeroIsize::new(10).unwrap()),
1184 d: Some(NonZeroU8::new(10).unwrap()),
1185 e: Some(NonZeroU32::new(10).unwrap()),
1186 f: Some(NonZeroUsize::new(10).unwrap()),
1187 };
1188 to_archived(&value, |archived| {
1189 assert!(archived.a.is_some());
1190 assert_eq!(archived.a.as_ref().unwrap().get(), 10);
1191 assert!(archived.b.is_some());
1192 assert_eq!(archived.b.as_ref().unwrap().get(), 10);
1193 assert!(archived.c.is_some());
1194 assert_eq!(archived.c.as_ref().unwrap().get(), 10);
1195 assert!(archived.d.is_some());
1196 assert_eq!(archived.d.as_ref().unwrap().get(), 10);
1197 assert!(archived.e.is_some());
1198 assert_eq!(archived.e.as_ref().unwrap().get(), 10);
1199 assert!(archived.f.is_some());
1200 assert_eq!(archived.f.as_ref().unwrap().get(), 10);
1201 });
1202
1203 let value = TestZeroNiche {
1204 a: None,
1205 b: None,
1206 c: None,
1207 d: None,
1208 e: None,
1209 f: None,
1210 };
1211 to_archived(&value, |archived| {
1212 assert!(archived.a.is_none());
1213 assert!(archived.b.is_none());
1214 assert!(archived.c.is_none());
1215 assert!(archived.d.is_none());
1216 assert!(archived.e.is_none());
1217 assert!(archived.f.is_none());
1218 });
1219
1220 assert!(
1221 size_of::<Archived<TestZeroNiche>>()
1222 < size_of::<Archived<TestNoNiching>>()
1223 );
1224 }
1225
1226 #[test]
1227 fn with_niche_float_nan() {
1228 #[derive(Archive, Serialize, Deserialize)]
1229 #[rkyv(crate)]
1230 struct Test {
1231 #[rkyv(with = NicheInto<NaN>)]
1232 a: Option<f32>,
1233 #[rkyv(with = NicheInto<NaN>)]
1234 b: Option<f64>,
1235 }
1236
1237 #[derive(Archive, Serialize, Deserialize)]
1238 #[rkyv(crate)]
1239 struct TestNoNiching {
1240 a: Option<f32>,
1241 b: Option<f64>,
1242 }
1243
1244 let value = Test {
1245 a: Some(123.45),
1246 b: Some(123.45),
1247 };
1248 to_archived(&value, |archived| {
1249 assert!(archived.a.is_some());
1250 assert_eq!(archived.a.as_ref().unwrap().to_native(), 123.45);
1251 assert!(archived.b.is_some());
1252 assert_eq!(archived.b.as_ref().unwrap().to_native(), 123.45);
1253 });
1254
1255 let value = Test {
1256 a: Some(f32::NAN),
1257 b: Some(f64::NAN),
1258 };
1259 to_archived(&value, |archived| {
1260 assert!(archived.a.is_none());
1261 assert!(archived.b.is_none());
1262 });
1263
1264 let value = Test { a: None, b: None };
1265 to_archived(&value, |archived| {
1266 assert!(archived.a.is_none());
1267 assert!(archived.b.is_none());
1268 });
1269
1270 assert!(
1271 size_of::<Archived<Test>>() < size_of::<Archived<TestNoNiching>>()
1272 );
1273 }
1274
1275 #[test]
1276 fn with_unsafe() {
1277 use core::cell::Cell;
1278
1279 #[derive(Archive, Debug, Deserialize, Serialize, PartialEq)]
1280 #[rkyv(crate, derive(Debug))]
1281 struct Test {
1282 #[rkyv(with = Unsafe)]
1283 inner: Cell<u32>,
1284 }
1285
1286 impl PartialEq<Test> for ArchivedTest {
1287 fn eq(&self, other: &Test) -> bool {
1288 self.inner == other.inner.get()
1289 }
1290 }
1291
1292 let value = Test {
1293 inner: Cell::new(100),
1294 };
1295 roundtrip(&value);
1296 }
1297
1298 #[test]
1299 fn with_identity() {
1300 #[derive(Archive, Serialize, Deserialize, Debug, PartialEq)]
1301 #[rkyv(crate, derive(Debug))]
1302 struct Test {
1303 #[rkyv(with = Identity)]
1304 value: i32,
1305 other: i32,
1306 }
1307
1308 let value = Test {
1309 value: 10,
1310 other: 10,
1311 };
1312 roundtrip_with(&value, |_, archived| {
1313 assert_eq!(archived.value, 10);
1314 assert_eq!(archived.other, 10);
1315 });
1316 }
1317
1318 #[test]
1319 fn with_map_array() {
1320 #[derive(Archive, Serialize, Deserialize, Debug, PartialEq)]
1321 #[rkyv(crate, derive(Debug))]
1322 struct Test {
1323 #[rkyv(with = Map<AsFloat>)]
1324 value: [i32; 2],
1325 other: [i32; 2],
1326 }
1327
1328 let value = Test {
1329 value: [1, 2],
1330 other: [1, 2],
1331 };
1332 roundtrip_with(&value, |_, archived| {
1333 assert_eq!(archived.value, [1.0, 2.0]);
1334 assert_eq!(archived.other, [1, 2]);
1335 });
1336 }
1337
1338 #[test]
1339 fn with_map_nested_array() {
1340 #[derive(Archive, Serialize, Deserialize, Debug, PartialEq)]
1341 #[rkyv(crate, derive(Debug))]
1342 struct Test {
1343 #[rkyv(with = Map<Map<AsFloat>>)]
1344 value: [[i32; 2]; 3],
1345 other: [[i32; 2]; 3],
1346 }
1347
1348 let value = Test {
1349 value: [[1, 2], [3, 4], [5, 6]],
1350 other: [[1, 2], [3, 4], [5, 6]],
1351 };
1352 roundtrip_with(&value, |_, archived| {
1353 assert_eq!(archived.value, [[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]);
1354 assert_eq!(archived.other, [[1, 2], [3, 4], [5, 6]]);
1355 });
1356 }
1357}