Update IterationContext to be an IntoContextElement and finish implementing section.
This commit is contained in:
parent
00699b84ba
commit
e28ebaf26a
@ -1,6 +1,9 @@
|
|||||||
|
use crate::renderer::breadcrumb_tree::BreadcrumbTreeElement;
|
||||||
use crate::renderer::context_element::CompareContextElement;
|
use crate::renderer::context_element::CompareContextElement;
|
||||||
use crate::renderer::context_element::ContextElement;
|
use crate::renderer::context_element::ContextElement;
|
||||||
|
use crate::renderer::context_element::IceResult;
|
||||||
use crate::renderer::context_element::IntoContextElement;
|
use crate::renderer::context_element::IntoContextElement;
|
||||||
|
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;
|
||||||
@ -16,7 +19,7 @@ use std::cmp::Ordering;
|
|||||||
/// Functions the same as the injected parameters contexts for
|
/// Functions the same as the injected parameters contexts for
|
||||||
/// helpers/partials with parameters but this has no need for storing
|
/// helpers/partials with parameters but this has no need for storing
|
||||||
/// breadcrumbs since its simply storing two integers.
|
/// breadcrumbs since its simply storing two integers.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub struct IterationContext {
|
pub struct IterationContext {
|
||||||
idx: OwnedLiteral,
|
idx: OwnedLiteral,
|
||||||
len: OwnedLiteral,
|
len: OwnedLiteral,
|
||||||
@ -32,32 +35,13 @@ impl IterationContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ContextElement for IterationContext {}
|
impl IntoContextElement for IterationContext {
|
||||||
|
fn into_context_element<'b>(
|
||||||
impl Truthiness for IterationContext {
|
&'b self,
|
||||||
fn is_truthy(&self) -> bool {
|
renderer: &DustRenderer,
|
||||||
// TODO: Would this even ever be called? Won't matter, but I'd
|
breadcrumbs: &'b Vec<BreadcrumbTreeElement<'b>>,
|
||||||
// like to know. Since it is injected 1 above the current
|
) -> Option<IceResult<'b>> {
|
||||||
// context, we wouldn't be able to access it with `{.}`.
|
panic!("into_context_element cannot be called on pseudo elements");
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Renderable for IterationContext {
|
|
||||||
fn render(&self, _filters: &Vec<Filter>) -> Result<String, RenderError> {
|
|
||||||
// TODO: Would this even ever be called? Won't matter, but I'd
|
|
||||||
// like to know. Since it is injected 1 above the current
|
|
||||||
// context, we wouldn't be able to access it with `{.}`.
|
|
||||||
Ok("[object Object]".to_owned())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Loopable for IterationContext {
|
|
||||||
fn get_loop_elements(&self) -> Vec<&dyn ContextElement> {
|
|
||||||
// TODO: Would this even ever be called? Won't matter, but I'd
|
|
||||||
// like to know. Since it is injected 1 above the current
|
|
||||||
// context, we wouldn't be able to access it with `{.}`.
|
|
||||||
Vec::new()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,15 +58,3 @@ impl Walkable for IterationContext {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompareContextElement for IterationContext {
|
|
||||||
fn equals(&self, other: &dyn ContextElement) -> bool {
|
|
||||||
// TODO: Does this ever happen? perhaps I should have a panic here.
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn partial_compare(&self, other: &dyn ContextElement) -> Option<Ordering> {
|
|
||||||
// TODO: Does this ever happen? perhaps I should have a panic here.
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -4,7 +4,7 @@ mod breadcrumb_tree;
|
|||||||
mod context_element;
|
mod context_element;
|
||||||
mod errors;
|
mod errors;
|
||||||
mod inline_partial_tree;
|
mod inline_partial_tree;
|
||||||
// mod iteration_context;
|
mod iteration_context;
|
||||||
mod parameters_context;
|
mod parameters_context;
|
||||||
mod renderer;
|
mod renderer;
|
||||||
mod tree_walking;
|
mod tree_walking;
|
||||||
|
@ -15,6 +15,7 @@ use crate::renderer::errors::RenderError;
|
|||||||
use crate::renderer::errors::WalkError;
|
use crate::renderer::errors::WalkError;
|
||||||
use crate::renderer::inline_partial_tree::extract_inline_partials;
|
use crate::renderer::inline_partial_tree::extract_inline_partials;
|
||||||
use crate::renderer::inline_partial_tree::InlinePartialTreeElement;
|
use crate::renderer::inline_partial_tree::InlinePartialTreeElement;
|
||||||
|
use crate::renderer::iteration_context::IterationContext;
|
||||||
use crate::renderer::parameters_context::ParametersContext;
|
use crate::renderer::parameters_context::ParametersContext;
|
||||||
use crate::renderer::tree_walking::walk_path;
|
use crate::renderer::tree_walking::walk_path;
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
@ -170,8 +171,7 @@ impl<'a> DustRenderer<'a> {
|
|||||||
let val = walk_path(breadcrumbs, &container.path.keys)
|
let val = walk_path(breadcrumbs, &container.path.keys)
|
||||||
.map(|ice| ice.into_context_element(self, breadcrumbs));
|
.map(|ice| ice.into_context_element(self, breadcrumbs));
|
||||||
match val {
|
match val {
|
||||||
Err(WalkError::CantWalk) => {
|
Err(WalkError::CantWalk) | Ok(None) => {
|
||||||
// TODO
|
|
||||||
let new_breadcrumbs = self.new_breadcrumbs_section(
|
let new_breadcrumbs = self.new_breadcrumbs_section(
|
||||||
breadcrumbs,
|
breadcrumbs,
|
||||||
None,
|
None,
|
||||||
@ -179,9 +179,84 @@ impl<'a> DustRenderer<'a> {
|
|||||||
&container.explicit_context,
|
&container.explicit_context,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
return self.render_maybe_body(
|
||||||
|
&container.else_contents,
|
||||||
|
new_breadcrumbs.as_ref().unwrap_or(breadcrumbs),
|
||||||
|
blocks,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Ok(final_val) => {
|
Ok(Some(final_val)) => {
|
||||||
// TODO
|
let context_element = final_val.get_context_element_reference();
|
||||||
|
return if context_element.is_truthy() {
|
||||||
|
match &container.contents {
|
||||||
|
None => Ok("".to_owned()),
|
||||||
|
Some(body) => {
|
||||||
|
let loop_elements: Vec<&dyn ContextElement> =
|
||||||
|
context_element.get_loop_elements();
|
||||||
|
if loop_elements.is_empty() {
|
||||||
|
// Scalar value
|
||||||
|
let new_breadcrumbs = self.new_breadcrumbs_section(
|
||||||
|
breadcrumbs,
|
||||||
|
None,
|
||||||
|
Some(&injected_context),
|
||||||
|
&container.explicit_context,
|
||||||
|
Some(context_element),
|
||||||
|
);
|
||||||
|
self.render_body(
|
||||||
|
body,
|
||||||
|
new_breadcrumbs.as_ref().unwrap_or(breadcrumbs),
|
||||||
|
blocks,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// Array-like value
|
||||||
|
let total_length = loop_elements.len();
|
||||||
|
let rendered_results: Result<Vec<String>, RenderError> =
|
||||||
|
loop_elements
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, array_elem)| {
|
||||||
|
let index_context =
|
||||||
|
IterationContext::new(i, total_length);
|
||||||
|
let new_breadcrumbs = self
|
||||||
|
.new_breadcrumbs_section(
|
||||||
|
breadcrumbs,
|
||||||
|
Some(&index_context),
|
||||||
|
Some(&injected_context),
|
||||||
|
&container.explicit_context,
|
||||||
|
Some(array_elem),
|
||||||
|
);
|
||||||
|
self.render_body(
|
||||||
|
&body,
|
||||||
|
new_breadcrumbs
|
||||||
|
.as_ref()
|
||||||
|
.unwrap_or(breadcrumbs),
|
||||||
|
blocks,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let rendered_slice: &[String] = &rendered_results?;
|
||||||
|
return Ok(rendered_slice.join(""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Oddly enough if the value is falsey (like
|
||||||
|
// an empty array or null), Dust uses the
|
||||||
|
// original context before walking the path as
|
||||||
|
// the context for rendering the else block
|
||||||
|
let new_breadcrumbs = self.new_breadcrumbs_section(
|
||||||
|
breadcrumbs,
|
||||||
|
None,
|
||||||
|
Some(&injected_context),
|
||||||
|
&container.explicit_context,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
self.render_maybe_body(
|
||||||
|
&container.else_contents,
|
||||||
|
new_breadcrumbs.as_ref().unwrap_or(breadcrumbs),
|
||||||
|
blocks,
|
||||||
|
)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -247,7 +322,6 @@ impl<'a> DustRenderer<'a> {
|
|||||||
injected_context: Option<&'b dyn IntoContextElement>,
|
injected_context: Option<&'b dyn IntoContextElement>,
|
||||||
explicit_context: &Option<Path<'b>>,
|
explicit_context: &Option<Path<'b>>,
|
||||||
) -> Option<Vec<BreadcrumbTreeElement<'b>>> {
|
) -> Option<Vec<BreadcrumbTreeElement<'b>>> {
|
||||||
|
|
||||||
// If none of the additional contexts are present, return None
|
// If none of the additional contexts are present, return None
|
||||||
// to signal that the original breadcrumbs should be used
|
// to signal that the original breadcrumbs should be used
|
||||||
// rather than incurring a copy here.
|
// rather than incurring a copy here.
|
||||||
@ -270,8 +344,11 @@ impl<'a> DustRenderer<'a> {
|
|||||||
// added after the current context but before the explicit
|
// added after the current context but before the explicit
|
||||||
// context.
|
// context.
|
||||||
match explicit_context {
|
match explicit_context {
|
||||||
None => new_stack.insert(Self::get_index_of_first_non_pseudo_element(&new_stack).unwrap_or(0), BreadcrumbTreeElement::from_borrowed(ctx)),
|
None => new_stack.insert(
|
||||||
_ => new_stack.push(BreadcrumbTreeElement::from_borrowed(ctx))
|
Self::get_index_of_first_non_pseudo_element(&new_stack).unwrap_or(0),
|
||||||
|
BreadcrumbTreeElement::from_borrowed(ctx),
|
||||||
|
),
|
||||||
|
_ => new_stack.push(BreadcrumbTreeElement::from_borrowed(ctx)),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -308,11 +385,12 @@ impl<'a> DustRenderer<'a> {
|
|||||||
final_filters
|
final_filters
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_index_of_first_non_pseudo_element<'b>(breadcrumbs: &'b Vec<BreadcrumbTreeElement<'b>>) -> Option<usize>
|
fn get_index_of_first_non_pseudo_element<'b>(
|
||||||
{
|
breadcrumbs: &'b Vec<BreadcrumbTreeElement<'b>>,
|
||||||
breadcrumbs
|
) -> Option<usize> {
|
||||||
.iter()
|
breadcrumbs.iter().rposition(|b| {
|
||||||
.rposition(|b| std::borrow::Borrow::<dyn IntoContextElement + 'b>::borrow(b).is_pseudo_element())
|
std::borrow::Borrow::<dyn IntoContextElement + 'b>::borrow(b).is_pseudo_element()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user