13个版本 (6个重大更新)
新版本 0.6.1 | 2024年8月23日 |
---|---|
0.5.2 | 2024年8月21日 |
0.4.2 | 2024年7月7日 |
#662 in 编码
每月584次下载
85KB
1.5K SLoC
bzipper
bzipper 是Rust语言的二进制(反)序列化器。
与 Serde/Bincode 相比,bzipper的目标是具有已知大小约束的序列化。因此,这个crate可能更适合网络或其他需要固定大小缓冲区的场景。
请注意,此项目仍在进行中。
此crate与 no_std
兼容。
数据模型
大多数基本类型可以无损序列化,例外的是 usize
和 isize
。这些分别序列化为 u32
和 i32
,出于可移植性原因。
不支持无大小类型,如 str
和切片。应使用数组。对于字符串,还提供了 FixedString
类型。
用法
此crate围绕 Serialise
和 Deserialise
特性展开,这两个特性通常与流(更具体地说,s-streams和d-streams)一起使用。
许多核心类型已通过bzipper实现,包括基本类型以及一些标准库类型,如 Option
和 Result
。
在大多数情况下,建议仅对自定义类型(枚举和结构)派生这些特性。在这里,每个字段都按照声明顺序链式连接
use bzipper::{Deserialise, Serialise};
#[derive(Debug, Deserialise, PartialEq, Serialise)]
struct IoRegister {
addr: u32,
value: u16,
}
let mut buf: [u8; IoRegister::SERIALISED_SIZE] = Default::default();
IoRegister { addr: 0x04000000, value: 0x0402 }.serialise(&mut buf).unwrap();
assert_eq!(buf, [0x04, 0x00, 0x00, 0x00, 0x04, 0x02]);
assert_eq!(IoRegister::deserialise(&buf).unwrap(), IoRegister { addr: 0x04000000, value: 0x0402 });
序列化
要序列化实现 Serialise
的对象,只需为序列化分配一个缓冲区。任何给定序列化的所需大小由 SERIALISED_SIZE
常量指定
use bzipper::Serialise;
let mut buf: [u8; char::SERIALISED_SIZE] = Default::default();
'Ж'.serialise(&mut buf).unwrap();
assert_eq!(buf, [0x00, 0x00, 0x04, 0x16]);
serialise
方法的唯一特殊要求是提供的字节切片的元素个数为恰好 SERIALISED_SIZE
。
我们还可以使用流来 链式 组合多个元素
use bzipper::Serialise;
let mut buf: [u8; char::SERIALISED_SIZE * 5] = Default::default();
let mut stream = bzipper::Sstream::new(&mut buf);
stream.append(&'ل');
stream.append(&'ا');
stream.append(&'م');
stream.append(&'د');
stream.append(&'ا');
assert_eq!(buf, [0x00, 0x00, 0x06, 0x44, 0x00, 0x00, 0x06, 0x27, 0x00, 0x00, 0x06, 0x45, 0x00, 0x00, 0x06, 0x2F, 0x00, 0x00, 0x06, 0x27]);
在序列化基本类型时,生成的字节流是大端字节序(也称为网络字节序)。建议实现者也遵循此约定。
反序列化
反序列化的语法几乎与序列化相同。
要将缓冲区反序列化,只需调用 deserialise
方法
use bzipper::Deserialise;
let data = [0x45, 0x54];
assert_eq!(<u16>::deserialise(&data).unwrap(), 0x4554);
与序列化类似,可以使用 Dstream
来反序列化链式元素
use bzipper::Deserialise;
let data = [0x45, 0x54];
let stream = bzipper::Dstream::new(&data);
assert_eq!(stream.take::<u8>().unwrap(), 0x45);
assert_eq!(stream.take::<u8>().unwrap(), 0x54);
依赖项
~260–710KB
~17K SLoC