7 个版本
0.1.7 | 2022 年 1 月 27 日 |
---|---|
0.1.6 | 2021 年 5 月 31 日 |
0.1.5 | 2020 年 12 月 25 日 |
#2263 在 编码
65 每月下载次数
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);
属性将 y
和 z
移动到位置 0,将 w
和 x
分别推回到位置 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