17 个版本 (10 个破坏性更改)

使用旧的 Rust 2015

0.11.3 2024 年 5 月 21 日
0.11.2 2021 年 5 月 31 日
0.11.1 2021 年 2 月 3 日
0.11.0 2020 年 6 月 20 日
0.3.0 2016 年 11 月 11 日

#169 in Rust 模式

Download history 5348/week @ 2024-05-03 6317/week @ 2024-05-10 6264/week @ 2024-05-17 6591/week @ 2024-05-24 6446/week @ 2024-05-31 5456/week @ 2024-06-07 6958/week @ 2024-06-14 6255/week @ 2024-06-21 5686/week @ 2024-06-28 5254/week @ 2024-07-05 5286/week @ 2024-07-12 5289/week @ 2024-07-19 5016/week @ 2024-07-26 5403/week @ 2024-08-02 6273/week @ 2024-08-09 4993/week @ 2024-08-16

每月下载量 22,468
用于 122 个 crate (22 个直接)

MIT 许可证

95KB
690

safe-transmute-rs TravisCI 构建状态 AppVeyorCI 构建状态 Licence

为 Rust 提供受保护的 transmute() 函数。

文档


lib.rs:

此 crate 包含了 transmutation 程序的 checked 实现,其中一些确保了内存安全。

crate 结构

以下模块可用

  • base 模块中的函数本身不是安全的,但只是防止越界访问(例如,尝试从 7 个字节创建一个 8 字节类型)。这些函数与传递给它们的数据一样安全:尝试将数据转换为一个无效的内存表示仍然是未定义行为。此外,未对齐的内存访问不会被阻止,必须由调用者事先确保。
  • guard 模块包含 Guard API,它在一个转换中强加切片边界限制。
  • 《trivial》模块引入了《TriviallyTransmutable》特质,它静态地确保任何位组合对于给定类型都构成一个有效的值。该模块中的函数比《base》模块更安全,但仍然不能防止未对齐的内存访问。
  • to_bytes 实现了将值重新解释为字节的反向操作。
  • 《bool》模块确保将字节安全地转换为布尔值。
  • 在该包的根目录中,有一些转换函数,经过足够的检查,可以在任何情况下使用。由于未对齐的数据或不可兼容的向量转换目标,操作可能还会任意返回(可恢复的)错误,但它不会吃掉你的衣物,并且有辅助函数可供程序员在特定用例中使用。

可以通过在导入时指定 default-features = false 来禁用 std 功能,从而在无 std 环境中使用此包。然而,std 只用于与 std::error::Error 集成。

请注意,这也会禁用对 alloc 的操作。如果你的无 std 环境有一个 alloc 实现,你将必须通过使用 features = ["alloc"] 来重新启用它们。

迁移

如果你在 v0.11 之前使用过 safe-transmute,我们建议查看 v0.11 迁移指南 以快速开始。

示例

将字节视为一系列 u16,具有单对多边界保护(至少一个值,允许多余的字节)

let bytes = &[0x00, 0x01, 0x12, 0x24,
              0x00]; // 1 spare byte
match transmute_many::<u16, SingleManyGuard>(bytes) {
    Ok(words) => {
        assert_eq!(words,
                   [u16::from_be(0x0001), u16::from_be(0x1224)]);
    },
    Err(Error::Unaligned(e)) => {
        // Copy needed, would otherwise trap on some archs
        let words = e.copy();
        assert_eq!(*words,
                   [u16::from_be(0x0001), u16::from_be(0x1224)]);
    },
    Err(e) => panic!("Unexpected error: {}", e),
}

由于无法始终确保字节切片在读取不同约束的数据(如从 u8u16)时对齐良好,因此操作可能无法成功,且没有简单的方法来防止这种情况。

作为补救措施,可以在新向量中逐字节复制数据,这得益于 try_copy! 宏的帮助。

let bytes = &[0x00, 0x01, 0x12, 0x24, 0x00];
let words = try_copy!(transmute_many::<u16, SingleManyGuard>(bytes));

assert_eq!(*words,
           [u16::from_be(0x0001), u16::from_be(0x1224)]);

将所有字节视为一系列 u16

// Assuming little-endian
let bytes = &[0x00, 0x01, 0x12, 0x34];
let words = try_copy!(transmute_many_pedantic::<u16>(bytes));

assert_eq!(*words, [0x0100, 0x3412]);

将字节切片视为单个 f64

assert_eq!(transmute_one::<f64>(
   &[0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x40])?,
   2.0);

将一系列 u16 视为字节

assert_eq!(transmute_to_bytes(&[0x0001u16,
                                0x1234u16]),
           &[0x01, 0x00, 0x34, 0x12]);

无运行时依赖

功能