Starting to remove the old RValues.

This commit is contained in:
Tom Alexander 2020-05-16 22:19:51 -04:00
parent 16d8891452
commit bc25c1ee16
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE

View File

@ -21,11 +21,10 @@ use std::{cmp::Ordering, collections::HashMap};
/// are imposing the cost of copying the data in the renderer because /// 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 /// the parser has no reason to not be able to reference data from the
/// input string. /// input string.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug)]
pub enum OwnedRValue { pub enum OwnedRValue {
RVPath(OwnedPath), RVPath(OwnedPath),
RVString(String), RVLiteral(OwnedLiteral),
RVPositiveInteger(u64),
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
@ -36,11 +35,15 @@ pub struct OwnedPath {
impl From<&RValue<'_>> for OwnedRValue { impl From<&RValue<'_>> for OwnedRValue {
fn from(original: &RValue<'_>) -> Self { fn from(original: &RValue<'_>) -> Self {
match original { match original {
RValue::RVString(text) => OwnedRValue::RVString(text.to_owned()), RValue::RVString(text) => {
OwnedRValue::RVLiteral(OwnedLiteral::LString(text.to_owned()))
}
RValue::RVPath(path) => OwnedRValue::RVPath(OwnedPath { RValue::RVPath(path) => OwnedRValue::RVPath(OwnedPath {
keys: path.keys.iter().map(|k| k.to_string()).collect(), keys: path.keys.iter().map(|k| k.to_string()).collect(),
}), }),
RValue::RVPositiveInteger(num) => OwnedRValue::RVPositiveInteger(*num), RValue::RVPositiveInteger(num) => {
OwnedRValue::RVLiteral(OwnedLiteral::LPositiveInteger(num.clone()))
}
} }
} }
} }
@ -51,16 +54,6 @@ pub enum OwnedLiteral {
LPositiveInteger(u64), LPositiveInteger(u64),
} }
impl From<&OwnedRValue> for OwnedLiteral {
fn from(original: &OwnedRValue) -> Self {
match original {
OwnedRValue::RVPath(_) => panic!("Cannot convert a path to a literal"),
OwnedRValue::RVString(text) => OwnedLiteral::LString(text.clone()),
OwnedRValue::RVPositiveInteger(num) => OwnedLiteral::LPositiveInteger(num.clone()),
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct ParametersContext { pub struct ParametersContext {
params: HashMap<String, OwnedRValue>, params: HashMap<String, OwnedRValue>,
@ -108,8 +101,7 @@ impl Walkable for ParametersContext {
let rval = self.params.get(segment).ok_or(WalkError::CantWalk)?; let rval = self.params.get(segment).ok_or(WalkError::CantWalk)?;
match rval { match rval {
OwnedRValue::RVPath(path) => owned_walk_path(&self.breadcrumbs, &path.keys), OwnedRValue::RVPath(path) => owned_walk_path(&self.breadcrumbs, &path.keys),
OwnedRValue::RVString(text) => Ok(text), OwnedRValue::RVLiteral(literal) => Ok(literal),
OwnedRValue::RVPositiveInteger(num) => Ok(num),
} }
} }
} }
@ -163,10 +155,10 @@ impl Loopable for OwnedLiteral {
if text.is_empty() { if text.is_empty() {
Vec::new() Vec::new()
} else { } else {
vec![text] vec![self]
} }
} }
OwnedLiteral::LPositiveInteger(num) => vec![num], OwnedLiteral::LPositiveInteger(num) => vec![self],
} }
} }
} }
@ -237,106 +229,106 @@ impl CompareContextElement for OwnedLiteral {
} }
} }
impl ContextElement for String {} // impl ContextElement for String {}
impl Renderable for String { // impl Renderable for String {
fn render(&self, _filters: &Vec<Filter>) -> Result<String, RenderError> { // fn render(&self, _filters: &Vec<Filter>) -> Result<String, RenderError> {
Ok(self.clone()) // Ok(self.clone())
} // }
} // }
impl Loopable for String { // impl Loopable for String {
fn get_loop_elements(&self) -> Vec<&dyn ContextElement> { // fn get_loop_elements(&self) -> Vec<&dyn ContextElement> {
if self.is_empty() { // if self.is_empty() {
Vec::new() // Vec::new()
} else { // } else {
vec![self] // vec![self]
} // }
} // }
} // }
impl Walkable for String { // impl Walkable for String {
fn walk(&self, segment: &str) -> Result<&dyn ContextElement, WalkError> { // fn walk(&self, segment: &str) -> Result<&dyn ContextElement, WalkError> {
Err(WalkError::CantWalk) // Err(WalkError::CantWalk)
} // }
} // }
impl CompareContextElement for String { // impl CompareContextElement for String {
fn equals(&self, other: &dyn ContextElement) -> bool { // fn equals(&self, other: &dyn ContextElement) -> bool {
// If its a String then compare them directly, otherwise defer // // If its a String then compare them directly, otherwise defer
// to the other type's implementation of CompareContextElement // // to the other type's implementation of CompareContextElement
// since the end user could add any type. // // since the end user could add any type.
match other.to_any().downcast_ref::<Self>() { // match other.to_any().downcast_ref::<Self>() {
None => other.equals(self), // None => other.equals(self),
Some(other_string) => self == other_string, // Some(other_string) => self == other_string,
} // }
} // }
fn partial_compare(&self, other: &dyn ContextElement) -> Option<Ordering> { // fn partial_compare(&self, other: &dyn ContextElement) -> Option<Ordering> {
println!("partial_compare String {:?} | {:?}", self, other); // println!("partial_compare String {:?} | {:?}", self, other);
// If its a string then compare them directly, otherwise defer // // If its a string then compare them directly, otherwise defer
// to the other type's implementation of CompareContextElement // // to the other type's implementation of CompareContextElement
// since the end user could add any type. // // since the end user could add any type.
match other.to_any().downcast_ref::<Self>() { // match other.to_any().downcast_ref::<Self>() {
None => match other.partial_compare(self) { // None => match other.partial_compare(self) {
None => None, // None => None,
Some(ord) => match ord { // Some(ord) => match ord {
Ordering::Equal => Some(Ordering::Equal), // Ordering::Equal => Some(Ordering::Equal),
Ordering::Greater => Some(Ordering::Less), // Ordering::Greater => Some(Ordering::Less),
Ordering::Less => Some(Ordering::Greater), // Ordering::Less => Some(Ordering::Greater),
}, // },
}, // },
Some(other_string) => self.partial_cmp(other_string), // Some(other_string) => self.partial_cmp(other_string),
} // }
} // }
} // }
impl ContextElement for u64 {} // impl ContextElement for u64 {}
impl Renderable for u64 { // impl Renderable for u64 {
fn render(&self, _filters: &Vec<Filter>) -> Result<String, RenderError> { // fn render(&self, _filters: &Vec<Filter>) -> Result<String, RenderError> {
Ok(self.to_string()) // Ok(self.to_string())
} // }
} // }
impl Loopable for u64 { // impl Loopable for u64 {
fn get_loop_elements(&self) -> Vec<&dyn ContextElement> { // fn get_loop_elements(&self) -> Vec<&dyn ContextElement> {
vec![self] // vec![self]
} // }
} // }
impl Walkable for u64 { // impl Walkable for u64 {
fn walk(&self, segment: &str) -> Result<&dyn ContextElement, WalkError> { // fn walk(&self, segment: &str) -> Result<&dyn ContextElement, WalkError> {
Err(WalkError::CantWalk) // Err(WalkError::CantWalk)
} // }
} // }
impl CompareContextElement for u64 { // impl CompareContextElement for u64 {
fn equals(&self, other: &dyn ContextElement) -> bool { // fn equals(&self, other: &dyn ContextElement) -> bool {
// If its a u64 then compare them directly, otherwise defer // // If its a u64 then compare them directly, otherwise defer
// to the other type's implementation of CompareContextElement // // to the other type's implementation of CompareContextElement
// since the end user could add any type. // // since the end user could add any type.
match other.to_any().downcast_ref::<Self>() { // match other.to_any().downcast_ref::<Self>() {
None => other.equals(self), // None => other.equals(self),
Some(other_num) => self == other_num, // Some(other_num) => self == other_num,
} // }
} // }
fn partial_compare(&self, other: &dyn ContextElement) -> Option<Ordering> { // fn partial_compare(&self, other: &dyn ContextElement) -> Option<Ordering> {
println!("partial_compare u64 {:?} | {:?}", self, other); // println!("partial_compare u64 {:?} | {:?}", self, other);
// If its a u64 then compare them directly, otherwise defer // // If its a u64 then compare them directly, otherwise defer
// to the other type's implementation of CompareContextElement // // to the other type's implementation of CompareContextElement
// since the end user could add any type. // // since the end user could add any type.
match other.to_any().downcast_ref::<Self>() { // match other.to_any().downcast_ref::<Self>() {
None => match other.partial_compare(self) { // None => match other.partial_compare(self) {
None => None, // None => None,
Some(ord) => match ord { // Some(ord) => match ord {
Ordering::Equal => Some(Ordering::Equal), // Ordering::Equal => Some(Ordering::Equal),
Ordering::Greater => Some(Ordering::Less), // Ordering::Greater => Some(Ordering::Less),
Ordering::Less => Some(Ordering::Greater), // Ordering::Less => Some(Ordering::Greater),
}, // },
}, // },
Some(other_num) => self.partial_cmp(other_num), // Some(other_num) => self.partial_cmp(other_num),
} // }
} // }
} // }