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
	 Tom Alexander
						Tom Alexander