diff --git a/src/parser/parser.rs b/src/parser/parser.rs index 49ffe64..d5c904e 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -30,6 +30,7 @@ enum DustTag<'a> { DTNotExists(Container<'a>), DTBlock(NamedBlock<'a>), DTInlinePartial(NamedBlock<'a>), + DTPartial(ParameterizedBlock<'a>), } #[derive(Clone, Debug, PartialEq)] @@ -86,6 +87,12 @@ struct NamedBlock<'a> { contents: Option>, } +#[derive(Clone, Debug, PartialEq)] +struct ParameterizedBlock<'a> { + name: String, + contents: Option>, +} + #[derive(Clone, Debug, PartialEq)] struct Body<'a> { elements: Vec>, @@ -115,6 +122,7 @@ fn dust_tag(i: &str) -> IResult<&str, DustTag> { conditional("{^", DustTag::DTNotExists), named_block("{+", DustTag::DTBlock), named_block("{<", DustTag::DTInlinePartial), + parameterized_self_closing_block("{>", DustTag::DTPartial), ))(i) } @@ -290,6 +298,26 @@ where } } +fn parameterized_self_closing_block<'a, F>( + open_matcher: &'static str, + constructor: F, +) -> impl Fn(&'a str) -> IResult<&'a str, DustTag<'a>> +where + F: Fn(ParameterizedBlock<'a>) -> DustTag<'a>, +{ + move |i: &'a str| { + let (i, name) = delimited(tag(open_matcher), key, tag("/}"))(i)?; + + Ok(( + i, + constructor(ParameterizedBlock { + name: name.to_owned(), + contents: None, + }), + )) + } +} + fn filter(i: &str) -> IResult<&str, Filter> { preceded( tag("|"), @@ -620,4 +648,18 @@ mod tests { Ok(("", r#"foo"bar\baz"#.to_owned())) ); } + + #[test] + fn test_self_closing_unquoted_partial() { + assert_eq!( + super::dust_tag("{>foo/}"), + Ok(( + "", + DustTag::DTPartial(ParameterizedBlock { + name: "foo".to_owned(), + contents: None + }) + )) + ); + } }