Starting the new parameters context object.
This commit is contained in:
parent
7bf8012d6e
commit
ff74d78fdb
@ -5,7 +5,7 @@ mod context_element;
|
|||||||
mod errors;
|
mod errors;
|
||||||
mod inline_partial_tree;
|
mod inline_partial_tree;
|
||||||
// mod iteration_context;
|
// mod iteration_context;
|
||||||
// mod parameters_context;
|
mod parameters_context;
|
||||||
mod renderer;
|
mod renderer;
|
||||||
mod tree_walking;
|
mod tree_walking;
|
||||||
mod walking;
|
mod walking;
|
||||||
|
@ -1,264 +1,20 @@
|
|||||||
use crate::parser::KVPair;
|
use crate::parser::KVPair;
|
||||||
use crate::parser::{Filter, OwnedLiteral, PartialNameElement, 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::context_element::IntoContextElement;
|
||||||
use crate::renderer::walking::walk_path;
|
|
||||||
use crate::renderer::DustRenderer;
|
use crate::renderer::DustRenderer;
|
||||||
use crate::renderer::Loopable;
|
use std::collections::HashMap;
|
||||||
use crate::renderer::RenderError;
|
|
||||||
use crate::renderer::Renderable;
|
|
||||||
use crate::renderer::Truthiness;
|
|
||||||
use crate::renderer::WalkError;
|
|
||||||
use crate::renderer::Walkable;
|
|
||||||
use std::{cmp::Ordering, collections::HashMap};
|
|
||||||
|
|
||||||
/// Copy the data from an RValue to an Owned struct
|
|
||||||
///
|
|
||||||
/// In order to get comparisons to work for our `ContextElement` trait
|
|
||||||
/// objects, we need to be able to use `std::any::Any`. Unfortunately,
|
|
||||||
/// `Any` requires that the structs do not have a lifetime (so they
|
|
||||||
/// will have a `'static` lifetime. This means that we cannot have a
|
|
||||||
/// `<'a>` appended to the struct type, so the struct cannot contain
|
|
||||||
/// any borrows. Rather than impose the copy cost in the parser, we
|
|
||||||
/// 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
|
|
||||||
/// input string.
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub enum OwnedRValue {
|
|
||||||
RVPath(OwnedPath),
|
|
||||||
RVTemplate(Vec<PartialNameElement>),
|
|
||||||
RVLiteral(OwnedLiteral),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub struct OwnedPath {
|
|
||||||
pub keys: Vec<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&RValue<'_>> for OwnedRValue {
|
|
||||||
fn from(original: &RValue<'_>) -> Self {
|
|
||||||
match original {
|
|
||||||
RValue::RVLiteral(literal) => OwnedRValue::RVLiteral(literal.clone()),
|
|
||||||
RValue::RVTemplate(template) => OwnedRValue::RVTemplate(template.clone()),
|
|
||||||
RValue::RVPath(path) => OwnedRValue::RVPath(OwnedPath {
|
|
||||||
keys: path.keys.iter().map(|k| k.to_string()).collect(),
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ParametersContext {
|
pub struct ParametersContext<'a> {
|
||||||
params: HashMap<String, OwnedRValue>,
|
params: HashMap<&'a str, &'a dyn IntoContextElement>,
|
||||||
breadcrumbs: Vec<Box<dyn IntoContextElement>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParametersContext {
|
impl<'a> ParametersContext<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
breadcrumbs: &Vec<&dyn IntoContextElement>,
|
|
||||||
params: &Vec<KVPair>,
|
|
||||||
) -> ParametersContext {
|
|
||||||
let owned_params: HashMap<String, OwnedRValue> = params
|
|
||||||
.iter()
|
|
||||||
.map(|kvpair| (kvpair.key.to_string(), OwnedRValue::from(&kvpair.value)))
|
|
||||||
.collect();
|
|
||||||
let owned_breadcrumbs: Vec<Box<dyn IntoContextElement>> =
|
|
||||||
breadcrumbs.iter().map(|ce| ce.clone_to_box()).collect();
|
|
||||||
|
|
||||||
ParametersContext {
|
|
||||||
params: owned_params,
|
|
||||||
breadcrumbs: owned_breadcrumbs,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ContextElement for ParametersContext {}
|
|
||||||
|
|
||||||
impl Truthiness for ParametersContext {
|
|
||||||
fn is_truthy(&self) -> bool {
|
|
||||||
// TODO: Would this even ever be called? Won't matter, but I'd
|
|
||||||
// like to know. Since it is injected 1 above the current
|
|
||||||
// context, we wouldn't be able to access it with `{.}`.
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Renderable for ParametersContext {
|
|
||||||
fn render(&self, _filters: &Vec<Filter>) -> Result<String, RenderError> {
|
|
||||||
// TODO: Would this even ever be called? Won't matter, but I'd
|
|
||||||
// like to know. Since it is injected 1 above the current
|
|
||||||
// context, we wouldn't be able to access it with `{.}`.
|
|
||||||
Ok("[object Object]".to_owned())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Loopable for ParametersContext {
|
|
||||||
fn get_loop_elements(&self) -> Vec<&dyn ContextElement> {
|
|
||||||
// TODO: Would this even ever be called? Won't matter, but I'd
|
|
||||||
// like to know. Since it is injected 1 above the current
|
|
||||||
// context, we wouldn't be able to access it with `{.}`.
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Walkable for ParametersContext {
|
|
||||||
fn walk(&self, segment: &str) -> Result<&dyn IntoContextElement, WalkError> {
|
|
||||||
let rval = self.params.get(segment).ok_or(WalkError::CantWalk)?;
|
|
||||||
match rval {
|
|
||||||
OwnedRValue::RVPath(path) => walk_path(&self.breadcrumbs, &path.keys),
|
|
||||||
OwnedRValue::RVTemplate(template) => Ok(template),
|
|
||||||
OwnedRValue::RVLiteral(literal) => Ok(literal),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_pseudo_element(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Clone for ParametersContext {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
let new_params: HashMap<String, OwnedRValue> = self
|
|
||||||
.params
|
|
||||||
.iter()
|
|
||||||
.map(|(k, v)| (k.clone(), v.clone()))
|
|
||||||
.collect();
|
|
||||||
let new_breadcrumbs: Vec<Box<dyn IntoContextElement>> = self
|
|
||||||
.breadcrumbs
|
|
||||||
.iter()
|
|
||||||
.map(|bread| bread.clone_to_box())
|
|
||||||
.collect();
|
|
||||||
ParametersContext {
|
|
||||||
params: new_params,
|
|
||||||
breadcrumbs: new_breadcrumbs,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CompareContextElement for ParametersContext {
|
|
||||||
fn equals(&self, other: &dyn ContextElement) -> bool {
|
|
||||||
// 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 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<Filter>) -> Result<String, RenderError> {
|
|
||||||
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::<Self>() {
|
|
||||||
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<Ordering> {
|
|
||||||
// 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::<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_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),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IntoContextElement for Vec<PartialNameElement> {
|
|
||||||
fn into_context_element(
|
|
||||||
&self,
|
|
||||||
renderer: &DustRenderer,
|
renderer: &DustRenderer,
|
||||||
breadcrumbs: &Vec<&dyn IntoContextElement>,
|
breadcrumbs: Option<&BreadcrumbTree>,
|
||||||
) -> &dyn ContextElement {
|
params: &Vec<KVPair>,
|
||||||
// OwnedLiteral::LString(
|
) -> Self {
|
||||||
// renderer
|
todo!()
|
||||||
// .render_partial_name(self, breadcrumbs)
|
|
||||||
// .expect("TODO: Make into_context_element return a RenderError"),
|
|
||||||
// )
|
|
||||||
// TODO
|
|
||||||
&OwnedLiteral::LPositiveInteger(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Walkable for Vec<PartialNameElement> {
|
|
||||||
fn walk(&self, segment: &str) -> Result<&dyn IntoContextElement, WalkError> {
|
|
||||||
Err(WalkError::CantWalk)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
264
src/renderer/parameters_context_old.rs
Normal file
264
src/renderer/parameters_context_old.rs
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
use crate::parser::KVPair;
|
||||||
|
use crate::parser::{Filter, OwnedLiteral, PartialNameElement, RValue};
|
||||||
|
use crate::renderer::context_element::CompareContextElement;
|
||||||
|
use crate::renderer::context_element::ContextElement;
|
||||||
|
use crate::renderer::context_element::IntoContextElement;
|
||||||
|
use crate::renderer::walking::walk_path;
|
||||||
|
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, collections::HashMap};
|
||||||
|
|
||||||
|
/// Copy the data from an RValue to an Owned struct
|
||||||
|
///
|
||||||
|
/// In order to get comparisons to work for our `ContextElement` trait
|
||||||
|
/// objects, we need to be able to use `std::any::Any`. Unfortunately,
|
||||||
|
/// `Any` requires that the structs do not have a lifetime (so they
|
||||||
|
/// will have a `'static` lifetime. This means that we cannot have a
|
||||||
|
/// `<'a>` appended to the struct type, so the struct cannot contain
|
||||||
|
/// any borrows. Rather than impose the copy cost in the parser, we
|
||||||
|
/// 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
|
||||||
|
/// input string.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum OwnedRValue {
|
||||||
|
RVPath(OwnedPath),
|
||||||
|
RVTemplate(Vec<PartialNameElement>),
|
||||||
|
RVLiteral(OwnedLiteral),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct OwnedPath {
|
||||||
|
pub keys: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&RValue<'_>> for OwnedRValue {
|
||||||
|
fn from(original: &RValue<'_>) -> Self {
|
||||||
|
match original {
|
||||||
|
RValue::RVLiteral(literal) => OwnedRValue::RVLiteral(literal.clone()),
|
||||||
|
RValue::RVTemplate(template) => OwnedRValue::RVTemplate(template.clone()),
|
||||||
|
RValue::RVPath(path) => OwnedRValue::RVPath(OwnedPath {
|
||||||
|
keys: path.keys.iter().map(|k| k.to_string()).collect(),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ParametersContext {
|
||||||
|
params: HashMap<String, OwnedRValue>,
|
||||||
|
breadcrumbs: Vec<Box<dyn IntoContextElement>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParametersContext {
|
||||||
|
pub fn new(
|
||||||
|
breadcrumbs: &Vec<&dyn IntoContextElement>,
|
||||||
|
params: &Vec<KVPair>,
|
||||||
|
) -> ParametersContext {
|
||||||
|
let owned_params: HashMap<String, OwnedRValue> = params
|
||||||
|
.iter()
|
||||||
|
.map(|kvpair| (kvpair.key.to_string(), OwnedRValue::from(&kvpair.value)))
|
||||||
|
.collect();
|
||||||
|
let owned_breadcrumbs: Vec<Box<dyn IntoContextElement>> =
|
||||||
|
breadcrumbs.iter().map(|ce| ce.clone_to_box()).collect();
|
||||||
|
|
||||||
|
ParametersContext {
|
||||||
|
params: owned_params,
|
||||||
|
breadcrumbs: owned_breadcrumbs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ContextElement for ParametersContext {}
|
||||||
|
|
||||||
|
impl Truthiness for ParametersContext {
|
||||||
|
fn is_truthy(&self) -> bool {
|
||||||
|
// TODO: Would this even ever be called? Won't matter, but I'd
|
||||||
|
// like to know. Since it is injected 1 above the current
|
||||||
|
// context, we wouldn't be able to access it with `{.}`.
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Renderable for ParametersContext {
|
||||||
|
fn render(&self, _filters: &Vec<Filter>) -> Result<String, RenderError> {
|
||||||
|
// TODO: Would this even ever be called? Won't matter, but I'd
|
||||||
|
// like to know. Since it is injected 1 above the current
|
||||||
|
// context, we wouldn't be able to access it with `{.}`.
|
||||||
|
Ok("[object Object]".to_owned())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Loopable for ParametersContext {
|
||||||
|
fn get_loop_elements(&self) -> Vec<&dyn ContextElement> {
|
||||||
|
// TODO: Would this even ever be called? Won't matter, but I'd
|
||||||
|
// like to know. Since it is injected 1 above the current
|
||||||
|
// context, we wouldn't be able to access it with `{.}`.
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Walkable for ParametersContext {
|
||||||
|
fn walk(&self, segment: &str) -> Result<&dyn IntoContextElement, WalkError> {
|
||||||
|
let rval = self.params.get(segment).ok_or(WalkError::CantWalk)?;
|
||||||
|
match rval {
|
||||||
|
OwnedRValue::RVPath(path) => walk_path(&self.breadcrumbs, &path.keys),
|
||||||
|
OwnedRValue::RVTemplate(template) => Ok(template),
|
||||||
|
OwnedRValue::RVLiteral(literal) => Ok(literal),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_pseudo_element(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for ParametersContext {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
let new_params: HashMap<String, OwnedRValue> = self
|
||||||
|
.params
|
||||||
|
.iter()
|
||||||
|
.map(|(k, v)| (k.clone(), v.clone()))
|
||||||
|
.collect();
|
||||||
|
let new_breadcrumbs: Vec<Box<dyn IntoContextElement>> = self
|
||||||
|
.breadcrumbs
|
||||||
|
.iter()
|
||||||
|
.map(|bread| bread.clone_to_box())
|
||||||
|
.collect();
|
||||||
|
ParametersContext {
|
||||||
|
params: new_params,
|
||||||
|
breadcrumbs: new_breadcrumbs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CompareContextElement for ParametersContext {
|
||||||
|
fn equals(&self, other: &dyn ContextElement) -> bool {
|
||||||
|
// 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 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<Filter>) -> Result<String, RenderError> {
|
||||||
|
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::<Self>() {
|
||||||
|
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<Ordering> {
|
||||||
|
// 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::<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_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),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoContextElement for Vec<PartialNameElement> {
|
||||||
|
fn into_context_element(
|
||||||
|
&self,
|
||||||
|
renderer: &DustRenderer,
|
||||||
|
breadcrumbs: &Vec<&dyn IntoContextElement>,
|
||||||
|
) -> &dyn ContextElement {
|
||||||
|
// OwnedLiteral::LString(
|
||||||
|
// renderer
|
||||||
|
// .render_partial_name(self, breadcrumbs)
|
||||||
|
// .expect("TODO: Make into_context_element return a RenderError"),
|
||||||
|
// )
|
||||||
|
// TODO
|
||||||
|
&OwnedLiteral::LPositiveInteger(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Walkable for Vec<PartialNameElement> {
|
||||||
|
fn walk(&self, segment: &str) -> Result<&dyn IntoContextElement, WalkError> {
|
||||||
|
Err(WalkError::CantWalk)
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user