From 34882024b3079ee00ed0e9a5150053f5e52a73c7 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sun, 5 Apr 2020 17:24:13 -0400 Subject: [PATCH] Add support for else blocks --- src/duster/parser.rs | 52 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/src/duster/parser.rs b/src/duster/parser.rs index a4166c6..026e98b 100644 --- a/src/duster/parser.rs +++ b/src/duster/parser.rs @@ -72,6 +72,7 @@ struct Span<'a> { struct Container<'a> { path: Path<'a>, contents: Option>, + else_contents: Option>, } #[derive(Clone, Debug, PartialEq)] @@ -168,13 +169,14 @@ where F: Fn(Container<'a>) -> DustTag<'a>, { move |i: &'a str| { - let (i, (opening_name, inner, _closing_name)) = verify( + let (i, (opening_name, inner, maybe_else, _closing_name)) = verify( tuple(( delimited(tag(open_matcher), path, tag("}")), opt(block), + opt(preceded(tag("{:else}"), opt(block))), delimited(tag("{/"), path, tag("}")), )), - |(open, _inn, close)| open == close, + |(open, _inn, _maybe_else, close)| open == close, )(i)?; Ok(( @@ -182,6 +184,7 @@ where constructor(Container { path: opening_name, contents: inner, + else_contents: maybe_else.flatten(), }), )) } @@ -202,6 +205,7 @@ where constructor(Container { path: path, contents: None, + else_contents: None, }), )) } @@ -366,7 +370,8 @@ mod tests { path: Path { keys: vec!["foo", "bar"] }, - contents: None + contents: None, + else_contents: None, }) )) ); @@ -382,7 +387,8 @@ mod tests { path: Path { keys: vec!["foo", "bar"] }, - contents: None + contents: None, + else_contents: None, }) )) ); @@ -406,7 +412,43 @@ mod tests { filters: Vec::new() })) ] - }) + }), + else_contents: None, + }) + )) + ); + } + + #[test] + fn test_section_with_else_body() { + assert_eq!( + super::dust_tag("{#greeting}hello {name}{:else}goodbye {name}{/greeting}"), + Ok(( + "", + DustTag::DTSection(Container { + path: Path { + keys: vec!["greeting"] + }, + contents: Some(Block { + elements: vec![ + TemplateElement::TESpan(Span { contents: "hello " }), + TemplateElement::TETag(DustTag::DTReference(Reference { + path: Path { keys: vec!["name"] }, + filters: Vec::new() + })) + ] + }), + else_contents: Some(Block { + elements: vec![ + TemplateElement::TESpan(Span { + contents: "goodbye " + }), + TemplateElement::TETag(DustTag::DTReference(Reference { + path: Path { keys: vec!["name"] }, + filters: Vec::new() + })) + ] + }), }) )) );