#serialization #serde #enums #data #versioning #data-structures #struct

pro-serde-versioned

通过serde序列化数据结构时,一个简单的版本控制和升级方法

2个稳定版本

1.0.2 2023年6月4日
1.0.1 2023年5月22日

#1312 in 编码

Download history 50/week @ 2024-03-11 21/week @ 2024-03-18 7/week @ 2024-03-25 28/week @ 2024-04-01 2/week @ 2024-04-08 6/week @ 2024-04-15 23/week @ 2024-04-22 15/week @ 2024-04-29 8/week @ 2024-05-06 28/week @ 2024-05-13 40/week @ 2024-05-20 34/week @ 2024-05-27 28/week @ 2024-06-03 20/week @ 2024-06-10 9/week @ 2024-06-17 21/week @ 2024-06-24

79每月下载量

Apache-2.0

12KB
99

pro-serde-versioned

此crate提供了一个简单的方法,用于在通过serde序列化时对数据结构进行版本控制和升级。

功能

  • VersionedSerializeVersionedDeserialize特性允许为枚举推导稳定的序列化方法,即使在未来添加了新的枚举情况,这些方法仍然可以正常工作
  • VersionedUpgrade特性通过提供一个将序列中的任何结构升级到最新版本的方法,定义了一个枚举序列的结构生成器。

VersionedSerialize/VersionedDeserialize示例

use serde::{Deserialize, Serialize};
use pro_serde_versioned::{
    VersionedSerialize,
    VersionedDeserialize,
};

// Let's say you have two generations of some serialized data structure ...
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
struct MyStructV1 {
    field: String
};

#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
struct MyStructV2 {
    field1: u32,
    new_field: String,
}

// Derive [`VersionedSerialize`] and [`VersionedDeserialize`]
#[derive(
    VersionedSerialize,
    VersionedDeserialize,
    Debug,
    PartialEq,
    Clone
)]
enum MyStructVersioned {
    V1(MyStructV1),
    V2(MyStructV2),
}

let versioned_struct: MyStructVersioned = 
    MyStructV1 { field: "123".to_string() }.into();

// Serializing `MyStructV1` to `serde_json::Value` format
let serialized_v1: serde_json::Value = versioned_struct.versioned_serialize()?;

// Deserialize `MyStructVersion` from JSON format 
let deserialized_v1 = MyStructVersioned::versioned_deserialize(&serialized_v1)?;
assert_eq!(deserialized_v1, versioned_struct);

# Ok::<(), Box<dyn std::error::Error>>(())

VersionedUpgrade示例

use pro_serde_versioned::{
    VersionedUpgrade,
    Upgrade,
};

// Given the same two generations of a serialized data structure ...
#[derive(Debug, PartialEq, Clone)]
struct MyStructV1(String);

#[derive(Debug, PartialEq, Clone)]
struct MyStructV2 {
    field1: u32,
    new_field: String,
}

// ... and an impl for the `Upgrade` trait which links them together ...
impl Upgrade<MyStructV2> for MyStructV1 {
    fn upgrade(self: MyStructV1) -> MyStructV2 {
        MyStructV2 {
            field1: self.0.parse().unwrap_or_default(),
            new_field: "default_value".to_string(),
        }
    }
}

// Derive the [`VersionedUpgrade`] trait on a wrapper enum
#[derive(
    VersionedUpgrade,
    Debug,
    PartialEq,
    Clone
)]
enum MyStructVersion {
    V1(MyStructV1),
    V2(MyStructV2),
}

// Now any struct can be upgraded to the latest enum of [`MyStructVersioned`]!
// Upgrade `MyStructV1` to `MyStructV2`.
let upgraded_v2 = 
    MyStructVersion::V1(MyStructV1("123".to_string())).upgrade_to_latest();

assert_eq!(
    upgraded_v2,
    MyStructV2 {
        field1: 123,
        new_field: "default_value".to_string(),
    }
);

# Ok::<(), Box<dyn std::error::Error>>(())

依赖项

~0.7–1.5MB
~34K SLoC