diff --git a/src/duster/parser.rs b/src/duster/parser.rs index d49a9c5..6ae838a 100644 --- a/src/duster/parser.rs +++ b/src/duster/parser.rs @@ -22,7 +22,9 @@ enum DustTag<'a> { DTSpecial(Special), DTComment(Comment<'a>), DTReference(Reference<'a>), - DTSection(Section<'a>), + DTSection(Container<'a>), + DTExists(Container<'a>), + DTNotExists(Container<'a>), } #[derive(Clone, Debug, PartialEq)] @@ -67,7 +69,7 @@ struct Span<'a> { } #[derive(Clone, Debug, PartialEq)] -struct Section<'a> { +struct Container<'a> { path: Path<'a>, contents: Option>, } @@ -88,21 +90,14 @@ enum TemplateElement<'a> { TETag(DustTag<'a>), } -impl<'a> Section<'a> { - fn new(path: Path<'a>, contents: std::option::Option>) -> DustTag<'a> { - DustTag::DTSection(Section { - path: path, - contents: contents, - }) - } -} - fn dust_tag(i: &str) -> IResult<&str, DustTag> { alt(( map(special, DustTag::DTSpecial), map(comment, DustTag::DTComment), map(reference, DustTag::DTReference), - container("{#", Section::new), + container("{#", DustTag::DTSection), + container("{?", DustTag::DTExists), + container("{^", DustTag::DTNotExists), ))(i) } @@ -154,10 +149,10 @@ fn reference(i: &str) -> IResult<&str, Reference> { fn container<'a, F>( open_matcher: &'static str, - foo: F, + constructor: F, ) -> impl Fn(&'a str) -> IResult<&'a str, DustTag<'a>> where - F: Fn(Path<'a>, Option>) -> DustTag<'a>, + F: Fn(Container<'a>) -> DustTag<'a>, { move |i: &'a str| { let (i, (opening_name, inner, _closing_name)) = verify( @@ -169,29 +164,16 @@ where |(open, _inn, close)| open == close, )(i)?; - Ok((i, foo(opening_name, inner))) + Ok(( + i, + constructor(Container { + path: opening_name, + contents: inner, + }), + )) } } -fn section(i: &str) -> IResult<&str, Section> { - let (i, (opening_name, inner, _closing_name)) = verify( - tuple(( - delimited(tag("{#"), path, tag("}")), - opt(block), - delimited(tag("{/"), path, tag("}")), - )), - |(open, inn, close)| open == close, - )(i)?; - - Ok(( - i, - Section { - path: opening_name, - contents: inner, - }, - )) -} - fn filter(i: &str) -> IResult<&str, Filter> { preceded( tag("|"), @@ -336,23 +318,23 @@ mod tests { #[test] fn test_section_mismatched_paths() { assert_eq!( - super::section("{#foo.bar}{/baz}"), - Err(Error(("{#foo.bar}{/baz}", ErrorKind::Verify))) + super::dust_tag("{#foo.bar}{/baz}"), + Err(Error(("{#foo.bar}{/baz}", ErrorKind::Tag))) ); } #[test] fn test_empty_section() { assert_eq!( - super::section("{#foo.bar}{/foo.bar}"), + super::dust_tag("{#foo.bar}{/foo.bar}"), Ok(( "", - Section { + DustTag::DTSection(Container { path: Path { keys: vec!["foo", "bar"] }, contents: None - } + }) )) ); } @@ -360,10 +342,10 @@ mod tests { #[test] fn test_section_with_body() { assert_eq!( - super::section("{#foo.bar}hello {name}{/foo.bar}"), + super::dust_tag("{#foo.bar}hello {name}{/foo.bar}"), Ok(( "", - Section { + DustTag::DTSection(Container { path: Path { keys: vec!["foo", "bar"] }, @@ -376,7 +358,7 @@ mod tests { })) ] }) - } + }) )) ); }