9个版本

0.5.2 2020年11月30日
0.5.0 2019年8月8日
0.4.1 2019年1月31日
0.3.1 2019年1月6日
0.2.3 2018年12月31日

#69#slack

每月 44 次下载
4 个库中使用 (通过 reformation)

MIT 许可证

34KB
897

Build Status

reformation

使用格式语法通过正则表达式进行解析

派生将需要属性 reformation 来指定格式字符串,该字符串将被视为格式字符串 -> 正则表达式字符串

默认实现 Reformation 的类型

  • 有符号整数:i8 i16 i32 i64 i128 isize
  • 无符号整数:u8 u16 u32 u64 u128 usize
  • 浮点数:f32 f64
  • String,&str
  • char

结构体

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

依赖关系

~3–4.5MB
~88K SLoC