Trait Objects
Trait object serialization is supported through the rkyv_dyn
crate. This crate is maintained as
part of rkyv, but is separate from the main crate to allow other implementations to be used instead.
This section will focus primarily on the architecture of rkyv_dyn
and how to use it effectively.
rkyv_dyn
may not work in some exotic environments due to the ✨magic✨ it uses to register trait objects. If you want these capabilities butrkyv_dyn
doesn't work in your environment, feel free to file an issue or drop by in the discord to talk it through.
Core traits
The new traits introduced by rkyv_dyn
are
SerializeDyn
and
DeserializeDyn
. These are
effectively type-erased versions of SerializeUnsized
and DeserializeUnsized
so that the traits
are object-safe. Likewise, it introduces type-erased versions of serializers and deserializers:
DynSerializer
and
DynDeserializer
. These
attempt to provide the basic functionality required to serialize most types, but may be more or less
capable than custom types require.
DynSerializer
implements theSerializer
andScratchSpace
traits, but that may not be suitable for all use cases. If you need more capabilities, file an issue or drop by in the discord to talk it through.
Architecture
It is highly recommended to use the provided
archive_dyn
macro to implement
the new traits and set everything up correctly.
Using archive_dyn
on a trait definition creates another trait definition with supertraits of your
trait and SerializeDyn
. This "shim" trait is blanket implemented for all types that implement your
trait and SerializeDyn
, so you should only ever have to implement your trait to use it.
The shim trait should be used everywhere that you have a trait object of your trait that you want to
serialize. By default, it will be named "Serialize" + your trait name. A different approach that
similar libraries take is directly adding SerializeDyn
as a supertrait of your trait. While more
ergonomic, this approach does not allow the implementation of the trait on types that cannot or
should not implement SerializeDyn
, so the shim trait approach was favored for rkyv_dyn
.
When the shim trait is serialized, it stores the type hash of the underlying type in its metadata so
it can get the correct vtable for it when accessed. This requires that all vtables for implementing
types must be known ahead of time, which is when we use archive_dyn
for the second time.