10 个版本
0.5.3 | 2020 年 12 月 8 日 |
---|---|
0.5.2 | 2020 年 11 月 30 日 |
0.5.0 | 2019 年 8 月 8 日 |
0.4.1 | 2019 年 2 月 1 日 |
0.2.3 | 2018 年 12 月 31 日 |
#1638 在 解析器实现 中
每月 35 次下载
在 3 crates 中使用
19KB
316 行
reformation
使用格式语法通过正则表达式进行解析
Derive 需要使用属性 reformattion 来指定格式字符串,该字符串将被视为格式字符串 -> 正则表达式字符串
默认实现 Reformation
的类型
- 有符号整数:
i8
i16
i32
i64
i128
isize
- 无符号整数:
u8
u16
u32
u64
u128
usize
- 浮点数:
f32
f64
String
, &strchar
结构体
use reformation::Reformation;
#[derive(Reformation, Debug)]
#[reformation(r"{year}-{month}-{day} {hour}:{minute}")]
struct Date{
year: u16,
month: u8,
day: u8,
hour: u8,
minute: u8,
}
fn main(){
let date = Date::parse("2018-12-22 20:23").unwrap();
assert_eq!(date.year, 2018);
assert_eq!(date.month, 12);
assert_eq!(date.day, 22);
assert_eq!(date.hour, 20);
assert_eq!(date.minute, 23);
}
元组结构体
use reformation::Reformation;
#[derive(Reformation)]
#[reformation(r"{} -> {}")]
struct Predicate(Empty, char);
#[derive(Reformation, Debug, PartialEq)]
#[reformation(r"Empty")]
struct Empty;
fn main(){
let p = Predicate::parse("Empty -> X").unwrap();
assert_eq!(p.0, Empty);
assert_eq!(p.1, 'X');
}
枚举
use reformation::Reformation;
#[derive(Reformation, Eq, PartialEq, Debug)]
enum Ant{
#[reformation(r"Queen\({}\)")]
Queen(String),
#[reformation(r"Worker\({}\)")]
Worker(i32),
#[reformation(r"Warrior")]
Warrior
}
fn main(){
let queen = Ant::parse("Queen(We are swarm)").unwrap();
assert_eq!(queen, Ant::Queen("We are swarm".to_string()));
let worker = Ant::parse("Worker(900000)").unwrap();
assert_eq!(worker, Ant::Worker(900000));
let warrior = Ant::parse("Warrior").unwrap();
assert_eq!(warrior, Ant::Warrior);
}
就地解析
use reformation::Reformation;
#[derive(Reformation, Eq, PartialEq, Debug)]
#[reformation("{a} {b}")]
struct InPlace<'a, 'b>{
#[reformation("[a-z]*")]
a: &'a str,
#[reformation("[a-z]*")]
b: &'b str,
}
fn main(){
// Then parsed from &'x str value will have type
// InPlace<'x, 'x>
let inplace = InPlace::parse("aval bval").unwrap();
assert_eq!(inplace, InPlace{a: "aval", b: "bval"})
}
模式
模式的指定顺序无关紧要。
fromstr
生成 FromStr
特性的实现。
与生命周期注解的结构不兼容。
use reformation::Reformation;
#[derive(Reformation, Debug)]
#[reformation(r"{year}-{month}-{day} {hour}:{minute}", fromstr = true)]
struct Date{
year: u16,
month: u8,
day: u8,
hour: u8,
minute: u8,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let date: Date = "2018-12-22 20:23".parse()?;
assert_eq!(date.year, 2018);
assert_eq!(date.month, 12);
assert_eq!(date.day, 22);
assert_eq!(date.hour, 20);
assert_eq!(date.minute, 23);
Ok(())
}
no_regex
通过转义所有特殊正则表达式字符,使格式字符串的行为像普通字符串(与作为正则表达式相比)。
use reformation::Reformation;
#[derive(Reformation, Debug)]
#[reformation("Vec{{{x}, {y}}}", no_regex=true)]
struct Vec{
x: i32,
y: i32,
}
fn main(){
let v= Vec::parse("Vec{-1, 1}").unwrap();
assert_eq!(v.x, -1);
assert_eq!(v.y, 1);
}
slack
允许在分隔符(逗号、分号、冒号)之后有任意数量的空格。为了使分隔符被识别为 slack,它必须在格式字符串后至少跟有一个空格。
use reformation::Reformation;
#[derive(Reformation, Debug)]
#[reformation(r"Vec\{{{x}, {y}\}}", slack=true)]
struct Vec{
x: i32,
y: i32,
}
fn main(){
let v = Vec::parse("Vec{-1,1}").unwrap();
assert_eq!(v.x, -1);
assert_eq!(v.y, 1);
let r = Vec::parse("Vec{15, 2}").unwrap();
assert_eq!(r.x, 15);
assert_eq!(r.y, 2);
}
许可协议:MIT
依赖关系
~2.5–4MB
~72K SLoC