1 个稳定版本
1.0.0 | 2022 年 8 月 22 日 |
---|
#2311 在 Rust 模式
14KB
164 行
Tartan C Enum
一个简单的宏,用于定义支持未知值的 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 (LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
由您选择。
贡献
除非您明确声明,否则您提交的任何旨在包含在作品中的贡献,根据 Apache-2.0 许可证定义,应按上述方式双重许可,不附加任何其他条款或条件。
此 README 是从文档注释生成的。使用 cargo readme
刷新它。