From 09e0b046a0eebcf4ad41c6d373be29d84f65853d Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sun, 31 May 2020 21:59:24 -0400 Subject: [PATCH] Copy over the implementation of ContextElement for OwnedLiteral which will be the result of calling IntoContextElement on RValues. --- src/renderer/parameters_context.rs | 121 +++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/src/renderer/parameters_context.rs b/src/renderer/parameters_context.rs index 3261b6e..6c45db6 100644 --- a/src/renderer/parameters_context.rs +++ b/src/renderer/parameters_context.rs @@ -1,7 +1,19 @@ +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::context_element::CompareContextElement; +use crate::renderer::context_element::ContextElement; 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::renderer::Walkable; +use std::cmp::Ordering; use std::collections::HashMap; #[derive(Debug)] @@ -18,3 +30,112 @@ impl<'a> ParametersContext<'a> { todo!() } } + +impl<'a> IntoContextElement for RValue<'a> { + fn into_context_element( + &self, + renderer: &DustRenderer, + breadcrumbs: Option<&BreadcrumbTree>, + ) -> &dyn ContextElement { + todo!() + } +} + +impl<'a> Walkable for RValue<'a> { + fn walk(&self, segment: &str) -> Result<&dyn IntoContextElement, WalkError> { + Err(WalkError::CantWalk) + } +} + +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) -> Result { + 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::() { + 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 { + // 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::() { + 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), + }, + } + } +}