rkyv_test/with/
core.rs

1use crate::{
2    boxed::{ArchivedBox, BoxResolver},
3    niche::option_nonzero::{
4        ArchivedOptionNonZeroI128, ArchivedOptionNonZeroI16, ArchivedOptionNonZeroI32,
5        ArchivedOptionNonZeroI64, ArchivedOptionNonZeroI8, ArchivedOptionNonZeroU128,
6        ArchivedOptionNonZeroU16, ArchivedOptionNonZeroU32, ArchivedOptionNonZeroU64,
7        ArchivedOptionNonZeroU8,
8    },
9    option::ArchivedOption,
10    with::{
11        ArchiveWith, AsBox, DeserializeWith, Inline, Map, Niche, RefAsBox, SerializeWith, Skip,
12        Unsafe,
13    },
14    Archive, ArchiveUnsized, Deserialize, Fallible, Serialize, SerializeUnsized,
15};
16use ::core::{
17    cell::{Cell, UnsafeCell},
18    convert::TryInto,
19    hint::unreachable_unchecked,
20    num::{
21        NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,
22        NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,
23    },
24    ptr,
25};
26
27// Map for Options
28
29// Copy-paste from Option's impls for the most part
30impl<A, O> ArchiveWith<Option<O>> for Map<A>
31where
32    A: ArchiveWith<O>,
33{
34    type Archived = ArchivedOption<<A as ArchiveWith<O>>::Archived>;
35    type Resolver = Option<<A as ArchiveWith<O>>::Resolver>;
36
37    unsafe fn resolve_with(
38        field: &Option<O>,
39        pos: usize,
40        resolver: Self::Resolver,
41        out: *mut Self::Archived,
42    ) {
43        match resolver {
44            None => {
45                let out = out.cast::<ArchivedOptionVariantNone>();
46                ptr::addr_of_mut!((*out).0).write(ArchivedOptionTag::None);
47            }
48            Some(resolver) => {
49                let out = out.cast::<ArchivedOptionVariantSome<<A as ArchiveWith<O>>::Archived>>();
50                ptr::addr_of_mut!((*out).0).write(ArchivedOptionTag::Some);
51
52                let value = if let Some(value) = field.as_ref() {
53                    value
54                } else {
55                    unreachable_unchecked();
56                };
57
58                let (fp, fo) = out_field!(out.1);
59                A::resolve_with(value, pos + fp, resolver, fo);
60            }
61        }
62    }
63}
64
65impl<A, O, S> SerializeWith<Option<O>, S> for Map<A>
66where
67    S: Fallible,
68    A: ArchiveWith<O> + SerializeWith<O, S>,
69{
70    fn serialize_with(field: &Option<O>, s: &mut S) -> Result<Self::Resolver, S::Error> {
71        field
72            .as_ref()
73            .map(|value| A::serialize_with(value, s))
74            .transpose()
75    }
76}
77
78impl<A, O, D> DeserializeWith<ArchivedOption<<A as ArchiveWith<O>>::Archived>, Option<O>, D>
79    for Map<A>
80where
81    D: Fallible,
82    A: ArchiveWith<O> + DeserializeWith<<A as ArchiveWith<O>>::Archived, O, D>,
83{
84    fn deserialize_with(
85        field: &ArchivedOption<<A as ArchiveWith<O>>::Archived>,
86        d: &mut D,
87    ) -> Result<Option<O>, D::Error> {
88        match field {
89            ArchivedOption::Some(value) => Ok(Some(A::deserialize_with(value, d)?)),
90            ArchivedOption::None => Ok(None),
91        }
92    }
93}
94
95#[repr(u8)]
96enum ArchivedOptionTag {
97    None,
98    Some,
99}
100
101#[repr(C)]
102struct ArchivedOptionVariantNone(ArchivedOptionTag);
103
104#[repr(C)]
105struct ArchivedOptionVariantSome<T>(ArchivedOptionTag, T);
106
107// Inline
108
109impl<F: Archive> ArchiveWith<&F> for Inline {
110    type Archived = F::Archived;
111    type Resolver = F::Resolver;
112
113    #[inline]
114    unsafe fn resolve_with(
115        field: &&F,
116        pos: usize,
117        resolver: Self::Resolver,
118        out: *mut Self::Archived,
119    ) {
120        field.resolve(pos, resolver, out);
121    }
122}
123
124impl<F: Serialize<S>, S: Fallible + ?Sized> SerializeWith<&F, S> for Inline {
125    #[inline]
126    fn serialize_with(field: &&F, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
127        field.serialize(serializer)
128    }
129}
130
131// RefAsBox
132
133impl<F: ArchiveUnsized + ?Sized> ArchiveWith<&F> for RefAsBox {
134    type Archived = ArchivedBox<F::Archived>;
135    type Resolver = BoxResolver<F::MetadataResolver>;
136
137    #[inline]
138    unsafe fn resolve_with(
139        field: &&F,
140        pos: usize,
141        resolver: Self::Resolver,
142        out: *mut Self::Archived,
143    ) {
144        ArchivedBox::resolve_from_ref(*field, pos, resolver, out);
145    }
146}
147
148impl<F: SerializeUnsized<S> + ?Sized, S: Fallible + ?Sized> SerializeWith<&F, S> for RefAsBox {
149    #[inline]
150    fn serialize_with(field: &&F, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
151        ArchivedBox::serialize_from_ref(*field, serializer)
152    }
153}
154
155// AsBox
156
157impl<F: ArchiveUnsized + ?Sized> ArchiveWith<F> for AsBox {
158    type Archived = ArchivedBox<F::Archived>;
159    type Resolver = BoxResolver<F::MetadataResolver>;
160
161    #[inline]
162    unsafe fn resolve_with(
163        field: &F,
164        pos: usize,
165        resolver: Self::Resolver,
166        out: *mut Self::Archived,
167    ) {
168        ArchivedBox::resolve_from_ref(field, pos, resolver, out);
169    }
170}
171
172impl<F: SerializeUnsized<S> + ?Sized, S: Fallible + ?Sized> SerializeWith<F, S> for AsBox {
173    #[inline]
174    fn serialize_with(field: &F, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
175        ArchivedBox::serialize_from_ref(field, serializer)
176    }
177}
178
179impl<F: Archive, D: Fallible + ?Sized> DeserializeWith<ArchivedBox<F::Archived>, F, D> for AsBox
180where
181    F::Archived: Deserialize<F, D>,
182{
183    #[inline]
184    fn deserialize_with(
185        field: &ArchivedBox<F::Archived>,
186        deserializer: &mut D,
187    ) -> Result<F, D::Error> {
188        field.get().deserialize(deserializer)
189    }
190}
191
192// Niche
193
194macro_rules! impl_nonzero_niche {
195    ($ar:ty, $nz:ty, $ne:ty) => {
196        impl ArchiveWith<Option<$nz>> for Niche {
197            type Archived = $ar;
198            type Resolver = ();
199
200            #[inline]
201            unsafe fn resolve_with(
202                field: &Option<$nz>,
203                _: usize,
204                _: Self::Resolver,
205                out: *mut Self::Archived,
206            ) {
207                <$ar>::resolve_from_option(*field, out);
208            }
209        }
210
211        impl<S: Fallible + ?Sized> SerializeWith<Option<$nz>, S> for Niche {
212            #[inline]
213            fn serialize_with(_: &Option<$nz>, _: &mut S) -> Result<Self::Resolver, S::Error> {
214                Ok(())
215            }
216        }
217
218        impl<D: Fallible + ?Sized> DeserializeWith<$ar, Option<$nz>, D> for Niche {
219            #[inline]
220            fn deserialize_with(field: &$ar, _: &mut D) -> Result<Option<$nz>, D::Error> {
221                Ok(field.as_ref().map(|x| (*x).into()))
222            }
223        }
224    };
225}
226
227impl_nonzero_niche!(ArchivedOptionNonZeroI8, NonZeroI8, i8);
228impl_nonzero_niche!(ArchivedOptionNonZeroI16, NonZeroI16, i16);
229impl_nonzero_niche!(ArchivedOptionNonZeroI32, NonZeroI32, i32);
230impl_nonzero_niche!(ArchivedOptionNonZeroI64, NonZeroI64, i64);
231impl_nonzero_niche!(ArchivedOptionNonZeroI128, NonZeroI128, i128);
232
233type FixedNonZeroIsize = pick_size_type!(NonZeroI16, NonZeroI32, NonZeroI64);
234type ArchivedOptionNonZeroIsize = pick_size_type!(
235    ArchivedOptionNonZeroI16,
236    ArchivedOptionNonZeroI32,
237    ArchivedOptionNonZeroI64,
238);
239
240impl ArchiveWith<Option<NonZeroIsize>> for Niche {
241    type Archived = ArchivedOptionNonZeroIsize;
242    type Resolver = ();
243
244    #[inline]
245    unsafe fn resolve_with(
246        field: &Option<NonZeroIsize>,
247        _: usize,
248        _: Self::Resolver,
249        out: *mut Self::Archived,
250    ) {
251        let f = field.as_ref().map(|&x| x.try_into().unwrap());
252        ArchivedOptionNonZeroIsize::resolve_from_option(f, out);
253    }
254}
255
256impl<S: Fallible + ?Sized> SerializeWith<Option<NonZeroIsize>, S> for Niche {
257    #[inline]
258    fn serialize_with(_: &Option<NonZeroIsize>, _: &mut S) -> Result<Self::Resolver, S::Error> {
259        Ok(())
260    }
261}
262
263impl<D: Fallible + ?Sized> DeserializeWith<ArchivedOptionNonZeroIsize, Option<NonZeroIsize>, D>
264    for Niche
265{
266    #[inline]
267    fn deserialize_with(
268        field: &ArchivedOptionNonZeroIsize,
269        _: &mut D,
270    ) -> Result<Option<NonZeroIsize>, D::Error> {
271        // This conversion is necessary with archive_be and archive_le
272        #[allow(clippy::useless_conversion)]
273        Ok(field
274            .as_ref()
275            .map(|x| FixedNonZeroIsize::from(*x).try_into().unwrap()))
276    }
277}
278
279impl_nonzero_niche!(ArchivedOptionNonZeroU8, NonZeroU8, u8);
280impl_nonzero_niche!(ArchivedOptionNonZeroU16, NonZeroU16, u16);
281impl_nonzero_niche!(ArchivedOptionNonZeroU32, NonZeroU32, u32);
282impl_nonzero_niche!(ArchivedOptionNonZeroU64, NonZeroU64, u64);
283impl_nonzero_niche!(ArchivedOptionNonZeroU128, NonZeroU128, u128);
284
285type FixedNonZeroUsize = pick_size_type!(NonZeroU16, NonZeroU32, NonZeroU64);
286type ArchivedOptionNonZeroUsize = pick_size_type!(
287    ArchivedOptionNonZeroU16,
288    ArchivedOptionNonZeroU32,
289    ArchivedOptionNonZeroU64,
290);
291
292impl ArchiveWith<Option<NonZeroUsize>> for Niche {
293    type Archived = ArchivedOptionNonZeroUsize;
294    type Resolver = ();
295
296    #[inline]
297    unsafe fn resolve_with(
298        field: &Option<NonZeroUsize>,
299        _: usize,
300        _: Self::Resolver,
301        out: *mut Self::Archived,
302    ) {
303        let f = field.as_ref().map(|&x| x.try_into().unwrap());
304        ArchivedOptionNonZeroUsize::resolve_from_option(f, out);
305    }
306}
307
308impl<S: Fallible + ?Sized> SerializeWith<Option<NonZeroUsize>, S> for Niche {
309    #[inline]
310    fn serialize_with(_: &Option<NonZeroUsize>, _: &mut S) -> Result<Self::Resolver, S::Error> {
311        Ok(())
312    }
313}
314
315impl<D: Fallible + ?Sized> DeserializeWith<ArchivedOptionNonZeroUsize, Option<NonZeroUsize>, D>
316    for Niche
317{
318    #[inline]
319    fn deserialize_with(
320        field: &ArchivedOptionNonZeroUsize,
321        _: &mut D,
322    ) -> Result<Option<NonZeroUsize>, D::Error> {
323        // This conversion is necessary with archive_be and archive_le
324        #[allow(clippy::useless_conversion)]
325        Ok(field
326            .as_ref()
327            .map(|x| FixedNonZeroUsize::from(*x).try_into().unwrap()))
328    }
329}
330
331// Unsafe
332
333impl<F: Archive> ArchiveWith<UnsafeCell<F>> for Unsafe {
334    type Archived = UnsafeCell<F::Archived>;
335    type Resolver = F::Resolver;
336
337    #[inline]
338    unsafe fn resolve_with(
339        field: &UnsafeCell<F>,
340        pos: usize,
341        resolver: Self::Resolver,
342        out: *mut Self::Archived,
343    ) {
344        F::resolve(&*field.get(), pos, resolver, out.cast());
345    }
346}
347
348impl<F: Serialize<S>, S: Fallible + ?Sized> SerializeWith<UnsafeCell<F>, S> for Unsafe {
349    #[inline]
350    fn serialize_with(
351        field: &UnsafeCell<F>,
352        serializer: &mut S,
353    ) -> Result<Self::Resolver, S::Error> {
354        unsafe { (&*field.get()).serialize(serializer) }
355    }
356}
357
358impl<F: Archive, D: Fallible + ?Sized> DeserializeWith<UnsafeCell<F::Archived>, UnsafeCell<F>, D>
359    for Unsafe
360where
361    F::Archived: Deserialize<F, D>,
362{
363    #[inline]
364    fn deserialize_with(
365        field: &UnsafeCell<F::Archived>,
366        deserializer: &mut D,
367    ) -> Result<UnsafeCell<F>, D::Error> {
368        unsafe {
369            (&*field.get())
370                .deserialize(deserializer)
371                .map(|x| UnsafeCell::new(x))
372        }
373    }
374}
375
376impl<F: Archive> ArchiveWith<Cell<F>> for Unsafe {
377    type Archived = Cell<F::Archived>;
378    type Resolver = F::Resolver;
379
380    #[inline]
381    unsafe fn resolve_with(
382        field: &Cell<F>,
383        pos: usize,
384        resolver: Self::Resolver,
385        out: *mut Self::Archived,
386    ) {
387        F::resolve(&*field.as_ptr(), pos, resolver, out.cast());
388    }
389}
390
391impl<F: Serialize<S>, S: Fallible + ?Sized> SerializeWith<Cell<F>, S> for Unsafe {
392    #[inline]
393    fn serialize_with(field: &Cell<F>, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
394        unsafe { (&*field.as_ptr()).serialize(serializer) }
395    }
396}
397
398impl<F: Archive, D: Fallible + ?Sized> DeserializeWith<Cell<F::Archived>, Cell<F>, D> for Unsafe
399where
400    F::Archived: Deserialize<F, D>,
401{
402    #[inline]
403    fn deserialize_with(
404        field: &Cell<F::Archived>,
405        deserializer: &mut D,
406    ) -> Result<Cell<F>, D::Error> {
407        unsafe {
408            (&*field.as_ptr())
409                .deserialize(deserializer)
410                .map(|x| Cell::new(x))
411        }
412    }
413}
414
415// Skip
416
417impl<F> ArchiveWith<F> for Skip {
418    type Archived = ();
419    type Resolver = ();
420
421    unsafe fn resolve_with(_: &F, _: usize, _: Self::Resolver, _: *mut Self::Archived) {}
422}
423
424impl<F, S: Fallible + ?Sized> SerializeWith<F, S> for Skip {
425    fn serialize_with(_: &F, _: &mut S) -> Result<(), S::Error> {
426        Ok(())
427    }
428}
429
430impl<F: Default, D: Fallible + ?Sized> DeserializeWith<(), F, D> for Skip {
431    fn deserialize_with(_: &(), _: &mut D) -> Result<F, D::Error> {
432        Ok(Default::default())
433    }
434}