#regex #from-str #parse

adhoc_derive

基于属性提供的正则表达式实现 FromStr

3个版本

0.1.2 2019年1月21日
0.1.1 2019年1月5日
0.1.0 2019年1月3日

#20 in #from-str

Download history 1/week @ 2024-06-29 50/week @ 2024-07-27

每月下载量 51

MIT 许可证

33KB
676

adhoc_derive  

实验性:基于属性提供的正则表达式实现 FromStr


使用方法

在您的 Cargo.toml 中添加以下内容

[dependencies]
adhoc_derive = "0.1.2"
lazy_static = "1.2.0"
regex = "1.1.0"

然后,您可以根据以下方式推导 FromStr 实现

use adhoc_derive::FromStr;

#[derive(FromStr)]
#[adhoc(regex = r"^#(?P<id>\d+) @ (?P<x>\d+),(?P<y>\d+): (?P<width>\d+)x(?P<height>\d+)$")]
struct Rectangle {
    id: usize,
    x: usize,
    y: usize,
    width: usize,
    height: usize,
}

let rect: Rectangle = "#123 @ 3,2: 5x4".parse().unwrap();
assert_eq!(123, rect.id);
assert_eq!(3, rect.x);
assert_eq!(2, rect.y);
assert_eq!(5, rect.width);
assert_eq!(4, rect.height);

通常,结构体的每个字段都需要实现 FromStr,并且每个字段标识符都需要对应于正则表达式中的命名捕获组。

对于枚举,您需要用正则表达式注解每个变体。第一个匹配的正则表达式(通常是唯一的)确定实例化的变体

#[derive(Debug, PartialEq, FromStr)]
enum Expression {
    #[adhoc(regex = r"^$")]
    Empty,
    #[adhoc(regex = r"^(?P<0>\d+)$")]
    Number(i32),
    #[adhoc(regex = r"^(?P<a>\d+)\+(?P<b>\d+)$")]
    Sum(#[adhoc(construct_with = "a: i32 + b: i32")] i32),
    #[adhoc(regex = r"^(?P<a>\d+)-(?P<b>\d+)$")]
    Difference(#[adhoc(construct_with = "a: i32 - b: i32")] i32),
}

let empty: Expression = "".parse().unwrap();
assert_eq!(Expression::Empty, empty);

let number: Expression = "4".parse().unwrap();
assert_eq!(Expression::Number(4), number);

let sum: Expression = "8+15".parse().unwrap();
assert_eq!(Expression::Sum(23), sum);

let difference: Expression = "16-23".parse().unwrap();
assert_eq!(Expression::Difference(-7), difference);

有关更全面的指南,请参阅 GUIDE.md

限制

此crate是实验性的,有很多粗糙的边缘。不分先后

  • 默认情况下不与泛型结构体一起使用(如果您自己添加所需的trait界限,则应该可以工作)
  • 尚未实现:可选模式,即 (...)? => Option<...>
  • 尚未实现:重复模式,即 (...)* => Vec<...>
  • 错误处理,尤其是错误报告基本上不存在
  • 提供的正则表达式在编译时未进行验证

依赖项

~5MB
~99K SLoC