Merge branch 'bug_partial_parse' into partial
This commit is contained in:
commit
df9ebaf0e0
@ -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::multispace0;
|
||||
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::map;
|
||||
use nom::combinator::opt;
|
||||
@ -387,7 +387,11 @@ where
|
||||
let (i, (name, params, inner, maybe_else, _closing_name)) = tuple((
|
||||
preceded(tag(open_matcher), tag(tag_name)),
|
||||
terminated(
|
||||
opt(preceded(space1, separated_list1(space1, key_value_pair))),
|
||||
opt(delimited(
|
||||
space1,
|
||||
separated_list1(space1, key_value_pair),
|
||||
space0,
|
||||
)),
|
||||
tag("}"),
|
||||
),
|
||||
opt(body),
|
||||
@ -420,7 +424,11 @@ where
|
||||
tag(open_matcher),
|
||||
tuple((
|
||||
tag(tag_name),
|
||||
opt(preceded(space1, separated_list1(space1, key_value_pair))),
|
||||
opt(delimited(
|
||||
space1,
|
||||
separated_list1(space1, key_value_pair),
|
||||
space0,
|
||||
)),
|
||||
)),
|
||||
tag("/}"),
|
||||
)(i)?;
|
||||
@ -449,7 +457,11 @@ where
|
||||
tag(open_matcher),
|
||||
tuple((
|
||||
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("/}"),
|
||||
)(i)?;
|
||||
@ -1052,4 +1064,55 @@ mod tests {
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_full_document_parameterized_partial() {
|
||||
assert_eq!(
|
||||
super::template(
|
||||
r#"{#level3.level4}{>partialtwo v1="b" v2="b" v3="b" v4="b" v5="b" /}{/level3.level4}"#
|
||||
),
|
||||
Ok::<_, nom::Err<(&str, ErrorKind)>>((
|
||||
"",
|
||||
Template {
|
||||
contents: Body {
|
||||
elements: vec![TemplateElement::TETag(DustTag::DTSection(Container {
|
||||
path: Path {
|
||||
keys: vec!["level3", "level4"]
|
||||
},
|
||||
contents: Some(Body {
|
||||
elements: vec![TemplateElement::TETag(DustTag::DTPartial(
|
||||
Partial {
|
||||
name: "partialtwo".to_owned(),
|
||||
params: vec![
|
||||
KVPair {
|
||||
key: "v1",
|
||||
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())
|
||||
}
|
||||
]
|
||||
}
|
||||
))]
|
||||
}),
|
||||
else_contents: None
|
||||
}))]
|
||||
}
|
||||
}
|
||||
))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
53
src/renderer/walking.rs
Normal file
53
src/renderer/walking.rs
Normal 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)
|
||||
}
|
Loading…
Reference in New Issue
Block a user