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