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::Renderable;
use renderer::WalkError; use renderer::WalkError;
use renderer::Walkable; use renderer::Walkable;
use std::cmp::Ordering;
use std::env; use std::env;
use std::fs; use std::fs;
use std::io::{self, Read}; use std::io::{self, Read};
@ -158,4 +159,9 @@ impl CompareContextElement for serde_json::Value {
} }
false 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::RenderError;
use crate::renderer::errors::WalkError; use crate::renderer::errors::WalkError;
use std::any::Any; use std::any::Any;
use std::fmt::Debug; use std::{cmp::Ordering, fmt::Debug};
pub trait ContextElement: pub trait ContextElement:
Debug + Walkable + Renderable + Loopable + CloneIntoBoxedContextElement + CompareContextElement Debug + Walkable + Renderable + Loopable + CloneIntoBoxedContextElement + CompareContextElement
@ -36,6 +36,8 @@ pub trait CastToAny {
pub trait CompareContextElement: CastToAny { pub trait CompareContextElement: CastToAny {
fn equals(&self, other: &dyn ContextElement) -> bool; fn equals(&self, other: &dyn ContextElement) -> bool;
fn partial_compare(&self, other: &dyn ContextElement) -> Option<Ordering>;
} }
pub trait CloneIntoBoxedContextElement { pub trait CloneIntoBoxedContextElement {
@ -59,3 +61,9 @@ impl<'a, 'b> PartialEq<&'b dyn ContextElement> for &'a dyn ContextElement {
self.equals(*other) 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::Renderable;
use crate::renderer::WalkError; use crate::renderer::WalkError;
use crate::renderer::Walkable; use crate::renderer::Walkable;
use std::collections::HashMap; use std::{cmp::Ordering, collections::HashMap};
/// Copy the data from an RValue to an Owned struct /// 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. // TODO: Does this ever happen? perhaps I should have a panic here.
false 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 {} impl ContextElement for String {}
@ -158,6 +163,23 @@ impl CompareContextElement for String {
Some(other_string) => self == other_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 {} impl ContextElement for u64 {}
@ -190,4 +212,21 @@ impl CompareContextElement for u64 {
Some(other_num) => self == other_num, 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),
}
}
} }