diff --git a/src/duster/parser.rs b/src/duster/parser.rs index 6ae838a..a4166c6 100644 --- a/src/duster/parser.rs +++ b/src/duster/parser.rs @@ -151,6 +151,19 @@ fn container<'a, F>( open_matcher: &'static str, constructor: F, ) -> impl Fn(&'a str) -> IResult<&'a str, DustTag<'a>> +where + F: Copy + Fn(Container<'a>) -> DustTag<'a>, +{ + alt(( + container_with_body(open_matcher, constructor), + self_closing_container(open_matcher, constructor), + )) +} + +fn container_with_body<'a, F>( + open_matcher: &'static str, + constructor: F, +) -> impl Fn(&'a str) -> IResult<&'a str, DustTag<'a>> where F: Fn(Container<'a>) -> DustTag<'a>, { @@ -174,6 +187,26 @@ where } } +fn self_closing_container<'a, F>( + open_matcher: &'static str, + constructor: F, +) -> impl Fn(&'a str) -> IResult<&'a str, DustTag<'a>> +where + F: Fn(Container<'a>) -> DustTag<'a>, +{ + move |i: &'a str| { + let (i, path) = delimited(tag(open_matcher), path, tag("/}"))(i)?; + + Ok(( + i, + constructor(Container { + path: path, + contents: None, + }), + )) + } +} + fn filter(i: &str) -> IResult<&str, Filter> { preceded( tag("|"), @@ -339,6 +372,22 @@ mod tests { ); } + #[test] + fn test_self_closing_section() { + assert_eq!( + super::dust_tag("{#foo.bar/}"), + Ok(( + "", + DustTag::DTSection(Container { + path: Path { + keys: vec!["foo", "bar"] + }, + contents: None + }) + )) + ); + } + #[test] fn test_section_with_body() { assert_eq!(