#枚举 #ffi

no-std tartan-c-enum

定义支持未知值的 FFI 安全枚举

1 个稳定版本

1.0.0 2022 年 8 月 22 日

#2311Rust 模式

MIT/Apache

14KB
164

Tartan C Enum

Crate Docs Build License

一个简单的宏,用于定义支持未知值的 FFI 安全枚举。

Rust 的 enum 类型在分配未知区分值(例如,通过指针转换或转换)时将触发未定义的行为。虽然这可以启用有用的编译器优化,但它也意味着枚举在 FFI 中不是安全的,因为 C 将枚举视为可以取底层整数类型范围内任何值的整数类型。

此 crate 提供了一种更类似于 C 的枚举类型的替代方案。使用 c_enum 宏定义的枚举是整数类型的简单包装器。已知变体定义为常量,并可以与代码中定义的名称(例如,用于 Debug 输出)关联,但完全支持未知值。由于它们具有透明表示,因此在从任意值转换时不会触发未定义的行为(只要您使用内置整数类型)并且可以在 FFI 结构和函数中安全使用。

c_enum! {
    pub enum Example(u16) {
        Foo,
        Bar = 2,
        Quux,
        Baz = 0xffff,
    }
}

// Known value
let x = Example::Bar;
assert_eq!(x, Example::from(2));
assert_eq!(u16::from(x), 2);
assert_eq!(x.name(), Some("Bar"));

// Omitted variant values assigned in sequence
assert_eq!(u16::from(Example::Foo), 0);
assert_eq!(u16::from(Example::Quux), 3);

// Unknown value
let y = Example::from(0xcafe);
assert_eq!(u16::from(y), 0xcafe);
assert_eq!(y.name(), None);

// Use in an FFI-safe struct
#[repr(C)]
#[derive(Debug, PartialEq)]
pub struct Quux(Example, u8, u8);
unsafe {
    assert_eq!(
        core::mem::transmute::<[u8; 4], Quux>([0xff, 0xff, 0x8c, 0xf2]),
        Quux(Example::Baz, 0x8c, 0xf2),
    );
    assert_eq!(
        core::mem::transmute::<[u8; 4], Quux>([0xab, 0xab, 0x05, 0x3b]),
        Quux(Example::from(0xabab), 0x05, 0x3b),
    );
}

有关更多示例,请参阅由此 crate 分离出来的 Tartan OS 项目。此宏与 Tartan Bitfield crate 结合使用效果良好。

安装

将以下内容添加到您的 Cargo.toml 中

[dependencies]
tartan-c-enum = 1.0.0

开发

这是一个相当标准的 Rust 库,使用 Cargo。

测试

cargo test --all-targets

格式化/Linting

cargo fmt
cargo clippy --all-targets

许可证

许可协议为以下之一

由您选择。

贡献

除非您明确声明,否则您提交的任何旨在包含在作品中的贡献,根据 Apache-2.0 许可证定义,应按上述方式双重许可,不附加任何其他条款或条件。


此 README 是从文档注释生成的。使用 cargo readme 刷新它。

无运行时依赖