Turns out the issue was the trailing space on the parameters.

This commit is contained in:
Tom Alexander 2020-05-09 15:15:43 -04:00
parent 369fbaf579
commit 2a9657e3d5
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
2 changed files with 94 additions and 9 deletions

View File

@ -6,7 +6,7 @@ use nom::bytes::complete::{tag, take_until, take_until_parser_matches};
use nom::character::complete::line_ending; use nom::character::complete::line_ending;
use nom::character::complete::multispace0; use nom::character::complete::multispace0;
use nom::character::complete::one_of; use nom::character::complete::one_of;
use nom::character::complete::space1; use nom::character::complete::{space0, space1};
use nom::combinator::all_consuming; use nom::combinator::all_consuming;
use nom::combinator::map; use nom::combinator::map;
use nom::combinator::opt; use nom::combinator::opt;
@ -387,7 +387,11 @@ where
let (i, (name, params, inner, maybe_else, _closing_name)) = tuple(( let (i, (name, params, inner, maybe_else, _closing_name)) = tuple((
preceded(tag(open_matcher), tag(tag_name)), preceded(tag(open_matcher), tag(tag_name)),
terminated( terminated(
opt(preceded(space1, separated_list1(space1, key_value_pair))), opt(delimited(
space1,
separated_list1(space1, key_value_pair),
space0,
)),
tag("}"), tag("}"),
), ),
opt(body), opt(body),
@ -420,7 +424,11 @@ where
tag(open_matcher), tag(open_matcher),
tuple(( tuple((
tag(tag_name), tag(tag_name),
opt(preceded(space1, separated_list1(space1, key_value_pair))), opt(delimited(
space1,
separated_list1(space1, key_value_pair),
space0,
)),
)), )),
tag("/}"), tag("/}"),
)(i)?; )(i)?;
@ -449,7 +457,11 @@ where
tag(open_matcher), tag(open_matcher),
tuple(( tuple((
alt((map(key, String::from), quoted_string)), alt((map(key, String::from), quoted_string)),
opt(preceded(space1, separated_list1(space1, key_value_pair))), opt(delimited(
space1,
separated_list1(space1, key_value_pair),
space0,
)),
)), )),
tag("/}"), tag("/}"),
)(i)?; )(i)?;
@ -1056,7 +1068,9 @@ mod tests {
#[test] #[test]
fn test_full_document_parameterized_partial() { fn test_full_document_parameterized_partial() {
assert_eq!( assert_eq!(
super::template(r#"{#level3.level4}{>partialtwo v1="b"/}{/level3.level4}"#), super::template(
r#"{#level3.level4}{>partialtwo v1="b" v2="b" v3="b" v4="b" v5="b" /}{/level3.level4}"#
),
Ok::<_, nom::Err<(&str, ErrorKind)>>(( Ok::<_, nom::Err<(&str, ErrorKind)>>((
"", "",
Template { Template {
@ -1069,10 +1083,28 @@ mod tests {
elements: vec![TemplateElement::TETag(DustTag::DTPartial( elements: vec![TemplateElement::TETag(DustTag::DTPartial(
Partial { Partial {
name: "partialtwo".to_owned(), name: "partialtwo".to_owned(),
params: vec![KVPair { params: vec![
KVPair {
key: "v1", key: "v1",
value: RValue::RVString("b".to_owned()) value: RValue::RVString("b".to_owned())
}] },
KVPair {
key: "v2",
value: RValue::RVString("b".to_owned())
},
KVPair {
key: "v3",
value: RValue::RVString("b".to_owned())
},
KVPair {
key: "v4",
value: RValue::RVString("b".to_owned())
},
KVPair {
key: "v5",
value: RValue::RVString("b".to_owned())
}
]
} }
))] ))]
}), }),

53
src/renderer/walking.rs Normal file
View File

@ -0,0 +1,53 @@
use crate::renderer::context_element::ContextElement;
use crate::renderer::WalkError;
enum WalkResult<'a> {
NoWalk,
PartialWalk,
FullyWalked(&'a dyn ContextElement),
}
fn walk_path_from_single_level<'a>(
context: &'a dyn ContextElement,
path: &Vec<&str>,
) -> WalkResult<'a> {
if path.is_empty() {
return WalkResult::FullyWalked(context);
}
let mut walk_failure = WalkResult::NoWalk;
let mut output = context;
for elem in path.iter() {
let new_val = output.walk(elem);
match output.walk(elem) {
Err(WalkError::CantWalk { .. }) => {
return walk_failure;
}
Ok(new_val) => {
walk_failure = WalkResult::PartialWalk;
output = new_val;
}
}
}
WalkResult::FullyWalked(output)
}
pub fn walk_path<'a>(
breadcrumbs: &Vec<&'a dyn ContextElement>,
path: &'a Vec<&str>,
) -> Result<&'a dyn ContextElement, WalkError> {
for context in breadcrumbs.iter().rev() {
match walk_path_from_single_level(*context, path) {
// If no walking was done at all, keep looping
WalkResult::NoWalk => {}
// If we partially walked then stop trying to find
// anything
WalkResult::PartialWalk => {
return Err(WalkError::CantWalk);
}
WalkResult::FullyWalked(new_context) => return Ok(new_context),
}
}
Err(WalkError::CantWalk)
}