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