Fully replaced conditional's Container type with ParameterizedBlock.

This commit is contained in:
Tom Alexander 2020-05-25 21:26:16 -04:00
parent dc92973313
commit 108cffb771
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE

View File

@ -29,9 +29,9 @@ pub enum DustTag<'a> {
DTComment(Comment<'a>), DTComment(Comment<'a>),
DTLiteralStringBlock(&'a str), DTLiteralStringBlock(&'a str),
DTReference(Reference<'a>), DTReference(Reference<'a>),
DTSection(Container<'a>), DTSection(ParameterizedBlock<'a>),
DTExists(Container<'a>), DTExists(ParameterizedBlock<'a>),
DTNotExists(Container<'a>), DTNotExists(ParameterizedBlock<'a>),
DTBlock(NamedBlock<'a>), DTBlock(NamedBlock<'a>),
DTInlinePartial(NamedBlock<'a>), DTInlinePartial(NamedBlock<'a>),
DTPartial(Partial<'a>), DTPartial(Partial<'a>),
@ -92,14 +92,6 @@ pub struct Span<'a> {
pub contents: &'a str, pub contents: &'a str,
} }
#[derive(Clone, Debug, PartialEq)]
pub struct Container<'a> {
pub path: Path<'a>,
pub explicit_context: Option<Path<'a>>,
pub contents: Option<Body<'a>>,
pub else_contents: Option<Body<'a>>,
}
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct NamedBlock<'a> { pub struct NamedBlock<'a> {
pub name: &'a str, pub name: &'a str,
@ -218,9 +210,9 @@ fn dust_tag(i: &str) -> IResult<&str, DustTag> {
map(comment, DustTag::DTComment), map(comment, DustTag::DTComment),
map(literal_string_block, DustTag::DTLiteralStringBlock), map(literal_string_block, DustTag::DTLiteralStringBlock),
map(reference, DustTag::DTReference), map(reference, DustTag::DTReference),
conditional("{#", DustTag::DTSection), map(parameterized_block("{#", path), DustTag::DTSection),
conditional("{?", DustTag::DTExists), map(parameterized_block("{?", path), DustTag::DTExists),
conditional("{^", DustTag::DTNotExists), map(parameterized_block("{^", path), DustTag::DTNotExists),
named_block("{+", DustTag::DTBlock), named_block("{+", DustTag::DTBlock),
named_block("{<", DustTag::DTInlinePartial), named_block("{<", DustTag::DTInlinePartial),
partial("{>", DustTag::DTPartial), 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>( fn named_block<'a, F>(
open_matcher: &'static str, open_matcher: &'static str,
constructor: F, constructor: F,
@ -920,11 +842,12 @@ mod tests {
super::dust_tag("{#foo.bar}{/foo.bar}"), super::dust_tag("{#foo.bar}{/foo.bar}"),
Ok(( Ok((
"", "",
DustTag::DTSection(Container { DustTag::DTSection(ParameterizedBlock {
path: Path { path: Path {
keys: vec!["foo", "bar"] keys: vec!["foo", "bar"]
}, },
explicit_context: None, explicit_context: None,
params: Vec::new(),
contents: None, contents: None,
else_contents: None, else_contents: None,
}) })
@ -938,11 +861,12 @@ mod tests {
super::dust_tag("{#foo.bar/}"), super::dust_tag("{#foo.bar/}"),
Ok(( Ok((
"", "",
DustTag::DTSection(Container { DustTag::DTSection(ParameterizedBlock {
path: Path { path: Path {
keys: vec!["foo", "bar"] keys: vec!["foo", "bar"]
}, },
explicit_context: None, explicit_context: None,
params: Vec::new(),
contents: None, contents: None,
else_contents: None, else_contents: None,
}) })
@ -956,11 +880,12 @@ mod tests {
super::dust_tag("{#foo.bar}hello {name}{/foo.bar}"), super::dust_tag("{#foo.bar}hello {name}{/foo.bar}"),
Ok(( Ok((
"", "",
DustTag::DTSection(Container { DustTag::DTSection(ParameterizedBlock {
path: Path { path: Path {
keys: vec!["foo", "bar"] keys: vec!["foo", "bar"]
}, },
explicit_context: None, explicit_context: None,
params: Vec::new(),
contents: Some(Body { contents: Some(Body {
elements: vec![ elements: vec![
TemplateElement::TESpan(Span { contents: "hello " }), TemplateElement::TESpan(Span { contents: "hello " }),
@ -982,11 +907,12 @@ mod tests {
super::dust_tag("{#greeting}hello {name}{:else}goodbye {name}{/greeting}"), super::dust_tag("{#greeting}hello {name}{:else}goodbye {name}{/greeting}"),
Ok(( Ok((
"", "",
DustTag::DTSection(Container { DustTag::DTSection(ParameterizedBlock {
path: Path { path: Path {
keys: vec!["greeting"] keys: vec!["greeting"]
}, },
explicit_context: None, explicit_context: None,
params: Vec::new(),
contents: Some(Body { contents: Some(Body {
elements: vec![ elements: vec![
TemplateElement::TESpan(Span { contents: "hello " }), TemplateElement::TESpan(Span { contents: "hello " }),
@ -1018,13 +944,14 @@ mod tests {
super::dust_tag("{#foo.bar:baz.ipsum}{/foo.bar}"), super::dust_tag("{#foo.bar:baz.ipsum}{/foo.bar}"),
Ok(( Ok((
"", "",
DustTag::DTSection(Container { DustTag::DTSection(ParameterizedBlock {
path: Path { path: Path {
keys: vec!["foo", "bar"] keys: vec!["foo", "bar"]
}, },
explicit_context: Some(Path { explicit_context: Some(Path {
keys: vec!["baz", "ipsum"] keys: vec!["baz", "ipsum"]
}), }),
params: Vec::new(),
contents: None, contents: None,
else_contents: None, else_contents: None,
}) })
@ -1038,11 +965,12 @@ mod tests {
super::dust_tag("{#foo.bar:$idx/}"), super::dust_tag("{#foo.bar:$idx/}"),
Ok(( Ok((
"", "",
DustTag::DTSection(Container { DustTag::DTSection(ParameterizedBlock {
path: Path { path: Path {
keys: vec!["foo", "bar"] keys: vec!["foo", "bar"]
}, },
explicit_context: Some(Path { keys: vec!["$idx"] }), explicit_context: Some(Path { keys: vec!["$idx"] }),
params: Vec::new(),
contents: None, contents: None,
else_contents: None, else_contents: None,
}) })
@ -1500,11 +1428,12 @@ mod tests {
TemplateElement::TEIgnoredWhitespace(IgnoredWhitespace::StartOfLine( TemplateElement::TEIgnoredWhitespace(IgnoredWhitespace::StartOfLine(
"\n" "\n"
)), )),
TemplateElement::TETag(DustTag::DTSection(Container { TemplateElement::TETag(DustTag::DTSection(ParameterizedBlock {
path: Path { path: Path {
keys: vec!["names"] keys: vec!["names"]
}, },
explicit_context: None, explicit_context: None,
params: Vec::new(),
contents: Some(Body { contents: Some(Body {
elements: vec![TemplateElement::TETag(DustTag::DTReference( elements: vec![TemplateElement::TETag(DustTag::DTReference(
Reference { Reference {
@ -1526,11 +1455,12 @@ mod tests {
TemplateElement::TEIgnoredWhitespace(IgnoredWhitespace::StartOfLine( TemplateElement::TEIgnoredWhitespace(IgnoredWhitespace::StartOfLine(
"\n" "\n"
)), )),
TemplateElement::TETag(DustTag::DTSection(Container { TemplateElement::TETag(DustTag::DTSection(ParameterizedBlock {
path: Path { path: Path {
keys: vec!["names"] keys: vec!["names"]
}, },
explicit_context: None, explicit_context: None,
params: Vec::new(),
contents: Some(Body { contents: Some(Body {
elements: vec![ elements: vec![
TemplateElement::TEIgnoredWhitespace( TemplateElement::TEIgnoredWhitespace(
@ -1564,55 +1494,58 @@ mod tests {
"", "",
Template { Template {
contents: Body { contents: Body {
elements: vec![TemplateElement::TETag(DustTag::DTSection(Container { elements: vec![TemplateElement::TETag(DustTag::DTSection(
path: Path { ParameterizedBlock {
keys: vec!["level3", "level4"] path: Path {
}, keys: vec!["level3", "level4"]
explicit_context: None, },
contents: Some(Body { explicit_context: None,
elements: vec![TemplateElement::TETag(DustTag::DTPartial( params: Vec::new(),
Partial { contents: Some(Body {
name: vec![PartialNameElement::PNSpan { elements: vec![TemplateElement::TETag(DustTag::DTPartial(
contents: "partialtwo".to_owned() Partial {
},], name: vec![PartialNameElement::PNSpan {
explicit_context: None, contents: "partialtwo".to_owned()
params: vec![ },],
KVPair { explicit_context: None,
key: "v1", params: vec![
value: RValue::RVLiteral(OwnedLiteral::LString( KVPair {
"b".to_owned() key: "v1",
)) value: RValue::RVLiteral(
}, OwnedLiteral::LString("b".to_owned())
KVPair { )
key: "v2", },
value: RValue::RVLiteral(OwnedLiteral::LString( KVPair {
"b".to_owned() key: "v2",
)) value: RValue::RVLiteral(
}, OwnedLiteral::LString("b".to_owned())
KVPair { )
key: "v3", },
value: RValue::RVLiteral(OwnedLiteral::LString( KVPair {
"b".to_owned() key: "v3",
)) value: RValue::RVLiteral(
}, OwnedLiteral::LString("b".to_owned())
KVPair { )
key: "v4", },
value: RValue::RVLiteral(OwnedLiteral::LString( KVPair {
"b".to_owned() key: "v4",
)) value: RValue::RVLiteral(
}, OwnedLiteral::LString("b".to_owned())
KVPair { )
key: "v5", },
value: RValue::RVLiteral(OwnedLiteral::LString( KVPair {
"b".to_owned() key: "v5",
)) value: RValue::RVLiteral(
} OwnedLiteral::LString("b".to_owned())
] )
} }
))] ]
}), }
else_contents: None ))]
}))] }),
else_contents: None
}
))]
} }
} }
)) ))