Starting an IntoContextElement trait to allow for delayed evaluation.

This commit is contained in:
Tom Alexander 2020-05-30 16:34:32 -04:00
parent 581f9f7e97
commit 975ab278ef
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
5 changed files with 53 additions and 1 deletions

View File

@ -110,6 +110,7 @@ pub struct Partial<'a> {
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum OwnedLiteral { pub enum OwnedLiteral {
LString(String),
LPositiveInteger(u64), LPositiveInteger(u64),
} }

View File

@ -12,6 +12,7 @@ pub trait ContextElement:
+ Loopable + Loopable
+ CloneIntoBoxedContextElement + CloneIntoBoxedContextElement
+ CompareContextElement + CompareContextElement
+ FromContextElement
{ {
} }
@ -86,3 +87,23 @@ impl<'a, 'b> PartialOrd<&'b dyn ContextElement> for &'a dyn ContextElement {
self.partial_compare(*other) self.partial_compare(*other)
} }
} }
pub trait FromContextElement {
fn from_context_element(&self) -> &dyn IntoContextElement;
}
impl<C: ContextElement> FromContextElement for C {
fn from_context_element(&self) -> &dyn IntoContextElement {
self
}
}
pub trait IntoContextElement {
fn into_context_element(&self) -> &dyn ContextElement;
}
impl<C: ContextElement> IntoContextElement for C {
fn into_context_element(&self) -> &dyn ContextElement {
self
}
}

View File

@ -11,6 +11,7 @@ mod walking;
pub use context_element::CloneIntoBoxedContextElement; pub use context_element::CloneIntoBoxedContextElement;
pub use context_element::CompareContextElement; pub use context_element::CompareContextElement;
pub use context_element::ContextElement; pub use context_element::ContextElement;
pub use context_element::IntoContextElement;
pub use context_element::Loopable; pub use context_element::Loopable;
pub use context_element::Renderable; pub use context_element::Renderable;
pub use context_element::Truthiness; pub use context_element::Truthiness;

View File

@ -1,7 +1,8 @@
use crate::parser::KVPair; use crate::parser::KVPair;
use crate::parser::{Filter, OwnedLiteral, RValue}; use crate::parser::{Filter, OwnedLiteral, PartialNameElement, RValue};
use crate::renderer::context_element::CompareContextElement; use crate::renderer::context_element::CompareContextElement;
use crate::renderer::context_element::ContextElement; use crate::renderer::context_element::ContextElement;
use crate::renderer::context_element::IntoContextElement;
use crate::renderer::walking::walk_path; use crate::renderer::walking::walk_path;
use crate::renderer::Loopable; use crate::renderer::Loopable;
use crate::renderer::RenderError; use crate::renderer::RenderError;
@ -37,6 +38,9 @@ impl From<&RValue<'_>> for OwnedRValue {
fn from(original: &RValue<'_>) -> Self { fn from(original: &RValue<'_>) -> Self {
match original { match original {
RValue::RVLiteral(literal) => OwnedRValue::RVLiteral(literal.clone()), RValue::RVLiteral(literal) => OwnedRValue::RVLiteral(literal.clone()),
RValue::RVTemplate(template) => {
OwnedRValue::RVLiteral(OwnedLiteral::LString("TODO".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(),
}), }),
@ -232,3 +236,9 @@ impl CompareContextElement for OwnedLiteral {
} }
} }
} }
impl IntoContextElement for Vec<PartialNameElement> {
fn into_context_element(&self) -> &dyn ContextElement {
&OwnedLiteral::LPositiveInteger(1)
}
}

View File

@ -9,6 +9,7 @@ use crate::parser::Special;
use crate::parser::Template; use crate::parser::Template;
use crate::parser::{Filter, TemplateElement}; use crate::parser::{Filter, TemplateElement};
use crate::renderer::context_element::ContextElement; use crate::renderer::context_element::ContextElement;
use crate::renderer::context_element::IntoContextElement;
use crate::renderer::errors::CompileError; use crate::renderer::errors::CompileError;
use crate::renderer::errors::RenderError; use crate::renderer::errors::RenderError;
use crate::renderer::errors::WalkError; use crate::renderer::errors::WalkError;
@ -664,6 +665,23 @@ impl<'a> DustRenderer<'a> {
.collect() .collect()
} }
fn new_get_rval<'b>(
breadcrumbs: &'b Vec<&'b dyn ContextElement>,
param_map: &HashMap<&str, &'b RValue<'b>>,
key: &str,
) -> Option<Result<&'b dyn IntoContextElement, WalkError>> {
match param_map.get(key) {
None => None,
Some(rval) => match rval {
RValue::RVLiteral(literal) => Some(Ok(literal)),
RValue::RVTemplate(template) => Some(Ok(template)),
RValue::RVPath(path) => {
Some(walk_path(breadcrumbs, &path.keys).map(|ce| ce.from_context_element()))
}
},
}
}
fn get_rval<'b>( fn get_rval<'b>(
breadcrumbs: &'b Vec<&'b dyn ContextElement>, breadcrumbs: &'b Vec<&'b dyn ContextElement>,
param_map: &HashMap<&str, &'b RValue<'b>>, param_map: &HashMap<&str, &'b RValue<'b>>,
@ -673,6 +691,7 @@ impl<'a> DustRenderer<'a> {
None => None, None => None,
Some(rval) => match rval { Some(rval) => match rval {
RValue::RVLiteral(literal) => Some(Ok(literal)), RValue::RVLiteral(literal) => Some(Ok(literal)),
RValue::RVTemplate(template) => None,
RValue::RVPath(path) => Some(walk_path(breadcrumbs, &path.keys)), RValue::RVPath(path) => Some(walk_path(breadcrumbs, &path.keys)),
}, },
} }