rkyv_test/impls/core/
option.rs1use crate::{option::ArchivedOption, Archive, Deserialize, Fallible, Serialize};
2use core::{hint::unreachable_unchecked, ptr};
3
4#[allow(dead_code)]
5#[repr(u8)]
6enum ArchivedOptionTag {
7 None,
8 Some,
9}
10
11#[repr(C)]
12struct ArchivedOptionVariantNone(ArchivedOptionTag);
13
14#[repr(C)]
15struct ArchivedOptionVariantSome<T>(ArchivedOptionTag, T);
16
17impl<T: Archive> Archive for Option<T> {
18 type Archived = ArchivedOption<T::Archived>;
19 type Resolver = Option<T::Resolver>;
20
21 #[inline]
22 unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) {
23 match resolver {
24 None => {
25 let out = out.cast::<ArchivedOptionVariantNone>();
26 ptr::addr_of_mut!((*out).0).write(ArchivedOptionTag::None);
27 }
28 Some(resolver) => {
29 let out = out.cast::<ArchivedOptionVariantSome<T::Archived>>();
30 ptr::addr_of_mut!((*out).0).write(ArchivedOptionTag::Some);
31
32 let value = if let Some(value) = self.as_ref() {
33 value
34 } else {
35 unreachable_unchecked();
36 };
37
38 let (fp, fo) = out_field!(out.1);
39 value.resolve(pos + fp, resolver, fo);
40 }
41 }
42 }
43}
44
45impl<T: Serialize<S>, S: Fallible + ?Sized> Serialize<S> for Option<T> {
46 #[inline]
47 fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
48 self.as_ref()
49 .map(|value| value.serialize(serializer))
50 .transpose()
51 }
52}
53
54impl<T: Archive, D: Fallible + ?Sized> Deserialize<Option<T>, D> for ArchivedOption<T::Archived>
55where
56 T::Archived: Deserialize<T, D>,
57{
58 #[inline]
59 fn deserialize(&self, deserializer: &mut D) -> Result<Option<T>, D::Error> {
60 match self {
61 ArchivedOption::Some(value) => Ok(Some(value.deserialize(deserializer)?)),
62 ArchivedOption::None => Ok(None),
63 }
64 }
65}