5个版本

0.1.4 2021年5月31日
0.1.3 2020年12月25日
0.1.2 2020年12月25日
0.1.1 2020年12月18日
0.1.0 2020年12月5日

#180 in #binary-format


binserde 中使用

MIT 许可证

14KB
357

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(跳过)]

适用于:字段

在序列化时跳过该字段。在反序列化时,使用 [Default::default()] 而不是从流中读取以填充字段。

#[binserde(不去重)]

适用于:字段

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

#[binserde(索引=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);

将属性移动到位置0,将yz推入,并将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实现序列化的Stringstr,并将其添加到单独的列表中,该列表被写入给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
约42K SLoC