14个版本 (8个破坏性版本)

新增 0.9.0 2024年8月23日
0.8.0 2024年7月9日
0.7.1 2024年6月19日
0.5.0 2023年8月29日

#168 in 编码

Download history 5913/week @ 2024-05-03 4553/week @ 2024-05-10 3986/week @ 2024-05-17 4557/week @ 2024-05-24 4426/week @ 2024-05-31 4075/week @ 2024-06-07 4495/week @ 2024-06-14 4229/week @ 2024-06-21 3615/week @ 2024-06-28 4329/week @ 2024-07-05 4125/week @ 2024-07-12 4720/week @ 2024-07-19 6329/week @ 2024-07-26 6328/week @ 2024-08-02 6114/week @ 2024-08-09 6814/week @ 2024-08-16

26,360 每月下载量
用于 62 个crate (14个直接使用)

Apache-2.0

74KB
2K SLoC


这是一个支持随时间进行模式演变的修订容错序列化和反序列化框架,允许对需要支持向后兼容性的数据存储需求进行轻松的版本控制,同时数据结构的设计随时间演变。


     

信息

Revision 是一个支持随时间进行模式演变的修订容错序列化和反序列化框架。它允许对需要支持向后兼容性的数据存储需求进行轻松的版本控制,同时数据结构的设计随时间演变。修订使得旧版本序列化的数据能够无缝地反序列化和转换为最新的数据结构。它使用 bincode 进行序列化和反序列化。

The Revisioned trait is automatically implemented for the following primitives: u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64, char, String, Vec<T>, Arrays up to 32 elements, Option<T>, Box<T>, Bound<T>, Wrapping<T>, Reverse<T>, (A, B), (A, B, C), (A, B, C, D), (A, B, C, D, E), Duration, HashMap<K, V>, BTreeMap<K, V>, HashSet<T>, BTreeSet<T>, BinaryHeap<T>, Result<T, E>, Cow<'_, T>, Decimal, regex::Regex, uuid::Uuid, chrono::DateTime<Utc>, geo::Point, geo::LineString geo::Polygon, geo::MultiPoint, geo::MultiLineString, geo::MultiPolygon, and ordered_float::NotNan.

灵感

此代码从为 Versionize 库汲取灵感,该库为 Amazon Firecracker 快照恢复开发预览开发。

修订应用实例

use revision::Error;
use revision::revisioned;

// The test structure is at revision 3.
#[derive(Debug, PartialEq)]
#[revisioned(revision = 3)]
pub struct TestStruct {
    a: u32,
    #[revision(start = 2, end = 3, convert_fn = "convert_b")]
    b: u8,
    #[revision(start = 3)]
    c: u64,
    #[revision(start = 3, default_fn = "default_c")]
    d: String,
}

impl TestStruct {
    // Used to set the default value for a newly added field.
    fn default_c(_revision: u16) -> String {
        "test_string".to_owned()
    }
    // Used to convert the field from an old revision to the latest revision
    fn convert_b(&mut self, _revision: u16, value: u8) -> Result<(), Error> {
        self.c = value as u64;
        Ok(())
    }
}

// The test structure is at revision 3.
#[derive(Debug, PartialEq)]
#[revisioned(revision = 3)]
pub enum TestEnum {
    #[revision(end = 2, convert_fn = "upgrade_zero")]
    Zero,
    #[revision(end = 2, convert_fn = "upgrade_one")]
    One(u32),
    #[revision(start = 2)]
    Two(u64),
    #[revision(start = 2)]
    Three {
        a: i64,
        #[revision(end = 2, convert_fn = "upgrade_three_b")]
        b: f32,
        #[revision(start = 2)]
        c: rust_decimal::Decimal,
        #[revision(start = 3)]
        d: String
    },
}

impl TestEnum {
    // Used to convert an old enum variant into a new variant.
    fn upgrade_zero((): ()) -> Result<TestEnum, Error> {
        Ok(Self::Two(0))
    }
    // Used to convert an old enum variant into a new variant.
    fn upgrade_one((v0,): (u32,)) -> Result<TestEnum, Error> {
        Ok(Self::Two(v0 as u64))
    }
    // Used to convert the field from an old revision to the latest revision
    fn upgrade_three_b(&mut self, _revision: u16, value: f32) -> Result<(), Error> {
        match self {
            TestEnum::Three {
                ref mut c,
                ..
            } => {
                *c = value.into();
            }
            _ => unreachable!(),
        }
        Ok(())
    }
}

依赖

~0.3–2.6MB
~49K SLoC