13个版本 (6个重大更新)

新版本 0.6.1 2024年8月23日
0.5.2 2024年8月21日
0.4.2 2024年7月7日

#662 in 编码

Download history 447/week @ 2024-06-07 38/week @ 2024-06-14 3/week @ 2024-06-21 6/week @ 2024-06-28 141/week @ 2024-07-05 7/week @ 2024-07-12 42/week @ 2024-07-26 264/week @ 2024-08-02 161/week @ 2024-08-09 117/week @ 2024-08-16

每月584次下载

LGPL-3.0-or-later

85KB
1.5K SLoC

bzipper

bzipper 是Rust语言的二进制(反)序列化器。

Serde/Bincode 相比,bzipper的目标是具有已知大小约束的序列化。因此,这个crate可能更适合网络或其他需要固定大小缓冲区的场景。

请注意,此项目仍在进行中。

此crate与 no_std 兼容。

数据模型

大多数基本类型可以无损序列化,例外的是 usizeisize。这些分别序列化为 u32i32,出于可移植性原因。

不支持无大小类型,如 str 和切片。应使用数组。对于字符串,还提供了 FixedString 类型。

用法

此crate围绕 SerialiseDeserialise 特性展开,这两个特性通常与流(更具体地说,s-streams和d-streams)一起使用。

许多核心类型已通过bzipper实现,包括基本类型以及一些标准库类型,如 OptionResult

在大多数情况下,建议仅对自定义类型(枚举和结构)派生这些特性。在这里,每个字段都按照声明顺序链式连接

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