|
|
|
@ -11,6 +11,7 @@ use crate::parser::Template;
|
|
|
|
|
use crate::parser::TemplateElement;
|
|
|
|
|
use crate::renderer::breadcrumb_tree::BreadcrumbTreeElement;
|
|
|
|
|
use crate::renderer::context_element::ContextElement;
|
|
|
|
|
use crate::renderer::context_element::IceResult;
|
|
|
|
|
use crate::renderer::context_element::IntoContextElement;
|
|
|
|
|
use crate::renderer::context_element::Walkable;
|
|
|
|
|
use crate::renderer::errors::CompileError;
|
|
|
|
@ -376,24 +377,6 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
let param_map =
|
|
|
|
|
ParametersContext::new(self, breadcrumbs, ¶meterized_block.params);
|
|
|
|
|
|
|
|
|
|
// Special case: when comparing two RVPaths, if the
|
|
|
|
|
// path is equal then dust assumes the values are
|
|
|
|
|
// equal (otherwise, non-scalar values are
|
|
|
|
|
// automatically not equal)
|
|
|
|
|
if Self::are_paths_identical(¶m_map, "key", "value") {
|
|
|
|
|
return match ¶meterized_block.contents {
|
|
|
|
|
None => Ok("".to_owned()),
|
|
|
|
|
Some(body) => {
|
|
|
|
|
let rendered_content = self.render_body(
|
|
|
|
|
body,
|
|
|
|
|
new_breadcrumbs.as_ref().unwrap_or(breadcrumbs),
|
|
|
|
|
blocks,
|
|
|
|
|
)?;
|
|
|
|
|
Ok(rendered_content)
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !param_map.contains_key("key") {
|
|
|
|
|
return Ok("".to_owned());
|
|
|
|
|
}
|
|
|
|
@ -403,15 +386,22 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
let right_side = param_map
|
|
|
|
|
.walk("value")
|
|
|
|
|
.map(|ice| ice.into_context_element(self, breadcrumbs));
|
|
|
|
|
if left_side.as_ref().map(|maybe_ice| {
|
|
|
|
|
maybe_ice
|
|
|
|
|
.as_ref()
|
|
|
|
|
.map(|ice| ice.get_context_element_reference())
|
|
|
|
|
}) == right_side.as_ref().map(|maybe_ice| {
|
|
|
|
|
maybe_ice
|
|
|
|
|
.as_ref()
|
|
|
|
|
.map(|ice| ice.get_context_element_reference())
|
|
|
|
|
}) {
|
|
|
|
|
// Special case: when comparing two RVPaths, if the
|
|
|
|
|
// path points to the same value then they are
|
|
|
|
|
// equal. This is particularly important for objects
|
|
|
|
|
// which compare memory locations rather than contents
|
|
|
|
|
// (javascript object equality).
|
|
|
|
|
if Self::new_are_paths_identical(&left_side, &right_side)
|
|
|
|
|
|| left_side.as_ref().map(|maybe_ice| {
|
|
|
|
|
maybe_ice
|
|
|
|
|
.as_ref()
|
|
|
|
|
.map(|ice| ice.get_context_element_reference())
|
|
|
|
|
}) == right_side.as_ref().map(|maybe_ice| {
|
|
|
|
|
maybe_ice
|
|
|
|
|
.as_ref()
|
|
|
|
|
.map(|ice| ice.get_context_element_reference())
|
|
|
|
|
})
|
|
|
|
|
{
|
|
|
|
|
return self.render_maybe_body(
|
|
|
|
|
¶meterized_block.contents,
|
|
|
|
|
new_breadcrumbs.as_ref().unwrap_or(breadcrumbs),
|
|
|
|
@ -436,24 +426,6 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
let param_map =
|
|
|
|
|
ParametersContext::new(self, breadcrumbs, ¶meterized_block.params);
|
|
|
|
|
|
|
|
|
|
// Special case: when comparing two RVPaths, if the
|
|
|
|
|
// path is equal then dust assumes the values are
|
|
|
|
|
// equal (otherwise, non-scalar values are
|
|
|
|
|
// automatically not equal)
|
|
|
|
|
if Self::are_paths_identical(¶m_map, "key", "value") {
|
|
|
|
|
return match ¶meterized_block.else_contents {
|
|
|
|
|
None => Ok("".to_owned()),
|
|
|
|
|
Some(body) => {
|
|
|
|
|
let rendered_content = self.render_body(
|
|
|
|
|
body,
|
|
|
|
|
new_breadcrumbs.as_ref().unwrap_or(breadcrumbs),
|
|
|
|
|
blocks,
|
|
|
|
|
)?;
|
|
|
|
|
Ok(rendered_content)
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !param_map.contains_key("key") {
|
|
|
|
|
return Ok("".to_owned());
|
|
|
|
|
}
|
|
|
|
@ -463,23 +435,30 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
let right_side = param_map
|
|
|
|
|
.walk("value")
|
|
|
|
|
.map(|ice| ice.into_context_element(self, breadcrumbs));
|
|
|
|
|
if left_side.as_ref().map(|maybe_ice| {
|
|
|
|
|
maybe_ice
|
|
|
|
|
.as_ref()
|
|
|
|
|
.map(|ice| ice.get_context_element_reference())
|
|
|
|
|
}) != right_side.as_ref().map(|maybe_ice| {
|
|
|
|
|
maybe_ice
|
|
|
|
|
.as_ref()
|
|
|
|
|
.map(|ice| ice.get_context_element_reference())
|
|
|
|
|
}) {
|
|
|
|
|
// Special case: when comparing two RVPaths, if the
|
|
|
|
|
// path points to the same value then they are
|
|
|
|
|
// equal. This is particularly important for objects
|
|
|
|
|
// which compare memory locations rather than contents
|
|
|
|
|
// (javascript object equality).
|
|
|
|
|
if Self::new_are_paths_identical(&left_side, &right_side)
|
|
|
|
|
|| left_side.as_ref().map(|maybe_ice| {
|
|
|
|
|
maybe_ice
|
|
|
|
|
.as_ref()
|
|
|
|
|
.map(|ice| ice.get_context_element_reference())
|
|
|
|
|
}) == right_side.as_ref().map(|maybe_ice| {
|
|
|
|
|
maybe_ice
|
|
|
|
|
.as_ref()
|
|
|
|
|
.map(|ice| ice.get_context_element_reference())
|
|
|
|
|
})
|
|
|
|
|
{
|
|
|
|
|
return self.render_maybe_body(
|
|
|
|
|
¶meterized_block.contents,
|
|
|
|
|
¶meterized_block.else_contents,
|
|
|
|
|
new_breadcrumbs.as_ref().unwrap_or(breadcrumbs),
|
|
|
|
|
blocks,
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
return self.render_maybe_body(
|
|
|
|
|
¶meterized_block.else_contents,
|
|
|
|
|
¶meterized_block.contents,
|
|
|
|
|
new_breadcrumbs.as_ref().unwrap_or(breadcrumbs),
|
|
|
|
|
blocks,
|
|
|
|
|
);
|
|
|
|
@ -800,6 +779,26 @@ impl<'a> DustRenderer<'a> {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn new_are_paths_identical<'b>(
|
|
|
|
|
left_side: &Result<Option<IceResult<'b>>, WalkError>,
|
|
|
|
|
right_side: &Result<Option<IceResult<'b>>, WalkError>,
|
|
|
|
|
) -> bool {
|
|
|
|
|
let left_resolved = left_side.as_ref().map(|maybe_ice| {
|
|
|
|
|
maybe_ice
|
|
|
|
|
.as_ref()
|
|
|
|
|
.map(|ice| ice.get_context_element_reference())
|
|
|
|
|
});
|
|
|
|
|
let right_resolved = right_side.as_ref().map(|maybe_ice| {
|
|
|
|
|
maybe_ice
|
|
|
|
|
.as_ref()
|
|
|
|
|
.map(|ice| ice.get_context_element_reference())
|
|
|
|
|
});
|
|
|
|
|
match (left_resolved, right_resolved) {
|
|
|
|
|
(Ok(Some(lce)), Ok(Some(rce))) => lce as *const _ == rce as *const _,
|
|
|
|
|
_ => false,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn preprocess_filters(filters: &Vec<Filter>) -> Vec<Filter> {
|
|
|
|
|
let mut final_filters: Vec<Filter> = filters
|
|
|
|
|
.into_iter()
|
|
|
|
|