duster/src/renderer/parameters_context.rs

87 lines
2.5 KiB
Rust
Raw Normal View History

use crate::parser::KVPair;
2020-05-09 02:34:58 +00:00
use crate::parser::{Filter, RValue};
use crate::renderer::context_element::ContextElement;
2020-05-09 18:53:53 +00:00
use crate::renderer::walking::walk_path;
2020-05-09 02:34:58 +00:00
use crate::renderer::Loopable;
use crate::renderer::RenderError;
use crate::renderer::Renderable;
2020-05-09 18:10:38 +00:00
use crate::renderer::WalkError;
2020-05-09 02:34:58 +00:00
use crate::renderer::Walkable;
use std::collections::HashMap;
#[derive(Clone, Debug)]
pub struct ParametersContext<'a> {
params: HashMap<&'a str, &'a RValue<'a>>,
breadcrumbs: &'a Vec<&'a dyn ContextElement>,
}
impl<'a> ParametersContext<'a> {
pub fn new(
breadcrumbs: &'a Vec<&'a dyn ContextElement>,
params: &'a Vec<KVPair<'a>>,
) -> ParametersContext<'a> {
let param_map = params
.iter()
.map(|pair: &KVPair<'a>| (pair.key, &pair.value))
.collect();
ParametersContext {
params: param_map,
breadcrumbs: breadcrumbs,
}
}
}
2020-05-09 02:34:58 +00:00
impl<'a> ContextElement for ParametersContext<'a> {}
impl<'a> Renderable for ParametersContext<'a> {
fn render(&self, _filters: &Vec<Filter>) -> Result<String, RenderError> {
2020-05-09 18:53:53 +00:00
// 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 `{.}`.
2020-05-09 02:34:58 +00:00
Ok("[object Object]".to_owned())
}
}
impl<'a> Loopable for ParametersContext<'a> {
2020-05-09 18:18:45 +00:00
fn get_loop_elements(&self) -> Vec<&dyn ContextElement> {
2020-05-09 18:53:53 +00:00
// 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 `{.}`.
2020-05-09 18:18:45 +00:00
vec![self]
2020-05-09 02:34:58 +00:00
}
}
impl<'a> Walkable for ParametersContext<'a> {
2020-05-09 18:10:38 +00:00
fn walk(&self, segment: &str) -> Result<&dyn ContextElement, WalkError> {
2020-05-09 18:53:53 +00:00
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> {
2020-05-09 18:10:38 +00:00
Err(WalkError::CantWalk)
2020-05-09 02:34:58 +00:00
}
}