|
|
|
@ -59,7 +59,7 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
pub fn render(
|
|
|
|
|
&'a self,
|
|
|
|
|
name: &str,
|
|
|
|
|
breadcrumbs: &Vec<&'a dyn ContextElement>,
|
|
|
|
|
breadcrumbs: &Vec<&'a dyn IntoContextElement>,
|
|
|
|
|
) -> Result<String, RenderError> {
|
|
|
|
|
self.render_template(name, breadcrumbs, None)
|
|
|
|
|
}
|
|
|
|
@ -67,7 +67,7 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
fn render_template(
|
|
|
|
|
&'a self,
|
|
|
|
|
name: &str,
|
|
|
|
|
breadcrumbs: &Vec<&'a dyn ContextElement>,
|
|
|
|
|
breadcrumbs: &Vec<&'a dyn IntoContextElement>,
|
|
|
|
|
blocks: Option<&'a InlinePartialTreeElement<'a>>,
|
|
|
|
|
) -> Result<String, RenderError> {
|
|
|
|
|
let main_template = match self.templates.get(name) {
|
|
|
|
@ -88,7 +88,7 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
fn render_maybe_body(
|
|
|
|
|
&'a self,
|
|
|
|
|
body: &'a Option<Body>,
|
|
|
|
|
breadcrumbs: &Vec<&'a dyn ContextElement>,
|
|
|
|
|
breadcrumbs: &Vec<&'a dyn IntoContextElement>,
|
|
|
|
|
blocks: &'a BlockContext<'a>,
|
|
|
|
|
) -> Result<String, RenderError> {
|
|
|
|
|
match body {
|
|
|
|
@ -100,7 +100,7 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
fn render_body(
|
|
|
|
|
&'a self,
|
|
|
|
|
body: &'a Body,
|
|
|
|
|
breadcrumbs: &Vec<&'a dyn ContextElement>,
|
|
|
|
|
breadcrumbs: &Vec<&'a dyn IntoContextElement>,
|
|
|
|
|
blocks: &'a BlockContext<'a>,
|
|
|
|
|
) -> Result<String, RenderError> {
|
|
|
|
|
let mut output = String::new();
|
|
|
|
@ -120,7 +120,7 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
fn render_partial_name(
|
|
|
|
|
&'a self,
|
|
|
|
|
body: &'a Vec<PartialNameElement>,
|
|
|
|
|
breadcrumbs: &Vec<&'a dyn ContextElement>,
|
|
|
|
|
breadcrumbs: &Vec<&'a dyn IntoContextElement>,
|
|
|
|
|
blocks: &'a BlockContext<'a>,
|
|
|
|
|
) -> Result<String, RenderError> {
|
|
|
|
|
let converted_to_template_elements: Vec<TemplateElement<'a>> =
|
|
|
|
@ -137,7 +137,7 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
fn render_tag(
|
|
|
|
|
&'a self,
|
|
|
|
|
tag: &'a DustTag,
|
|
|
|
|
breadcrumbs: &Vec<&'a dyn ContextElement>,
|
|
|
|
|
breadcrumbs: &Vec<&'a dyn IntoContextElement>,
|
|
|
|
|
blocks: &'a BlockContext<'a>,
|
|
|
|
|
) -> Result<String, RenderError> {
|
|
|
|
|
match tag {
|
|
|
|
@ -154,7 +154,8 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
}
|
|
|
|
|
DustTag::DTLiteralStringBlock(literal) => return Ok((*literal).to_owned()),
|
|
|
|
|
DustTag::DTReference(reference) => {
|
|
|
|
|
let val = walk_path(breadcrumbs, &reference.path.keys);
|
|
|
|
|
let val = walk_path(breadcrumbs, &reference.path.keys)
|
|
|
|
|
.map(|ice| ice.into_context_element(breadcrumbs));
|
|
|
|
|
match val {
|
|
|
|
|
Err(WalkError::CantWalk) => return Ok("".to_owned()),
|
|
|
|
|
Ok(final_val) => {
|
|
|
|
@ -168,7 +169,8 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
}
|
|
|
|
|
DustTag::DTSection(container) => {
|
|
|
|
|
let injected_context = ParametersContext::new(breadcrumbs, &container.params);
|
|
|
|
|
let val = walk_path(breadcrumbs, &container.path.keys);
|
|
|
|
|
let val = walk_path(breadcrumbs, &container.path.keys)
|
|
|
|
|
.map(|ice| ice.into_context_element(breadcrumbs));
|
|
|
|
|
match val {
|
|
|
|
|
Err(WalkError::CantWalk) => {
|
|
|
|
|
let new_breadcrumbs = Self::new_breadcrumbs_section(
|
|
|
|
@ -269,7 +271,8 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
None,
|
|
|
|
|
&container.explicit_context,
|
|
|
|
|
);
|
|
|
|
|
let val = walk_path(breadcrumbs, &container.path.keys);
|
|
|
|
|
let val = walk_path(breadcrumbs, &container.path.keys)
|
|
|
|
|
.map(|ice| ice.into_context_element(breadcrumbs));
|
|
|
|
|
return if val.map(|v| v.is_truthy()).unwrap_or(false) {
|
|
|
|
|
self.render_maybe_body(
|
|
|
|
|
&container.contents,
|
|
|
|
@ -291,7 +294,8 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
None,
|
|
|
|
|
&container.explicit_context,
|
|
|
|
|
);
|
|
|
|
|
let val = walk_path(breadcrumbs, &container.path.keys);
|
|
|
|
|
let val = walk_path(breadcrumbs, &container.path.keys)
|
|
|
|
|
.map(|ice| ice.into_context_element(breadcrumbs));
|
|
|
|
|
return if !val.map(|v| v.is_truthy()).unwrap_or(false) {
|
|
|
|
|
self.render_maybe_body(
|
|
|
|
|
&container.contents,
|
|
|
|
@ -391,11 +395,12 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
let left_side: Result<&dyn ContextElement, WalkError> =
|
|
|
|
|
match Self::get_rval(breadcrumbs, ¶m_map, "key") {
|
|
|
|
|
None => return Ok("".to_owned()),
|
|
|
|
|
Some(res) => res,
|
|
|
|
|
Some(res) => res.map(|ice| ice.into_context_element(breadcrumbs)),
|
|
|
|
|
};
|
|
|
|
|
let right_side: Result<&dyn ContextElement, WalkError> =
|
|
|
|
|
Self::get_rval(breadcrumbs, ¶m_map, "value")
|
|
|
|
|
.unwrap_or(Err(WalkError::CantWalk));
|
|
|
|
|
.unwrap_or(Err(WalkError::CantWalk))
|
|
|
|
|
.map(|ice| ice.into_context_element(breadcrumbs));
|
|
|
|
|
|
|
|
|
|
if left_side == right_side {
|
|
|
|
|
return self.render_maybe_body(
|
|
|
|
@ -441,11 +446,12 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
let left_side: Result<&dyn ContextElement, WalkError> =
|
|
|
|
|
match Self::get_rval(breadcrumbs, ¶m_map, "key") {
|
|
|
|
|
None => return Ok("".to_owned()),
|
|
|
|
|
Some(res) => res,
|
|
|
|
|
Some(res) => res.map(|ice| ice.into_context_element(breadcrumbs)),
|
|
|
|
|
};
|
|
|
|
|
let right_side: Result<&dyn ContextElement, WalkError> =
|
|
|
|
|
Self::get_rval(breadcrumbs, ¶m_map, "value")
|
|
|
|
|
.unwrap_or(Err(WalkError::CantWalk));
|
|
|
|
|
.unwrap_or(Err(WalkError::CantWalk))
|
|
|
|
|
.map(|ice| ice.into_context_element(breadcrumbs));
|
|
|
|
|
if left_side != right_side {
|
|
|
|
|
return self.render_maybe_body(
|
|
|
|
|
¶meterized_block.contents,
|
|
|
|
@ -472,11 +478,12 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
let left_side: Result<&dyn ContextElement, WalkError> =
|
|
|
|
|
match Self::get_rval(breadcrumbs, ¶m_map, "key") {
|
|
|
|
|
None => return Ok("".to_owned()),
|
|
|
|
|
Some(res) => res,
|
|
|
|
|
Some(res) => res.map(|ice| ice.into_context_element(breadcrumbs)),
|
|
|
|
|
};
|
|
|
|
|
let right_side: Result<&dyn ContextElement, WalkError> =
|
|
|
|
|
Self::get_rval(breadcrumbs, ¶m_map, "value")
|
|
|
|
|
.unwrap_or(Err(WalkError::CantWalk));
|
|
|
|
|
.unwrap_or(Err(WalkError::CantWalk))
|
|
|
|
|
.map(|ice| ice.into_context_element(breadcrumbs));
|
|
|
|
|
match (left_side, right_side) {
|
|
|
|
|
(Err(_), _) | (_, Err(_)) => {
|
|
|
|
|
return self.render_maybe_body(
|
|
|
|
@ -514,11 +521,12 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
let left_side: Result<&dyn ContextElement, WalkError> =
|
|
|
|
|
match Self::get_rval(breadcrumbs, ¶m_map, "key") {
|
|
|
|
|
None => return Ok("".to_owned()),
|
|
|
|
|
Some(res) => res,
|
|
|
|
|
Some(res) => res.map(|ice| ice.into_context_element(breadcrumbs)),
|
|
|
|
|
};
|
|
|
|
|
let right_side: Result<&dyn ContextElement, WalkError> =
|
|
|
|
|
Self::get_rval(breadcrumbs, ¶m_map, "value")
|
|
|
|
|
.unwrap_or(Err(WalkError::CantWalk));
|
|
|
|
|
.unwrap_or(Err(WalkError::CantWalk))
|
|
|
|
|
.map(|ice| ice.into_context_element(breadcrumbs));
|
|
|
|
|
match (left_side, right_side) {
|
|
|
|
|
(Err(_), _) | (_, Err(_)) => {
|
|
|
|
|
return self.render_maybe_body(
|
|
|
|
@ -556,11 +564,12 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
let left_side: Result<&dyn ContextElement, WalkError> =
|
|
|
|
|
match Self::get_rval(breadcrumbs, ¶m_map, "key") {
|
|
|
|
|
None => return Ok("".to_owned()),
|
|
|
|
|
Some(res) => res,
|
|
|
|
|
Some(res) => res.map(|ice| ice.into_context_element(breadcrumbs)),
|
|
|
|
|
};
|
|
|
|
|
let right_side: Result<&dyn ContextElement, WalkError> =
|
|
|
|
|
Self::get_rval(breadcrumbs, ¶m_map, "value")
|
|
|
|
|
.unwrap_or(Err(WalkError::CantWalk));
|
|
|
|
|
.unwrap_or(Err(WalkError::CantWalk))
|
|
|
|
|
.map(|ice| ice.into_context_element(breadcrumbs));
|
|
|
|
|
match (left_side, right_side) {
|
|
|
|
|
(Err(_), _) | (_, Err(_)) => {
|
|
|
|
|
return self.render_maybe_body(
|
|
|
|
@ -598,11 +607,12 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
let left_side: Result<&dyn ContextElement, WalkError> =
|
|
|
|
|
match Self::get_rval(breadcrumbs, ¶m_map, "key") {
|
|
|
|
|
None => return Ok("".to_owned()),
|
|
|
|
|
Some(res) => res,
|
|
|
|
|
Some(res) => res.map(|ice| ice.into_context_element(breadcrumbs)),
|
|
|
|
|
};
|
|
|
|
|
let right_side: Result<&dyn ContextElement, WalkError> =
|
|
|
|
|
Self::get_rval(breadcrumbs, ¶m_map, "value")
|
|
|
|
|
.unwrap_or(Err(WalkError::CantWalk));
|
|
|
|
|
.unwrap_or(Err(WalkError::CantWalk))
|
|
|
|
|
.map(|ice| ice.into_context_element(breadcrumbs));
|
|
|
|
|
match (left_side, right_side) {
|
|
|
|
|
(Err(_), _) | (_, Err(_)) => {
|
|
|
|
|
return self.render_maybe_body(
|
|
|
|
@ -665,33 +675,17 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
.collect()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn new_get_rval<'b>(
|
|
|
|
|
breadcrumbs: &'b Vec<&'b dyn ContextElement>,
|
|
|
|
|
param_map: &HashMap<&str, &'b RValue<'b>>,
|
|
|
|
|
key: &str,
|
|
|
|
|
) -> Option<Result<&'b dyn IntoContextElement, WalkError>> {
|
|
|
|
|
match param_map.get(key) {
|
|
|
|
|
None => None,
|
|
|
|
|
Some(rval) => match rval {
|
|
|
|
|
RValue::RVLiteral(literal) => Some(Ok(literal)),
|
|
|
|
|
RValue::RVTemplate(template) => Some(Ok(template)),
|
|
|
|
|
RValue::RVPath(path) => {
|
|
|
|
|
Some(walk_path(breadcrumbs, &path.keys).map(|ce| ce.from_context_element()))
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn get_rval<'b>(
|
|
|
|
|
breadcrumbs: &'b Vec<&'b dyn ContextElement>,
|
|
|
|
|
breadcrumbs: &'b Vec<&'b dyn IntoContextElement>,
|
|
|
|
|
param_map: &HashMap<&str, &'b RValue<'b>>,
|
|
|
|
|
key: &str,
|
|
|
|
|
) -> Option<Result<&'b dyn ContextElement, WalkError>> {
|
|
|
|
|
) -> Option<Result<&'b dyn IntoContextElement, WalkError>> {
|
|
|
|
|
match param_map.get(key) {
|
|
|
|
|
None => None,
|
|
|
|
|
Some(rval) => match rval {
|
|
|
|
|
RValue::RVLiteral(literal) => Some(Ok(literal)),
|
|
|
|
|
RValue::RVTemplate(template) => None,
|
|
|
|
|
// TODO: Do I resolve the IntoContextElement here for RVPath?
|
|
|
|
|
RValue::RVPath(path) => Some(walk_path(breadcrumbs, &path.keys)),
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
@ -713,12 +707,12 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn new_breadcrumbs_section<'b>(
|
|
|
|
|
breadcrumbs: &'b Vec<&'b dyn ContextElement>,
|
|
|
|
|
index_context: Option<&'b dyn ContextElement>,
|
|
|
|
|
injected_context: Option<&'b dyn ContextElement>,
|
|
|
|
|
breadcrumbs: &'b Vec<&'b dyn IntoContextElement>,
|
|
|
|
|
index_context: Option<&'b dyn IntoContextElement>,
|
|
|
|
|
injected_context: Option<&'b dyn IntoContextElement>,
|
|
|
|
|
explicit_context: &Option<Path<'b>>,
|
|
|
|
|
new_context_element: Option<&'b dyn ContextElement>,
|
|
|
|
|
) -> Option<Vec<&'b dyn ContextElement>> {
|
|
|
|
|
) -> Option<Vec<&'b dyn IntoContextElement>> {
|
|
|
|
|
// If none of the additional contexts are present, return None
|
|
|
|
|
// to signal that the original breadcrumbs should be used
|
|
|
|
|
// rather than incurring a copy here.
|
|
|
|
@ -736,24 +730,26 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
None => breadcrumbs.clone(),
|
|
|
|
|
};
|
|
|
|
|
explicit_context.as_ref().map(|path| {
|
|
|
|
|
walk_path(breadcrumbs, &path.keys).map(|val| {
|
|
|
|
|
if val.is_truthy() {
|
|
|
|
|
new_stack.push(val)
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
walk_path(breadcrumbs, &path.keys)
|
|
|
|
|
.map(|ice| ice.into_context_element(breadcrumbs))
|
|
|
|
|
.map(|val| {
|
|
|
|
|
if val.is_truthy() {
|
|
|
|
|
new_stack.push(val.from_context_element())
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
injected_context.map(|ctx| new_stack.push(ctx));
|
|
|
|
|
new_context_element.map(|ctx| new_stack.push(ctx));
|
|
|
|
|
new_context_element.map(|ctx| new_stack.push(ctx.from_context_element()));
|
|
|
|
|
index_context.map(|ctx| new_stack.push(ctx));
|
|
|
|
|
Some(new_stack)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn new_breadcrumbs_partial<'b>(
|
|
|
|
|
breadcrumbs: &'b Vec<&'b dyn ContextElement>,
|
|
|
|
|
explicit_context_breadcrumbs: &'b Vec<&'b dyn ContextElement>,
|
|
|
|
|
injected_context: Option<&'b dyn ContextElement>,
|
|
|
|
|
breadcrumbs: &'b Vec<&'b dyn IntoContextElement>,
|
|
|
|
|
explicit_context_breadcrumbs: &'b Vec<&'b dyn IntoContextElement>,
|
|
|
|
|
injected_context: Option<&'b dyn IntoContextElement>,
|
|
|
|
|
explicit_context: &Option<Path<'b>>,
|
|
|
|
|
) -> Option<Vec<&'b dyn ContextElement>> {
|
|
|
|
|
) -> Option<Vec<&'b dyn IntoContextElement>> {
|
|
|
|
|
// If none of the additional contexts are present, return None
|
|
|
|
|
// to signal that the original breadcrumbs should be used
|
|
|
|
|
// rather than incurring a copy here.
|
|
|
|
@ -780,18 +776,21 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
explicit_context.as_ref().map(|path| {
|
|
|
|
|
walk_path(explicit_context_breadcrumbs, &path.keys).map(|val| {
|
|
|
|
|
if val.is_truthy() {
|
|
|
|
|
new_stack.push(val)
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
walk_path(explicit_context_breadcrumbs, &path.keys)
|
|
|
|
|
// TODO should resolving the value here use explicit_context_breadcrumbs or breadcrumbs?
|
|
|
|
|
.map(|ice| ice.into_context_element(explicit_context_breadcrumbs))
|
|
|
|
|
.map(|val| {
|
|
|
|
|
if val.is_truthy() {
|
|
|
|
|
new_stack.push(val.from_context_element())
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
Some(new_stack)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn get_index_of_first_non_pseudo_element<'b, B>(breadcrumbs: &'b Vec<B>) -> Option<usize>
|
|
|
|
|
where
|
|
|
|
|
B: Borrow<dyn ContextElement + 'a>,
|
|
|
|
|
B: Borrow<dyn IntoContextElement + 'a>,
|
|
|
|
|
{
|
|
|
|
|
breadcrumbs
|
|
|
|
|
.iter()
|
|
|
|
@ -801,7 +800,7 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
|
|
|
|
|
struct BlockContext<'a> {
|
|
|
|
|
/// The breadcrumbs at the time of entering the current partial
|
|
|
|
|
breadcrumbs: &'a Vec<&'a dyn ContextElement>,
|
|
|
|
|
breadcrumbs: &'a Vec<&'a dyn IntoContextElement>,
|
|
|
|
|
blocks: &'a InlinePartialTreeElement<'a>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|