From d5c3985c295e1ca104565728413608b53485d41e Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 11 Apr 2020 20:31:44 -0400 Subject: [PATCH 01/18] initial walkable implementation --- src/renderer/mod.rs | 2 ++ src/renderer/renderer.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index 6f91eb7..81b7e79 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -3,8 +3,10 @@ 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::Walkable; diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index 99f3aba..383e99f 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -5,6 +5,7 @@ use crate::parser::TemplateElement; use crate::renderer::errors::CompileError; use crate::renderer::errors::RenderError; use crate::renderer::renderable::Renderable; +use crate::renderer::walkable::Walkable; use std::collections::HashMap; use std::ops::Index; @@ -93,3 +94,42 @@ impl<'a> DustRenderer<'a> { Ok("".to_owned()) } } + +fn walk_path<'a, C>(context: &'a C, path: &Vec<&str>) -> &'a C +where + C: Walkable, +{ + let mut output: &C = context; + + for elem in path.iter() { + output = context.walk(elem); + } + + output +} + +#[cfg(test)] +mod tests { + use super::*; + + impl<'a> Walkable for HashMap<&str, &str> { + type Output = str; + + fn walk(&self, segment: &str) -> &str { + self.get(segment).unwrap() + } + } + + #[test] + fn test_walk_path() { + let context: HashMap<&str, &str> = [ + ("cat", "kitty"), + ("dog", "doggy"), + ("tiger", "murder kitty"), + ] + .iter() + .cloned() + .collect(); + assert_eq!(context.walk("cat"), "kitty"); + } +} From 7ace4be3c747a1a7a3828c0be5dcfc2669e73b06 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 11 Apr 2020 20:34:16 -0400 Subject: [PATCH 02/18] working on two levels --- src/renderer/renderer.rs | 8 ++++++++ src/renderer/walkable.rs | 7 +++++++ 2 files changed, 15 insertions(+) create mode 100644 src/renderer/walkable.rs diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index 383e99f..5ec7a3c 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -120,6 +120,14 @@ mod tests { } } + impl<'a> Walkable for str { + type Output = str; + + fn walk(&self, segment: &str) -> &str { + panic!("Tried to walk down a str"); + } + } + #[test] fn test_walk_path() { let context: HashMap<&str, &str> = [ diff --git a/src/renderer/walkable.rs b/src/renderer/walkable.rs new file mode 100644 index 0000000..1c2fdc9 --- /dev/null +++ b/src/renderer/walkable.rs @@ -0,0 +1,7 @@ +use super::renderable::Renderable; + +pub trait Walkable { + type Output: ?Sized + Walkable; + + fn walk(&self, segment: &str) -> &Self::Output; +} From d296ad6b5673b0da3fda4c37470d5368b730d946 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 11 Apr 2020 21:03:21 -0400 Subject: [PATCH 03/18] Maybe have a generic implementation of walkable working --- src/renderer/renderer.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index 5ec7a3c..60a7db9 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -112,32 +112,32 @@ where mod tests { use super::*; - impl<'a> Walkable for HashMap<&str, &str> { - type Output = str; + impl<'a, I: Walkable> Walkable for HashMap<&str, I> { + type Output = I; - fn walk(&self, segment: &str) -> &str { + fn walk(&self, segment: &str) -> &I { self.get(segment).unwrap() } } - impl<'a> Walkable for str { - type Output = str; + impl<'a> Walkable for u32 { + type Output = u32; - fn walk(&self, segment: &str) -> &str { + fn walk(&self, segment: &str) -> &u32 { panic!("Tried to walk down a str"); } } + fn do_the_walk<'a>(c: &'a (dyn Walkable + 'a), path: &str) -> &'a u32 { + c.walk(path) + } + #[test] fn test_walk_path() { - let context: HashMap<&str, &str> = [ - ("cat", "kitty"), - ("dog", "doggy"), - ("tiger", "murder kitty"), - ] - .iter() - .cloned() - .collect(); - assert_eq!(context.walk("cat"), "kitty"); + let context: HashMap<&str, u32> = [("cat", 1), ("dog", 2), ("tiger", 3)] + .iter() + .cloned() + .collect(); + assert_eq!(do_the_walk(&context, "cat"), &1); } } From 63124bc6e302fbacc1c0b642a3c1bf5e903ddf0e Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 11 Apr 2020 21:07:12 -0400 Subject: [PATCH 04/18] Adding &str --- src/renderer/renderer.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index 60a7db9..724ec3e 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -120,6 +120,14 @@ mod tests { } } + impl<'a> Walkable for &str { + type Output = u32; + + fn walk(&self, segment: &str) -> &u32 { + panic!("Tried to walk down a str"); + } + } + impl<'a> Walkable for u32 { type Output = u32; @@ -128,16 +136,17 @@ mod tests { } } - fn do_the_walk<'a>(c: &'a (dyn Walkable + 'a), path: &str) -> &'a u32 { + fn do_the_walk<'a>(c: &'a (dyn Walkable + 'a), path: &str) -> &'a str { c.walk(path) } #[test] fn test_walk_path() { - let context: HashMap<&str, u32> = [("cat", 1), ("dog", 2), ("tiger", 3)] - .iter() - .cloned() - .collect(); - assert_eq!(do_the_walk(&context, "cat"), &1); + let context: HashMap<&str, &str> = + [("cat", "kitty"), ("dog", "doggy"), ("tiger", "murderkitty")] + .iter() + .cloned() + .collect(); + assert_eq!(do_the_walk(&context, "cat"), "kitty"); } } From 9e1f1025401c70f1f1e190e021d89385fbd943a0 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 11 Apr 2020 21:07:39 -0400 Subject: [PATCH 05/18] removing unnecessary static --- src/renderer/renderer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index 724ec3e..85cf017 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -136,7 +136,7 @@ mod tests { } } - fn do_the_walk<'a>(c: &'a (dyn Walkable + 'a), path: &str) -> &'a str { + fn do_the_walk<'a>(c: &'a (dyn Walkable + 'a), path: &str) -> &'a str { c.walk(path) } From c64730166216a3738adaf19c31ff2cbd678c97b8 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 11 Apr 2020 21:08:33 -0400 Subject: [PATCH 06/18] removing unnecessary lifetime --- src/renderer/renderer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index 85cf017..6bd7778 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -136,7 +136,7 @@ mod tests { } } - fn do_the_walk<'a>(c: &'a (dyn Walkable + 'a), path: &str) -> &'a str { + fn do_the_walk<'a>(c: &'a (dyn Walkable), path: &str) -> &'a str { c.walk(path) } From 54e6613f14ceac07298510a320ce23789c671892 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 11 Apr 2020 21:12:42 -0400 Subject: [PATCH 07/18] do_the_walk may be generic now? --- src/renderer/renderer.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index 6bd7778..0426e8f 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -136,7 +136,7 @@ mod tests { } } - fn do_the_walk<'a>(c: &'a (dyn Walkable), path: &str) -> &'a str { + fn do_the_walk<'a, O: Walkable>(c: &'a dyn Walkable, path: &str) -> &'a O { c.walk(path) } @@ -147,6 +147,10 @@ mod tests { .iter() .cloned() .collect(); - assert_eq!(do_the_walk(&context, "cat"), "kitty"); + let number_context: HashMap<&str, u32> = [("cat", 1), ("dog", 2), ("tiger", 3)] + .iter() + .cloned() + .collect(); + assert_eq!(do_the_walk(&context, "cat"), &"kitty"); } } From d89d3d9f3c54cf5adf854fae8d512715746987be Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 11 Apr 2020 21:13:21 -0400 Subject: [PATCH 08/18] Added another test proving do_the_walk is now generic --- src/renderer/renderer.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index 0426e8f..5e05388 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -152,5 +152,6 @@ mod tests { .cloned() .collect(); assert_eq!(do_the_walk(&context, "cat"), &"kitty"); + assert_eq!(do_the_walk(&number_context, "tiger"), &3); } } From f62d50df95015cb845b95ff0dc843a6e24755aea Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 11 Apr 2020 21:20:45 -0400 Subject: [PATCH 09/18] Taking 1 step in a deep context is working! --- src/renderer/renderer.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index 5e05388..f5f5641 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -151,7 +151,19 @@ mod tests { .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!(do_the_walk(&context, "cat"), &"kitty"); assert_eq!(do_the_walk(&number_context, "tiger"), &3); + assert_eq!( + do_the_walk(&deep_context, "tiger"), + &[("food", "people")].iter().cloned().collect() + ); } } From 43e57f4134e305fa671a0e73eb50fde43c65f477 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 11 Apr 2020 21:26:36 -0400 Subject: [PATCH 10/18] setup for moving into a multi-step walk function --- src/renderer/renderer.rs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index f5f5641..446a95d 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -136,8 +136,19 @@ mod tests { } } - fn do_the_walk<'a, O: Walkable>(c: &'a dyn Walkable, path: &str) -> &'a O { - c.walk(path) + fn do_the_walk<'a, O: Walkable>( + context: &'a dyn Walkable, + path: &Vec<&str>, + ) -> &'a O { + let mut output = context; + + context.walk(path.first().unwrap()) + + // for elem in path.iter() { + // output = context.walk(elem); + // } + + // output } #[test] @@ -159,10 +170,10 @@ mod tests { .iter() .cloned() .collect(); - assert_eq!(do_the_walk(&context, "cat"), &"kitty"); - assert_eq!(do_the_walk(&number_context, "tiger"), &3); + assert_eq!(do_the_walk(&context, &vec!["cat"]), &"kitty"); + assert_eq!(do_the_walk(&number_context, &vec!["tiger"]), &3); assert_eq!( - do_the_walk(&deep_context, "tiger"), + do_the_walk(&deep_context, &vec!["tiger"]), &[("food", "people")].iter().cloned().collect() ); } From 110b03fc45ec357ec9798c2299f70c6a27359c90 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 11 Apr 2020 21:44:42 -0400 Subject: [PATCH 11/18] Going to try returning impl trait before resorting to boxing --- src/renderer/renderer.rs | 26 +++++++++++++++++++------- src/renderer/walkable.rs | 2 ++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index 446a95d..87f3101 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -118,6 +118,10 @@ mod tests { fn walk(&self, segment: &str) -> &I { self.get(segment).unwrap() } + + fn val(&self) -> String { + "val".to_owned() + } } impl<'a> Walkable for &str { @@ -126,6 +130,10 @@ mod tests { fn walk(&self, segment: &str) -> &u32 { panic!("Tried to walk down a str"); } + + fn val(&self) -> String { + "val".to_owned() + } } impl<'a> Walkable for u32 { @@ -134,12 +142,16 @@ mod tests { fn walk(&self, segment: &str) -> &u32 { panic!("Tried to walk down a str"); } + + fn val(&self) -> String { + "val".to_owned() + } } fn do_the_walk<'a, O: Walkable>( context: &'a dyn Walkable, path: &Vec<&str>, - ) -> &'a O { + ) -> &'a impl Walkable { let mut output = context; context.walk(path.first().unwrap()) @@ -170,11 +182,11 @@ mod tests { .iter() .cloned() .collect(); - assert_eq!(do_the_walk(&context, &vec!["cat"]), &"kitty"); - assert_eq!(do_the_walk(&number_context, &vec!["tiger"]), &3); - assert_eq!( - do_the_walk(&deep_context, &vec!["tiger"]), - &[("food", "people")].iter().cloned().collect() - ); + assert_eq!(do_the_walk(&context, &vec!["cat"]).val(), "kitty"); + // assert_eq!(do_the_walk(&number_context, &vec!["tiger"]), &3); + // assert_eq!( + // do_the_walk(&deep_context, &vec!["tiger"]), + // &[("food", "people")].iter().cloned().collect() + // ); } } diff --git a/src/renderer/walkable.rs b/src/renderer/walkable.rs index 1c2fdc9..99c31de 100644 --- a/src/renderer/walkable.rs +++ b/src/renderer/walkable.rs @@ -4,4 +4,6 @@ pub trait Walkable { type Output: ?Sized + Walkable; fn walk(&self, segment: &str) -> &Self::Output; + + fn val(&self) -> String; } From ec3276af79a76bbd7264656286704faafd92b2bc Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 11 Apr 2020 21:51:12 -0400 Subject: [PATCH 12/18] Much cleaner with impl walkable but don't know if I can loop yet --- src/renderer/renderer.rs | 5 +---- src/renderer/walkable.rs | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index 87f3101..78192ec 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -148,10 +148,7 @@ mod tests { } } - fn do_the_walk<'a, O: Walkable>( - context: &'a dyn Walkable, - path: &Vec<&str>, - ) -> &'a impl Walkable { + fn do_the_walk<'a>(context: &'a impl Walkable, path: &Vec<&str>) -> &'a impl Walkable { let mut output = context; context.walk(path.first().unwrap()) diff --git a/src/renderer/walkable.rs b/src/renderer/walkable.rs index 99c31de..f93eef1 100644 --- a/src/renderer/walkable.rs +++ b/src/renderer/walkable.rs @@ -1,7 +1,7 @@ use super::renderable::Renderable; pub trait Walkable { - type Output: ?Sized + Walkable; + type Output: Walkable; fn walk(&self, segment: &str) -> &Self::Output; From 5098ee63383ea830a5972a240565c7bb09c44251 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 11 Apr 2020 21:57:24 -0400 Subject: [PATCH 13/18] Switching over to dyn Walkables --- src/renderer/renderer.rs | 34 ++++++++++++++-------------------- src/renderer/walkable.rs | 4 ++-- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index 78192ec..94c6e3b 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -95,27 +95,25 @@ impl<'a> DustRenderer<'a> { } } -fn walk_path<'a, C>(context: &'a C, path: &Vec<&str>) -> &'a C -where - C: Walkable, -{ - let mut output: &C = context; +// fn walk_path<'a, C>(context: &'a C, path: &Vec<&str>) -> &'a C +// where +// C: Walkable, +// { +// let mut output: &C = context; - for elem in path.iter() { - output = context.walk(elem); - } +// for elem in path.iter() { +// output = context.walk(elem); +// } - output -} +// output +// } #[cfg(test)] mod tests { use super::*; impl<'a, I: Walkable> Walkable for HashMap<&str, I> { - type Output = I; - - fn walk(&self, segment: &str) -> &I { + fn walk(&self, segment: &str) -> &dyn Walkable { self.get(segment).unwrap() } @@ -125,9 +123,7 @@ mod tests { } impl<'a> Walkable for &str { - type Output = u32; - - fn walk(&self, segment: &str) -> &u32 { + fn walk(&self, segment: &str) -> &dyn Walkable { panic!("Tried to walk down a str"); } @@ -137,9 +133,7 @@ mod tests { } impl<'a> Walkable for u32 { - type Output = u32; - - fn walk(&self, segment: &str) -> &u32 { + fn walk(&self, segment: &str) -> &dyn Walkable { panic!("Tried to walk down a str"); } @@ -148,7 +142,7 @@ mod tests { } } - fn do_the_walk<'a>(context: &'a impl Walkable, path: &Vec<&str>) -> &'a impl Walkable { + fn do_the_walk<'a>(context: &'a impl Walkable, path: &Vec<&str>) -> &'a dyn Walkable { let mut output = context; context.walk(path.first().unwrap()) diff --git a/src/renderer/walkable.rs b/src/renderer/walkable.rs index f93eef1..e8bf09f 100644 --- a/src/renderer/walkable.rs +++ b/src/renderer/walkable.rs @@ -1,9 +1,9 @@ use super::renderable::Renderable; pub trait Walkable { - type Output: Walkable; + // type Output: Walkable; - fn walk(&self, segment: &str) -> &Self::Output; + fn walk(&self, segment: &str) -> &dyn Walkable; fn val(&self) -> String; } From c09499703239fe86d763d6ae2c3c124894baa300 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 11 Apr 2020 21:59:21 -0400 Subject: [PATCH 14/18] Getting rid of some lifetimes --- src/renderer/renderer.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index 94c6e3b..d5fe632 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -112,7 +112,7 @@ impl<'a> DustRenderer<'a> { mod tests { use super::*; - impl<'a, I: Walkable> Walkable for HashMap<&str, I> { + impl Walkable for HashMap<&str, I> { fn walk(&self, segment: &str) -> &dyn Walkable { self.get(segment).unwrap() } @@ -122,7 +122,7 @@ mod tests { } } - impl<'a> Walkable for &str { + impl Walkable for &str { fn walk(&self, segment: &str) -> &dyn Walkable { panic!("Tried to walk down a str"); } @@ -132,7 +132,7 @@ mod tests { } } - impl<'a> Walkable for u32 { + impl Walkable for u32 { fn walk(&self, segment: &str) -> &dyn Walkable { panic!("Tried to walk down a str"); } From 07e5c9f0aff83170b256dccae9c1b2b78c07c42a Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 11 Apr 2020 22:04:44 -0400 Subject: [PATCH 15/18] turns out putting dyn everywhere fixes it --- src/renderer/renderer.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index d5fe632..fbb79dd 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -142,16 +142,14 @@ mod tests { } } - fn do_the_walk<'a>(context: &'a impl Walkable, path: &Vec<&str>) -> &'a dyn Walkable { + fn do_the_walk<'a>(context: &'a dyn Walkable, path: &Vec<&str>) -> &'a dyn Walkable { let mut output = context; - context.walk(path.first().unwrap()) + for elem in path.iter() { + output = context.walk(elem); + } - // for elem in path.iter() { - // output = context.walk(elem); - // } - - // output + output } #[test] From 5efa650b67d98568a77785f83685f53e11893643 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 11 Apr 2020 22:19:54 -0400 Subject: [PATCH 16/18] Switching to a combined ContextElement trait for Walkable and Renderable --- src/renderer/mod.rs | 1 + src/renderer/renderer.rs | 44 ++++++++++++++++++++++++++++++++-------- src/renderer/walkable.rs | 6 +++--- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index 81b7e79..c80f1a5 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -9,4 +9,5 @@ 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; diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index fbb79dd..88e2986 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -111,9 +111,32 @@ impl<'a> DustRenderer<'a> { #[cfg(test)] mod tests { use super::*; + use crate::renderer::walkable::ContextElement; - impl Walkable for HashMap<&str, I> { - fn walk(&self, segment: &str) -> &dyn Walkable { + impl ContextElement for u32 {} + impl ContextElement for &str {} + impl 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 Renderable for HashMap<&str, I> { + fn render(&self) -> std::string::String { + panic!("Attempted to render a hashmap"); + } + } + + impl Walkable for HashMap<&str, I> { + fn walk(&self, segment: &str) -> &dyn ContextElement { self.get(segment).unwrap() } @@ -123,7 +146,7 @@ mod tests { } impl Walkable for &str { - fn walk(&self, segment: &str) -> &dyn Walkable { + fn walk(&self, segment: &str) -> &dyn ContextElement { panic!("Tried to walk down a str"); } @@ -133,7 +156,7 @@ mod tests { } impl Walkable for u32 { - fn walk(&self, segment: &str) -> &dyn Walkable { + fn walk(&self, segment: &str) -> &dyn ContextElement { panic!("Tried to walk down a str"); } @@ -142,7 +165,10 @@ mod tests { } } - fn do_the_walk<'a>(context: &'a dyn Walkable, path: &Vec<&str>) -> &'a dyn Walkable { + fn do_the_walk<'a>( + context: &'a dyn ContextElement, + path: &Vec<&str>, + ) -> &'a dyn ContextElement { let mut output = context; for elem in path.iter() { @@ -171,11 +197,11 @@ mod tests { .iter() .cloned() .collect(); - assert_eq!(do_the_walk(&context, &vec!["cat"]).val(), "kitty"); - // assert_eq!(do_the_walk(&number_context, &vec!["tiger"]), &3); + assert_eq!(do_the_walk(&context, &vec!["cat"]).render(), "kitty"); + assert_eq!(do_the_walk(&number_context, &vec!["tiger"]).render(), "3"); // assert_eq!( - // do_the_walk(&deep_context, &vec!["tiger"]), - // &[("food", "people")].iter().cloned().collect() + // do_the_walk(&deep_context, &vec!["tiger", "food"]).render(), + // "people" // ); } } diff --git a/src/renderer/walkable.rs b/src/renderer/walkable.rs index e8bf09f..22b7426 100644 --- a/src/renderer/walkable.rs +++ b/src/renderer/walkable.rs @@ -1,9 +1,9 @@ use super::renderable::Renderable; -pub trait Walkable { - // type Output: Walkable; +pub trait ContextElement: Walkable + Renderable {} - fn walk(&self, segment: &str) -> &dyn Walkable; +pub trait Walkable { + fn walk(&self, segment: &str) -> &dyn ContextElement; fn val(&self) -> String; } From 47bb055b67afea75c9c407705d9c2d0106926a03 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 11 Apr 2020 22:23:59 -0400 Subject: [PATCH 17/18] I think its working --- src/renderer/renderer.rs | 22 +++++----------------- src/renderer/walkable.rs | 5 ++--- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index 88e2986..8fba149 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -139,30 +139,18 @@ mod tests { fn walk(&self, segment: &str) -> &dyn ContextElement { self.get(segment).unwrap() } - - fn val(&self) -> String { - "val".to_owned() - } } impl Walkable for &str { fn walk(&self, segment: &str) -> &dyn ContextElement { panic!("Tried to walk down a str"); } - - fn val(&self) -> String { - "val".to_owned() - } } impl Walkable for u32 { fn walk(&self, segment: &str) -> &dyn ContextElement { panic!("Tried to walk down a str"); } - - fn val(&self) -> String { - "val".to_owned() - } } fn do_the_walk<'a>( @@ -172,7 +160,7 @@ mod tests { let mut output = context; for elem in path.iter() { - output = context.walk(elem); + output = output.walk(elem); } output @@ -199,9 +187,9 @@ mod tests { .collect(); assert_eq!(do_the_walk(&context, &vec!["cat"]).render(), "kitty"); assert_eq!(do_the_walk(&number_context, &vec!["tiger"]).render(), "3"); - // assert_eq!( - // do_the_walk(&deep_context, &vec!["tiger", "food"]).render(), - // "people" - // ); + assert_eq!( + do_the_walk(&deep_context, &vec!["tiger", "food"]).render(), + "people" + ); } } diff --git a/src/renderer/walkable.rs b/src/renderer/walkable.rs index 22b7426..b861deb 100644 --- a/src/renderer/walkable.rs +++ b/src/renderer/walkable.rs @@ -1,9 +1,8 @@ use super::renderable::Renderable; +use std::fmt::Debug; -pub trait ContextElement: Walkable + Renderable {} +pub trait ContextElement: Walkable + Renderable + Debug {} pub trait Walkable { fn walk(&self, segment: &str) -> &dyn ContextElement; - - fn val(&self) -> String; } From dbfa7ea4dc4b3407323bce4c40db716c68b670c2 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 11 Apr 2020 22:36:22 -0400 Subject: [PATCH 18/18] Cleaning up --- src/renderer/renderer.rs | 42 +++++++++++++--------------------------- 1 file changed, 13 insertions(+), 29 deletions(-) diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index 8fba149..f40ecdc 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -5,6 +5,7 @@ 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; @@ -95,23 +96,19 @@ impl<'a> DustRenderer<'a> { } } -// fn walk_path<'a, C>(context: &'a C, path: &Vec<&str>) -> &'a C -// where -// C: Walkable, -// { -// let mut output: &C = context; +fn walk_path<'a>(context: &'a dyn ContextElement, path: &Vec<&str>) -> &'a dyn ContextElement { + let mut output = context; -// for elem in path.iter() { -// output = context.walk(elem); -// } + for elem in path.iter() { + output = output.walk(elem); + } -// output -// } + output +} #[cfg(test)] mod tests { use super::*; - use crate::renderer::walkable::ContextElement; impl ContextElement for u32 {} impl ContextElement for &str {} @@ -142,30 +139,17 @@ mod tests { } impl Walkable for &str { - fn walk(&self, segment: &str) -> &dyn ContextElement { + 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 { + fn walk(&self, _segment: &str) -> &dyn ContextElement { panic!("Tried to walk down a str"); } } - fn do_the_walk<'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 - } - #[test] fn test_walk_path() { let context: HashMap<&str, &str> = @@ -185,10 +169,10 @@ mod tests { .iter() .cloned() .collect(); - assert_eq!(do_the_walk(&context, &vec!["cat"]).render(), "kitty"); - assert_eq!(do_the_walk(&number_context, &vec!["tiger"]).render(), "3"); + assert_eq!(walk_path(&context, &vec!["cat"]).render(), "kitty"); + assert_eq!(walk_path(&number_context, &vec!["tiger"]).render(), "3"); assert_eq!( - do_the_walk(&deep_context, &vec!["tiger", "food"]).render(), + walk_path(&deep_context, &vec!["tiger", "food"]).render(), "people" ); }