diff --git a/src/bin.rs b/src/bin.rs index f764ebd..c72d00d 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -11,6 +11,7 @@ use renderer::RenderError; use renderer::Renderable; use renderer::WalkError; use renderer::Walkable; +use std::cmp::Ordering; use std::env; use std::fs; use std::io::{self, Read}; @@ -158,4 +159,9 @@ impl CompareContextElement for serde_json::Value { } false } + + fn partial_compare(&self, other: &dyn ContextElement) -> Option { + // TODO: Implement + None + } } diff --git a/src/renderer/context_element.rs b/src/renderer/context_element.rs index 3db0f27..bb43cf8 100644 --- a/src/renderer/context_element.rs +++ b/src/renderer/context_element.rs @@ -2,7 +2,7 @@ use crate::parser::Filter; use crate::renderer::errors::RenderError; use crate::renderer::errors::WalkError; use std::any::Any; -use std::fmt::Debug; +use std::{cmp::Ordering, fmt::Debug}; pub trait ContextElement: Debug + Walkable + Renderable + Loopable + CloneIntoBoxedContextElement + CompareContextElement @@ -36,6 +36,8 @@ pub trait CastToAny { pub trait CompareContextElement: CastToAny { fn equals(&self, other: &dyn ContextElement) -> bool; + + fn partial_compare(&self, other: &dyn ContextElement) -> Option; } pub trait CloneIntoBoxedContextElement { @@ -59,3 +61,9 @@ impl<'a, 'b> PartialEq<&'b dyn ContextElement> for &'a dyn ContextElement { self.equals(*other) } } + +impl<'a, 'b> PartialOrd<&'b dyn ContextElement> for &'a dyn ContextElement { + fn partial_cmp(&self, other: &&'b dyn ContextElement) -> Option { + self.partial_compare(*other) + } +} diff --git a/src/renderer/parameters_context.rs b/src/renderer/parameters_context.rs index 9d5d749..5812ce3 100644 --- a/src/renderer/parameters_context.rs +++ b/src/renderer/parameters_context.rs @@ -8,7 +8,7 @@ use crate::renderer::RenderError; use crate::renderer::Renderable; use crate::renderer::WalkError; use crate::renderer::Walkable; -use std::collections::HashMap; +use std::{cmp::Ordering, collections::HashMap}; /// Copy the data from an RValue to an Owned struct /// @@ -122,6 +122,11 @@ impl CompareContextElement for ParametersContext { // TODO: Does this ever happen? perhaps I should have a panic here. false } + + fn partial_compare(&self, other: &dyn ContextElement) -> Option { + // TODO: Does this ever happen? perhaps I should have a panic here. + None + } } impl ContextElement for String {} @@ -158,6 +163,23 @@ impl CompareContextElement for String { Some(other_string) => self == other_string, } } + + fn partial_compare(&self, other: &dyn ContextElement) -> Option { + // If its a string 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_string) => self.partial_cmp(other_string), + } + } } impl ContextElement for u64 {} @@ -190,4 +212,21 @@ impl CompareContextElement for u64 { Some(other_num) => self == other_num, } } + + fn partial_compare(&self, other: &dyn ContextElement) -> Option { + // If its a u64 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_num) => self.partial_cmp(other_num), + } + } }