diff --git a/src/parser/parser.rs b/src/parser/parser.rs index 3f4232e..f9fe91d 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -118,6 +118,7 @@ pub struct ParameterizedBlock<'a> { #[derive(Clone, Debug, PartialEq)] pub struct Partial<'a> { pub name: Vec, + pub explicit_context: Option>, pub params: Vec>, } @@ -546,10 +547,11 @@ fn partial_with_plain_tag<'a>( open_matcher: &'static str, ) -> impl Fn(&'a str) -> IResult<&'a str, Partial<'a>> { move |i: &'a str| { - let (i, (name, params)) = delimited( + let (i, (name, maybe_explicit_context, params)) = delimited( tag(open_matcher), tuple(( key, + opt(preceded(tag(":"), path)), opt(delimited( space1, separated_list1(space1, key_value_pair), @@ -565,6 +567,7 @@ fn partial_with_plain_tag<'a>( name: vec![PartialNameElement::PNSpan { contents: name.to_owned(), }], + explicit_context: maybe_explicit_context, params: params.unwrap_or(Vec::new()), }, )) @@ -582,12 +585,13 @@ fn partial_with_quoted_tag<'a>( open_matcher: &'static str, ) -> impl Fn(&'a str) -> IResult<&'a str, Partial<'a>> { move |i: &'a str| { - let (i, (name, params)) = delimited( + let (i, (name, maybe_explicit_context, params)) = delimited( tag(open_matcher), tuple(( verify(quoted_string, |s: &String| { partial_quoted_tag(s.as_str()).is_ok() }), + opt(preceded(tag(":"), path)), opt(delimited( space1, separated_list1(space1, key_value_pair), @@ -608,6 +612,7 @@ fn partial_with_quoted_tag<'a>( i, Partial { name: partial_name_elements, + explicit_context: maybe_explicit_context, params: params.unwrap_or(Vec::new()), }, )) @@ -1149,7 +1154,7 @@ mod tests { name: vec![PartialNameElement::PNSpan { contents: "foo".to_owned() },], - + explicit_context: None, params: vec![ KVPair { key: "bar", @@ -1175,6 +1180,7 @@ mod tests { name: vec![PartialNameElement::PNSpan { contents: r#"template name * with * special " characters"#.to_owned() },], + explicit_context: None, params: vec![ KVPair { key: "bar", @@ -1209,6 +1215,65 @@ mod tests { contents: "template".to_owned() } ], + explicit_context: None, + params: vec![ + KVPair { + key: "bar", + value: RValue::RVPath(Path { keys: vec!["baz"] }) + }, + KVPair { + key: "animal", + value: RValue::RVLiteral(OwnedLiteral::LString("cat".to_owned())) + } + ] + }) + )) + ); + } + + #[test] + fn test_unquoted_partial_with_explicit_context() { + assert_eq!( + dust_tag(r#"{>foo:foo.bar bar=baz animal="cat"/}"#), + Ok(( + "", + DustTag::DTPartial(Partial { + name: vec![PartialNameElement::PNSpan { + contents: "foo".to_owned() + },], + explicit_context: Some(Path { + keys: vec!["foo", "bar"] + }), + params: vec![ + KVPair { + key: "bar", + value: RValue::RVPath(Path { keys: vec!["baz"] }) + }, + KVPair { + key: "animal", + value: RValue::RVLiteral(OwnedLiteral::LString("cat".to_owned())) + } + ] + }) + )) + ); + } + + #[test] + fn test_quoted_partial_with_explicit_context() { + assert_eq!( + dust_tag( + r#"{>"template name * with * special \" characters":foo.bar bar=baz animal="cat"/}"# + ), + Ok(( + "", + DustTag::DTPartial(Partial { + name: vec![PartialNameElement::PNSpan { + contents: r#"template name * with * special " characters"#.to_owned() + },], + explicit_context: Some(Path { + keys: vec!["foo", "bar"] + }), params: vec![ KVPair { key: "bar", @@ -1234,6 +1299,7 @@ mod tests { name: vec![PartialNameElement::PNSpan { contents: "foo".to_owned() },], + explicit_context: None, params: vec![ KVPair { key: "a", @@ -1408,6 +1474,7 @@ mod tests { name: vec![PartialNameElement::PNSpan { contents: "partialtwo".to_owned() },], + explicit_context: None, params: vec![ KVPair { key: "v1",