Skip to main content

rkyv/impls/core/with/
mod.rs

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// This is used by various internal impls, but isn't something we want to make a
54// public API. However, in some build configurations there end up being no uses
55// of this helper at all. So the most straightforward way to solve this is to
56// just allow this code to be unused.
57#[allow(dead_code)]
58// Wrapper for O so that we have an Archive and Serialize implementation
59// and ArchivedVec::serialize_from_* is happy about the bound
60// constraints
61pub 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
96// InlineAsBox
97
98impl<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
124// AsString
125
126impl 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
153// AsVec
154
155impl<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
181// AsBox
182
183impl<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
223// Map
224
225// Copy-paste from Option's impls for the most part
226impl<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
314// SAFETY: `ArchivedOptionTag` is `repr(u8)` and so always consists of a single
315// well-defined byte.
316unsafe impl NoUndef for ArchivedOptionTag {}
317
318#[repr(C)]
319struct ArchivedOptionVariantNone(ArchivedOptionTag);
320
321#[repr(C)]
322struct ArchivedOptionVariantSome<T>(ArchivedOptionTag, T);
323
324// [O; N]
325
326impl<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
383// Niche
384
385macro_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        // This conversion is necessary with archive_be and archive_le
470        #[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        // This conversion is necessary with archive_be and archive_le
511        #[allow(clippy::useless_conversion)]
512        Ok(field
513            .as_ref()
514            .map(|x| FixedNonZeroUsize::from(*x).try_into().unwrap()))
515    }
516}
517
518// NicheInto
519
520impl<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
587// MapNiche
588
589impl<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
652// DefaultNiche
653
654impl<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
700// Inline
701
702impl<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
724// Unsafe
725
726impl<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
808// Skip
809
810impl<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
829// Identity
830
831impl<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}