Add a special case to not render anything if the method parameter to the math helper is a template to match the official DustJS implementation.
This commit is contained in:
parent
b897656cef
commit
2c5c2d239c
@ -24,7 +24,7 @@ use std::collections::HashMap;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ParametersContext<'a> {
|
pub struct ParametersContext<'a> {
|
||||||
parent: Option<&'a ParametersContext<'a>>,
|
parent: Option<&'a ParametersContext<'a>>,
|
||||||
params: HashMap<&'a str, Option<BreadcrumbTreeElement<'a>>>,
|
params: HashMap<&'a str, (&'a RValue<'a>, Option<BreadcrumbTreeElement<'a>>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ParametersContext<'a> {
|
impl<'a> ParametersContext<'a> {
|
||||||
@ -42,25 +42,26 @@ 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, Option<BreadcrumbTreeElement<'a>>> = params
|
let rendered_params: HashMap<&'a str, (&'a RValue<'a>, Option<BreadcrumbTreeElement<'a>>)> =
|
||||||
.iter()
|
params
|
||||||
.map(|kvpair| {
|
.iter()
|
||||||
let k = kvpair.key;
|
.map(|kvpair| {
|
||||||
let v: Option<BreadcrumbTreeElement<'a>> = match &kvpair.value {
|
let k = kvpair.key;
|
||||||
RValue::RVLiteral(_owned_literal) => {
|
let v: Option<BreadcrumbTreeElement<'a>> = match &kvpair.value {
|
||||||
Some(BreadcrumbTreeElement::from_borrowed(&kvpair.value))
|
RValue::RVLiteral(_owned_literal) => {
|
||||||
}
|
Some(BreadcrumbTreeElement::from_borrowed(&kvpair.value))
|
||||||
RValue::RVPath(_path) => kvpair
|
}
|
||||||
.value
|
RValue::RVPath(_path) => kvpair
|
||||||
.into_context_element(renderer, breadcrumbs)
|
.value
|
||||||
.map(std::convert::From::from),
|
.into_context_element(renderer, breadcrumbs)
|
||||||
RValue::RVTemplate(_template) => {
|
.map(std::convert::From::from),
|
||||||
Some(BreadcrumbTreeElement::from_borrowed(&kvpair.value))
|
RValue::RVTemplate(_template) => {
|
||||||
}
|
Some(BreadcrumbTreeElement::from_borrowed(&kvpair.value))
|
||||||
};
|
}
|
||||||
(k, v)
|
};
|
||||||
})
|
(k, (&kvpair.value, v))
|
||||||
.collect();
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
ParametersContext {
|
ParametersContext {
|
||||||
parent: parent,
|
parent: parent,
|
||||||
@ -70,7 +71,7 @@ impl<'a> ParametersContext<'a> {
|
|||||||
|
|
||||||
pub fn from_values(
|
pub fn from_values(
|
||||||
parent: Option<&'a ParametersContext<'a>>,
|
parent: Option<&'a ParametersContext<'a>>,
|
||||||
params: HashMap<&'a str, Option<BreadcrumbTreeElement<'a>>>,
|
params: HashMap<&'a str, (&'a RValue<'a>, Option<BreadcrumbTreeElement<'a>>)>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
ParametersContext {
|
ParametersContext {
|
||||||
parent: parent,
|
parent: parent,
|
||||||
@ -85,6 +86,17 @@ impl<'a> ParametersContext<'a> {
|
|||||||
.map(|p| p.contains_key(segment))
|
.map(|p| p.contains_key(segment))
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_original_rvalue(&self, segment: &str) -> Option<&'a RValue<'a>> {
|
||||||
|
self.params
|
||||||
|
.get(segment)
|
||||||
|
.map(|(rvalue, _bte)| *rvalue)
|
||||||
|
.or_else(|| {
|
||||||
|
self.parent
|
||||||
|
.map(|p| p.get_original_rvalue(segment))
|
||||||
|
.flatten()
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> IntoContextElement for ParametersContext<'a> {
|
impl<'a> IntoContextElement for ParametersContext<'a> {
|
||||||
@ -99,7 +111,7 @@ impl<'a> IntoContextElement for ParametersContext<'a> {
|
|||||||
|
|
||||||
impl<'a> Walkable for ParametersContext<'a> {
|
impl<'a> Walkable for ParametersContext<'a> {
|
||||||
fn walk(&self, segment: &str) -> Result<&dyn IntoContextElement, WalkError> {
|
fn walk(&self, segment: &str) -> Result<&dyn IntoContextElement, WalkError> {
|
||||||
match self.params.get(segment) {
|
match self.params.get(segment).map(|(_rvalue, bte)| bte) {
|
||||||
Some(Some(bte)) => Ok(bte.borrow()),
|
Some(Some(bte)) => Ok(bte.borrow()),
|
||||||
Some(None) => Err(WalkError::CantWalk),
|
Some(None) => Err(WalkError::CantWalk),
|
||||||
None => self
|
None => self
|
||||||
|
@ -5,6 +5,7 @@ use crate::parser::Filter;
|
|||||||
use crate::parser::OwnedLiteral;
|
use crate::parser::OwnedLiteral;
|
||||||
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;
|
||||||
@ -675,8 +676,13 @@ impl<'a> DustRenderer<'a> {
|
|||||||
|
|
||||||
// Generate a ParametersContext with the result of the math operation as key
|
// Generate a ParametersContext with the result of the math operation as key
|
||||||
let converted_value: BreadcrumbTreeElement<'_> = calculated_value.into();
|
let converted_value: BreadcrumbTreeElement<'_> = calculated_value.into();
|
||||||
let calculated_param_map: HashMap<&str, Option<BreadcrumbTreeElement<'_>>> =
|
let dummy_rvalue = RValue::RVLiteral(OwnedLiteral::LPositiveInteger(0));
|
||||||
vec![("key", Some(converted_value))].into_iter().collect();
|
let calculated_param_map: HashMap<
|
||||||
|
&str,
|
||||||
|
(&RValue<'_>, Option<BreadcrumbTreeElement<'_>>),
|
||||||
|
> = vec![("key", (&dummy_rvalue, Some(converted_value)))]
|
||||||
|
.into_iter()
|
||||||
|
.collect();
|
||||||
let calculated_context =
|
let calculated_context =
|
||||||
ParametersContext::from_values(None, calculated_param_map);
|
ParametersContext::from_values(None, calculated_param_map);
|
||||||
// calculate are_any_checks_true
|
// calculate are_any_checks_true
|
||||||
@ -982,6 +988,21 @@ impl<'a> DustRenderer<'a> {
|
|||||||
breadcrumbs: &'a Vec<BreadcrumbTreeElement<'a>>,
|
breadcrumbs: &'a Vec<BreadcrumbTreeElement<'a>>,
|
||||||
math_parameters: &'a ParametersContext<'a>,
|
math_parameters: &'a ParametersContext<'a>,
|
||||||
) -> Option<IceResult<'a>> {
|
) -> Option<IceResult<'a>> {
|
||||||
|
// Special case: if method is a template then do not render
|
||||||
|
// anything. This is to match the behavior of dustjs even
|
||||||
|
// though it works fine.
|
||||||
|
match math_parameters.get_original_rvalue("method") {
|
||||||
|
Some(RValue::RVTemplate(template)) => {
|
||||||
|
if template.iter().any(|pne| match pne {
|
||||||
|
PartialNameElement::PNReference { .. } => true,
|
||||||
|
PartialNameElement::PNSpan { .. } => false,
|
||||||
|
}) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
|
||||||
let method = match self.tap(breadcrumbs, math_parameters, "method") {
|
let method = match self.tap(breadcrumbs, math_parameters, "method") {
|
||||||
None | Some(Err(_)) => return None,
|
None | Some(Err(_)) => return None,
|
||||||
Some(Ok(ice_result)) => ice_result,
|
Some(Ok(ice_result)) => ice_result,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user