5个版本

0.6.2 2024年8月24日
0.6.1 2024年8月23日
0.6.0 2024年8月23日
0.5.2 2024年8月21日
0.5.0 2024年8月21日

#1042 in 过程宏

Download history 191/week @ 2024-08-16

191 每月下载量
用于 bzipper

LGPL-3.0-or-later

29KB
347

bzipper

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

Serde/Bincode 不同,bzipper 的目标是进行具有已知大小限制的序列化。因此,这个包可能更适合网络或其他需要固定大小缓冲区的情况。

请注意,这个项目仍在开发中。

这个包与 no_std 兼容。

数据模型

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

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

用法

这个包围绕 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);

依赖项

~290–750KB
~18K SLoC