Switching back to a Vec because inserting multiple elements into the linked list structure while maintaining ownership of each node proved to be difficult.
This commit is contained in:
parent
78bffb5f04
commit
71592a9a32
@ -5,11 +5,6 @@ use crate::renderer::context_element::IntoRcIce;
|
||||
use std::borrow::Borrow;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct BreadcrumbTree<'a> {
|
||||
parent: Option<&'a BreadcrumbTree<'a>>,
|
||||
element: BreadcrumbTreeElement<'a>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum BreadcrumbTreeElement<'a> {
|
||||
// Using Rc so that when we need to create BreadcrumbTrees with
|
||||
@ -54,43 +49,6 @@ impl<'a> From<IceResult<'a>> for BreadcrumbTreeElement<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> BreadcrumbTree<'a> {
|
||||
pub fn new(parent: Option<&'a BreadcrumbTree>, element: BreadcrumbTreeElement<'a>) -> Self {
|
||||
BreadcrumbTree {
|
||||
parent: parent,
|
||||
element: element,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_ice(&self) -> &dyn IntoContextElement {
|
||||
self.element.borrow()
|
||||
}
|
||||
|
||||
pub fn get_parent(&self) -> Option<&BreadcrumbTree> {
|
||||
self.parent
|
||||
}
|
||||
|
||||
pub fn get_element(&self) -> &BreadcrumbTreeElement<'a> {
|
||||
&self.element
|
||||
}
|
||||
|
||||
pub fn ice_iter(&'a self) -> impl Iterator<Item = &dyn IntoContextElement> {
|
||||
self.breadcrumb_iter().map(|b| b.get_ice())
|
||||
}
|
||||
|
||||
pub fn breadcrumb_iter(&'a self) -> BreadcrumbTreeIterator<'a> {
|
||||
BreadcrumbTreeIterator(Some(self))
|
||||
}
|
||||
|
||||
pub fn clone_to_new_parent(&self, parent: Option<&'a BreadcrumbTree>) -> Self {
|
||||
// TODO: Maybe not needed anymore?
|
||||
BreadcrumbTree {
|
||||
parent: parent,
|
||||
element: self.element.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Borrow<dyn IntoContextElement + 'a> for BreadcrumbTreeElement<'a> {
|
||||
fn borrow(&self) -> &(dyn IntoContextElement + 'a) {
|
||||
match self {
|
||||
@ -99,24 +57,3 @@ impl<'a> Borrow<dyn IntoContextElement + 'a> for BreadcrumbTreeElement<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for &'a BreadcrumbTree<'a> {
|
||||
type Item = &'a BreadcrumbTree<'a>;
|
||||
type IntoIter = BreadcrumbTreeIterator<'a>;
|
||||
|
||||
fn into_iter(self) -> BreadcrumbTreeIterator<'a> {
|
||||
self.breadcrumb_iter()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BreadcrumbTreeIterator<'a>(Option<&'a BreadcrumbTree<'a>>);
|
||||
|
||||
impl<'a> Iterator for BreadcrumbTreeIterator<'a> {
|
||||
type Item = &'a BreadcrumbTree<'a>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let ret = self.0;
|
||||
self.0 = self.0.map(|node| node.get_parent()).flatten();
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::parser::Filter;
|
||||
use crate::renderer::breadcrumb_tree::BreadcrumbTree;
|
||||
use crate::renderer::breadcrumb_tree::BreadcrumbTreeElement;
|
||||
use crate::renderer::errors::RenderError;
|
||||
use crate::renderer::errors::WalkError;
|
||||
use crate::renderer::DustRenderer;
|
||||
@ -106,7 +106,7 @@ pub trait IntoContextElement: Debug + Walkable /* + CloneIntoBoxedContextElement
|
||||
fn into_context_element<'a>(
|
||||
&'a self,
|
||||
renderer: &DustRenderer,
|
||||
breadcrumbs: Option<&'a BreadcrumbTree<'a>>,
|
||||
breadcrumbs: &'a Vec<BreadcrumbTreeElement<'a>>,
|
||||
) -> Option<IceResult<'a>>;
|
||||
}
|
||||
|
||||
@ -114,7 +114,7 @@ impl<C: ContextElement> IntoContextElement for C {
|
||||
fn into_context_element<'a>(
|
||||
&'a self,
|
||||
renderer: &DustRenderer,
|
||||
breadcrumbs: Option<&'a BreadcrumbTree<'a>>,
|
||||
breadcrumbs: &'a Vec<BreadcrumbTreeElement<'a>>,
|
||||
) -> Option<IceResult<'a>> {
|
||||
Some(IceResult::from_borrowed(self))
|
||||
}
|
||||
@ -161,7 +161,7 @@ impl<'a> IntoContextElement for IceResult<'a> {
|
||||
fn into_context_element<'b>(
|
||||
&'b self,
|
||||
renderer: &DustRenderer,
|
||||
breadcrumbs: Option<&'b BreadcrumbTree<'b>>,
|
||||
breadcrumbs: &'b Vec<BreadcrumbTreeElement<'b>>,
|
||||
) -> Option<IceResult<'b>> {
|
||||
match self {
|
||||
IceResult::Owned(rc_ce) => Some(IceResult::from_borrowed(rc_ce.as_ref())),
|
||||
|
@ -2,7 +2,6 @@ use crate::parser::Filter;
|
||||
use crate::parser::KVPair;
|
||||
use crate::parser::OwnedLiteral;
|
||||
use crate::parser::RValue;
|
||||
use crate::renderer::breadcrumb_tree::BreadcrumbTree;
|
||||
use crate::renderer::breadcrumb_tree::BreadcrumbTreeElement;
|
||||
use crate::renderer::context_element::CompareContextElement;
|
||||
use crate::renderer::context_element::ContextElement;
|
||||
@ -29,7 +28,7 @@ pub struct ParametersContext<'a> {
|
||||
impl<'a> ParametersContext<'a> {
|
||||
pub fn new(
|
||||
renderer: &DustRenderer,
|
||||
breadcrumbs: Option<&'a BreadcrumbTree>,
|
||||
breadcrumbs: &'a Vec<BreadcrumbTreeElement<'a>>,
|
||||
params: &'a Vec<KVPair>,
|
||||
) -> Self {
|
||||
// If the parameter is a Path, then we resolve it immediately
|
||||
@ -72,7 +71,7 @@ impl<'a> IntoContextElement for ParametersContext<'a> {
|
||||
fn into_context_element<'b>(
|
||||
&'b self,
|
||||
renderer: &DustRenderer,
|
||||
breadcrumbs: Option<&'b BreadcrumbTree<'b>>,
|
||||
breadcrumbs: &'b Vec<BreadcrumbTreeElement<'b>>,
|
||||
) -> Option<IceResult<'b>> {
|
||||
panic!("into_context_element cannot be called on pseudo elements");
|
||||
}
|
||||
@ -95,7 +94,7 @@ impl<'a> IntoContextElement for RValue<'a> {
|
||||
fn into_context_element<'b>(
|
||||
&'b self,
|
||||
renderer: &DustRenderer,
|
||||
breadcrumbs: Option<&'b BreadcrumbTree<'b>>,
|
||||
breadcrumbs: &'b Vec<BreadcrumbTreeElement<'b>>,
|
||||
) -> Option<IceResult<'b>> {
|
||||
match self {
|
||||
RValue::RVLiteral(owned_literal) => Some(IceResult::from_borrowed(owned_literal)),
|
||||
|
@ -7,7 +7,6 @@ use crate::parser::Path;
|
||||
use crate::parser::Special;
|
||||
use crate::parser::Template;
|
||||
use crate::parser::TemplateElement;
|
||||
use crate::renderer::breadcrumb_tree::BreadcrumbTree;
|
||||
use crate::renderer::breadcrumb_tree::BreadcrumbTreeElement;
|
||||
use crate::renderer::context_element::ContextElement;
|
||||
use crate::renderer::context_element::IntoContextElement;
|
||||
@ -49,15 +48,16 @@ impl<'a> DustRenderer<'a> {
|
||||
where
|
||||
C: IntoContextElement,
|
||||
{
|
||||
let breadcrumbs =
|
||||
context.map(|ctx| BreadcrumbTree::new(None, BreadcrumbTreeElement::from_borrowed(ctx)));
|
||||
let breadcrumbs = context
|
||||
.map(|ctx| vec![BreadcrumbTreeElement::from_borrowed(ctx)])
|
||||
.unwrap_or(Vec::new());
|
||||
self.render_template(name, breadcrumbs.as_ref(), None)
|
||||
}
|
||||
|
||||
pub fn render_template(
|
||||
&'a self,
|
||||
name: &str,
|
||||
breadcrumbs: Option<&'a BreadcrumbTree>,
|
||||
breadcrumbs: &'a Vec<BreadcrumbTreeElement<'a>>,
|
||||
blocks: Option<&'a InlinePartialTreeElement<'a>>,
|
||||
) -> Result<String, RenderError> {
|
||||
let main_template = match self.templates.get(name) {
|
||||
@ -78,7 +78,7 @@ impl<'a> DustRenderer<'a> {
|
||||
fn render_maybe_body(
|
||||
&'a self,
|
||||
body: &'a Option<Body>,
|
||||
breadcrumbs: Option<&'a BreadcrumbTree>,
|
||||
breadcrumbs: &'a Vec<BreadcrumbTreeElement<'a>>,
|
||||
blocks: &'a BlockContext<'a>,
|
||||
) -> Result<String, RenderError> {
|
||||
match body {
|
||||
@ -90,7 +90,7 @@ impl<'a> DustRenderer<'a> {
|
||||
fn render_body(
|
||||
&'a self,
|
||||
body: &'a Body,
|
||||
breadcrumbs: Option<&'a BreadcrumbTree>,
|
||||
breadcrumbs: &'a Vec<BreadcrumbTreeElement<'a>>,
|
||||
blocks: &'a BlockContext<'a>,
|
||||
) -> Result<String, RenderError> {
|
||||
let mut output = String::new();
|
||||
@ -110,7 +110,7 @@ impl<'a> DustRenderer<'a> {
|
||||
pub fn render_partial_name(
|
||||
&'a self,
|
||||
body: &'a Vec<PartialNameElement>,
|
||||
breadcrumbs: Option<&'a BreadcrumbTree>,
|
||||
breadcrumbs: &'a Vec<BreadcrumbTreeElement<'a>>,
|
||||
) -> Result<String, RenderError> {
|
||||
let converted_to_template_elements: Vec<TemplateElement<'a>> =
|
||||
body.into_iter().map(|e| e.into()).collect();
|
||||
@ -118,7 +118,7 @@ impl<'a> DustRenderer<'a> {
|
||||
// cannot contain blocks or inline partials, so we use a blank
|
||||
// BlockContext.
|
||||
let empty_block_context = BlockContext {
|
||||
breadcrumbs: None,
|
||||
breadcrumbs: &Vec::new(),
|
||||
blocks: &InlinePartialTreeElement::new(None, HashMap::new()),
|
||||
};
|
||||
self.render_body(
|
||||
@ -133,7 +133,7 @@ impl<'a> DustRenderer<'a> {
|
||||
fn render_tag(
|
||||
&'a self,
|
||||
tag: &'a DustTag,
|
||||
breadcrumbs: Option<&'a BreadcrumbTree>,
|
||||
breadcrumbs: &'a Vec<BreadcrumbTreeElement<'a>>,
|
||||
blocks: &'a BlockContext<'a>,
|
||||
) -> Result<String, RenderError> {
|
||||
match tag {
|
||||
@ -190,23 +190,15 @@ impl<'a> DustRenderer<'a> {
|
||||
Ok("".to_owned())
|
||||
}
|
||||
|
||||
/// Returns a option of a tuple of (parent, new_node_elements)
|
||||
/// which can then be formed into new BreadcrumbTreeNodes
|
||||
///
|
||||
/// If None is returned, then it is a signal to simply re-use the
|
||||
/// existing breadcrumbs.
|
||||
///
|
||||
/// Otherwise, the parent (which may be None, especially for
|
||||
/// explicit contexts) and the additional node elements (which may
|
||||
/// be empty) should be combined into a final BreadcrumbTreeNode
|
||||
fn new_breadcrumbs_section<'b>(
|
||||
&'b self,
|
||||
maybe_breadcrumbs: Option<&'b BreadcrumbTree>,
|
||||
maybe_breadcrumbs: &'b Vec<BreadcrumbTreeElement<'b>>,
|
||||
index_context: Option<&'b dyn IntoContextElement>,
|
||||
injected_context: Option<&'b dyn IntoContextElement>,
|
||||
explicit_context: &Option<Path<'b>>,
|
||||
new_context_element: Option<&'b dyn ContextElement>,
|
||||
) -> Option<(Option<&'b BreadcrumbTree>, Vec<BreadcrumbTreeElement<'b>>)> {
|
||||
) {
|
||||
/*
|
||||
// If none of the additional contexts are present, return None
|
||||
// to signal that the original breadcrumbs should be used
|
||||
// rather than incurring a copy here.
|
||||
@ -248,24 +240,18 @@ impl<'a> DustRenderer<'a> {
|
||||
index_context.map(|ctx| new_nodes.push(BreadcrumbTreeElement::from_borrowed(ctx)));
|
||||
|
||||
Some((parent, new_nodes))
|
||||
*/
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Returns a option of a tuple of (parent, new_node_elements)
|
||||
/// which can then be formed into new BreadcrumbTreeNodes
|
||||
///
|
||||
/// If None is returned, then it is a signal to simply re-use the
|
||||
/// existing breadcrumbs.
|
||||
///
|
||||
/// Otherwise, the parent (which may be None, especially for
|
||||
/// explicit contexts) and the additional node elements (which may
|
||||
/// be empty) should be combined into a final BreadcrumbTreeNode
|
||||
fn new_breadcrumbs_partial<'b>(
|
||||
&'b self,
|
||||
maybe_breadcrumbs: Option<&'b BreadcrumbTree>,
|
||||
explicit_context_maybe_breadcrumbs: Option<&'b BreadcrumbTree>,
|
||||
maybe_breadcrumbs: &'b Vec<BreadcrumbTreeElement<'b>>,
|
||||
explicit_context_maybe_breadcrumbs: &'a Vec<BreadcrumbTreeElement<'a>>,
|
||||
injected_context: Option<&'b dyn IntoContextElement>,
|
||||
explicit_context: &Option<Path<'b>>,
|
||||
) -> Option<(Option<&'b BreadcrumbTree>, Vec<BreadcrumbTreeElement<'b>>)> {
|
||||
) {
|
||||
/*
|
||||
// If none of the additional contexts are present, return None
|
||||
// to signal that the original breadcrumbs should be used
|
||||
// rather than incurring a copy here.
|
||||
@ -313,33 +299,8 @@ impl<'a> DustRenderer<'a> {
|
||||
});
|
||||
});
|
||||
|
||||
Some((parent, new_nodes))
|
||||
}
|
||||
|
||||
/// Returns a Breadcrumb tree where all the bottom nodes that do
|
||||
/// not match the predicate and the first node that match the
|
||||
/// predicate are shaved off, and a list of those nodes that are
|
||||
/// shaved off.
|
||||
fn split_tree_at_predicate<'b, F>(
|
||||
maybe_breadcrumbs: Option<&'b BreadcrumbTree>,
|
||||
f: F,
|
||||
) -> (Option<&'b BreadcrumbTree<'b>>, Vec<&'b BreadcrumbTree<'b>>)
|
||||
where
|
||||
F: Fn(&'b BreadcrumbTree) -> bool,
|
||||
{
|
||||
match maybe_breadcrumbs {
|
||||
None => return (None, Vec::new()),
|
||||
Some(breadcrumbs) => {
|
||||
let mut passed_nodes: Vec<&'b BreadcrumbTree<'b>> = Vec::new();
|
||||
for tree_node in breadcrumbs {
|
||||
passed_nodes.push(tree_node);
|
||||
if f(tree_node) {
|
||||
return (tree_node.get_parent(), passed_nodes);
|
||||
}
|
||||
}
|
||||
return (None, passed_nodes);
|
||||
}
|
||||
}
|
||||
Some((parent, new_nodes))*/
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn preprocess_filters(filters: &Vec<Filter>) -> Vec<Filter> {
|
||||
@ -360,6 +321,6 @@ impl<'a> DustRenderer<'a> {
|
||||
|
||||
struct BlockContext<'a> {
|
||||
/// The breadcrumbs at the time of entering the current partial
|
||||
breadcrumbs: Option<&'a BreadcrumbTree<'a>>,
|
||||
breadcrumbs: &'a Vec<BreadcrumbTreeElement<'a>>,
|
||||
blocks: &'a InlinePartialTreeElement<'a>,
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::renderer::breadcrumb_tree::BreadcrumbTree;
|
||||
use crate::renderer::breadcrumb_tree::BreadcrumbTreeElement;
|
||||
use crate::renderer::context_element::IntoContextElement;
|
||||
use crate::renderer::WalkError;
|
||||
use std::borrow::Borrow;
|
||||
@ -38,25 +38,34 @@ where
|
||||
}
|
||||
|
||||
fn get_first_non_pseudo_element<'a>(
|
||||
breadcrumbs: &'a BreadcrumbTree,
|
||||
) -> Option<&'a BreadcrumbTree<'a>> {
|
||||
breadcrumbs: &'a Vec<BreadcrumbTreeElement<'a>>,
|
||||
) -> Option<&'a BreadcrumbTreeElement<'a>> {
|
||||
breadcrumbs
|
||||
.breadcrumb_iter()
|
||||
.filter(|b| b.get_ice().is_pseudo_element())
|
||||
.iter()
|
||||
.rev()
|
||||
.filter(|b| {
|
||||
std::borrow::Borrow::<dyn IntoContextElement + 'a>::borrow(*b).is_pseudo_element()
|
||||
})
|
||||
.next()
|
||||
}
|
||||
|
||||
pub fn walk_path<'a, P>(
|
||||
maybe_breadcrumbs: Option<&'a BreadcrumbTree>,
|
||||
breadcrumbs: &'a Vec<BreadcrumbTreeElement<'a>>,
|
||||
path: &Vec<P>,
|
||||
) -> Result<&'a dyn IntoContextElement, WalkError>
|
||||
where
|
||||
P: Borrow<str>,
|
||||
{
|
||||
match (maybe_breadcrumbs, path.first()) {
|
||||
(None, _) => return Err(WalkError::CantWalk),
|
||||
(Some(breadcrumbs), None) => return Ok(breadcrumbs.get_ice()),
|
||||
(Some(breadcrumbs), Some(path_first)) if path_first.borrow() == "." => {
|
||||
/*
|
||||
match (breadcrumbs.is_empty(), path.first()) {
|
||||
(true, _) => return Err(WalkError::CantWalk),
|
||||
(false, None) => {
|
||||
return breadcrumbs
|
||||
.last()
|
||||
.map(|bte| bte.borrow())
|
||||
.ok_or(WalkError::CantWalk)
|
||||
}
|
||||
(false, Some(path_first)) if path_first.borrow() == "." => {
|
||||
let first_non_pseudo_element = get_first_non_pseudo_element(breadcrumbs);
|
||||
return match first_non_pseudo_element {
|
||||
None => Err(WalkError::CantWalk),
|
||||
@ -71,7 +80,7 @@ where
|
||||
}
|
||||
};
|
||||
}
|
||||
(Some(breadcrumbs), Some(path_first)) => {
|
||||
(false, Some(path_first)) => {
|
||||
for context in breadcrumbs.ice_iter() {
|
||||
match walk_path_from_single_level(context, path) {
|
||||
// If no walking was done at all, keep looping
|
||||
@ -88,4 +97,6 @@ where
|
||||
}
|
||||
|
||||
Err(WalkError::CantWalk)
|
||||
*/
|
||||
todo!()
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user