pub trait SerializeDyn {
    // Required methods
    fn serialize_dyn(
        &self,
        serializer: &mut dyn DynSerializer
    ) -> Result<usize, DynError>;
    fn archived_type_id(&self) -> u64;
}
Expand description

A trait object that can be archived.

To add archive support for a trait object:

  1. Add archive_dyn on your trait to make a serializable version of it. By default, it will be named “Serialize” + your trait name. To rename the trait, pass the argument serialize = "..." as a parameter.
  2. Implement Archive and Serialize for the type you want to make trait objects of and TypeName for the archived versions of them.
  3. Implement your trait for your type and add the attribute #[archive_dyn] to it. Make sure to implement your trait for your archived type as well. This invocation must have the same attributes as the trait invocation.
  4. If deserialization support is desired, add deserialize or deserialize = "..." as parameters and implement Deserialize for the type. By default, the deserialize trait will be named “Deserialize” + your trait name. Passing a trait name will use that name instead.

Then you’re ready to serialize boxed trait objects!

Even though your deserialized values are boxed as serialize trait objects, your archived values are boxed as regular trait objects. This is because your deserialized values have to implement SerializeDyn but your archived values do not.

§Examples

See archive_dyn for customization options.

use rkyv::{
    archived_value,
    ser::{
        serializers::AllocSerializer,
        Serializer,
    },
    AlignedVec,
    Archive,
    Archived,
    Deserialize,
    Infallible,
    Serialize,
};
use rkyv_dyn::archive_dyn;
use rkyv_typename::TypeName;

#[archive_dyn(deserialize)]
trait ExampleTrait {
    fn value(&self) -> String;
}

#[derive(Archive, Serialize, Deserialize)]
#[archive_attr(derive(TypeName))]
struct StringStruct(String);

#[archive_dyn(deserialize)]
impl ExampleTrait for StringStruct {
    fn value(&self) -> String {
        self.0.clone()
    }
}

impl ExampleTrait for Archived<StringStruct> {
    fn value(&self) -> String {
        self.0.as_str().to_string()
    }
}

#[derive(Archive, Serialize, Deserialize)]
#[archive_attr(derive(TypeName))]
struct IntStruct(i32);

#[archive_dyn(deserialize)]
impl ExampleTrait for IntStruct {
    fn value(&self) -> String {
        format!("{}", self.0)
    }
}

impl ExampleTrait for Archived<IntStruct> {
    fn value(&self) -> String {
        format!("{}", self.0)
    }
}

let boxed_int = Box::new(IntStruct(42)) as Box<dyn SerializeExampleTrait>;
let boxed_string = Box::new(StringStruct("hello world".to_string()))
    as Box<dyn SerializeExampleTrait>;
let mut serializer = AllocSerializer::<256>::default();
let int_pos = serializer.serialize_value(&boxed_int)
    .expect("failed to archive boxed int");
let str_pos = serializer.serialize_value(&boxed_string)
    .expect("failed to archive boxed string");
let buf = serializer.into_serializer().into_inner();
let archived_int = unsafe {
    archived_value::<Box<dyn SerializeExampleTrait>>(buf.as_ref(), int_pos)
};
let archived_string = unsafe {
    archived_value::<Box<dyn SerializeExampleTrait>>(buf.as_ref(), str_pos)
};
assert_eq!(archived_int.value(), "42");
assert_eq!(archived_string.value(), "hello world");

let deserialized_int: Box<dyn SerializeExampleTrait> = archived_int
    .deserialize(&mut Infallible).unwrap();
let deserialized_string: Box<dyn SerializeExampleTrait> = archived_string
    .deserialize(&mut Infallible).unwrap();
assert_eq!(deserialized_int.value(), "42");
assert_eq!(deserialized_string.value(), "hello world");

Required Methods§

source

fn serialize_dyn( &self, serializer: &mut dyn DynSerializer ) -> Result<usize, DynError>

Writes the value to the serializer and returns the position it was written to.

source

fn archived_type_id(&self) -> u64

Returns the type ID of the archived version of this type.

Implementors§

source§

impl<T: for<'a> Serialize<dyn DynSerializer + 'a>> SerializeDyn for T
where T::Archived: TypeName,