From 9031108d2a07557c86d49d19754476c48dca01fa Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Mon, 25 May 2020 13:55:17 -0400 Subject: [PATCH] Implemented parsing for explicit contexts in NamedBlocks. --- src/parser/parser.rs | 63 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/src/parser/parser.rs b/src/parser/parser.rs index 2969115..3f4232e 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -103,6 +103,7 @@ pub struct Container<'a> { #[derive(Clone, Debug, PartialEq)] pub struct NamedBlock<'a> { pub name: &'a str, + pub explicit_context: Option>, pub contents: Option>, } @@ -412,19 +413,21 @@ where F: Fn(NamedBlock<'a>) -> DustTag<'a>, { move |i: &'a str| { - let (i, (opening_name, inner, _closing_name)) = verify( + let (i, (opening_name, maybe_explicit_context, inner, _closing_name)) = verify( tuple(( - delimited(tag(open_matcher), key, tag("}")), + preceded(tag(open_matcher), key), + terminated(opt(preceded(tag(":"), path)), tag("}")), opt(body), delimited(tag("{/"), key, tag("}")), )), - |(open, _inn, close)| open == close, + |(open, _maybe_explicit, _inn, close)| open == close, )(i)?; Ok(( i, constructor(NamedBlock { name: opening_name, + explicit_context: maybe_explicit_context, contents: inner, }), )) @@ -439,12 +442,16 @@ where F: Fn(NamedBlock<'a>) -> DustTag<'a>, { move |i: &'a str| { - let (i, name) = delimited(tag(open_matcher), key, tag("/}"))(i)?; + let (i, (opening_name, maybe_explicit_context)) = tuple(( + preceded(tag(open_matcher), key), + terminated(opt(preceded(tag(":"), path)), tag("/}")), + ))(i)?; Ok(( i, constructor(NamedBlock { - name: name, + name: opening_name, + explicit_context: maybe_explicit_context, contents: None, }), )) @@ -1014,6 +1021,7 @@ mod tests { "", DustTag::DTBlock(NamedBlock { name: "foo", + explicit_context: None, contents: None }) )) @@ -1028,6 +1036,49 @@ mod tests { "", DustTag::DTBlock(NamedBlock { name: "foo", + explicit_context: None, + contents: Some(Body { + elements: vec![ + TemplateElement::TESpan(Span { contents: "hello " }), + TemplateElement::TETag(DustTag::DTReference(Reference { + path: Path { keys: vec!["name"] }, + filters: Vec::new() + })) + ] + }) + }) + )) + ); + } + + #[test] + fn test_self_closing_block_with_explicit_context() { + assert_eq!( + super::dust_tag("{+foo:bar.baz/}"), + Ok(( + "", + DustTag::DTBlock(NamedBlock { + name: "foo", + explicit_context: Some(Path { + keys: vec!["bar", "baz"] + }), + contents: None + }) + )) + ); + } + + #[test] + fn test_block_with_explicit_context() { + assert_eq!( + super::dust_tag("{+foo:bar.baz}hello {name}{/foo}"), + Ok(( + "", + DustTag::DTBlock(NamedBlock { + name: "foo", + explicit_context: Some(Path { + keys: vec!["bar", "baz"] + }), contents: Some(Body { elements: vec![ TemplateElement::TESpan(Span { contents: "hello " }), @@ -1050,6 +1101,7 @@ mod tests { "", DustTag::DTInlinePartial(NamedBlock { name: "foo", + explicit_context: None, contents: None }) )) @@ -1064,6 +1116,7 @@ mod tests { "", DustTag::DTInlinePartial(NamedBlock { name: "foo", + explicit_context: None, contents: Some(Body { elements: vec![ TemplateElement::TESpan(Span { contents: "hello " }),