1 个不稳定版本
0.1.0 | 2023年10月2日 |
---|
2971 in Rust 模式
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