Remove unused code and clean up warnings.
This commit is contained in:
		
							parent
							
								
									4ab311c178
								
							
						
					
					
						commit
						d06fbea288
					
				
							
								
								
									
										44
									
								
								src/bin.rs
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								src/bin.rs
									
									
									
									
									
								
							| @ -312,7 +312,6 @@ impl Loopable for serde_json::Value { | ||||
| 
 | ||||
| impl CompareContextElement for serde_json::Value { | ||||
|     fn equals(&self, other: &dyn ContextElement) -> bool { | ||||
|         // println!("equals json {:?} | {:?}", self, other);
 | ||||
|         // Handle other serde_json::Value
 | ||||
|         match other.to_any().downcast_ref::<Self>() { | ||||
|             None => (), | ||||
| @ -340,7 +339,6 @@ impl CompareContextElement for serde_json::Value { | ||||
|     } | ||||
| 
 | ||||
|     fn partial_compare(&self, other: &dyn ContextElement) -> Option<Ordering> { | ||||
|         // println!("partial_compare json {:?} | {:?}", self, other);
 | ||||
|         // Handle type coerced objects
 | ||||
| 
 | ||||
|         // When doing a greater than or less than comparison,
 | ||||
| @ -383,9 +381,10 @@ impl CompareContextElement for serde_json::Value { | ||||
|                         serde_json::Value::String(other_string), | ||||
|                     ) => self_string.partial_cmp(other_string), | ||||
|                     ( | ||||
|                         serde_json::Value::Array(self_array), | ||||
|                         serde_json::Value::Array(other_array), | ||||
|                         serde_json::Value::Array(_self_array), | ||||
|                         serde_json::Value::Array(_other_array), | ||||
|                     ) => { | ||||
|                         // TODO: is this reachable given the early convert to string before this block?
 | ||||
|                         return self | ||||
|                             .render(&Vec::new()) | ||||
|                             .unwrap_or("".to_owned()) | ||||
| @ -393,7 +392,7 @@ impl CompareContextElement for serde_json::Value { | ||||
|                                 &other_json_value | ||||
|                                     .render(&Vec::new()) | ||||
|                                     .unwrap_or("".to_owned()), | ||||
|                             ) | ||||
|                             ); | ||||
|                     } | ||||
|                     _ => None, | ||||
|                 }; | ||||
| @ -408,14 +407,14 @@ impl CompareContextElement for serde_json::Value { | ||||
|                 } | ||||
|                 ( | ||||
|                     serde_json::Value::String(self_string), | ||||
|                     OwnedLiteral::LPositiveInteger(other_num), | ||||
|                     OwnedLiteral::LPositiveInteger(_other_num), | ||||
|                 ) => return compare_json_numbers(self_string, other_literal), | ||||
|                 (serde_json::Value::Number(self_num), OwnedLiteral::LString(other_string)) => { | ||||
|                     return compare_json_numbers(self_num, other_string) | ||||
|                 } | ||||
|                 ( | ||||
|                     serde_json::Value::Number(self_num), | ||||
|                     OwnedLiteral::LPositiveInteger(other_num), | ||||
|                     OwnedLiteral::LPositiveInteger(_other_num), | ||||
|                 ) => return compare_json_numbers(self_num, other_literal), | ||||
|                 (serde_json::Value::Array(_), _) => { | ||||
|                     // TODO
 | ||||
| @ -439,20 +438,6 @@ impl CompareContextElement for serde_json::Value { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// Create a new vec by of references to the serde_json::Values as
 | ||||
| /// ContextElement trait objects so we can use its implementation of
 | ||||
| /// PartialOrd.
 | ||||
| ///
 | ||||
| /// You cannot implement a trait you do not define for a type you do
 | ||||
| /// not define, so I cannot implement PartialOrd for
 | ||||
| /// serde_json::value. Instead, I just re-use the PartialOrd
 | ||||
| /// implementation for ContextElement which unfortunately has extra
 | ||||
| /// overhead of downcasting. This would be a good spot for
 | ||||
| /// optimization.
 | ||||
| fn convert_vec_to_context_element(array: &Vec<serde_json::Value>) -> Vec<&dyn ContextElement> { | ||||
|     array.iter().map(|v| v as _).collect() | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| enum JsonNumber { | ||||
|     UnsignedInteger(u64), | ||||
| @ -518,10 +503,6 @@ where | ||||
| { | ||||
|     let self_number: JsonNumber = self_input.into(); | ||||
|     let other_number: JsonNumber = other_input.into(); | ||||
|     // println!(
 | ||||
|     //     "compare_number_and_string {:?} | {:?}",
 | ||||
|     //     self_number, other_number
 | ||||
|     // );
 | ||||
|     // TODO: Figure out how javascript compares floats and ints
 | ||||
|     match (self_number, other_number) { | ||||
|         (JsonNumber::Failure, _) => return None, | ||||
| @ -529,26 +510,25 @@ where | ||||
|         (JsonNumber::UnsignedInteger(self_num), JsonNumber::UnsignedInteger(other_num)) => { | ||||
|             return self_num.partial_cmp(&other_num) | ||||
|         } | ||||
|         (JsonNumber::UnsignedInteger(self_num), JsonNumber::SignedInteger(other_num)) => { | ||||
|         (JsonNumber::UnsignedInteger(_self_num), JsonNumber::SignedInteger(_other_num)) => { | ||||
|             return Some(Ordering::Greater) | ||||
|         } | ||||
|         (JsonNumber::UnsignedInteger(self_num), JsonNumber::Decimal(other_num)) => return None, | ||||
|         (JsonNumber::UnsignedInteger(_self_num), JsonNumber::Decimal(_other_num)) => return None, | ||||
| 
 | ||||
|         (JsonNumber::SignedInteger(self_num), JsonNumber::UnsignedInteger(other_num)) => { | ||||
|         (JsonNumber::SignedInteger(_self_num), JsonNumber::UnsignedInteger(_other_num)) => { | ||||
|             return Some(Ordering::Less) | ||||
|         } | ||||
|         (JsonNumber::SignedInteger(self_num), JsonNumber::SignedInteger(other_num)) => { | ||||
|             return self_num.partial_cmp(&other_num) | ||||
|         } | ||||
|         (JsonNumber::SignedInteger(self_num), JsonNumber::Decimal(other_num)) => return None, | ||||
|         (JsonNumber::SignedInteger(_self_num), JsonNumber::Decimal(_other_num)) => return None, | ||||
| 
 | ||||
|         (JsonNumber::Decimal(self_num), JsonNumber::UnsignedInteger(other_num)) => return None, | ||||
|         (JsonNumber::Decimal(self_num), JsonNumber::SignedInteger(other_num)) => return None, | ||||
|         (JsonNumber::Decimal(_self_num), JsonNumber::UnsignedInteger(_other_num)) => return None, | ||||
|         (JsonNumber::Decimal(_self_num), JsonNumber::SignedInteger(_other_num)) => return None, | ||||
|         (JsonNumber::Decimal(self_num), JsonNumber::Decimal(other_num)) => { | ||||
|             return self_num.partial_cmp(&other_num) | ||||
|         } | ||||
|     } | ||||
|     None | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
|  | ||||
| @ -2,7 +2,7 @@ use nom::branch::alt; | ||||
| use nom::bytes::complete::escaped_transform; | ||||
| use nom::bytes::complete::is_a; | ||||
| use nom::bytes::complete::is_not; | ||||
| use nom::bytes::complete::{tag, take_until, take_until_parser_matches, take_while}; | ||||
| use nom::bytes::complete::{tag, take_until, take_until_parser_matches}; | ||||
| use nom::character::complete::line_ending; | ||||
| use nom::character::complete::multispace0; | ||||
| use nom::character::complete::one_of; | ||||
|  | ||||
| @ -1,7 +1,5 @@ | ||||
| use crate::renderer::context_element::ContextElement; | ||||
| use crate::renderer::context_element::IceResult; | ||||
| use crate::renderer::context_element::IntoContextElement; | ||||
| use crate::renderer::context_element::IntoRcIce; | ||||
| use std::borrow::Borrow; | ||||
| use std::rc::Rc; | ||||
| 
 | ||||
|  | ||||
| @ -113,8 +113,8 @@ pub trait IntoContextElement: Debug + Walkable /* + CloneIntoBoxedContextElement | ||||
| impl<C: ContextElement> IntoContextElement for C { | ||||
|     fn into_context_element<'a>( | ||||
|         &'a self, | ||||
|         renderer: &DustRenderer, | ||||
|         breadcrumbs: &'a Vec<BreadcrumbTreeElement<'a>>, | ||||
|         _renderer: &DustRenderer, | ||||
|         _breadcrumbs: &'a Vec<BreadcrumbTreeElement<'a>>, | ||||
|     ) -> Option<IceResult<'a>> { | ||||
|         Some(IceResult::from_borrowed(self)) | ||||
|     } | ||||
| @ -160,8 +160,8 @@ impl<'a> IceResult<'a> { | ||||
| impl<'a> IntoContextElement for IceResult<'a> { | ||||
|     fn into_context_element<'b>( | ||||
|         &'b self, | ||||
|         renderer: &DustRenderer, | ||||
|         breadcrumbs: &'b Vec<BreadcrumbTreeElement<'b>>, | ||||
|         _renderer: &DustRenderer, | ||||
|         _breadcrumbs: &'b Vec<BreadcrumbTreeElement<'b>>, | ||||
|     ) -> Option<IceResult<'b>> { | ||||
|         match self { | ||||
|             IceResult::Owned(rc_ce) => Some(IceResult::from_borrowed(rc_ce.as_ref())), | ||||
|  | ||||
| @ -48,7 +48,7 @@ fn extract_inline_partials_from_body<'a, 'b>( | ||||
|     for elem in &body.elements { | ||||
|         match elem { | ||||
|             TemplateElement::TEIgnoredWhitespace(_) => (), | ||||
|             TemplateElement::TESpan(span) => (), | ||||
|             TemplateElement::TESpan(_span) => (), | ||||
|             TemplateElement::TETag(dt) => { | ||||
|                 extract_inline_partials_from_tag(blocks, dt); | ||||
|             } | ||||
|  | ||||
| @ -1,19 +1,11 @@ | ||||
| use crate::renderer::breadcrumb_tree::BreadcrumbTreeElement; | ||||
| use crate::renderer::context_element::CompareContextElement; | ||||
| use crate::renderer::context_element::ContextElement; | ||||
| use crate::renderer::context_element::IceResult; | ||||
| use crate::renderer::context_element::IntoContextElement; | ||||
| use crate::renderer::DustRenderer; | ||||
| use crate::renderer::Loopable; | ||||
| use crate::renderer::RenderError; | ||||
| use crate::renderer::Renderable; | ||||
| use crate::renderer::Truthiness; | ||||
| use crate::renderer::WalkError; | ||||
| use crate::{parser::Filter, parser::OwnedLiteral, renderer::Walkable}; | ||||
| use crate::{parser::OwnedLiteral, renderer::Walkable}; | ||||
| use std::convert::TryInto; | ||||
| 
 | ||||
| use std::cmp::Ordering; | ||||
| 
 | ||||
| /// An injected context for $idx and $len
 | ||||
| ///
 | ||||
| /// Functions the same as the injected parameters contexts for
 | ||||
| @ -38,8 +30,8 @@ impl IterationContext { | ||||
| impl IntoContextElement for IterationContext { | ||||
|     fn into_context_element<'b>( | ||||
|         &'b self, | ||||
|         renderer: &DustRenderer, | ||||
|         breadcrumbs: &'b Vec<BreadcrumbTreeElement<'b>>, | ||||
|         _renderer: &DustRenderer, | ||||
|         _breadcrumbs: &'b Vec<BreadcrumbTreeElement<'b>>, | ||||
|     ) -> Option<IceResult<'b>> { | ||||
|         panic!("into_context_element cannot be called on pseudo elements"); | ||||
|     } | ||||
|  | ||||
| @ -7,7 +7,6 @@ mod inline_partial_tree; | ||||
| mod iteration_context; | ||||
| mod parameters_context; | ||||
| mod renderer; | ||||
| mod tree_walking; | ||||
| mod walking; | ||||
| 
 | ||||
| // pub use context_element::CloneIntoBoxedContextElement;
 | ||||
|  | ||||
| @ -7,7 +7,7 @@ use crate::renderer::context_element::CompareContextElement; | ||||
| use crate::renderer::context_element::ContextElement; | ||||
| use crate::renderer::context_element::IceResult; | ||||
| use crate::renderer::context_element::IntoContextElement; | ||||
| use crate::renderer::tree_walking::walk_path; | ||||
| use crate::renderer::walking::walk_path; | ||||
| use crate::renderer::DustRenderer; | ||||
| use crate::renderer::Loopable; | ||||
| use crate::renderer::RenderError; | ||||
| @ -18,7 +18,6 @@ use crate::renderer::Walkable; | ||||
| use std::borrow::Borrow; | ||||
| use std::cmp::Ordering; | ||||
| use std::collections::HashMap; | ||||
| use std::rc::Rc; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct ParametersContext<'a> { | ||||
| @ -45,14 +44,14 @@ impl<'a> ParametersContext<'a> { | ||||
|                 .map(|kvpair| { | ||||
|                     let k = kvpair.key; | ||||
|                     let v: Option<BreadcrumbTreeElement<'a>> = match &kvpair.value { | ||||
|                         RValue::RVLiteral(owned_literal) => { | ||||
|                         RValue::RVLiteral(_owned_literal) => { | ||||
|                             Some(BreadcrumbTreeElement::from_borrowed(&kvpair.value)) | ||||
|                         } | ||||
|                         RValue::RVPath(path) => kvpair | ||||
|                         RValue::RVPath(_path) => kvpair | ||||
|                             .value | ||||
|                             .into_context_element(renderer, breadcrumbs) | ||||
|                             .map(std::convert::From::from), | ||||
|                         RValue::RVTemplate(template) => { | ||||
|                         RValue::RVTemplate(_template) => { | ||||
|                             Some(BreadcrumbTreeElement::from_borrowed(&kvpair.value)) | ||||
|                         } | ||||
|                     }; | ||||
| @ -65,10 +64,6 @@ impl<'a> ParametersContext<'a> { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_original_rvalue(&self, segment: &str) -> Option<&'a RValue<'a>> { | ||||
|         self.params.get(segment).map(|(rvalue, _bte)| *rvalue) | ||||
|     } | ||||
| 
 | ||||
|     pub fn contains_key(&self, segment: &str) -> bool { | ||||
|         self.params.contains_key(segment) | ||||
|     } | ||||
| @ -77,8 +72,8 @@ impl<'a> ParametersContext<'a> { | ||||
| impl<'a> IntoContextElement for ParametersContext<'a> { | ||||
|     fn into_context_element<'b>( | ||||
|         &'b self, | ||||
|         renderer: &DustRenderer, | ||||
|         breadcrumbs: &'b Vec<BreadcrumbTreeElement<'b>>, | ||||
|         _renderer: &DustRenderer, | ||||
|         _breadcrumbs: &'b Vec<BreadcrumbTreeElement<'b>>, | ||||
|     ) -> Option<IceResult<'b>> { | ||||
|         panic!("into_context_element cannot be called on pseudo elements"); | ||||
|     } | ||||
| @ -119,7 +114,7 @@ impl<'a> IntoContextElement for RValue<'a> { | ||||
| } | ||||
| 
 | ||||
| impl<'a> Walkable for RValue<'a> { | ||||
|     fn walk(&self, segment: &str) -> Result<&dyn IntoContextElement, WalkError> { | ||||
|     fn walk(&self, _segment: &str) -> Result<&dyn IntoContextElement, WalkError> { | ||||
|         Err(WalkError::CantWalk) | ||||
|     } | ||||
| } | ||||
| @ -130,7 +125,7 @@ impl Truthiness for OwnedLiteral { | ||||
|     fn is_truthy(&self) -> bool { | ||||
|         match self { | ||||
|             OwnedLiteral::LString(text) => !text.is_empty(), | ||||
|             OwnedLiteral::LPositiveInteger(num) => true, | ||||
|             OwnedLiteral::LPositiveInteger(_num) => true, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -151,14 +146,13 @@ impl Loopable for OwnedLiteral { | ||||
| } | ||||
| 
 | ||||
| impl Walkable for OwnedLiteral { | ||||
|     fn walk(&self, segment: &str) -> Result<&dyn IntoContextElement, WalkError> { | ||||
|     fn walk(&self, _segment: &str) -> Result<&dyn IntoContextElement, WalkError> { | ||||
|         Err(WalkError::CantWalk) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl CompareContextElement for OwnedLiteral { | ||||
|     fn equals(&self, other: &dyn ContextElement) -> bool { | ||||
|         // println!("equals literal {:?} | {:?}", self, other);
 | ||||
|         // If its an OwnedLiteral then compare them directly,
 | ||||
|         // otherwise defer to the other type's implementation of
 | ||||
|         // CompareContextElement since the end user could add any
 | ||||
| @ -184,7 +178,6 @@ impl CompareContextElement for OwnedLiteral { | ||||
|     } | ||||
| 
 | ||||
|     fn partial_compare(&self, other: &dyn ContextElement) -> Option<Ordering> { | ||||
|         // println!("partial_compare literal {:?} | {:?}", self, other);
 | ||||
|         // If its an OwnedLiteral then compare them directly,
 | ||||
|         // otherwise defer to the other type's implementation of
 | ||||
|         // CompareContextElement since the end user could add any
 | ||||
|  | ||||
| @ -1,264 +0,0 @@ | ||||
| use crate::parser::KVPair; | ||||
| use crate::parser::{Filter, OwnedLiteral, PartialNameElement, RValue}; | ||||
| use crate::renderer::context_element::CompareContextElement; | ||||
| use crate::renderer::context_element::ContextElement; | ||||
| use crate::renderer::context_element::IntoContextElement; | ||||
| use crate::renderer::walking::walk_path; | ||||
| use crate::renderer::DustRenderer; | ||||
| use crate::renderer::Loopable; | ||||
| use crate::renderer::RenderError; | ||||
| use crate::renderer::Renderable; | ||||
| use crate::renderer::Truthiness; | ||||
| use crate::renderer::WalkError; | ||||
| use crate::renderer::Walkable; | ||||
| use std::{cmp::Ordering, collections::HashMap}; | ||||
| 
 | ||||
| /// Copy the data from an RValue to an Owned struct
 | ||||
| ///
 | ||||
| /// In order to get comparisons to work for our `ContextElement` trait
 | ||||
| /// objects, we need to be able to use `std::any::Any`. Unfortunately,
 | ||||
| /// `Any` requires that the structs do not have a lifetime (so they
 | ||||
| /// will have a `'static` lifetime. This means that we cannot have a
 | ||||
| /// `<'a>` appended to the struct type, so the struct cannot contain
 | ||||
| /// any borrows. Rather than impose the copy cost in the parser, we
 | ||||
| /// are imposing the cost of copying the data in the renderer because
 | ||||
| /// the parser has no reason to not be able to reference data from the
 | ||||
| /// input string.
 | ||||
| #[derive(Clone, Debug)] | ||||
| pub enum OwnedRValue { | ||||
|     RVPath(OwnedPath), | ||||
|     RVTemplate(Vec<PartialNameElement>), | ||||
|     RVLiteral(OwnedLiteral), | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, PartialEq)] | ||||
| pub struct OwnedPath { | ||||
|     pub keys: Vec<String>, | ||||
| } | ||||
| 
 | ||||
| impl From<&RValue<'_>> for OwnedRValue { | ||||
|     fn from(original: &RValue<'_>) -> Self { | ||||
|         match original { | ||||
|             RValue::RVLiteral(literal) => OwnedRValue::RVLiteral(literal.clone()), | ||||
|             RValue::RVTemplate(template) => OwnedRValue::RVTemplate(template.clone()), | ||||
|             RValue::RVPath(path) => OwnedRValue::RVPath(OwnedPath { | ||||
|                 keys: path.keys.iter().map(|k| k.to_string()).collect(), | ||||
|             }), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct ParametersContext { | ||||
|     params: HashMap<String, OwnedRValue>, | ||||
|     breadcrumbs: Vec<Box<dyn IntoContextElement>>, | ||||
| } | ||||
| 
 | ||||
| impl ParametersContext { | ||||
|     pub fn new( | ||||
|         breadcrumbs: &Vec<&dyn IntoContextElement>, | ||||
|         params: &Vec<KVPair>, | ||||
|     ) -> ParametersContext { | ||||
|         let owned_params: HashMap<String, OwnedRValue> = params | ||||
|             .iter() | ||||
|             .map(|kvpair| (kvpair.key.to_string(), OwnedRValue::from(&kvpair.value))) | ||||
|             .collect(); | ||||
|         let owned_breadcrumbs: Vec<Box<dyn IntoContextElement>> = | ||||
|             breadcrumbs.iter().map(|ce| ce.clone_to_box()).collect(); | ||||
| 
 | ||||
|         ParametersContext { | ||||
|             params: owned_params, | ||||
|             breadcrumbs: owned_breadcrumbs, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ContextElement for ParametersContext {} | ||||
| 
 | ||||
| impl Truthiness for ParametersContext { | ||||
|     fn is_truthy(&self) -> bool { | ||||
|         // 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 `{.}`.
 | ||||
|         true | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Renderable for ParametersContext { | ||||
|     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 ParametersContext { | ||||
|     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() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Walkable for ParametersContext { | ||||
|     fn walk(&self, segment: &str) -> Result<&dyn IntoContextElement, WalkError> { | ||||
|         let rval = self.params.get(segment).ok_or(WalkError::CantWalk)?; | ||||
|         match rval { | ||||
|             OwnedRValue::RVPath(path) => walk_path(&self.breadcrumbs, &path.keys), | ||||
|             OwnedRValue::RVTemplate(template) => Ok(template), | ||||
|             OwnedRValue::RVLiteral(literal) => Ok(literal), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn is_pseudo_element(&self) -> bool { | ||||
|         true | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Clone for ParametersContext { | ||||
|     fn clone(&self) -> Self { | ||||
|         let new_params: HashMap<String, OwnedRValue> = self | ||||
|             .params | ||||
|             .iter() | ||||
|             .map(|(k, v)| (k.clone(), v.clone())) | ||||
|             .collect(); | ||||
|         let new_breadcrumbs: Vec<Box<dyn IntoContextElement>> = self | ||||
|             .breadcrumbs | ||||
|             .iter() | ||||
|             .map(|bread| bread.clone_to_box()) | ||||
|             .collect(); | ||||
|         ParametersContext { | ||||
|             params: new_params, | ||||
|             breadcrumbs: new_breadcrumbs, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl CompareContextElement for ParametersContext { | ||||
|     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 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ContextElement for OwnedLiteral {} | ||||
| 
 | ||||
| impl Truthiness for OwnedLiteral { | ||||
|     fn is_truthy(&self) -> bool { | ||||
|         match self { | ||||
|             OwnedLiteral::LString(text) => !text.is_empty(), | ||||
|             OwnedLiteral::LPositiveInteger(num) => true, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Renderable for OwnedLiteral { | ||||
|     fn render(&self, _filters: &Vec<Filter>) -> Result<String, RenderError> { | ||||
|         match self { | ||||
|             OwnedLiteral::LString(text) => Ok(text.clone()), | ||||
|             OwnedLiteral::LPositiveInteger(num) => Ok(num.to_string()), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Loopable for OwnedLiteral { | ||||
|     fn get_loop_elements(&self) -> Vec<&dyn ContextElement> { | ||||
|         Vec::new() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Walkable for OwnedLiteral { | ||||
|     fn walk(&self, segment: &str) -> Result<&dyn IntoContextElement, WalkError> { | ||||
|         Err(WalkError::CantWalk) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl CompareContextElement for OwnedLiteral { | ||||
|     fn equals(&self, other: &dyn ContextElement) -> bool { | ||||
|         // println!("equals literal {:?} | {:?}", self, other);
 | ||||
|         // If its an OwnedLiteral then compare them directly,
 | ||||
|         // otherwise defer to the other type's implementation of
 | ||||
|         // CompareContextElement since the end user could add any
 | ||||
|         // type.
 | ||||
|         match other.to_any().downcast_ref::<Self>() { | ||||
|             None => other.equals(self), | ||||
|             Some(other_literal) => match (self, other_literal) { | ||||
|                 (OwnedLiteral::LString(self_text), OwnedLiteral::LString(other_text)) => { | ||||
|                     self_text == other_text | ||||
|                 } | ||||
|                 (OwnedLiteral::LPositiveInteger(self_num), OwnedLiteral::LString(other_text)) => { | ||||
|                     &self_num.to_string() == other_text | ||||
|                 } | ||||
|                 (OwnedLiteral::LString(self_text), OwnedLiteral::LPositiveInteger(other_num)) => { | ||||
|                     self_text == &other_num.to_string() | ||||
|                 } | ||||
|                 ( | ||||
|                     OwnedLiteral::LPositiveInteger(self_num), | ||||
|                     OwnedLiteral::LPositiveInteger(other_num), | ||||
|                 ) => self_num == other_num, | ||||
|             }, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn partial_compare(&self, other: &dyn ContextElement) -> Option<Ordering> { | ||||
|         // println!("partial_compare literal {:?} | {:?}", self, other);
 | ||||
|         // If its an OwnedLiteral then compare them directly,
 | ||||
|         // otherwise defer to the other type's implementation of
 | ||||
|         // CompareContextElement since the end user could add any
 | ||||
|         // type.
 | ||||
|         match other.to_any().downcast_ref::<Self>() { | ||||
|             None => match other.partial_compare(self) { | ||||
|                 None => None, | ||||
|                 Some(ord) => match ord { | ||||
|                     Ordering::Equal => Some(Ordering::Equal), | ||||
|                     Ordering::Greater => Some(Ordering::Less), | ||||
|                     Ordering::Less => Some(Ordering::Greater), | ||||
|                 }, | ||||
|             }, | ||||
|             Some(other_literal) => match (self, other_literal) { | ||||
|                 (OwnedLiteral::LString(self_text), OwnedLiteral::LString(other_text)) => { | ||||
|                     self_text.partial_cmp(other_text) | ||||
|                 } | ||||
|                 (OwnedLiteral::LPositiveInteger(self_num), OwnedLiteral::LString(other_text)) => { | ||||
|                     self_num.to_string().partial_cmp(other_text) | ||||
|                 } | ||||
|                 (OwnedLiteral::LString(self_text), OwnedLiteral::LPositiveInteger(other_num)) => { | ||||
|                     self_text.partial_cmp(&other_num.to_string()) | ||||
|                 } | ||||
|                 ( | ||||
|                     OwnedLiteral::LPositiveInteger(self_num), | ||||
|                     OwnedLiteral::LPositiveInteger(other_num), | ||||
|                 ) => self_num.partial_cmp(other_num), | ||||
|             }, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl IntoContextElement for Vec<PartialNameElement> { | ||||
|     fn into_context_element( | ||||
|         &self, | ||||
|         renderer: &DustRenderer, | ||||
|         breadcrumbs: &Vec<&dyn IntoContextElement>, | ||||
|     ) -> &dyn ContextElement { | ||||
|         // OwnedLiteral::LString(
 | ||||
|         //     renderer
 | ||||
|         //         .render_partial_name(self, breadcrumbs)
 | ||||
|         //         .expect("TODO: Make into_context_element return a RenderError"),
 | ||||
|         // )
 | ||||
|         // TODO
 | ||||
|         &OwnedLiteral::LPositiveInteger(1) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Walkable for Vec<PartialNameElement> { | ||||
|     fn walk(&self, segment: &str) -> Result<&dyn IntoContextElement, WalkError> { | ||||
|         Err(WalkError::CantWalk) | ||||
|     } | ||||
| } | ||||
| @ -2,10 +2,8 @@ use crate::parser::template; | ||||
| use crate::parser::Body; | ||||
| use crate::parser::DustTag; | ||||
| use crate::parser::Filter; | ||||
| use crate::parser::KVPair; | ||||
| use crate::parser::PartialNameElement; | ||||
| use crate::parser::Path; | ||||
| use crate::parser::RValue; | ||||
| use crate::parser::Special; | ||||
| use crate::parser::Template; | ||||
| use crate::parser::TemplateElement; | ||||
| @ -21,10 +19,8 @@ use crate::renderer::inline_partial_tree::extract_inline_partials; | ||||
| use crate::renderer::inline_partial_tree::InlinePartialTreeElement; | ||||
| use crate::renderer::iteration_context::IterationContext; | ||||
| use crate::renderer::parameters_context::ParametersContext; | ||||
| use crate::renderer::tree_walking::walk_path; | ||||
| use std::borrow::Borrow; | ||||
| use crate::renderer::walking::walk_path; | ||||
| use std::collections::HashMap; | ||||
| use std::rc::Rc; | ||||
| 
 | ||||
| #[derive(Clone, Debug)] | ||||
| pub struct DustRenderer<'a> { | ||||
| @ -32,7 +28,7 @@ pub struct DustRenderer<'a> { | ||||
| } | ||||
| 
 | ||||
| pub fn compile_template<'a>(source: &'a str) -> Result<Template<'a>, CompileError> { | ||||
|     let (_remaining, parsed_template) = template(source).map_err(|err| CompileError { | ||||
|     let (_remaining, parsed_template) = template(source).map_err(|_err| CompileError { | ||||
|         message: "Failed to compile template".to_owned(), | ||||
|     })?; | ||||
|     Ok(parsed_template) | ||||
| @ -391,7 +387,7 @@ impl<'a> DustRenderer<'a> { | ||||
|                 // equal. This is particularly important for objects
 | ||||
|                 // which compare memory locations rather than contents
 | ||||
|                 // (javascript object equality).
 | ||||
|                 if Self::new_are_paths_identical(&left_side, &right_side) | ||||
|                 if Self::are_paths_identical(&left_side, &right_side) | ||||
|                     || left_side.as_ref().map(|maybe_ice| { | ||||
|                         maybe_ice | ||||
|                             .as_ref() | ||||
| @ -440,7 +436,7 @@ impl<'a> DustRenderer<'a> { | ||||
|                 // equal. This is particularly important for objects
 | ||||
|                 // which compare memory locations rather than contents
 | ||||
|                 // (javascript object equality).
 | ||||
|                 if Self::new_are_paths_identical(&left_side, &right_side) | ||||
|                 if Self::are_paths_identical(&left_side, &right_side) | ||||
|                     || left_side.as_ref().map(|maybe_ice| { | ||||
|                         maybe_ice | ||||
|                             .as_ref() | ||||
| @ -648,7 +644,6 @@ impl<'a> DustRenderer<'a> { | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             _ => panic!("Unsupported tag"), | ||||
|         } | ||||
| 
 | ||||
|         Ok("".to_owned()) | ||||
| @ -760,26 +755,6 @@ impl<'a> DustRenderer<'a> { | ||||
|     } | ||||
| 
 | ||||
|     fn are_paths_identical<'b>( | ||||
|         param_map: &ParametersContext<'b>, | ||||
|         left_key: &str, | ||||
|         right_key: &str, | ||||
|     ) -> bool { | ||||
|         match ( | ||||
|             param_map.get_original_rvalue(left_key), | ||||
|             param_map.get_original_rvalue(right_key), | ||||
|         ) { | ||||
|             (None, _) => false, | ||||
|             (_, None) => false, | ||||
|             (Some(key_rval), Some(value_rval)) => match (key_rval, value_rval) { | ||||
|                 (RValue::RVPath(key_path), RValue::RVPath(value_path)) => { | ||||
|                     key_path.keys == value_path.keys | ||||
|                 } | ||||
|                 _ => false, | ||||
|             }, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn new_are_paths_identical<'b>( | ||||
|         left_side: &Result<Option<IceResult<'b>>, WalkError>, | ||||
|         right_side: &Result<Option<IceResult<'b>>, WalkError>, | ||||
|     ) -> bool { | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,94 +0,0 @@ | ||||
| use crate::renderer::breadcrumb_tree::BreadcrumbTreeElement; | ||||
| use crate::renderer::context_element::IntoContextElement; | ||||
| use crate::renderer::WalkError; | ||||
| use std::borrow::Borrow; | ||||
| 
 | ||||
| enum WalkResult<'a> { | ||||
|     NoWalk, | ||||
|     PartialWalk, | ||||
|     FullyWalked(&'a dyn IntoContextElement), | ||||
| } | ||||
| 
 | ||||
| fn walk_path_from_single_level<'a, P>( | ||||
|     context: &'a dyn IntoContextElement, | ||||
|     path: &[P], | ||||
| ) -> WalkResult<'a> | ||||
| where | ||||
|     P: Borrow<str>, | ||||
| { | ||||
|     if path.is_empty() { | ||||
|         return WalkResult::FullyWalked(context); | ||||
|     } | ||||
| 
 | ||||
|     let mut walk_failure = WalkResult::NoWalk; | ||||
|     let mut output = context; | ||||
|     for elem in path.iter() { | ||||
|         match output.walk(elem.borrow()) { | ||||
|             Err(WalkError::CantWalk { .. }) => { | ||||
|                 return walk_failure; | ||||
|             } | ||||
|             Ok(new_val) => { | ||||
|                 walk_failure = WalkResult::PartialWalk; | ||||
|                 output = new_val; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     WalkResult::FullyWalked(output) | ||||
| } | ||||
| 
 | ||||
| fn get_first_non_pseudo_element<'a>( | ||||
|     breadcrumbs: &'a Vec<BreadcrumbTreeElement<'a>>, | ||||
| ) -> Option<&'a BreadcrumbTreeElement<'a>> { | ||||
|     breadcrumbs | ||||
|         .iter() | ||||
|         .rev() | ||||
|         .filter(|b| { | ||||
|             !std::borrow::Borrow::<dyn IntoContextElement + 'a>::borrow(*b).is_pseudo_element() | ||||
|         }) | ||||
|         .next() | ||||
| } | ||||
| 
 | ||||
| pub fn walk_path<'a, P>( | ||||
|     breadcrumbs: &'a Vec<BreadcrumbTreeElement<'a>>, | ||||
|     path: &Vec<P>, | ||||
| ) -> Result<&'a dyn IntoContextElement, WalkError> | ||||
| where | ||||
|     P: Borrow<str>, | ||||
| { | ||||
|     match (breadcrumbs.last(), path.first()) { | ||||
|         (None, _) => return Err(WalkError::CantWalk), | ||||
|         (Some(last_elem), None) => return Ok(last_elem.borrow()), | ||||
|         (Some(_), 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), | ||||
|                 Some(current_context) => { | ||||
|                     match walk_path_from_single_level(current_context.borrow(), &path[1..]) { | ||||
|                         // If no walking was done at all or we partially walked
 | ||||
|                         // then stop trying to find anything because '.' restricts
 | ||||
|                         // us to the current scope
 | ||||
|                         WalkResult::NoWalk | WalkResult::PartialWalk => Err(WalkError::CantWalk), | ||||
|                         WalkResult::FullyWalked(new_context) => Ok(new_context), | ||||
|                     } | ||||
|                 } | ||||
|             }; | ||||
|         } | ||||
|         (Some(_), Some(path_first)) => { | ||||
|             for context in breadcrumbs.iter().rev() { | ||||
|                 match walk_path_from_single_level(context.borrow(), path) { | ||||
|                     // If no walking was done at all, keep looping
 | ||||
|                     WalkResult::NoWalk => {} | ||||
|                     // If we partially walked then stop trying to find
 | ||||
|                     // anything
 | ||||
|                     WalkResult::PartialWalk => { | ||||
|                         return Err(WalkError::CantWalk); | ||||
|                     } | ||||
|                     WalkResult::FullyWalked(new_context) => return Ok(new_context), | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     Err(WalkError::CantWalk) | ||||
| } | ||||
| @ -1,4 +1,4 @@ | ||||
| use crate::renderer::context_element::ContextElement; | ||||
| use crate::renderer::breadcrumb_tree::BreadcrumbTreeElement; | ||||
| use crate::renderer::context_element::IntoContextElement; | ||||
| use crate::renderer::WalkError; | ||||
| use std::borrow::Borrow; | ||||
| @ -9,19 +9,21 @@ enum WalkResult<'a> { | ||||
|     FullyWalked(&'a dyn IntoContextElement), | ||||
| } | ||||
| 
 | ||||
| fn walk_path_from_single_level<'a, P, C>(context: &'a C, path: &[P]) -> WalkResult<'a> | ||||
| fn walk_path_from_single_level<'a, P>( | ||||
|     context: &'a dyn IntoContextElement, | ||||
|     path: &[P], | ||||
| ) -> WalkResult<'a> | ||||
| where | ||||
|     P: Borrow<str>, | ||||
|     C: Borrow<dyn IntoContextElement + 'a>, | ||||
| { | ||||
|     if path.is_empty() { | ||||
|         return WalkResult::FullyWalked(context.borrow()); | ||||
|         return WalkResult::FullyWalked(context); | ||||
|     } | ||||
| 
 | ||||
|     let mut walk_failure = WalkResult::NoWalk; | ||||
|     let mut output = context.borrow(); | ||||
|     let mut output = context; | ||||
|     for elem in path.iter() { | ||||
|         match output.borrow().walk(elem.borrow()) { | ||||
|         match output.walk(elem.borrow()) { | ||||
|             Err(WalkError::CantWalk { .. }) => { | ||||
|                 return walk_failure; | ||||
|             } | ||||
| @ -35,68 +37,58 @@ where | ||||
|     WalkResult::FullyWalked(output) | ||||
| } | ||||
| 
 | ||||
| pub fn get_first_non_pseudo_element<'a, B>(breadcrumbs: &'a Vec<B>) -> Option<&B> | ||||
| where | ||||
|     B: Borrow<dyn IntoContextElement + 'a>, | ||||
| { | ||||
| fn get_first_non_pseudo_element<'a>( | ||||
|     breadcrumbs: &'a Vec<BreadcrumbTreeElement<'a>>, | ||||
| ) -> Option<&'a BreadcrumbTreeElement<'a>> { | ||||
|     breadcrumbs | ||||
|         .iter() | ||||
|         .rev() | ||||
|         .filter(|b| !(*b).borrow().is_pseudo_element()) | ||||
|         .filter(|b| { | ||||
|             !std::borrow::Borrow::<dyn IntoContextElement + 'a>::borrow(*b).is_pseudo_element() | ||||
|         }) | ||||
|         .next() | ||||
| } | ||||
| 
 | ||||
| pub fn walk_path<'a, B, P>( | ||||
|     breadcrumbs: &'a Vec<B>, | ||||
| pub fn walk_path<'a, P>( | ||||
|     breadcrumbs: &'a Vec<BreadcrumbTreeElement<'a>>, | ||||
|     path: &Vec<P>, | ||||
| ) -> Result<&'a dyn IntoContextElement, WalkError> | ||||
| where | ||||
|     B: Borrow<dyn IntoContextElement + 'a>, | ||||
|     P: Borrow<str>, | ||||
| { | ||||
|     if breadcrumbs.is_empty() { | ||||
|         // This happens when you use a section with an explicit
 | ||||
|         // context path, where both the path and the explicit context
 | ||||
|         // path fail, leaving you with absolutely no context.
 | ||||
|         return Err(WalkError::CantWalk); | ||||
|     } | ||||
|     if path.is_empty() { | ||||
|         return Ok(breadcrumbs | ||||
|             .last() | ||||
|             .expect("Breadcrumbs should never be empty.") | ||||
|             .borrow()); | ||||
|     } | ||||
|     if path | ||||
|         .first() | ||||
|         .expect("Already proved path is not empty") | ||||
|         .borrow() | ||||
|         == "." | ||||
|     { | ||||
|         let first_non_pseudo_element = get_first_non_pseudo_element(breadcrumbs); | ||||
|         return match first_non_pseudo_element { | ||||
|             None => Err(WalkError::CantWalk), | ||||
|             Some(current_context) => { | ||||
|                 match walk_path_from_single_level(current_context, &path[1..]) { | ||||
|                     // If no walking was done at all or we partially walked
 | ||||
|                     // then stop trying to find anything because '.' restricts
 | ||||
|                     // us to the current scope
 | ||||
|                     WalkResult::NoWalk | WalkResult::PartialWalk => Err(WalkError::CantWalk), | ||||
|                     WalkResult::FullyWalked(new_context) => Ok(new_context), | ||||
|     match (breadcrumbs.last(), path.first()) { | ||||
|         (None, _) => return Err(WalkError::CantWalk), | ||||
|         (Some(last_elem), None) => return Ok(last_elem.borrow()), | ||||
|         (Some(_), 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), | ||||
|                 Some(current_context) => { | ||||
|                     match walk_path_from_single_level(current_context.borrow(), &path[1..]) { | ||||
|                         // If no walking was done at all or we partially walked
 | ||||
|                         // then stop trying to find anything because '.' restricts
 | ||||
|                         // us to the current scope
 | ||||
|                         WalkResult::NoWalk | WalkResult::PartialWalk => Err(WalkError::CantWalk), | ||||
|                         WalkResult::FullyWalked(new_context) => Ok(new_context), | ||||
|                     } | ||||
|                 } | ||||
|             }; | ||||
|         } | ||||
|         (Some(_), Some(_path_first)) => { | ||||
|             for context in breadcrumbs.iter().rev() { | ||||
|                 match walk_path_from_single_level(context.borrow(), path) { | ||||
|                     // If no walking was done at all, keep looping
 | ||||
|                     WalkResult::NoWalk => {} | ||||
|                     // If we partially walked then stop trying to find
 | ||||
|                     // anything
 | ||||
|                     WalkResult::PartialWalk => { | ||||
|                         return Err(WalkError::CantWalk); | ||||
|                     } | ||||
|                     WalkResult::FullyWalked(new_context) => return Ok(new_context), | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
|     for context in breadcrumbs.iter().rev() { | ||||
|         match walk_path_from_single_level(context, path) { | ||||
|             // If no walking was done at all, keep looping
 | ||||
|             WalkResult::NoWalk => {} | ||||
|             // If we partially walked then stop trying to find
 | ||||
|             // anything
 | ||||
|             WalkResult::PartialWalk => { | ||||
|                 return Err(WalkError::CantWalk); | ||||
|             } | ||||
|             WalkResult::FullyWalked(new_context) => return Ok(new_context), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     Err(WalkError::CantWalk) | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Tom Alexander
						Tom Alexander