7个版本
0.8.14 | 2024年4月17日 |
---|---|
0.8.12 | 2023年7月21日 |
0.8.11 | 2022年4月19日 |
0.8.10 | 2021年2月2日 |
0.4.0 |
|
#23 in 编码
1,676,316 每月下载量
在 1,552 个crate中(113个直接使用) 使用
92KB
1.5K SLoC
Rust MessagePack库
RMP是纯Rust实现的MessagePack高效二进制序列化格式。这个crate提供了低级核心功能,包括原始值的写入器和读取器,并且直接映射到二进制MessagePack格式。
这个crate代表了与MessagePack格式交互所需的基本功能。在理念上,它是作为构建高级抽象的基础而开发的。
用法
要使用rmp
,首先将其添加到你的Cargo.toml
[dependencies.rmp]
rmp = "0.8"
功能
-
低级API
RMP设计得轻量级且简单直接。它提供了低级API,让你完全控制编码/解码过程。支持
no-std
环境。 -
零拷贝值解码
RMP允许以零拷贝方式从缓冲区中解码字节,无需任何堆分配。它简单且速度极快。Rust静态检查确保数据在缓冲区生存期间有效。
-
清晰的错误处理
RMP的错误系统保证你永远不会收到包含不可达变体的错误枚举。
-
稳健且经过测试
该项目使用TDD和CI进行开发,因此任何发现的错误都会得到修复而不会破坏现有功能。
详细
目前有两个大型模块:编码和解码。更多详细信息请查看相应的章节。
形式上,每个MessagePack消息都由一些封装数据类型的标记和实际数据本身组成。有时没有单独的数据块,例如布尔值。在这些情况下,标记包含值。例如,true
值编码为0xc3
。
let mut buf = Vec::new();
rmp::encode::write_bool(&mut buf, true).unwrap();
assert_eq!([0xc3], buf[..]);
有时单个值可以以多种方式编码。例如,值42
可以表示为:[0x2a], [0xcc, 0x2a], [0xcd, 0x00, 0x2a]
等等,所有这些都被认为是有效的表示。为了允许对这种值的编码进行细粒度控制,库提供了直接映射函数。
let mut bufs = vec![vec![]; 5];
rmp::encode::write_pfix(&mut bufs[0], 42).unwrap();
rmp::encode::write_u8(&mut bufs[1], 42).unwrap();
rmp::encode::write_u16(&mut bufs[2], 42).unwrap();
rmp::encode::write_u32(&mut bufs[3], 42).unwrap();
rmp::encode::write_u64(&mut bufs[4], 42).unwrap();
assert_eq!([0x2a], bufs[0][..]);
assert_eq!([0xcc, 0x2a], bufs[1][..]);
assert_eq!([0xcd, 0x00, 0x2a], bufs[2][..]);
assert_eq!([0xce, 0x00, 0x00, 0x00, 0x2a], bufs[3][..]);
assert_eq!([0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a], bufs[4][..]);
但它们并不打算被广泛使用。相反,我们经常需要将字节紧凑地编码以节省空间。在这些情况下,RMP提供了保证选择最紧凑表示的函数。
let mut buf = Vec::new();
rmp::encode::write_sint(&mut buf, 300).unwrap();
assert_eq!([0xcd, 0x1, 0x2c], buf[..]);
另一方面,对于反序列化,值编码的表示方式并不重要——RMP处理所有这些表示。
有时你已知确切的类型表示,并希望强制执行反序列化过程以使其强类型安全。
let buf = [0xcd, 0x1, 0x2c];
assert_eq!(300, rmp::decode::read_u16(&mut &buf[..]).unwrap());
然而,如果你尝试将这样的bytearray解码为其他整数类型,例如u32
,将会出现类型不匹配错误。
let buf = [0xcd, 0x1, 0x2c];
rmp::decode::read_u32(&mut &buf[..]).err().unwrap();
但有时你只是想要编码一个整数,它必须适合指定的类型,无论它是如何编码的。RMP提供了such
函数,以简化与其他MessagePack库的集成。
let buf = [0xcd, 0x1, 0x2c];
assert_eq!(300i16, rmp::decode::read_int(&mut &buf[..]).unwrap());
assert_eq!(300i32, rmp::decode::read_int(&mut &buf[..]).unwrap());
assert_eq!(300i64, rmp::decode::read_int(&mut &buf[..]).unwrap());
assert_eq!(300u16, rmp::decode::read_int(&mut &buf[..]).unwrap());
assert_eq!(300u32, rmp::decode::read_int(&mut &buf[..]).unwrap());
assert_eq!(300u64, rmp::decode::read_int(&mut &buf[..]).unwrap());
API
几乎所有的API都是以纯函数的形式表示的,它接受一个泛型Write
或Read
以及要编码/解码的值。例如,让我们对π数字做一个往返。
let pi = std::f64::consts::PI;
let mut buf = Vec::new();
rmp::encode::write_f64(&mut buf, pi).unwrap();
assert_eq!([0xcb, 0x40, 0x9, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18], buf[..]);
assert_eq!(pi, rmp::decode::read_f64(&mut &buf[..]).unwrap());
许可:MIT
依赖项
~175–270KB