Closed fuchaoqun closed 1 month ago
We currently only support 0.7
, but I'll raise an MR for 0.8
support instead (removing 0.7
).
If you need support immediately, consider using remote derive support.
Actually, @paupino, how do you want to handle an rkyv
bump?
The problem is as follows:
rkyv
is used for serializing/deserializing types.rkyv
with the same feature name would be a breaking change.Options I see are:
rkyv
version (set it to *
):
rkyv
feature set-ups which I'm not sure is possible; as the size_32
feature doesn't exist in 0.8
cargo update
would then update user's rkyv
versions (although I've not confirmed this behaviour)rkyv-0.8
featurerkyv
's remote derive feature@Tony-Samuels That remote derive feature is quite a nice approach! Ultimately, that is probably the best way forward since maintaining multiple versions is always a bit of a nightmare.
We have handled a situation like this before with regards to diesel
. In that we handled version 1 and 2 simultaneously by namespacing the dependency. That said, I'm not a big fan of this as it creates a bit of a mess in regards to feature management (i.e. need to allow both versions to be enabled at once, picking only one etc). It's also not incredibly scalable since there is always a hard dependency on someone keeping things updated.
Perhaps collectively if we can provide an example remote derive then that could be beneficial - eventually we can bake it into our docs too about how to use it (maybe via examples?). At least, that is definitely an avenue I think we should explore.
hope for an example of a performance-critical use case.
#[derive(Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
#[rkyv(remote = rust_decimal::Decimal)]
pub struct ArchivedDecimal {
#[rkyv(getter = get_bytes)]
bytes: [u8; 16],
}
fn get_bytes(d: &Decimal) -> [u8; 16] {
d.serialize()
}
impl From<ArchivedDecimal> for Decimal {
fn from(value: ArchivedDecimal) -> Self {
Decimal::deserialize(value.bytes)
}
}
#[derive(Debug, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize)]
pub struct FB {
pub foo: String,
#[rkyv(with = ArchivedDecimal)]
pub bar: Decimal,
}
let foo = FB {
foo: "Foo".to_string(),
bar: Decimal::from_str("123.456789").unwrap(),
};
let bar = rkyv::to_bytes::<rkyv::rancor::Error>(&foo).unwrap();
let archived = rkyv::access::<ArchivedFB, rkyv::rancor::Error>(&bar).unwrap();
let deserialized = rkyv::deserialize::<FB, rkyv::rancor::Error>(archived).unwrap();
an ugly example, is there any better implement? performance critical use case.
Prettiness-wise that's nearly as good as you're going to get. You can replace the get_bytes
function with #[rkyv(getter = Decimal::serialize)]
to make it cleaner. At that point it's just a #[rkyv(with = ArchivedDecimal)]
where you want it included and less than 10 lines of conversion code.
Performance-wise, it should be pretty close to a direct derive.
let a = Decimal::from_str("0.123").unwrap(); let bytes = rkyv::tobytes::<, 256>(&a).unwrap();
Cargo.toml
rkyv = "0.8"
can not build with rkyv 0.8.x, 0.7.x works