rust 编写一个宏到AlphabertEnum的所有变量(26个)上的“#[derive(strum_macros::EnumString)]”

hgb9j2n6  于 2023-03-02  发布在  Mac
关注(0)|答案(1)|浏览(170)

我非常了解strum crate及其关联的EnumString trait,使用它可以将String类型的字符串“转换”为枚举变量。
我有一个名为Alphabert的枚举,它有26个变体。

enum Alphabert {
    A
    B
    C
// omitted
    Z
}

现在,要写26行类似#[strum(serialize = "A", serialize = "a")](docs)的代码是相当疯狂的,所以我想为它写一个宏。我希望生成的代码看起来像这样:

#[derive(EnumString)]
enum Alphabert {
    #[strum(serialize = "A", serialize = "a")]
    A
    #[strum(serialize = "B", serialize = "b")]
    B
// omitted
    #[strum(serialize = "Z", serialize = "z")]
    Z
}

下面是我编写这样一个宏的尝试:

#[macro_export]
macro_rules! enum_impl_display_debug_enumstring {
  (pub enum $name:ident {
        $($variant:ident),*,
    }) => {
    
    #[derive(strum_macros::EnumString)]
    pub enum $name {
        // need to be able to 'cast' the token `$variant` to type `&str` and both lower and upper cases
        $(#[strum(serialize = $variant, serialize = $variant)]
        $variant),*
      }
}

编译器错误为:

error: expected string literal
 --> src/enums.rs:6:5
  |
6 |     T,
  |     ^

这肯定是因为$variant标记不是&str类型。宏stringify将标记转换为String类型。所以我不知道有任何帮助宏或机制可以用来将标记$variant转换为&str类型。
另外,如何将“结果”&str类型转换为小写和大写?

UPDATE / EDIT在Jmb更新之后,我更新了我的枚举定义,它工作正常,如下所示:

#[derive(Debug, Eq, PartialEq, Display, EnumString)]
#[strum(serialize_all = "UPPERCASE")]
#[strum(ascii_case_insensitive)]
pub enum Alphaberts {
    A
    B
// omitted
    Z

}

fn main() {
    let a = Alphaberts::from_str("t").unwrap();
    println!("a: {}!", a); // Outputs: a: A!
tvokkenx

tvokkenx1#

Strum允许你配置序列化变量的大小写,你想要的可以用#[strum(ascii_case_insensitive)]来实现:

#[derive(EnumString)]
#[strum(ascii_case_insensitive)]
enum Alphabert {
    A,
    B,
// omitted
    Z
}

相关问题