3 个版本 (破坏性更新)
| 0.3.0 | 2018年12月15日 | 
|---|---|
| 0.2.0 | 2018年12月13日 | 
| 0.1.0 | 2018年12月12日 | 
#234 in 解析工具
27KB
409 行
banjin
手动解析的简单代码生成器
属性
结构体
有几个属性可以控制解析器的行为,每个属性都附加到结构体的字段上
- starts_with = <prefix>- 指定下一个解析步骤应该开始的字符串(可以堆叠)。如果缺少前缀,则错误。
- ends_with = <prefix>- 指定解析步骤应该结束的字符串(可以堆叠)。如果缺少后缀,则错误。如果为空,则期望EOF。
- skip = <chars>- 指定要跳过的字符,直到不遇到字符串中指定的字符。
- skip(ws)- 指定要跳过所有空白字符。
- format(<format>)- 指定应包含要解析的值的字符列表。
- format(not(<format>))- 指定应包含要解析的值的字符列表。
格式
- 文字字符串 - 当字符串被指定为 format的参数时,它被用作字符集。
- numeric- 当指定时,使用- char::is_numeric()进行匹配
- digit(<base>)- 当指定时,使用- char::is_digit(<base>)进行匹配
- ascii- 当指定时,使用- char::is_ascii()
- alphabetic- 当指定时,使用- char::is_alphabetic()
枚举
- format = <format>- 指定要匹配的字符串。
- case- 指定大小写敏感匹配。默认情况下是不区分大小写的。
- default- 指定变体使用默认值。应仅接受单个- String,并且只能有一个
使用方法
结构体
use std::str::FromStr;
#[derive(banjin::Parser)]
pub struct Data {
    #[starts_with = "prefix"]
    #[skip(ws)]
    #[starts_with = "+"]
    #[skip(ws)]
    #[format(ascii)]
    #[format(digit(10))]
    pub first: u32,
    #[skip(ws)]
    #[format(not("d"))]
    #[format("13")]
    #[ends_with = "d"]
    #[ends_with = ""]
    pub second: String,
}
fn main() {
    let data = Data::from_str("prefix + 666   13d").expect("Parse");
    assert_eq!(data.first, 666);
    assert_eq!(data.second, "13");
    let data = Data::from_str("prefix + 666   13");
    assert!(data.is_err());
    let data = Data::from_str("prefix 666   13d");
    assert!(data.is_err());
    let data = Data::from_str("prefix + 666   13dg");
    assert!(data.is_err());
    let data = Data::from_str("");
    assert!(data.is_err());
}
枚举
use std::str::FromStr;
#[derive(banjin::Parser, PartialEq, Eq, Debug)]
enum Gender {
    Male,
    #[case]
    Female,
    #[default]
    Other(String)
}
fn main() {
    let gender = Gender::from_str("male").expect("Parse");
    assert_eq!(gender, Gender::Male);
    let gender = Gender::from_str("female").expect("Parse");
    match gender {
        Gender::Other(text) => assert_eq!(text, "female"),
        _ => panic!("Unexpected!")
    }
    let gender = Gender::from_str("none").expect("Parse");
    match gender {
        Gender::Other(text) => assert_eq!(text, "none"),
        _ => panic!("Unexpected!")
    }
}
依赖关系
~2MB
~46K SLoC