Merge branch 'walkable' into render

This commit is contained in:
Tom Alexander 2020-04-11 22:37:27 -04:00
commit 0f60baf31c
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
3 changed files with 95 additions and 0 deletions

View File

@ -3,8 +3,11 @@
mod errors;
mod renderable;
mod renderer;
mod walkable;
pub use renderable::Renderable;
pub use renderer::compile_template;
pub use renderer::CompiledTemplate;
pub use renderer::DustRenderer;
pub use walkable::ContextElement;
pub use walkable::Walkable;

View File

@ -5,6 +5,8 @@ use crate::parser::TemplateElement;
use crate::renderer::errors::CompileError;
use crate::renderer::errors::RenderError;
use crate::renderer::renderable::Renderable;
use crate::renderer::walkable::ContextElement;
use crate::renderer::walkable::Walkable;
use std::collections::HashMap;
use std::ops::Index;
@ -93,3 +95,85 @@ impl<'a> DustRenderer<'a> {
Ok("".to_owned())
}
}
fn walk_path<'a>(context: &'a dyn ContextElement, path: &Vec<&str>) -> &'a dyn ContextElement {
let mut output = context;
for elem in path.iter() {
output = output.walk(elem);
}
output
}
#[cfg(test)]
mod tests {
use super::*;
impl ContextElement for u32 {}
impl ContextElement for &str {}
impl<I: ContextElement> ContextElement for HashMap<&str, I> {}
impl Renderable for u32 {
fn render(&self) -> std::string::String {
self.to_string()
}
}
impl Renderable for &str {
fn render(&self) -> std::string::String {
self.to_string()
}
}
impl<I: ContextElement> Renderable for HashMap<&str, I> {
fn render(&self) -> std::string::String {
panic!("Attempted to render a hashmap");
}
}
impl<I: ContextElement> Walkable for HashMap<&str, I> {
fn walk(&self, segment: &str) -> &dyn ContextElement {
self.get(segment).unwrap()
}
}
impl Walkable for &str {
fn walk(&self, _segment: &str) -> &dyn ContextElement {
panic!("Tried to walk down a str");
}
}
impl Walkable for u32 {
fn walk(&self, _segment: &str) -> &dyn ContextElement {
panic!("Tried to walk down a str");
}
}
#[test]
fn test_walk_path() {
let context: HashMap<&str, &str> =
[("cat", "kitty"), ("dog", "doggy"), ("tiger", "murderkitty")]
.iter()
.cloned()
.collect();
let number_context: HashMap<&str, u32> = [("cat", 1), ("dog", 2), ("tiger", 3)]
.iter()
.cloned()
.collect();
let deep_context: HashMap<&str, HashMap<&str, &str>> = [
("cat", [("food", "meat")].iter().cloned().collect()),
("dog", [("food", "meat")].iter().cloned().collect()),
("tiger", [("food", "people")].iter().cloned().collect()),
]
.iter()
.cloned()
.collect();
assert_eq!(walk_path(&context, &vec!["cat"]).render(), "kitty");
assert_eq!(walk_path(&number_context, &vec!["tiger"]).render(), "3");
assert_eq!(
walk_path(&deep_context, &vec!["tiger", "food"]).render(),
"people"
);
}
}

8
src/renderer/walkable.rs Normal file
View File

@ -0,0 +1,8 @@
use super::renderable::Renderable;
use std::fmt::Debug;
pub trait ContextElement: Walkable + Renderable + Debug {}
pub trait Walkable {
fn walk(&self, segment: &str) -> &dyn ContextElement;
}