Partial simple is working.
This commit is contained in:
parent
ad498abb74
commit
bbb9b8d9d3
@ -4,6 +4,7 @@ mod context_element;
|
|||||||
mod errors;
|
mod errors;
|
||||||
mod parameters_context;
|
mod parameters_context;
|
||||||
mod renderer;
|
mod renderer;
|
||||||
|
mod walking;
|
||||||
|
|
||||||
pub use context_element::ContextElement;
|
pub use context_element::ContextElement;
|
||||||
pub use context_element::Loopable;
|
pub use context_element::Loopable;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use crate::parser::KVPair;
|
use crate::parser::KVPair;
|
||||||
use crate::parser::{Filter, RValue};
|
use crate::parser::{Filter, RValue};
|
||||||
use crate::renderer::context_element::ContextElement;
|
use crate::renderer::context_element::ContextElement;
|
||||||
|
use crate::renderer::walking::walk_path;
|
||||||
use crate::renderer::Loopable;
|
use crate::renderer::Loopable;
|
||||||
use crate::renderer::RenderError;
|
use crate::renderer::RenderError;
|
||||||
use crate::renderer::Renderable;
|
use crate::renderer::Renderable;
|
||||||
@ -34,20 +35,52 @@ impl<'a> ContextElement for ParametersContext<'a> {}
|
|||||||
|
|
||||||
impl<'a> Renderable for ParametersContext<'a> {
|
impl<'a> Renderable for ParametersContext<'a> {
|
||||||
fn render(&self, _filters: &Vec<Filter>) -> Result<String, RenderError> {
|
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())
|
Ok("[object Object]".to_owned())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Loopable for ParametersContext<'a> {
|
impl<'a> Loopable for ParametersContext<'a> {
|
||||||
fn get_loop_elements(&self) -> Vec<&dyn ContextElement> {
|
fn get_loop_elements(&self) -> Vec<&dyn ContextElement> {
|
||||||
// TODO: Would this even ever be called? Won't matter, but I'd like to know.
|
// 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![self]
|
vec![self]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Walkable for ParametersContext<'a> {
|
impl<'a> Walkable for ParametersContext<'a> {
|
||||||
fn walk(&self, segment: &str) -> Result<&dyn ContextElement, WalkError> {
|
fn walk(&self, segment: &str) -> Result<&dyn ContextElement, WalkError> {
|
||||||
// TODO: Actually implement
|
let rval = self.params.get(segment).ok_or(WalkError::CantWalk)?;
|
||||||
|
match rval {
|
||||||
|
RValue::RVPath(path) => walk_path(self.breadcrumbs, &path.keys),
|
||||||
|
RValue::RVString(text) => Ok(text),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ContextElement for String {}
|
||||||
|
|
||||||
|
impl Renderable for String {
|
||||||
|
fn render(&self, _filters: &Vec<Filter>) -> Result<String, RenderError> {
|
||||||
|
Ok(self.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Loopable for String {
|
||||||
|
fn get_loop_elements(&self) -> Vec<&dyn ContextElement> {
|
||||||
|
if self.is_empty() {
|
||||||
|
Vec::new()
|
||||||
|
} else {
|
||||||
|
vec![self]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Walkable for String {
|
||||||
|
fn walk(&self, segment: &str) -> Result<&dyn ContextElement, WalkError> {
|
||||||
Err(WalkError::CantWalk)
|
Err(WalkError::CantWalk)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ 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;
|
||||||
use crate::renderer::parameters_context::ParametersContext;
|
use crate::renderer::parameters_context::ParametersContext;
|
||||||
|
use crate::renderer::walking::walk_path;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -202,57 +203,6 @@ impl<'a> DustRenderer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum WalkResult<'a> {
|
|
||||||
NoWalk,
|
|
||||||
PartialWalk,
|
|
||||||
FullyWalked(&'a dyn ContextElement),
|
|
||||||
}
|
|
||||||
|
|
||||||
fn walk_path_from_single_level<'a>(
|
|
||||||
context: &'a dyn ContextElement,
|
|
||||||
path: &Vec<&str>,
|
|
||||||
) -> WalkResult<'a> {
|
|
||||||
if path.is_empty() {
|
|
||||||
return WalkResult::FullyWalked(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut walk_failure = WalkResult::NoWalk;
|
|
||||||
let mut output = context;
|
|
||||||
for elem in path.iter() {
|
|
||||||
let new_val = output.walk(elem);
|
|
||||||
match output.walk(elem) {
|
|
||||||
Err(WalkError::CantWalk { .. }) => {
|
|
||||||
return walk_failure;
|
|
||||||
}
|
|
||||||
Ok(new_val) => {
|
|
||||||
walk_failure = WalkResult::PartialWalk;
|
|
||||||
output = new_val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WalkResult::FullyWalked(output)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn walk_path<'a>(
|
|
||||||
breadcrumbs: &Vec<&'a dyn ContextElement>,
|
|
||||||
path: &'a Vec<&str>,
|
|
||||||
) -> Result<&'a dyn ContextElement, WalkError> {
|
|
||||||
for context in breadcrumbs.iter().rev() {
|
|
||||||
match walk_path_from_single_level(*context, path) {
|
|
||||||
// If no walking was done at all, keep looping
|
|
||||||
WalkResult::NoWalk => {}
|
|
||||||
// If we partially walked then stop trying to find
|
|
||||||
// anything
|
|
||||||
WalkResult::PartialWalk => {
|
|
||||||
return Err(WalkError::CantWalk);
|
|
||||||
}
|
|
||||||
WalkResult::FullyWalked(new_context) => return Ok(new_context),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(WalkError::CantWalk)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
Loading…
Reference in New Issue
Block a user