port over the equals/not equals helpers.
This commit is contained in:
parent
c8de395038
commit
8cbb31251c
@ -22,7 +22,7 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ParametersContext<'a> {
|
pub struct ParametersContext<'a> {
|
||||||
params: HashMap<&'a str, BreadcrumbTreeElement<'a>>,
|
params: HashMap<&'a str, (&'a RValue<'a>, BreadcrumbTreeElement<'a>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ParametersContext<'a> {
|
impl<'a> ParametersContext<'a> {
|
||||||
@ -39,7 +39,7 @@ impl<'a> ParametersContext<'a> {
|
|||||||
// then those are resolved at the time of access rather than
|
// then those are resolved at the time of access rather than
|
||||||
// the time of assignment, so we leave them into their
|
// the time of assignment, so we leave them into their
|
||||||
// original IntoContextElement state.
|
// original IntoContextElement state.
|
||||||
let rendered_params: HashMap<&'a str, BreadcrumbTreeElement<'a>> = params
|
let rendered_params: HashMap<&'a str, (&'a RValue<'a>, BreadcrumbTreeElement<'a>)> = params
|
||||||
.iter()
|
.iter()
|
||||||
.map(|kvpair| {
|
.map(|kvpair| {
|
||||||
let k = kvpair.key;
|
let k = kvpair.key;
|
||||||
@ -55,7 +55,7 @@ impl<'a> ParametersContext<'a> {
|
|||||||
Some(BreadcrumbTreeElement::from_borrowed(&kvpair.value))
|
Some(BreadcrumbTreeElement::from_borrowed(&kvpair.value))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
v.map(|some_v| (k, some_v))
|
v.map(|some_v| (k, (&kvpair.value, some_v)))
|
||||||
})
|
})
|
||||||
// TODO: Should a None value here be the same as a key not existing, or should we store the Nones?
|
// TODO: Should a None value here be the same as a key not existing, or should we store the Nones?
|
||||||
.filter_map(|pair| pair)
|
.filter_map(|pair| pair)
|
||||||
@ -65,6 +65,10 @@ impl<'a> ParametersContext<'a> {
|
|||||||
params: rendered_params,
|
params: rendered_params,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_original_rvalue(&self, segment: &str) -> Option<&'a RValue<'a>> {
|
||||||
|
self.params.get(segment).map(|(rvalue, _bte)| *rvalue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> IntoContextElement for ParametersContext<'a> {
|
impl<'a> IntoContextElement for ParametersContext<'a> {
|
||||||
@ -81,7 +85,7 @@ impl<'a> Walkable for ParametersContext<'a> {
|
|||||||
fn walk(&self, segment: &str) -> Result<&dyn IntoContextElement, WalkError> {
|
fn walk(&self, segment: &str) -> Result<&dyn IntoContextElement, WalkError> {
|
||||||
self.params
|
self.params
|
||||||
.get(segment)
|
.get(segment)
|
||||||
.map(|bte| bte.borrow())
|
.map(|(_rvalue, bte)| bte.borrow())
|
||||||
.ok_or(WalkError::CantWalk)
|
.ok_or(WalkError::CantWalk)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,14 +2,17 @@ use crate::parser::template;
|
|||||||
use crate::parser::Body;
|
use crate::parser::Body;
|
||||||
use crate::parser::DustTag;
|
use crate::parser::DustTag;
|
||||||
use crate::parser::Filter;
|
use crate::parser::Filter;
|
||||||
|
use crate::parser::KVPair;
|
||||||
use crate::parser::PartialNameElement;
|
use crate::parser::PartialNameElement;
|
||||||
use crate::parser::Path;
|
use crate::parser::Path;
|
||||||
|
use crate::parser::RValue;
|
||||||
use crate::parser::Special;
|
use crate::parser::Special;
|
||||||
use crate::parser::Template;
|
use crate::parser::Template;
|
||||||
use crate::parser::TemplateElement;
|
use crate::parser::TemplateElement;
|
||||||
use crate::renderer::breadcrumb_tree::BreadcrumbTreeElement;
|
use crate::renderer::breadcrumb_tree::BreadcrumbTreeElement;
|
||||||
use crate::renderer::context_element::ContextElement;
|
use crate::renderer::context_element::ContextElement;
|
||||||
use crate::renderer::context_element::IntoContextElement;
|
use crate::renderer::context_element::IntoContextElement;
|
||||||
|
use crate::renderer::context_element::Walkable;
|
||||||
use crate::renderer::errors::CompileError;
|
use crate::renderer::errors::CompileError;
|
||||||
use crate::renderer::errors::RenderError;
|
use crate::renderer::errors::RenderError;
|
||||||
use crate::renderer::errors::WalkError;
|
use crate::renderer::errors::WalkError;
|
||||||
@ -362,6 +365,124 @@ impl<'a> DustRenderer<'a> {
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
DustTag::DTHelperEquals(parameterized_block) => {
|
||||||
|
let new_breadcrumbs = self.new_breadcrumbs_partial(
|
||||||
|
breadcrumbs,
|
||||||
|
breadcrumbs,
|
||||||
|
None,
|
||||||
|
¶meterized_block.explicit_context,
|
||||||
|
);
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let left_side = match param_map
|
||||||
|
.walk("key")
|
||||||
|
.map(|ice| ice.into_context_element(self, breadcrumbs))
|
||||||
|
{
|
||||||
|
Err(WalkError::CantWalk) | Ok(None) => return Ok("".to_owned()),
|
||||||
|
Ok(Some(res)) => res,
|
||||||
|
};
|
||||||
|
let right_side = param_map
|
||||||
|
.walk("value")
|
||||||
|
.map(|ice| ice.into_context_element(self, breadcrumbs));
|
||||||
|
if Ok(Some(left_side.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),
|
||||||
|
blocks,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return self.render_maybe_body(
|
||||||
|
¶meterized_block.else_contents,
|
||||||
|
new_breadcrumbs.as_ref().unwrap_or(breadcrumbs),
|
||||||
|
blocks,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DustTag::DTHelperNotEquals(parameterized_block) => {
|
||||||
|
let new_breadcrumbs = self.new_breadcrumbs_partial(
|
||||||
|
breadcrumbs,
|
||||||
|
breadcrumbs,
|
||||||
|
None,
|
||||||
|
¶meterized_block.explicit_context,
|
||||||
|
);
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let left_side = match param_map
|
||||||
|
.walk("key")
|
||||||
|
.map(|ice| ice.into_context_element(self, breadcrumbs))
|
||||||
|
{
|
||||||
|
Err(WalkError::CantWalk) | Ok(None) => return Ok("".to_owned()),
|
||||||
|
Ok(Some(res)) => res,
|
||||||
|
};
|
||||||
|
let right_side = param_map
|
||||||
|
.walk("value")
|
||||||
|
.map(|ice| ice.into_context_element(self, breadcrumbs));
|
||||||
|
if Ok(Some(left_side.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),
|
||||||
|
blocks,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return self.render_maybe_body(
|
||||||
|
¶meterized_block.else_contents,
|
||||||
|
new_breadcrumbs.as_ref().unwrap_or(breadcrumbs),
|
||||||
|
blocks,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => panic!("Unsupported tag"),
|
_ => panic!("Unsupported tag"),
|
||||||
}
|
}
|
||||||
Ok("".to_owned())
|
Ok("".to_owned())
|
||||||
@ -472,6 +593,26 @@ impl<'a> DustRenderer<'a> {
|
|||||||
Some(new_stack)
|
Some(new_stack)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn are_paths_identical<'b>(
|
||||||
|
param_map: &ParametersContext<'b>,
|
||||||
|
left_key: &str,
|
||||||
|
right_key: &str,
|
||||||
|
) -> bool {
|
||||||
|
match (
|
||||||
|
param_map.get_original_rvalue(left_key),
|
||||||
|
param_map.get_original_rvalue(right_key),
|
||||||
|
) {
|
||||||
|
(None, _) => false,
|
||||||
|
(_, None) => false,
|
||||||
|
(Some(key_rval), Some(value_rval)) => match (key_rval, value_rval) {
|
||||||
|
(RValue::RVPath(key_path), RValue::RVPath(value_path)) => {
|
||||||
|
key_path.keys == value_path.keys
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn preprocess_filters(filters: &Vec<Filter>) -> Vec<Filter> {
|
fn preprocess_filters(filters: &Vec<Filter>) -> Vec<Filter> {
|
||||||
let mut final_filters: Vec<Filter> = filters
|
let mut final_filters: Vec<Filter> = filters
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user