#枚举 #过程宏 #变体 #关联 #创建 #过程 #函数

enum-from-functions

一个过程宏,可以创建一个枚举,每个枚举值都有一个相应的函数

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 2023年7月24日

#1728 in 过程宏

每月30次下载

OSL-3.0 许可证

17KB
240

enum-from-functions.rs CI/CD Crates.io

一个过程宏,可以创建一个枚举,每个枚举值都有一个相应的函数。

文档可以在行内或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() -> Tasync 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()
}
}

asyncconstunsafe 函数都受支持。如果存在这些关键字中的任何一个,生成的 map 函数将具有相同的关键字。因此,asyncconst 函数不能存在于同一个 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