From 108cffb7715d53ea105b04567d0a01554a5227aa Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Mon, 25 May 2020 21:26:16 -0400 Subject: [PATCH] Fully replaced conditional's Container type with ParameterizedBlock. --- src/parser/parser.rs | 215 +++++++++++++++---------------------------- 1 file changed, 74 insertions(+), 141 deletions(-) diff --git a/src/parser/parser.rs b/src/parser/parser.rs index bdf6f8c..9451372 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -29,9 +29,9 @@ pub enum DustTag<'a> { DTComment(Comment<'a>), DTLiteralStringBlock(&'a str), DTReference(Reference<'a>), - DTSection(Container<'a>), - DTExists(Container<'a>), - DTNotExists(Container<'a>), + DTSection(ParameterizedBlock<'a>), + DTExists(ParameterizedBlock<'a>), + DTNotExists(ParameterizedBlock<'a>), DTBlock(NamedBlock<'a>), DTInlinePartial(NamedBlock<'a>), DTPartial(Partial<'a>), @@ -92,14 +92,6 @@ pub struct Span<'a> { pub contents: &'a str, } -#[derive(Clone, Debug, PartialEq)] -pub struct Container<'a> { - pub path: Path<'a>, - pub explicit_context: Option>, - pub contents: Option>, - pub else_contents: Option>, -} - #[derive(Clone, Debug, PartialEq)] pub struct NamedBlock<'a> { pub name: &'a str, @@ -218,9 +210,9 @@ fn dust_tag(i: &str) -> IResult<&str, DustTag> { map(comment, DustTag::DTComment), map(literal_string_block, DustTag::DTLiteralStringBlock), map(reference, DustTag::DTReference), - conditional("{#", DustTag::DTSection), - conditional("{?", DustTag::DTExists), - conditional("{^", DustTag::DTNotExists), + map(parameterized_block("{#", path), DustTag::DTSection), + map(parameterized_block("{?", path), DustTag::DTExists), + map(parameterized_block("{^", path), DustTag::DTNotExists), named_block("{+", DustTag::DTBlock), named_block("{<", DustTag::DTInlinePartial), partial("{>", DustTag::DTPartial), @@ -350,76 +342,6 @@ fn reference(i: &str) -> IResult<&str, Reference> { )) } -fn conditional<'a, F>( - open_matcher: &'static str, - constructor: F, -) -> impl FnMut(&'a str) -> IResult<&'a str, DustTag<'a>> -where - F: Copy + Fn(Container<'a>) -> DustTag<'a>, -{ - alt(( - conditional_with_body(open_matcher, constructor), - self_closing_conditional(open_matcher, constructor), - )) -} - -fn conditional_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>, -{ - move |i: &'a str| { - let (i, (opening_name, maybe_explicit_context, inner, maybe_else, _closing_name)) = - verify( - tuple(( - preceded(tag(open_matcher), path), - terminated(opt(preceded(tag(":"), path)), tag("}")), - opt(body), - opt(preceded(tag("{:else}"), opt(body))), - delimited(tag("{/"), path, tag("}")), - )), - |(open, _maybe_explicit, _inn, _maybe_else, close)| open == close, - )(i)?; - - Ok(( - i, - constructor(Container { - path: opening_name, - explicit_context: maybe_explicit_context, - contents: inner, - else_contents: maybe_else.flatten(), - }), - )) - } -} - -fn self_closing_conditional<'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, (opening_name, maybe_explicit_context)) = tuple(( - preceded(tag(open_matcher), path), - terminated(opt(preceded(tag(":"), path)), tag("/}")), - ))(i)?; - - Ok(( - i, - constructor(Container { - path: opening_name, - explicit_context: maybe_explicit_context, - contents: None, - else_contents: None, - }), - )) - } -} - fn named_block<'a, F>( open_matcher: &'static str, constructor: F, @@ -920,11 +842,12 @@ mod tests { super::dust_tag("{#foo.bar}{/foo.bar}"), Ok(( "", - DustTag::DTSection(Container { + DustTag::DTSection(ParameterizedBlock { path: Path { keys: vec!["foo", "bar"] }, explicit_context: None, + params: Vec::new(), contents: None, else_contents: None, }) @@ -938,11 +861,12 @@ mod tests { super::dust_tag("{#foo.bar/}"), Ok(( "", - DustTag::DTSection(Container { + DustTag::DTSection(ParameterizedBlock { path: Path { keys: vec!["foo", "bar"] }, explicit_context: None, + params: Vec::new(), contents: None, else_contents: None, }) @@ -956,11 +880,12 @@ mod tests { super::dust_tag("{#foo.bar}hello {name}{/foo.bar}"), Ok(( "", - DustTag::DTSection(Container { + DustTag::DTSection(ParameterizedBlock { path: Path { keys: vec!["foo", "bar"] }, explicit_context: None, + params: Vec::new(), contents: Some(Body { elements: vec![ TemplateElement::TESpan(Span { contents: "hello " }), @@ -982,11 +907,12 @@ mod tests { super::dust_tag("{#greeting}hello {name}{:else}goodbye {name}{/greeting}"), Ok(( "", - DustTag::DTSection(Container { + DustTag::DTSection(ParameterizedBlock { path: Path { keys: vec!["greeting"] }, explicit_context: None, + params: Vec::new(), contents: Some(Body { elements: vec![ TemplateElement::TESpan(Span { contents: "hello " }), @@ -1018,13 +944,14 @@ mod tests { super::dust_tag("{#foo.bar:baz.ipsum}{/foo.bar}"), Ok(( "", - DustTag::DTSection(Container { + DustTag::DTSection(ParameterizedBlock { path: Path { keys: vec!["foo", "bar"] }, explicit_context: Some(Path { keys: vec!["baz", "ipsum"] }), + params: Vec::new(), contents: None, else_contents: None, }) @@ -1038,11 +965,12 @@ mod tests { super::dust_tag("{#foo.bar:$idx/}"), Ok(( "", - DustTag::DTSection(Container { + DustTag::DTSection(ParameterizedBlock { path: Path { keys: vec!["foo", "bar"] }, explicit_context: Some(Path { keys: vec!["$idx"] }), + params: Vec::new(), contents: None, else_contents: None, }) @@ -1500,11 +1428,12 @@ mod tests { TemplateElement::TEIgnoredWhitespace(IgnoredWhitespace::StartOfLine( "\n" )), - TemplateElement::TETag(DustTag::DTSection(Container { + TemplateElement::TETag(DustTag::DTSection(ParameterizedBlock { path: Path { keys: vec!["names"] }, explicit_context: None, + params: Vec::new(), contents: Some(Body { elements: vec![TemplateElement::TETag(DustTag::DTReference( Reference { @@ -1526,11 +1455,12 @@ mod tests { TemplateElement::TEIgnoredWhitespace(IgnoredWhitespace::StartOfLine( "\n" )), - TemplateElement::TETag(DustTag::DTSection(Container { + TemplateElement::TETag(DustTag::DTSection(ParameterizedBlock { path: Path { keys: vec!["names"] }, explicit_context: None, + params: Vec::new(), contents: Some(Body { elements: vec![ TemplateElement::TEIgnoredWhitespace( @@ -1564,55 +1494,58 @@ mod tests { "", Template { contents: Body { - elements: vec![TemplateElement::TETag(DustTag::DTSection(Container { - path: Path { - keys: vec!["level3", "level4"] - }, - explicit_context: None, - contents: Some(Body { - elements: vec![TemplateElement::TETag(DustTag::DTPartial( - Partial { - name: vec![PartialNameElement::PNSpan { - contents: "partialtwo".to_owned() - },], - explicit_context: None, - params: vec![ - KVPair { - key: "v1", - value: RValue::RVLiteral(OwnedLiteral::LString( - "b".to_owned() - )) - }, - KVPair { - key: "v2", - value: RValue::RVLiteral(OwnedLiteral::LString( - "b".to_owned() - )) - }, - KVPair { - key: "v3", - value: RValue::RVLiteral(OwnedLiteral::LString( - "b".to_owned() - )) - }, - KVPair { - key: "v4", - value: RValue::RVLiteral(OwnedLiteral::LString( - "b".to_owned() - )) - }, - KVPair { - key: "v5", - value: RValue::RVLiteral(OwnedLiteral::LString( - "b".to_owned() - )) - } - ] - } - ))] - }), - else_contents: None - }))] + elements: vec![TemplateElement::TETag(DustTag::DTSection( + ParameterizedBlock { + path: Path { + keys: vec!["level3", "level4"] + }, + explicit_context: None, + params: Vec::new(), + contents: Some(Body { + elements: vec![TemplateElement::TETag(DustTag::DTPartial( + Partial { + name: vec![PartialNameElement::PNSpan { + contents: "partialtwo".to_owned() + },], + explicit_context: None, + params: vec![ + KVPair { + key: "v1", + value: RValue::RVLiteral( + OwnedLiteral::LString("b".to_owned()) + ) + }, + KVPair { + key: "v2", + value: RValue::RVLiteral( + OwnedLiteral::LString("b".to_owned()) + ) + }, + KVPair { + key: "v3", + value: RValue::RVLiteral( + OwnedLiteral::LString("b".to_owned()) + ) + }, + KVPair { + key: "v4", + value: RValue::RVLiteral( + OwnedLiteral::LString("b".to_owned()) + ) + }, + KVPair { + key: "v5", + value: RValue::RVLiteral( + OwnedLiteral::LString("b".to_owned()) + ) + } + ] + } + ))] + }), + else_contents: None + } + ))] } } ))