#flow #migration #serialization #serde

serde_flow_derive

简化serde和零拷贝实体的迁移

4个稳定版本

1.1.1 2024年3月14日
1.1.0 2024年3月13日
1.0.1 2024年3月7日

165#flow

Download history 14/week @ 2024-04-01 7/week @ 2024-05-20 1/week @ 2024-05-27 3/week @ 2024-06-03 4/week @ 2024-06-10 30/week @ 2024-07-01 17/week @ 2024-07-08 68/week @ 2024-07-15

115 每月下载量
2 个crate中使用 (通过 serde_flow)

MIT 协议

34KB
625

Serde Flow - 兼容性框架

build status

该库帮助您平滑地反序列化您序列化信息的早期变体。

描述

Rust库,简化软件开发过程中对序列化数据格式的更改管理,通过支持序列化数据的版本化来维持版本兼容性,从而实现无缝文件迁移。

功能

  1. 序列化/反序列化实体的版本化
  2. 序列化字节的迁移
  3. 异步迁移
  4. 零拷贝反序列化
  5. 数据完整性验证

主要概念

Serde Flow主要包含三个主要组件

  1. #[derive(Flow)]:要使用Serde Flow,必须使用serde_flow::Flow注解您的类。这个注解作为库的一个信号,表明该类符合数据迁移的资格。
  2. #[flow(variant = N)]:使用此注解指定实体的版本。只需将N替换为表示版本的u16数字即可。这有助于有效地管理您数据结构的不同版本。
    • variant = N - 定义具有数字(u16) N 的结构体版本
    • file(option1, option2)file - 实现从文件加载
      • blocking - (默认) - 正常阻塞IO加载和反序列化
      • nonblocking - 异步IO加载和反序列化(同时使用blocking和非blocking是可能的)
      • verify_write - 通过计算校验和验证写入的数据
    • zerocopy - 使用 rkyv 进行零拷贝反序列化。
    • bytes - 使用内存迁移,不持久化到磁盘(只需调用 encode()->Vec<u8>decode(Vec<u8>)->T
  3. #[variants(StructA, StructB, ...)] (可选): 此注释是可选的,但强烈推荐用于全面的数据迁移管理。在此,您列出对于迁移到具有此注释的突出显示的 struct 所必需的结构体。 为确保,您需要为 From<VariantStruct> 实现所有在 #[variants(..)] 中列出的结构体。

🛠️ 开始使用

[dependencies]
serde_flow = "1.1.0"

假设您有一个随时间演变过的 User 结构体,其版本为 UserV1 -> UserV2 -> User(当前),而之前的版本 UserV1UserV2 仍存在于其他地方。为了有效管理这种情况,请按照以下步骤操作

  1. 版本控制: 首先从开始设置适当的版本控制。用户的初始创建应该用 #[flow(variant = 1)] 注释。
  2. 增量版本控制: 当您迭代并创建后续版本时,确保在注释中增加版本号,例如下一个版本为 #[flow(variant = 2)]
  3. 迁移准备: 当您准备好迁移到新版本时,将 #[variants(UserV1, UserV2)] 注释添加到主 User 结构体。包括所有您打算从其迁移的先前变体非常重要。
  4. 实现范围: 变体必须在与主变体相同的文件中实现,以确保在迁移过程中适当管理和访问。

通过遵守这些指南,您可以有效地管理数据结构的演变,同时确保版本间的无缝迁移。

设置 - 向您的结构体添加属性

use serde_flow::{Flow};
use serde::{Deserialize, Serialize};

// The last (variant 3) of the User
#[derive(Serialize, Deserialize, Flow)]
#[flow(variant = 3, file)]
#[variants(UserV1, UserV2)]
pub struct User {
    pub first_name: String,
    pub middle_name: String,
    pub last_name: String,
}

// previous variant
#[derive(Serialize, Deserialize, Flow)]
#[flow(variant = 2)]
pub struct UserV2 {
    pub first_name: String,
    pub last_name: String,
}

// the first variant of the User entity
#[derive(Serialize, Deserialize, Flow)]
#[flow(variant = 1)]
pub struct UserV1 {
    pub name: String,
}

// Migration from UserV1 and UserV2 for User
impl From<UserV1> for User { /* migration */ }
impl From<UserV2> for User { /* migration */ }

用法

use serde_flow::{encoder::bincode, flow::File, flow::FileMigrate, Flow};

// create an old struct UserV2
let user_v2 = UserV2 {
    name: "John Adam Doe".to_string(),
};

// serialize to the disk
user_v2
    .save_to_path::<bincode::Encoder>(&Path::new("/path/to/user"))
    .unwrap();

// deserialize as User
let user = User::load_from_path::<bincode::Encoder>(path.as_path()).unwrap();

// Migrate and load (loads, migrates, saves, and returns new entity)
let user User::load_and_migrate::<bincode::Encoder>(path.as_path()).unwrap();

// Just migrate (loads, migrates, and saves new entity)
User::migrate::<bincode::Encoder>(path.as_path()).unwrap();

📜 许可证

Serde-flow 是开源软件,在 MIT 许可证下免费提供。

依赖项

~0.4–1MB
~22K SLoC