#serialization #byte #old #plain #pod #parser #string

no-std watto

解析和序列化纯旧数据的实用工具

1 个不稳定版本

0.1.0 2022年9月12日

#1329编码

Download history 3109/week @ 2024-03-14 3252/week @ 2024-03-21 3268/week @ 2024-03-28 3618/week @ 2024-04-04 3788/week @ 2024-04-11 3397/week @ 2024-04-18 3748/week @ 2024-04-25 3815/week @ 2024-05-02 2275/week @ 2024-05-09 2778/week @ 2024-05-16 2805/week @ 2024-05-23 4010/week @ 2024-05-30 3445/week @ 2024-06-06 2805/week @ 2024-06-13 1893/week @ 2024-06-20 2255/week @ 2024-06-27

11,441 每月下载量
用于 8 个crate(5个直接使用)

Apache-2.0

17KB
212

Watto

Build Status codecov

解析和序列化纯旧数据的实用工具。

Pod

API 主要定义在 [Pod] trait 上,该trait可以为 #[repr(C)] 类型实现。然后可以从底层缓冲区直接获取对该 [Pod] 或其切片的引用。同样,[Pod] 也可以转换为其底层缓冲区,例如写入输出缓冲区。

功能

writer: 导出了一个包装 Writer 的额外 std::io::Write,允许通过添加填充字节显式对输出缓冲区进行对齐。

strings: 导出一个 StringTable 用于序列化和读取去重字符串。

端到端示例

use std::mem;
use std::io::Write;

use watto::Pod;

/// Our format looks like this:
/// * A header, containing the number of `A`s.
/// * An aligned slice of `A`s (length given by the header)
/// * An aligned slice of `B`s (length implicitly given by end of buffer)
#[repr(C)]
struct Header {
    version: u32,
    num_as: u32,
}
unsafe impl Pod for Header {}

#[repr(C)]
#[derive(Debug, PartialEq)]
struct A(u16);
unsafe impl Pod for A {}

#[repr(C)]
#[derive(Debug, PartialEq)]
struct B(u64);
unsafe impl Pod for B {}

// Writing into an output buffer:
let mut writer = watto::Writer::new(vec![]);

writer.write_all(Header { version: 1, num_as: 3 }.as_bytes()).unwrap();
writer.align_to(mem::align_of::<A>()).unwrap();
writer.write_all(&[A(1), A(2), A(3)].as_bytes()).unwrap();
writer.align_to(mem::align_of::<B>()).unwrap();
writer.write_all(&[B(4), B(5), B(6)].as_bytes()).unwrap();

let buffer = writer.into_inner();

// Reading from a buffer:
let buffer = &buffer;

let (header, buffer) = Header::ref_from_prefix(buffer).unwrap();
let (_, buffer) = watto::align_to(buffer, mem::align_of::<A>()).unwrap();
let (r#as, buffer) = A::slice_from_prefix(buffer, header.num_as as usize).unwrap();
let (_, buffer) = watto::align_to(buffer, mem::align_of::<B>()).unwrap();
let bs = B::slice_from_bytes(buffer).unwrap();

assert_eq!(header.num_as, 3);
assert_eq!(r#as, &[A(1), A(2), A(3)]);
assert_eq!(bs, &[B(4), B(5), B(6)]);

替代方案

Watto 强烈受到 zerocopy 的启发。

这两个之间的区别包括

  • zerocopy 有两个不同的特质用于读取和写入字节,而 watto 只有一个用于两者。
  • zerocopy 中,读取一个值需要将其包装在 LayoutVerified 中。而在 watto 中,实现 Pod 的类型可以直接读取。
  • watto 包含一个允许显式对输出进行对齐的 Writer
  • watto 包含一个用于(反)序列化字符串的 StringTable
  • zerocopy 包含了具有端序感知的整型类型。

为什么选择 Watto?

Qui-Gon Jinn:我在一场冒险游戏中得到了一个pod。这是有史以来建造最快的。

Watto:我希望你没有为此杀了我认识的人。

-- 星球大战:第一集——幽灵的威胁

许可证

Watto遵循Apache-2.0许可证。

依赖项

~125KB