#枚举 #match #

extrude

一个将枚举值展开为Option的宏

1个不稳定版本

0.1.0 2021年11月4日

#2086Rust模式

Apache-2.0

13KB
145 代码行

extrude

extrude,一个枚举提取库。

extrude!() 宏与标准 matches!() 宏非常相似,但它返回的并不是匹配是否成功,而是将match中的所有绑定变量作为一个元组包裹在 Option 中返回。

最好通过实践来理解

enum Ast<'a> {
  Literal(i64),
  Ident(&'a str),
  Op {
    lhs: &'a Ast<'a>,
    rhs: Option<&'a Ast<'a>>,
  },
}

let ast = Ast::Op {
    lhs: &Ast::Literal(5),
    rhs: Some(&Ast::Ident("x")),
};

let (lhs, rhs) = extrude!(ast, Ast::Op {
  lhs,
  rhs: Some(Ast::Ident(id)),
}).unwrap();
assert_eq!(lhs, &Ast::Literal(5));
assert_eq!(rhs, &"x");

为什么?

Option 为提取和转换包含项提供了一系列助手,而大多数 enum 都没有。虽然可以使用第三方 derive 来减轻这些限制,但这些通常很复杂,并且需要类型的所有权。

另一方面,extrude!() 将你关心的枚举值的部分转换为选项元组,让你可以在常见情况下使用现有的词汇,而不需要编写 match

注意事项

目前这个功能实现为一个声明式宏,这意味着它不能完美地解析模式语法。特别是,带有泛型参数的路径和单元素路径模式(rustc通过名称查找来区分)不支持。

此外,元组是通过基本特性行建的,无法支持无限大的元组。我们支持最多32个元素的元组。

使用单个绑定值的模式进行展开不会产生单元素元组 (T,),因为这几乎从来不是你想要的。这个特殊情况可能不会让你感到惊讶,但仍然值得指出。

这个宏不能做所有的事情,这是可以的! match 在大多数情况下是一个更合适的工具。《let-else》语句一旦稳定,将取代一些crates的预期用途。在这种情况下,请优先使用 let-else

许可证:Apache-2.0

没有运行时依赖