Add the renderer to calls to convert to a context element.

This commit is contained in:
Tom Alexander 2020-05-30 18:16:58 -04:00
parent 917da5a073
commit 737c98d8b7
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
3 changed files with 42 additions and 34 deletions

View File

@ -1,6 +1,7 @@
use crate::parser::Filter; use crate::parser::Filter;
use crate::renderer::errors::RenderError; use crate::renderer::errors::RenderError;
use crate::renderer::errors::WalkError; use crate::renderer::errors::WalkError;
use crate::renderer::DustRenderer;
use std::any::Any; use std::any::Any;
use std::{cmp::Ordering, fmt::Debug}; use std::{cmp::Ordering, fmt::Debug};
@ -101,6 +102,7 @@ impl<C: ContextElement> FromContextElement for C {
pub trait IntoContextElement: Debug + Walkable + CloneIntoBoxedContextElement { pub trait IntoContextElement: Debug + Walkable + CloneIntoBoxedContextElement {
fn into_context_element( fn into_context_element(
&self, &self,
renderer: &DustRenderer,
breadcrumbs: &Vec<&dyn IntoContextElement>, breadcrumbs: &Vec<&dyn IntoContextElement>,
) -> &dyn ContextElement; ) -> &dyn ContextElement;
} }
@ -108,6 +110,7 @@ pub trait IntoContextElement: Debug + Walkable + CloneIntoBoxedContextElement {
impl<C: ContextElement> IntoContextElement for C { impl<C: ContextElement> IntoContextElement for C {
fn into_context_element( fn into_context_element(
&self, &self,
renderer: &DustRenderer,
breadcrumbs: &Vec<&dyn IntoContextElement>, breadcrumbs: &Vec<&dyn IntoContextElement>,
) -> &dyn ContextElement { ) -> &dyn ContextElement {
self self

View File

@ -4,6 +4,7 @@ use crate::renderer::context_element::CompareContextElement;
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::walking::walk_path; use crate::renderer::walking::walk_path;
use crate::renderer::DustRenderer;
use crate::renderer::Loopable; use crate::renderer::Loopable;
use crate::renderer::RenderError; use crate::renderer::RenderError;
use crate::renderer::Renderable; use crate::renderer::Renderable;
@ -243,8 +244,10 @@ impl CompareContextElement for OwnedLiteral {
impl IntoContextElement for Vec<PartialNameElement> { impl IntoContextElement for Vec<PartialNameElement> {
fn into_context_element( fn into_context_element(
&self, &self,
renderer: &DustRenderer,
breadcrumbs: &Vec<&dyn IntoContextElement>, breadcrumbs: &Vec<&dyn IntoContextElement>,
) -> &dyn ContextElement { ) -> &dyn ContextElement {
// renderer.render_partial_name(self,
// TODO // TODO
&OwnedLiteral::LPositiveInteger(1) &OwnedLiteral::LPositiveInteger(1)
} }

View File

@ -155,7 +155,7 @@ impl<'a> DustRenderer<'a> {
DustTag::DTLiteralStringBlock(literal) => return Ok((*literal).to_owned()), DustTag::DTLiteralStringBlock(literal) => return Ok((*literal).to_owned()),
DustTag::DTReference(reference) => { 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)); .map(|ice| ice.into_context_element(self, breadcrumbs));
match val { match val {
Err(WalkError::CantWalk) => return Ok("".to_owned()), Err(WalkError::CantWalk) => return Ok("".to_owned()),
Ok(final_val) => { Ok(final_val) => {
@ -170,10 +170,10 @@ impl<'a> DustRenderer<'a> {
DustTag::DTSection(container) => { DustTag::DTSection(container) => {
let injected_context = ParametersContext::new(breadcrumbs, &container.params); 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)); .map(|ice| ice.into_context_element(self, breadcrumbs));
match val { match val {
Err(WalkError::CantWalk) => { Err(WalkError::CantWalk) => {
let new_breadcrumbs = Self::new_breadcrumbs_section( let new_breadcrumbs = self.new_breadcrumbs_section(
breadcrumbs, breadcrumbs,
None, None,
Some(&injected_context), Some(&injected_context),
@ -199,7 +199,7 @@ impl<'a> DustRenderer<'a> {
final_val.get_loop_elements(); final_val.get_loop_elements();
if loop_elements.is_empty() { if loop_elements.is_empty() {
// Scalar value // Scalar value
let new_breadcrumbs = Self::new_breadcrumbs_section( let new_breadcrumbs = self.new_breadcrumbs_section(
breadcrumbs, breadcrumbs,
None, None,
Some(&injected_context), Some(&injected_context),
@ -221,8 +221,8 @@ impl<'a> DustRenderer<'a> {
.map(|(i, array_elem)| { .map(|(i, array_elem)| {
let index_context = let index_context =
IterationContext::new(i, total_length); IterationContext::new(i, total_length);
let new_breadcrumbs = let new_breadcrumbs = self
Self::new_breadcrumbs_section( .new_breadcrumbs_section(
breadcrumbs, breadcrumbs,
Some(&index_context), Some(&index_context),
Some(&injected_context), Some(&injected_context),
@ -248,7 +248,7 @@ impl<'a> DustRenderer<'a> {
// an empty array or null), Dust uses the // an empty array or null), Dust uses the
// original context before walking the path as // original context before walking the path as
// the context for rendering the else block // the context for rendering the else block
let new_breadcrumbs = Self::new_breadcrumbs_section( let new_breadcrumbs = self.new_breadcrumbs_section(
breadcrumbs, breadcrumbs,
None, None,
Some(&injected_context), Some(&injected_context),
@ -265,14 +265,14 @@ impl<'a> DustRenderer<'a> {
} }
} }
DustTag::DTExists(container) => { DustTag::DTExists(container) => {
let new_breadcrumbs = Self::new_breadcrumbs_partial( let new_breadcrumbs = self.new_breadcrumbs_partial(
breadcrumbs, breadcrumbs,
breadcrumbs, breadcrumbs,
None, None,
&container.explicit_context, &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)); .map(|ice| ice.into_context_element(self, breadcrumbs));
return if val.map(|v| v.is_truthy()).unwrap_or(false) { return if val.map(|v| v.is_truthy()).unwrap_or(false) {
self.render_maybe_body( self.render_maybe_body(
&container.contents, &container.contents,
@ -288,14 +288,14 @@ impl<'a> DustRenderer<'a> {
}; };
} }
DustTag::DTNotExists(container) => { DustTag::DTNotExists(container) => {
let new_breadcrumbs = Self::new_breadcrumbs_partial( let new_breadcrumbs = self.new_breadcrumbs_partial(
breadcrumbs, breadcrumbs,
breadcrumbs, breadcrumbs,
None, None,
&container.explicit_context, &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)); .map(|ice| ice.into_context_element(self, breadcrumbs));
return if !val.map(|v| v.is_truthy()).unwrap_or(false) { return if !val.map(|v| v.is_truthy()).unwrap_or(false) {
self.render_maybe_body( self.render_maybe_body(
&container.contents, &container.contents,
@ -313,7 +313,7 @@ impl<'a> DustRenderer<'a> {
DustTag::DTPartial(partial) => { DustTag::DTPartial(partial) => {
let partial_name = self.render_partial_name(&partial.name, breadcrumbs, blocks)?; let partial_name = self.render_partial_name(&partial.name, breadcrumbs, blocks)?;
if partial.params.is_empty() { if partial.params.is_empty() {
let new_breadcrumbs = Self::new_breadcrumbs_partial( let new_breadcrumbs = self.new_breadcrumbs_partial(
breadcrumbs, breadcrumbs,
breadcrumbs, breadcrumbs,
None, None,
@ -327,7 +327,7 @@ impl<'a> DustRenderer<'a> {
return Ok(rendered_content); return Ok(rendered_content);
} else { } else {
let injected_context = ParametersContext::new(breadcrumbs, &partial.params); let injected_context = ParametersContext::new(breadcrumbs, &partial.params);
let new_breadcrumbs = Self::new_breadcrumbs_partial( let new_breadcrumbs = self.new_breadcrumbs_partial(
breadcrumbs, breadcrumbs,
breadcrumbs, breadcrumbs,
Some(&injected_context), Some(&injected_context),
@ -346,7 +346,7 @@ impl<'a> DustRenderer<'a> {
return Ok("".to_owned()); return Ok("".to_owned());
} }
DustTag::DTBlock(named_block) => { DustTag::DTBlock(named_block) => {
let new_breadcrumbs = Self::new_breadcrumbs_partial( let new_breadcrumbs = self.new_breadcrumbs_partial(
breadcrumbs, breadcrumbs,
blocks.breadcrumbs, blocks.breadcrumbs,
None, None,
@ -366,7 +366,7 @@ impl<'a> DustRenderer<'a> {
}; };
} }
DustTag::DTHelperEquals(parameterized_block) => { DustTag::DTHelperEquals(parameterized_block) => {
let new_breadcrumbs = Self::new_breadcrumbs_partial( let new_breadcrumbs = self.new_breadcrumbs_partial(
breadcrumbs, breadcrumbs,
breadcrumbs, breadcrumbs,
None, None,
@ -395,12 +395,12 @@ impl<'a> DustRenderer<'a> {
let left_side: Result<&dyn ContextElement, WalkError> = let left_side: Result<&dyn ContextElement, WalkError> =
match Self::get_rval(breadcrumbs, &param_map, "key") { match Self::get_rval(breadcrumbs, &param_map, "key") {
None => return Ok("".to_owned()), None => return Ok("".to_owned()),
Some(res) => res.map(|ice| ice.into_context_element(breadcrumbs)), Some(res) => res.map(|ice| ice.into_context_element(self, breadcrumbs)),
}; };
let right_side: Result<&dyn ContextElement, WalkError> = let right_side: Result<&dyn ContextElement, WalkError> =
Self::get_rval(breadcrumbs, &param_map, "value") Self::get_rval(breadcrumbs, &param_map, "value")
.unwrap_or(Err(WalkError::CantWalk)) .unwrap_or(Err(WalkError::CantWalk))
.map(|ice| ice.into_context_element(breadcrumbs)); .map(|ice| ice.into_context_element(self, breadcrumbs));
if left_side == right_side { if left_side == right_side {
return self.render_maybe_body( return self.render_maybe_body(
@ -417,7 +417,7 @@ impl<'a> DustRenderer<'a> {
} }
} }
DustTag::DTHelperNotEquals(parameterized_block) => { DustTag::DTHelperNotEquals(parameterized_block) => {
let new_breadcrumbs = Self::new_breadcrumbs_partial( let new_breadcrumbs = self.new_breadcrumbs_partial(
breadcrumbs, breadcrumbs,
breadcrumbs, breadcrumbs,
None, None,
@ -446,12 +446,12 @@ impl<'a> DustRenderer<'a> {
let left_side: Result<&dyn ContextElement, WalkError> = let left_side: Result<&dyn ContextElement, WalkError> =
match Self::get_rval(breadcrumbs, &param_map, "key") { match Self::get_rval(breadcrumbs, &param_map, "key") {
None => return Ok("".to_owned()), None => return Ok("".to_owned()),
Some(res) => res.map(|ice| ice.into_context_element(breadcrumbs)), Some(res) => res.map(|ice| ice.into_context_element(self, breadcrumbs)),
}; };
let right_side: Result<&dyn ContextElement, WalkError> = let right_side: Result<&dyn ContextElement, WalkError> =
Self::get_rval(breadcrumbs, &param_map, "value") Self::get_rval(breadcrumbs, &param_map, "value")
.unwrap_or(Err(WalkError::CantWalk)) .unwrap_or(Err(WalkError::CantWalk))
.map(|ice| ice.into_context_element(breadcrumbs)); .map(|ice| ice.into_context_element(self, breadcrumbs));
if left_side != right_side { if left_side != right_side {
return self.render_maybe_body( return self.render_maybe_body(
&parameterized_block.contents, &parameterized_block.contents,
@ -467,7 +467,7 @@ impl<'a> DustRenderer<'a> {
} }
} }
DustTag::DTHelperGreaterThan(parameterized_block) => { DustTag::DTHelperGreaterThan(parameterized_block) => {
let new_breadcrumbs = Self::new_breadcrumbs_partial( let new_breadcrumbs = self.new_breadcrumbs_partial(
breadcrumbs, breadcrumbs,
breadcrumbs, breadcrumbs,
None, None,
@ -478,12 +478,12 @@ impl<'a> DustRenderer<'a> {
let left_side: Result<&dyn ContextElement, WalkError> = let left_side: Result<&dyn ContextElement, WalkError> =
match Self::get_rval(breadcrumbs, &param_map, "key") { match Self::get_rval(breadcrumbs, &param_map, "key") {
None => return Ok("".to_owned()), None => return Ok("".to_owned()),
Some(res) => res.map(|ice| ice.into_context_element(breadcrumbs)), Some(res) => res.map(|ice| ice.into_context_element(self, breadcrumbs)),
}; };
let right_side: Result<&dyn ContextElement, WalkError> = let right_side: Result<&dyn ContextElement, WalkError> =
Self::get_rval(breadcrumbs, &param_map, "value") Self::get_rval(breadcrumbs, &param_map, "value")
.unwrap_or(Err(WalkError::CantWalk)) .unwrap_or(Err(WalkError::CantWalk))
.map(|ice| ice.into_context_element(breadcrumbs)); .map(|ice| ice.into_context_element(self, breadcrumbs));
match (left_side, right_side) { match (left_side, right_side) {
(Err(_), _) | (_, Err(_)) => { (Err(_), _) | (_, Err(_)) => {
return self.render_maybe_body( return self.render_maybe_body(
@ -510,7 +510,7 @@ impl<'a> DustRenderer<'a> {
} }
} }
DustTag::DTHelperGreaterThanOrEquals(parameterized_block) => { DustTag::DTHelperGreaterThanOrEquals(parameterized_block) => {
let new_breadcrumbs = Self::new_breadcrumbs_partial( let new_breadcrumbs = self.new_breadcrumbs_partial(
breadcrumbs, breadcrumbs,
breadcrumbs, breadcrumbs,
None, None,
@ -521,12 +521,12 @@ impl<'a> DustRenderer<'a> {
let left_side: Result<&dyn ContextElement, WalkError> = let left_side: Result<&dyn ContextElement, WalkError> =
match Self::get_rval(breadcrumbs, &param_map, "key") { match Self::get_rval(breadcrumbs, &param_map, "key") {
None => return Ok("".to_owned()), None => return Ok("".to_owned()),
Some(res) => res.map(|ice| ice.into_context_element(breadcrumbs)), Some(res) => res.map(|ice| ice.into_context_element(self, breadcrumbs)),
}; };
let right_side: Result<&dyn ContextElement, WalkError> = let right_side: Result<&dyn ContextElement, WalkError> =
Self::get_rval(breadcrumbs, &param_map, "value") Self::get_rval(breadcrumbs, &param_map, "value")
.unwrap_or(Err(WalkError::CantWalk)) .unwrap_or(Err(WalkError::CantWalk))
.map(|ice| ice.into_context_element(breadcrumbs)); .map(|ice| ice.into_context_element(self, breadcrumbs));
match (left_side, right_side) { match (left_side, right_side) {
(Err(_), _) | (_, Err(_)) => { (Err(_), _) | (_, Err(_)) => {
return self.render_maybe_body( return self.render_maybe_body(
@ -553,7 +553,7 @@ impl<'a> DustRenderer<'a> {
} }
} }
DustTag::DTHelperLessThan(parameterized_block) => { DustTag::DTHelperLessThan(parameterized_block) => {
let new_breadcrumbs = Self::new_breadcrumbs_partial( let new_breadcrumbs = self.new_breadcrumbs_partial(
breadcrumbs, breadcrumbs,
breadcrumbs, breadcrumbs,
None, None,
@ -564,12 +564,12 @@ impl<'a> DustRenderer<'a> {
let left_side: Result<&dyn ContextElement, WalkError> = let left_side: Result<&dyn ContextElement, WalkError> =
match Self::get_rval(breadcrumbs, &param_map, "key") { match Self::get_rval(breadcrumbs, &param_map, "key") {
None => return Ok("".to_owned()), None => return Ok("".to_owned()),
Some(res) => res.map(|ice| ice.into_context_element(breadcrumbs)), Some(res) => res.map(|ice| ice.into_context_element(self, breadcrumbs)),
}; };
let right_side: Result<&dyn ContextElement, WalkError> = let right_side: Result<&dyn ContextElement, WalkError> =
Self::get_rval(breadcrumbs, &param_map, "value") Self::get_rval(breadcrumbs, &param_map, "value")
.unwrap_or(Err(WalkError::CantWalk)) .unwrap_or(Err(WalkError::CantWalk))
.map(|ice| ice.into_context_element(breadcrumbs)); .map(|ice| ice.into_context_element(self, breadcrumbs));
match (left_side, right_side) { match (left_side, right_side) {
(Err(_), _) | (_, Err(_)) => { (Err(_), _) | (_, Err(_)) => {
return self.render_maybe_body( return self.render_maybe_body(
@ -596,7 +596,7 @@ impl<'a> DustRenderer<'a> {
} }
} }
DustTag::DTHelperLessThanOrEquals(parameterized_block) => { DustTag::DTHelperLessThanOrEquals(parameterized_block) => {
let new_breadcrumbs = Self::new_breadcrumbs_partial( let new_breadcrumbs = self.new_breadcrumbs_partial(
breadcrumbs, breadcrumbs,
breadcrumbs, breadcrumbs,
None, None,
@ -607,12 +607,12 @@ impl<'a> DustRenderer<'a> {
let left_side: Result<&dyn ContextElement, WalkError> = let left_side: Result<&dyn ContextElement, WalkError> =
match Self::get_rval(breadcrumbs, &param_map, "key") { match Self::get_rval(breadcrumbs, &param_map, "key") {
None => return Ok("".to_owned()), None => return Ok("".to_owned()),
Some(res) => res.map(|ice| ice.into_context_element(breadcrumbs)), Some(res) => res.map(|ice| ice.into_context_element(self, breadcrumbs)),
}; };
let right_side: Result<&dyn ContextElement, WalkError> = let right_side: Result<&dyn ContextElement, WalkError> =
Self::get_rval(breadcrumbs, &param_map, "value") Self::get_rval(breadcrumbs, &param_map, "value")
.unwrap_or(Err(WalkError::CantWalk)) .unwrap_or(Err(WalkError::CantWalk))
.map(|ice| ice.into_context_element(breadcrumbs)); .map(|ice| ice.into_context_element(self, breadcrumbs));
match (left_side, right_side) { match (left_side, right_side) {
(Err(_), _) | (_, Err(_)) => { (Err(_), _) | (_, Err(_)) => {
return self.render_maybe_body( return self.render_maybe_body(
@ -707,6 +707,7 @@ impl<'a> DustRenderer<'a> {
} }
fn new_breadcrumbs_section<'b>( fn new_breadcrumbs_section<'b>(
&self,
breadcrumbs: &'b Vec<&'b dyn IntoContextElement>, breadcrumbs: &'b Vec<&'b dyn IntoContextElement>,
index_context: Option<&'b dyn IntoContextElement>, index_context: Option<&'b dyn IntoContextElement>,
injected_context: Option<&'b dyn IntoContextElement>, injected_context: Option<&'b dyn IntoContextElement>,
@ -731,7 +732,7 @@ impl<'a> DustRenderer<'a> {
}; };
explicit_context.as_ref().map(|path| { explicit_context.as_ref().map(|path| {
walk_path(breadcrumbs, &path.keys) walk_path(breadcrumbs, &path.keys)
.map(|ice| ice.into_context_element(breadcrumbs)) .map(|ice| ice.into_context_element(self, breadcrumbs))
.map(|val| { .map(|val| {
if val.is_truthy() { if val.is_truthy() {
new_stack.push(val.from_context_element()) new_stack.push(val.from_context_element())
@ -745,6 +746,7 @@ impl<'a> DustRenderer<'a> {
} }
fn new_breadcrumbs_partial<'b>( fn new_breadcrumbs_partial<'b>(
&self,
breadcrumbs: &'b Vec<&'b dyn IntoContextElement>, breadcrumbs: &'b Vec<&'b dyn IntoContextElement>,
explicit_context_breadcrumbs: &'b Vec<&'b dyn IntoContextElement>, explicit_context_breadcrumbs: &'b Vec<&'b dyn IntoContextElement>,
injected_context: Option<&'b dyn IntoContextElement>, injected_context: Option<&'b dyn IntoContextElement>,
@ -778,7 +780,7 @@ impl<'a> DustRenderer<'a> {
explicit_context.as_ref().map(|path| { explicit_context.as_ref().map(|path| {
walk_path(explicit_context_breadcrumbs, &path.keys) walk_path(explicit_context_breadcrumbs, &path.keys)
// TODO should resolving the value here use explicit_context_breadcrumbs or breadcrumbs? // TODO should resolving the value here use explicit_context_breadcrumbs or breadcrumbs?
.map(|ice| ice.into_context_element(explicit_context_breadcrumbs)) .map(|ice| ice.into_context_element(self, explicit_context_breadcrumbs))
.map(|val| { .map(|val| {
if val.is_truthy() { if val.is_truthy() {
new_stack.push(val.from_context_element()) new_stack.push(val.from_context_element())