use rkyv::{rancor::Error, with::AsBox, Archive, Deserialize, Serialize};
#[derive(Archive, Deserialize, Serialize)]
struct ExampleV1 {
a: i32,
b: u32,
}
#[derive(Archive, Deserialize, Serialize)]
struct ExampleV2 {
a: i32,
b: i32,
c: String,
}
#[derive(Archive, Deserialize, Serialize)]
#[repr(transparent)]
struct Versioned<T>(#[rkyv(with = AsBox)] pub T);
fn print_v1(value: &ArchivedExampleV1) {
println!("v1: a = {}, b = {}", value.a, value.b);
}
fn print_v2(value: &ArchivedExampleV2) {
println!("v2: a = {}, b = {}, c = {}", value.a, value.b, value.c);
}
fn main() {
let v1 = Versioned(ExampleV1 { a: 10, b: 20 });
let v2 = Versioned(ExampleV2 {
a: 30,
b: 50,
c: "hello world".to_string(),
});
let v1_bytes =
rkyv::to_bytes::<Error>(&v1).expect("failed to serialize v1");
let v2_bytes =
rkyv::to_bytes::<Error>(&v2).expect("failed to serialize v2");
let v1_as_v1 =
rkyv::access::<rkyv::Archived<Versioned<ExampleV1>>, Error>(&v1_bytes)
.unwrap();
print_v1(&v1_as_v1.0);
let v2_as_v1 =
rkyv::access::<rkyv::Archived<Versioned<ExampleV1>>, Error>(&v2_bytes)
.unwrap();
print_v1(&v2_as_v1.0);
let v2_as_v2 =
rkyv::access::<rkyv::Archived<Versioned<ExampleV2>>, Error>(&v2_bytes)
.unwrap();
print_v2(&v2_as_v2.0);
if rkyv::access::<rkyv::Archived<Versioned<ExampleV2>>, Error>(&v1_bytes)
.is_ok()
{
panic!("v1 bytes should not validate as v2");
} else {
println!("verified that v1 cannot be viewed as v2");
}
}