use crate::parser::template; use crate::parser::Path; use crate::parser::Template; use crate::renderer::breadcrumb_tree::BreadcrumbTree; use crate::renderer::breadcrumb_tree::BreadcrumbTreeElement; use crate::renderer::context_element::ContextElement; use crate::renderer::context_element::IntoContextElement; use crate::renderer::errors::CompileError; use crate::renderer::tree_walking::walk_path; use std::collections::HashMap; #[derive(Clone, Debug)] pub struct CompiledTemplate<'a> { template: Template<'a>, pub name: String, } #[derive(Clone, Debug)] pub struct DustRenderer<'a> { templates: HashMap>, } pub fn compile_template<'a>( source: &'a str, name: String, ) -> Result, CompileError> { // TODO: This could use better error management let (_remaining, parsed_template) = template(source).expect("Failed to compile template"); Ok(CompiledTemplate { template: parsed_template, name: name, }) } impl<'a> DustRenderer<'a> { pub fn new() -> DustRenderer<'a> { DustRenderer { templates: HashMap::new(), } } pub fn load_source(&mut self, template: &'a CompiledTemplate) { self.templates .insert(template.name.clone(), &template.template); } /// 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>( &self, maybe_breadcrumbs: Option<&'a BreadcrumbTree>, index_context: Option<&'b dyn IntoContextElement>, injected_context: Option<&'b dyn IntoContextElement>, explicit_context: &Option>, new_context_element: Option<&'b dyn ContextElement>, ) -> Option<(Option<&'b BreadcrumbTree>, Vec>)> { // 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. match ( index_context, injected_context, explicit_context, new_context_element, ) { (None, None, None, None) => return None, _ => (), } // If there is an explicit context, then drop all the current // context let mut parent = match explicit_context { Some(_) => None, None => maybe_breadcrumbs, }; let mut new_nodes = Vec::new(); // explicit_context.as_ref().map(|path| { // let x = walk_path(maybe_breadcrumbs, &path.keys); // x.map(|ice| ice.into_context_element(self, breadcrumbs)) // .map(|val| { // if val.is_truthy() { // new_nodes.push(val.from_context_element()) // } // }); // }); injected_context.map(|ctx| new_nodes.push(BreadcrumbTreeElement::Borrowed(ctx))); new_context_element .map(|ctx| new_nodes.push(BreadcrumbTreeElement::Borrowed(ctx.from_context_element()))); index_context.map(|ctx| new_nodes.push(BreadcrumbTreeElement::Borrowed(ctx))); Some((parent, new_nodes)) } }