Trait rkyv::with::ArchiveWith [−][src]
pub trait ArchiveWith<F: ?Sized> { type Archived; type Resolver; unsafe fn resolve_with(
field: &F,
pos: usize,
resolver: Self::Resolver,
out: *mut Self::Archived
); }
Expand description
A variant of Archive
that works with With
wrappers.
Creating a wrapper allows users to customize how fields are archived easily without changing the unarchived type.
This trait allows wrapper types to transparently change the archive behaviors for struct fields.
When a field is serialized, its reference may be converted to a With
reference, and that
reference may be serialized instead. With
references look for implementations of ArchiveWith
to determine how a wrapped field should be treated.
Example
use rkyv::{ archived_root, ser::{ serializers::AllocSerializer, Serializer, }, with::{ ArchiveWith, DeserializeWith, SerializeWith, }, Archive, Archived, Deserialize, Fallible, Infallible, Resolver, Serialize, }; struct Incremented; impl ArchiveWith<i32> for Incremented { type Archived = Archived<i32>; type Resolver = Resolver<i32>; unsafe fn resolve_with(field: &i32, pos: usize, _: (), out: *mut Self::Archived) { let incremented = field + 1; incremented.resolve(pos, (), out); } } impl<S: Fallible + ?Sized> SerializeWith<i32, S> for Incremented where i32: Serialize<S>, { fn serialize_with(field: &i32, serializer: &mut S) -> Result<Self::Resolver, S::Error> { let incremented = field + 1; incremented.serialize(serializer) } } impl<D: Fallible + ?Sized> DeserializeWith<Archived<i32>, i32, D> for Incremented where Archived<i32>: Deserialize<i32, D>, { fn deserialize_with(field: &Archived<i32>, deserializer: &mut D) -> Result<i32, D::Error> { Ok(field.deserialize(deserializer)? - 1) } } #[derive(Archive, Deserialize, Serialize)] struct Example { #[with(Incremented)] a: i32, // Another i32 field, but not incremented this time b: i32, } let value = Example { a: 4, b: 9, }; let mut serializer = AllocSerializer::<4096>::default(); serializer.serialize_value(&value).unwrap(); let buf = serializer.into_serializer().into_inner(); let archived = unsafe { archived_root::<Example>(buf.as_ref()) }; // The wrapped field has been incremented assert_eq!(archived.a, 5); // ... and the unwrapped field has not assert_eq!(archived.b, 9); let deserialized: Example = archived.deserialize(&mut Infallible).unwrap(); // The wrapped field is back to normal assert_eq!(deserialized.a, 4); // ... and the unwrapped field is unchanged assert_eq!(deserialized.b, 9);