#版本化 #序列化

tfhe-versionable

tfhe-versionable:为用于序列化的Rust类型添加版本信息/向后兼容性

3个不稳定版本

0.2.1 2024年8月14日
0.2.0 2024年7月17日
0.1.0 2024年6月24日

17 in #版本化

Download history 153/week @ 2024-06-19 158/week @ 2024-06-26 201/week @ 2024-07-03 189/week @ 2024-07-10 304/week @ 2024-07-17 229/week @ 2024-07-24 301/week @ 2024-07-31 242/week @ 2024-08-07

1,115 每月下载量
tfhe 中使用

BSD-3-Clause-Clear

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实现它们的versionizeunversionize方法,这些方法应在调用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