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
use crate::{option::ArchivedOption, Archive, Deserialize, Fallible, Serialize}; use core::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 (fp, fo) = out_field!(out.1); self.as_ref().unwrap().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), } } }