3个不稳定版本
新 0.2.1 | 2024年8月14日 |
---|---|
0.2.0 | 2024年7月17日 |
0.1.0 | 2024年6月24日 |
17 in #版本化
1,115 每月下载量
在 tfhe 中使用
39KB
743 行
TFHE-versionable
此crate提供了序列化数据的类型级别版本控制。它提供了一种为任何数据类型添加向后兼容性的方法。版本控制方案是递归的,且独立于所选的序列化后端。
要使用它,只需定义一个枚举,其中包含针对目标类型每个版本的变体。
例如,如果您已定义一个内部类型
struct MyStruct {
val: u32
}
您必须定义以下枚举
enum MyStructVersions {
V0(MyStruct)
}
如果您在后续某个时间点想要向此结构体添加字段,思路是复制先前定义的结构体版本,并创建一个新的包含添加字段的版本。这通常变为
struct MyStruct {
val: u32,
newval: u64
}
struct MyStructV0 {
val: u32
}
enum MyStructVersions {
V0(MyStructV0),
V1(MyStruct)
}
您还必须实现Upgrade
trait,它告诉如何从一个版本转换到另一个版本。
为了使其递归工作,此crate定义了3个 derive宏,应在这些类型上使用
Versionize
应用于您的当前类型版本,即代码中使用的版本Version
用于此类型的每个先前版本VersionsDispatch
用于包含所有版本的枚举
这将为Versionize/
Unversionize
trait实现它们的versionize
和unversionize
方法,这些方法应在调用serialize
/deserialize
之前/之后使用。
枚举变体应在版本之间保持顺序和名称。唯一支持的操作是添加新的变体。
完整示例
use tfhe_versionable::{Unversionize, Upgrade, Version, Versionize, VersionsDispatch};
// The structure that should be versioned, as defined in your code
#[derive(Versionize)]
#[versionize(MyStructVersions)] // Link to the enum type that will holds all the versions of this type
struct MyStruct<T: Default> {
attr: T,
builtin: u32,
}
// To avoid polluting your code, the old versions can be defined in another module/file, along with the dispatch enum
#[derive(Version)] // Used to mark an old version of the type
struct MyStructV0 {
builtin: u32,
}
// The Upgrade trait tells how to go from the first version to the last. During unversioning, the
// upgrade method will be called on the deserialized value enough times to go to the last variant.
impl<T: Default> Upgrade<MyStruct<T>> for MyStructV0 {
fn upgrade(self) -> MyStruct<T> {
MyStruct {
attr: T::default(),
builtin: self.builtin,
}
}
}
// This is the dispatch enum, that holds one variant for each version of your type.
#[derive(VersionsDispatch)]
// This enum is not directly used but serves as a template to generate new enums that will be
// serialized. This allows recursive versioning.
#[allow(unused)]
enum MyStructVersions<T: Default> {
V0(MyStructV0),
V1(MyStruct<T>),
}
fn main() {
let ms = MyStruct {
attr: 37u64,
builtin: 1234,
};
let serialized = bincode::serialize(&ms.versionize()).unwrap();
// This can be called in future versions of your application, when more variants have been added
let _unserialized = MyStruct::<u64>::unversionize(bincode::deserialize(&serialized).unwrap());
}
请参阅examples
文件夹以获取更多用例。
依赖项
~0.7–1.3MB
~30K SLoC