7 个版本

0.1.7 2022 年 1 月 27 日
0.1.6 2021 年 5 月 31 日
0.1.5 2020 年 12 月 25 日

#2263编码

Download history

65 每月下载次数

MIT 许可证

47KB
1K SLoC

binserde

一个与 serde 类似的 crate,但专门用于将数据结构序列化为紧凑的二进制格式,包括字符串去重等特性。

此 crate 目前处于非常初期的开发阶段。 目前未实现但计划包括支持增量版本,以便在数据格式更改时仍然可以加载旧格式,去重任意数据结构,以及显式标记(将结构体或枚举序列化为一系列键/值对,而不是按照声明顺序序列化项,以提高对格式变化的抵抗力,但会以输出大小为代价)。

使用

use std::fs::File;
use std::io::BufReader;

#[derive(BinSerialize, BinDeserialize, Eq, PartialEq)]
struct MyData {
    v1: String,
    v2: Option<usize>,
}

let my_data = MyData {
    v1: "Some Text".to_string(),
    v2: Some(12415165),
};

let vec = binserde::serialize(&my_data).unwrap();

let copy_of_my_data: MyData = binserde::deserialize(&vec).unwrap();

assert_eq!(my_data, copy_of_my_data);

宏属性

#[derive(BinSerialize)]#[derive(BinDeserialize)] 允许使用属性来控制(反)序列化。

#[binserde(skip)]

有效范围:字段

序列化时跳过字段。反序列化时使用 [Default::default()] 替代从流中读取来填充字段。

#[binserde(no_dedup)]

有效范围:字段

关闭此字段的去重。有关去重工作原理的更多信息,请参阅 [去重]。

#[binserde(index=n)]

有效范围:字段

未实现

序列化时将字段及其所有后续字段移动到指定的位置 n,将原来位于该位置之后的所有内容向右移动。

示例

#[derive(BinSerialize)]
struct S {
    w: u8,
    x: u8,
    #[binserde(index = 0)]
    y: u8,
    z: u8,
}

let vec = binserde::serialize(&S { w: 0, x: 1, y: 2, z: 3 });

assert_eq!(&[2, 3, 0, 1], &vec);

属性将 yz 移动到位置 0,将 wx 分别推回到位置 2 和 3。

该属性可以应用于多个字段,此时移动操作将从上到下进行评估。这意味着,以下结构体将按照 z, x, y, w 的顺序序列化,而不是 x, y, z, w 或其他任何顺序。

#[derive(BinSerialize)]
struct S {
    w: u8,
    #[binserde(index = 0)]
    x: u8,
    y: u8,
    #[binserde(index = 0)]
    z: u8,
}

去重

去重目前仅针对字符串实现。它通过将任何使用其 BinSerializer 实现序列化的 String 或 [str] 添加到单独的列表中,并将该列表写入给 serialize(或等效函数)的缓冲区的开头。在数据中,字符串被替换为一个指向字符串列表索引的 usize。实际上,去重数据结构将转换为以下内容

struct S {
    s1: String,
    s2: String,
    strs: Vec<String>,
    something_else: u32,
}

struct S1 {
    strings: Vec<String>,
    s1: usize,
    s2: usize,
    strs: Vec<usize>,
    something_else: u32,
}

序列化时变为这样。当出现多个相同的字符串时,这可能会对序列化数据结构的最终大小产生重大影响。

依赖项

约 2MB
约 44K SLoC