diff --git a/src/duster/parser.rs b/src/duster/parser.rs index 42f51ec..a0024c3 100644 --- a/src/duster/parser.rs +++ b/src/duster/parser.rs @@ -1,15 +1,20 @@ use nom::branch::alt; +use nom::bytes::complete::is_a; use nom::bytes::complete::tag; use nom::bytes::complete::take_until; use nom::combinator::map; +use nom::combinator::recognize; use nom::combinator::value; +use nom::multi::separated_list; use nom::sequence::delimited; +use nom::sequence::tuple; use nom::IResult; #[derive(Clone, Debug)] enum DustTag<'a> { DTSpecial(Special), DTComment(Comment<'a>), + DTReference(Reference<'a>), } #[derive(Clone, Debug)] @@ -26,10 +31,21 @@ struct Comment<'a> { value: &'a str, } +#[derive(Clone, Debug)] +struct Path<'a> { + keys: Vec<&'a str>, +} + +#[derive(Clone, Debug)] +struct Reference<'a> { + path: Path<'a>, +} + fn dust_tag(i: &str) -> IResult<&str, DustTag> { alt(( map(special, DustTag::DTSpecial), map(comment, DustTag::DTComment), + map(reference, DustTag::DTReference), ))(i) } @@ -52,3 +68,22 @@ fn comment(i: &str) -> IResult<&str, Comment> { Comment { value: body } })(i) } + +fn path(i: &str) -> IResult<&str, Path> { + map( + separated_list( + tag("."), + recognize(tuple(( + is_a("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$"), + is_a("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$0123456789-"), + ))), + ), + |body| Path { keys: body }, + )(i) +} + +fn reference(i: &str) -> IResult<&str, Reference> { + // TODO: Add support for filters + let (remaining, p) = delimited(tag("{"), path, tag("}"))(i)?; + Ok((remaining, Reference { path: p })) +}