Switching back to a Vec because inserting multiple elements into the linked list structure while maintaining ownership of each node proved to be difficult.

master
Tom Alexander 4 years ago
parent 78bffb5f04
commit 71592a9a32
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE

@ -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…
Cancel
Save