#枚举 # #实用工具

vnum

为每个变体创建关联常量值的枚举

1个不稳定版本

0.1.0 2022年8月27日

#1386Rust模式

MIT/Apache

71KB
152

vnum

为每个变体创建关联常量值的枚举。

特性

  • 通过 .value() 方法或通过 From / Into 特性来获取值
  • 您的属性(#[...])和文档会自动添加到生成的枚举中
  • 生成的文档会显示每个变体的值:[图片链接]

示例

value_enum! {
    enum Fruit: &'static str {
        Apple = "red",
        Banana = "yellow",
        Pear = "green"
    }
}

// Get the value with the `.value()` method:
let apple = Fruit::Apple;
println!("Apple: {}", apple.value()); // Apple: red

// Get the value with the From / Into traits:
let pear = Fruit::Pear;
let value: &str = pear.into();
println!("Pear: {}", value); // Pear: green

注意: 值的类型必须在枚举名称后面指定,就像上面这样(在这种情况下是 &'static str)。

注意: 如果值类型是引用(&)或包含引用,必须使用 'static 生命周期,否则Rust编译器不知道值是从哪里借来的。
否则,Rust编译器不知道值是从哪里借来的。


value_enum! {
    #[derive(Debug)]
    enum Color: u8 {
        Red = 1,
        Green = 2,
        Yellow = 3
    }
}

let red = Color::Red;
println!("{:?}: {}", red, red.value()); // Red: 1

let yellow = Color::Yellow;
let value: u8 = yellow.into();
println!("Yellow: {}", value); // Yellow: 3

注意: 如果您想为您的枚举实现更多特性,您必须自己完成。
在上面的示例中,实现了 Debug 特性。

注意: 等号右侧只能使用常量表达式,这意味着它们必须在编译时评估。
这意味着它们必须在编译时评估。
在此处查看所有类型的常量表达式:https://doc.rust-lang.net.cn/reference/const_eval.html#constant-expressions

替代方案

  • 简单的 常量

    简单,但不能

    • 限制可能的值
    • 添加其他项目(例如,方法、特性实现、常量)

    简单常量的使用示例

    const RED: u8 = 1;
    const GREEN: u8 = 2;
    const YELLOW: u8 = 3;
    
    fn display_color(color: u8) { }
    
    display_color(RED);
    display_color(GREEN);
    
    // But also accepts other `u8` values:
    display_color(42);
    

    您还可以

    • 创建一个 类型别名 以提高可读性

      type Color = u8;
      // `Color` is now an alias for `u8`
      fn display_color(color: Color) { }
      
      display_color(RED);
      
      // Note: Because `Color` is only an alias and not a new type,
      //       you can still use any other `u8` value:
      display_color(42);
      
    • 将常量放入自己的模块中,以便像 Color::RED 这样使用

      mod Color {
          const RED: u8 = 1;
          // ...
      }
      

  • 具有 区分符 的枚举

    • 枚举 区分符 只能是整数,
      因此,您无法重新创建上面的 &str 示例。
      您可以通过 as 将变体类型转换为整数类型。

    使用带有区分符的枚举的示例

    enum Color {
        Red = 1,
        Green = 2,
        Yellow = 3
    }
    
    fn display_color(color: Color) {
      // Now cast to any integer type via `as`:
      takes_u8(color as u8);
      takes_i32(color as i32);
    }
    
    display_color(Color::Yellow);
    

    您还可以

    • 创建一个获取值的方法

      impl Color {
          fn value(&self) -> u8 {
              self as u8
          }
      }
      // ...
      takes_u8(color.value())
      // ...
      

  • 手动将枚举变体转换为值

    这正是这个库自动执行的操作。

    手动将枚举变体转换为值的示例

    enum Color {
        Red,
        Green,
        Yellow
    }
    
    impl Color {
        const fn value(&self) -> u8 {
            const RED: u8 = 1;
            const GREEN: u8 = 2;
            const YELLOW: u8 = 3;
            match self {
                Color::Red => RED,
                Color::Green => GREEN,
                Color::Yelllow => YELLOW
            }
        }
    }
    
    display_color(Color::Yellow);
    
    fn display_color(color: Color) {
      // Now cast to any integer type via `as`:
      takes_u8(color as u8);
      takes_i32(color as i32);
    }
    

    注意: 除了生成这样的方法之外,这个库还会生成文档和 From 实现。
    查看文件开头以获取更多信息。


计划中的功能

  • 允许在一个宏调用中创建多个值枚举
  • 确保唯一值的选项
  • 禁用自动生成文档的选项
  • 使生成的文档中关于值类型的说明可点击
    (目前不起作用,因为 rustdoc 只为没有或包含引用的类型创建链接)
  • no_std 支持
  • 也许
    • 通过值获取变体
    • 可选的“通配符”变体,可以包含该类型的所有值
    • 使重复值的名称类似于 Python 的 enum 模块 中的别名
    • 可选的 Debug 实现,显示变体名称和值,也类似于 Python 的枚举模块

许可

在您的选择下,许可协议为以下之一

贡献

除非您明确声明,否则您提交的任何贡献,按照 Apache-2.0 许可证定义的,将按照上述方式双许可,没有附加条款或条件。

无运行时依赖项