4个版本 (2个破坏性更新)
0.3.0 | 2023年8月14日 |
---|---|
0.2.0 | 2023年7月25日 |
0.1.1 | 2023年7月25日 |
0.1.0 | 2023年7月25日 |
0.0.0 |
|
#1728 in 过程宏
每月30次下载
17KB
240 行
enum-from-functions.rs
一个过程宏,可以创建一个枚举,每个枚举值都有一个相应的函数。
文档可以在行内或docs.rs上找到。
lib.rs
:
这个软件包包含一个过程宏属性,可以放置在一个 impl
块上。它将根据 impl
块中定义的函数生成一个 enum
。生成的 enum
将为每个函数提供一个变体,并在 impl
块中添加一个新的函数 map
,该函数将根据变体调用相应的函数。
示例
#[enum_from_functions]
impl Enum {
async fn foo() -> &'static str {
"Foo"
}
unsafe fn bar(baz: i32) -> &'static str {
"Bar"
}
}
展开为
enum Enum {
Foo,
Bar {
baz: i32
},
}
impl Enum {
async fn foo() -> &'static str {
"Foo"
}
unsafe fn bar(baz: i32) -> &'static str {
"Bar"
}
async unsafe fn map(&self) -> &'static str {
match self {
Enum::Foo => Enum::foo().await,
Enum::Bar(baz) => Enum::bar(baz),
}
}
}
impl
块中函数的签名可能不同,只要它们都具有相同的返回类型即可。
请注意,即使后者在技术上返回一个 impl
,但 fn f() -> T
和 async fn f() -> T
被认为是返回相同类型。有关更多信息,请参阅 async
关键字文档。
#[enum_from_functions]
impl Enum {
fn foo(baz: i32) -> &'static str {
"Foo"
}
async fn bar(&self, baz: bool) -> &'static str {
"Bar"
}
}
// Causes a compile error because the return types don't match.
#[enum_from_functions]
impl Enum {
fn foo() -> &'static str {
"Foo"
}
fn bar() -> String {
"Bar".to_owned()
}
}
async
、const
和 unsafe
函数都受支持。如果存在这些关键字中的任何一个,生成的 map
函数将具有相同的关键字。因此,async
和 const
函数不能存在于同一个 impl
块中(尽管 unsafe
函数可以与另外两个中的任何一个一起存在)。
#[enum_from_functions]
impl Enum {
async fn foo() -> &'static str {
"Foo"
}
const fn bar() -> &'static str {
"Bar"
}
// This would result in `async const map(...` which is not supported in Rust.
}
您也可以通过不在 impl
块中提供任何函数来创建一个空的 enum
(尽管我不确定为什么你想这样做)。
#[enum_from_functions]
impl EmptyEnum {}
如果您需要将生成的 enum
类型导出其父模块,请向宏属性提供 pub
参数。
mod internal {
#[enum_from_functions(pub)]
impl Visible {
fn example() -> bool {
true
}
}
}
// Will compile because the generated `enum` is visible outside of the `internal` module.
use internal::Visible;
mod internal {
#[enum_from_functions]
impl NotVisible {
fn example() -> bool {
false
}
}
}
// Causes a compile error because the generated `enum` is not visible outside of the `internal` module.
use internal::NotVisible;
impl
块中不是函数的项目将被忽略并原样传递到输出中。同样,任何在宏属性之前或之后应用的属性都将应用于生成的 enum
声明。
#[enum_from_functions]
##[derive(Debug)]
impl Enum {
const FOO: &'static str = "Foo";
fn foo() -> &'static str {
Self::FOO
}
const BAR: &'static str = "Bar";
fn bar() -> &'static str {
Self::BAR
}
const BAZ: &'static str = "Baz";
fn baz() -> &'static str {
Self::BAZ
}
}
依赖项
~0.9–1.4MB
~27K SLoC