3 个版本 (破坏性更新)
0.3.0 | 2023 年 3 月 28 日 |
---|---|
0.2.0 | 2023 年 3 月 24 日 |
0.1.0 | 2023 年 3 月 23 日 |
6 在 #c-like
每月 2,832 次下载
用于 enum-tag
11KB
82 行
[2]: https://github.com/Robbepop/enum-tag/actions/workflows/rust.yml [4]: https://docs.rs/enum-tag [6]: https://crates.io/crates/enum-tag
持续集成 | 文档 | Crates.io |
---|---|---|
[][2] | [][4] | [][6] |
#[derive(EnumTag)]
此包提供过程宏,以派生给定的 Rust enum
的 #derive(EnumTag)
特性。此过程宏仅适用于 Rust enum
类型,并生成以下内容:
- 一个与输入 Rust
enum
有相同变体但不含所有关联数据的类似 C 的enum
类型。 - 为 Rust
enum
派生EnumTag
特性的实现。
派生的 EnumTag
特性使得可以创建生成的类似 C 的 enum
类型的实例,并通过 <RustEnum as EnumTag>::Tag
链接到其定义。
何时使用此功能?
这对于拥有独特的枚举
标签类型的crate来说非常有用,同时它还托管了带有大量变体的Rust 枚举
类型,这使得维护这两种枚举类型之间的镜像变得负担重重。
这个crate的动机是一个Wasm解释器,它将指令表示为枚举,但同时也希望访问指令的指令码而不涉及数据。在这个例子中,指令码是指令的枚举
标签。
示例
use ::enum_tag::EnumTag;
#[derive(EnumTag)]
#[repr(u8)] // Rust needs this for `B = 42`
enum Foo {
A,
B = 42,
C(i32),
D(i32, i64),
E { a: i32 },
F { a: i32, b: i64 },
}
/// This is how we can access the generated C-like enum type and name it.
type FooTag = <Foo as EnumTag>::Tag;
assert_eq!(FooTag::A, Foo::A.tag());
assert_eq!(FooTag::B, Foo::B.tag());
assert_eq!(FooTag::C, Foo::C(1).tag());
assert_eq!(FooTag::D, Foo::D(2, 3).tag());
assert_eq!(FooTag::E, Foo::E { a: 4 }.tag());
assert_eq!(FooTag::F, Foo::F { a: 5, b: 6 }.tag());
assert_eq!(FooTag::B as u8, 42);
上面的#[derive(EnumTag)]
生成以下Rust代码
const _: () = {
#[derive(
::core::fmt::Debug,
::core::clone::Clone,
::core::marker::Copy,
::core::cmp::PartialEq,
::core::cmp::Eq,
::core::cmp::PartialOrd,
::core::cmp::Ord,
::core::hash::Hash,
)]
pub enum FooTag {
A,
B = 42,
C,
D,
E,
F,
}
impl ::enum_tag::EnumTag for Foo {
type Tag = FooTag;
fn tag(&self) -> <Self as ::enum_tag::EnumTag>::Tag {
match self {
Self::A { .. } => <Self as ::enum_tag::EnumTag>::Tag::A,
Self::B { .. } => <Self as ::enum_tag::EnumTag>::Tag::B,
Self::C { .. } => <Self as ::enum_tag::EnumTag>::Tag::C,
Self::D { .. } => <Self as ::enum_tag::EnumTag>::Tag::D,
Self::E { .. } => <Self as ::enum_tag::EnumTag>::Tag::E,
Self::F { .. } => <Self as ::enum_tag::EnumTag>::Tag::F,
}
}
}
};
依赖关系
~290–750KB
~18K SLoC