From f2740987ec94108aafb1696e15c8ea271de41416 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sun, 7 Jun 2020 17:56:51 -0400 Subject: [PATCH] Add a parent to ParametersContext so we can chain parameters contexts for use with the select helper. --- src/renderer/parameters_context.rs | 13 ++++++- src/renderer/renderer.rs | 61 +++++++++++++++++++++++++----- 2 files changed, 64 insertions(+), 10 deletions(-) diff --git a/src/renderer/parameters_context.rs b/src/renderer/parameters_context.rs index c8e0988..e7d13aa 100644 --- a/src/renderer/parameters_context.rs +++ b/src/renderer/parameters_context.rs @@ -21,6 +21,7 @@ use std::collections::HashMap; #[derive(Debug)] pub struct ParametersContext<'a> { + parent: Option<&'a ParametersContext<'a>>, params: HashMap<&'a str, (&'a RValue<'a>, Option>)>, } @@ -29,6 +30,7 @@ impl<'a> ParametersContext<'a> { renderer: &DustRenderer, breadcrumbs: &'a Vec>, params: &'a Vec, + parent: Option<&'a ParametersContext<'a>>, ) -> Self { // If the parameter is a Path, then we resolve it immediately // to a context element because those are resolved using the @@ -60,12 +62,17 @@ impl<'a> ParametersContext<'a> { .collect(); ParametersContext { + parent: parent, params: rendered_params, } } pub fn contains_key(&self, segment: &str) -> bool { self.params.contains_key(segment) + || self + .parent + .map(|p| p.contains_key(segment)) + .unwrap_or(false) } } @@ -83,7 +90,11 @@ impl<'a> Walkable for ParametersContext<'a> { fn walk(&self, segment: &str) -> Result<&dyn IntoContextElement, WalkError> { match self.params.get(segment).map(|(_rvalue, bte)| bte) { Some(Some(bte)) => Ok(bte.borrow()), - _ => Err(WalkError::CantWalk), + Some(None) => Err(WalkError::CantWalk), + None => self + .parent + .map(|p| p.walk(segment)) + .unwrap_or(Err(WalkError::CantWalk)), } } diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index d2e1405..f1434e6 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -169,7 +169,8 @@ impl<'a> DustRenderer<'a> { } } DustTag::DTSection(container) => { - let injected_context = ParametersContext::new(self, breadcrumbs, &container.params); + let injected_context = + ParametersContext::new(self, breadcrumbs, &container.params, None); let val = walk_path(breadcrumbs, &container.path.keys) .map(|ice| ice.into_context_element(self, breadcrumbs)); match val { @@ -325,7 +326,7 @@ impl<'a> DustRenderer<'a> { return Ok(rendered_content); } else { let injected_context = - ParametersContext::new(self, breadcrumbs, &partial.params); + ParametersContext::new(self, breadcrumbs, &partial.params, None); let new_breadcrumbs = self.new_breadcrumbs_partial( breadcrumbs, breadcrumbs, @@ -373,7 +374,7 @@ impl<'a> DustRenderer<'a> { ); let param_map = - ParametersContext::new(self, breadcrumbs, ¶meterized_block.params); + ParametersContext::new(self, breadcrumbs, ¶meterized_block.params, None); let left_side = self.tap(breadcrumbs, ¶m_map, "key"); let right_side = self.tap(breadcrumbs, ¶m_map, "value"); @@ -425,7 +426,7 @@ impl<'a> DustRenderer<'a> { ); let param_map = - ParametersContext::new(self, breadcrumbs, ¶meterized_block.params); + ParametersContext::new(self, breadcrumbs, ¶meterized_block.params, None); let left_side = self.tap(breadcrumbs, ¶m_map, "key"); let right_side = self.tap(breadcrumbs, ¶m_map, "value"); @@ -477,7 +478,7 @@ impl<'a> DustRenderer<'a> { ); let param_map = - ParametersContext::new(self, breadcrumbs, ¶meterized_block.params); + ParametersContext::new(self, breadcrumbs, ¶meterized_block.params, None); let left_side = self.tap(breadcrumbs, ¶m_map, "key"); let right_side = self.tap(breadcrumbs, ¶m_map, "value"); @@ -518,7 +519,7 @@ impl<'a> DustRenderer<'a> { ); let param_map = - ParametersContext::new(self, breadcrumbs, ¶meterized_block.params); + ParametersContext::new(self, breadcrumbs, ¶meterized_block.params, None); let left_side = self.tap(breadcrumbs, ¶m_map, "key"); let right_side = self.tap(breadcrumbs, ¶m_map, "value"); @@ -559,7 +560,7 @@ impl<'a> DustRenderer<'a> { ); let param_map = - ParametersContext::new(self, breadcrumbs, ¶meterized_block.params); + ParametersContext::new(self, breadcrumbs, ¶meterized_block.params, None); let left_side = self.tap(breadcrumbs, ¶m_map, "key"); let right_side = self.tap(breadcrumbs, ¶m_map, "value"); @@ -600,7 +601,7 @@ impl<'a> DustRenderer<'a> { ); let param_map = - ParametersContext::new(self, breadcrumbs, ¶meterized_block.params); + ParametersContext::new(self, breadcrumbs, ¶meterized_block.params, None); let left_side = self.tap(breadcrumbs, ¶m_map, "key"); let right_side = self.tap(breadcrumbs, ¶m_map, "value"); @@ -756,7 +757,31 @@ impl<'a> DustRenderer<'a> { } } } - DustTag::DTHelperSelect(parameterized_block) => todo!(), + DustTag::DTHelperSelect(parameterized_block) => { + let new_breadcrumbs = self.new_breadcrumbs_partial( + breadcrumbs, + breadcrumbs, + None, + ¶meterized_block.explicit_context, + ); + match ¶meterized_block.contents { + None => return Ok("".to_owned()), + Some(body) => { + let comparison_helpers = body.elements.iter().filter_map(|te| match te { + TemplateElement::TETag(dt) => match dt { + DustTag::DTHelperEquals(_) + | DustTag::DTHelperNotEquals(_) + | DustTag::DTHelperGreaterThan(_) + | DustTag::DTHelperLessThan(_) + | DustTag::DTHelperGreaterThanOrEquals(_) + | DustTag::DTHelperLessThanOrEquals(_) => Some(dt), + _ => None, + }, + _ => None, + }); + } + } + } DustTag::DTHelperAny(parameterized_block) => todo!(), DustTag::DTHelperNone(parameterized_block) => todo!(), } @@ -944,6 +969,24 @@ impl<'a> DustRenderer<'a> { !std::borrow::Borrow::::borrow(b).is_pseudo_element() }) } + + fn perform_comparison_check( + &'a self, + tag: &'a DustTag, + breadcrumbs: &'a Vec>, + select_parameters: Option<&'a ParametersContext<'a>>, + ) -> bool { + let param_map = match tag { + DustTag::DTHelperEquals(parameterized_block) + | DustTag::DTHelperNotEquals(parameterized_block) + | DustTag::DTHelperGreaterThan(parameterized_block) + | DustTag::DTHelperLessThan(parameterized_block) + | DustTag::DTHelperGreaterThanOrEquals(parameterized_block) + | DustTag::DTHelperLessThanOrEquals(parameterized_block) => ParametersContext::new(self, breadcrumbs, ¶meterized_block.params, select_parameters), + _ => panic!("perform_comparison_check only implemented for comparison helpers (eq, ne, gt, gte, lt, lte)") + }; + todo!() + } } struct BlockContext<'a> {