rkyv-with
Third-party derive macro for rkyv's {Archive/Serialize/Deserialize}With traits.
The main use-case for this derive is to be able to use rkyv on remote types that don't implement Archive, Serialize, and Deserialize themselves.
This provides a somewhat similar workaround for rusts orphan rule as serde's remote support.
Macros
The ArchiveWith derive macro implements both the ArchiveWith and the SerializeWith traits. For the DeserializeWith trait, use the DeserializeWith derive macro.
The #[archive_with(...)] attribute helps to fine-tune the implementations.
archive_with(from(TypeName))indicates what the original type is. This attribute is required to be specified at the top level of the type definition. Multiple comma-separated types are allowed, i.e.from(Type1, Type2). The attribute can also be used on fields.archive_with(via(TypeWrapper))provides a way to convert the type of a field into something else e.g. the unarchivable type contains aPathBuffield and in the archivable counterpart it's aStringby specifyingvia(rkyv::with::AsString)archive_with(getter = "path::to::function")must be used in case the unarchivable type includes private fields. The function must beFn(&U) -> TorFn(&U) -> &TwhereUis the unarchivable type andTis the field's type.archive_with(getter_owned)can be specified in addition togetter = "..."when the function takes an owned instance instead of a reference.
Applying the macros
// Both trait and macro must be imported
use ArchiveWith;
use ArchiveWith;
// This could come from some dependency or otherwise remote module.
// Importantly, this does not implement the rkyv traits
// must be specified
Using the resulting implementations
use ;
use ;
use ;
// Can be serialized as usual and
// also serves as serialization wrapper
// Can be serialized as usual
let unarchivable = Unarchivable ;
// Serialize the instance
let wrapper = cast;
let bytes = .unwrap;
let archived = unsafe ;
// Can go back to the original type
let deserialized_unarchivable: Unarchivable =
deserialize_with.unwrap;
// Or stick with the wrapper
let deserialized_wrapper: ArchivesTheUnarchivable =
archived.deserialize.unwrap;
Private fields
If fields are not directly accessible due to them being private, deriving the traits requires manual specification of getter functions.
use ArchiveWith;
use Archive;
use ArchiveWith;
// Imagine again that this is a remote module that you have no way of modifying
// Since creating instances of a type that has private fields cannot be done in a general way,
// `DeserializeWith` cannot be derived for such types and instead has to be implemented manually.
// An implementation for the example above could look as follows:
use DeserializeWith;
use ;