#枚举 #映射 #try-from # #from

enum-mapping-macro

将枚举变体映射到数字,反之亦然

2 个版本

新版本 0.1.1 2024 年 8 月 25 日
0.1.0 2024 年 8 月 25 日

#716 in 开发工具

BSD-2-Clause

12KB
245 代码行

枚举映射

有时,在枚举变体和数字代码之间进行转换很有用,反之亦然。虽然这对于简单变体(不带字段)来说很简单,但当处理更复杂的变体时,这可能会变得繁琐。

此宏自动为您枚举实现 FromTryFrom 特性。如果指定范围内的每个数字都由一个变体覆盖,则宏实现 From;否则,它实现 TryFrom

使用方法

use std::convert::TryInto;
use enum_mapping_macro::U8Mapped;

#[derive(U8Mapped)]
#[repr(u8)]
enum MessageKind {
    Hello,
    Text(String) = 0x10,
    Cfg { version: u8, debug: bool }
}

fn decode_next(buf: &[u8]) -> Result<MessageKind, ()> {
    buf[0].try_into()
}

在这个示例中,宏为 TryFrom<u8> 特性实现了 MessageKind,将 0 => Hello0x10 => Text0x11 => Cfg 进行映射。

映射详情

  • 如果变体有区分符,则该值用作其映射值。
  • 如果变体没有区分符,则其值通过将前一个变体的值加 1 来确定。除非显式提供区分符,否则第一个变体始终映射到 0。

此外,该宏还为 From<MessageKind> 实现了 u8,因此您可以使用类似这样的代码

use enum_mapping_macro::U8Mapped;

#[derive(U8Mapped)]
#[repr(u8)]
enum MessageKind {
    Hello,
    Text(String) = 0x10,
    Cfg { version: u8, debug: bool }
}

fn test(m: MessageKind) -> u8 {
    m.into()
}

使用默认变体

如果您更喜欢使用 From 而不是 TryFrom,则可以定义一个 "通配符" 变体,作为没有其他变体匹配时的默认值

use enum_mapping_macro::U8Mapped;
use std::convert::Into;

#[derive(U8Mapped)]
#[repr(u8)]
enum MessageKind {
    Hello,
    Text(String) = 0x10,
    Cfg { version: u8, debug: bool },

    #[catch_all]
    None = 0xff
}

fn decode_next(buf: &[u8]) -> MessageKind {
    buf[0].into()
}

在这种情况下,如果没有特定变体与提供的值匹配,则返回 None 变体。

依赖关系

~285–740KB
~18K SLoC