Structure for ordering, need to implement for serde_json::Value.

This commit is contained in:
Tom Alexander 2020-05-16 13:31:52 -04:00
parent 8a44bc6fd9
commit 8748cb7063
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
3 changed files with 55 additions and 2 deletions

View File

@ -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<Ordering> {
// TODO: Implement
None
}
}

View File

@ -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<Ordering>;
}
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<Ordering> {
self.partial_compare(*other)
}
}

View File

@ -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<Ordering> {
// 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<Ordering> {
// 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::<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_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<Ordering> {
// 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::<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_num) => self.partial_cmp(other_num),
}
}
}