#枚举 #属性 #解析器 # #过程宏 #序列化 #生成

enum_parse

生成解析枚举变体的样板代码的过程宏

1 个不稳定版本

0.1.0 2023年10月2日

2971 in Rust 模式

MIT 许可证

21KB
319

enum_parse

提供enum_parse过程宏,用于生成解析枚举变体的样板代码。

#[enum_parse(derive(SomehowParsable, Debug),
             repr(C, packed),
             attr(parse_input = &[u8], parse_fn = somehow_parse))]
pub enum Payload {
    #[attr(ID = 0x2b)]
    Hello { a: u8, b: u64, c: u64, d: u8 },
    #[attr(ID = 0x42)]
    Goodbye { a: u8, e: u8 },
    #[attr(ID = _)]
    Unknown,
}

pub fn parse_packet(data: &[u8]) -> Option<Payload> {
    let id: usize = data[0] as usize;
    // parse method is generated by the macro
    Payload::parse(&data[1..], id)
}

(SomehowParsable 是一个假设的 derive,实现了 trait) 这将被评估为以下代码

pub enum Payload {
    Hello(Hello),
    Goodbye(Goodbye),
    Unknown,
}

impl Payload {
    pub fn parse(data: &[u8], id: usize) -> Option<Self> {
        match id {
            Hello::ID => Hello::read_from(data).map(|s| Self::Hello(s)),
            Goodbye::ID => Goodbye::read_from(data).map(|s| Self::Goodbye(s)),
            _ => Some(Self::Unknown),
        }
    }
}

#[derive(SomehowParsable, Debug, Default)]
#[repr(C, packed)]
pub struct Hello {
    pub a: u8,
    pub b: u64,
    pub c: u64,
    pub d: u8,
}
impl Hello {
    pub const ID: usize = 0x2b;
}

#[derive(SomehowParsable, Debug, Default)]
#[repr(C, packed)]
pub struct Goodbye {
    pub a: u8,
    pub e: u8,
}
impl Goodbye {
    pub const ID: usize = 0x42;
}

#[derive(SomehowParsable, Debug, Default)]
#[repr(C, packed)]
pub struct Unknown {}

pub fn parse_packet(data: &[u8]) -> Option<Payload> {
    let id: usize = data[0] as usize;
    Payload::parse(&data[1..], id)
}

展开代码中有很多重复代码 - 每个结构体都需要被属性化、放入枚举中,并在 parse() 方法中给定一个匹配案例。这就是为什么使用过程宏非常有用的原因。

依赖关系

~260–710KB
~17K SLoC