diff --git a/src/bin.rs b/src/bin.rs index 2b19174..f913772 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -10,6 +10,7 @@ use renderer::DustRenderer; use renderer::Loopable; use renderer::RenderError; use renderer::Renderable; +use renderer::Truthiness; use renderer::WalkError; use renderer::Walkable; use std::cmp::Ordering; @@ -236,6 +237,19 @@ fn apply_filters( impl ContextElement for serde_json::Value {} +impl Truthiness for serde_json::Value { + fn is_truthy(&self) -> bool { + match self { + serde_json::Value::Null => false, + serde_json::Value::Bool(boolean) => *boolean, + serde_json::Value::Number(_num) => true, + serde_json::Value::String(string_value) => !string_value.is_empty(), + serde_json::Value::Array(array_value) => !array_value.is_empty(), + serde_json::Value::Object(_obj) => true, + } + } +} + impl Renderable for serde_json::Value { fn render(&self, _filters: &Vec) -> Result { let after_apply = if _filters.is_empty() { diff --git a/src/renderer/context_element.rs b/src/renderer/context_element.rs index bb43cf8..bb0369f 100644 --- a/src/renderer/context_element.rs +++ b/src/renderer/context_element.rs @@ -5,10 +5,20 @@ use std::any::Any; use std::{cmp::Ordering, fmt::Debug}; pub trait ContextElement: - Debug + Walkable + Renderable + Loopable + CloneIntoBoxedContextElement + CompareContextElement + Debug + + Truthiness + + Walkable + + Renderable + + Loopable + + CloneIntoBoxedContextElement + + CompareContextElement { } +pub trait Truthiness { + fn is_truthy(&self) -> bool; +} + pub trait Walkable { fn walk(&self, segment: &str) -> Result<&dyn ContextElement, WalkError>; } diff --git a/src/renderer/iteration_context.rs b/src/renderer/iteration_context.rs index d294817..51619ae 100644 --- a/src/renderer/iteration_context.rs +++ b/src/renderer/iteration_context.rs @@ -3,6 +3,7 @@ use crate::renderer::context_element::ContextElement; use crate::renderer::Loopable; use crate::renderer::RenderError; use crate::renderer::Renderable; +use crate::renderer::Truthiness; use crate::renderer::WalkError; use crate::{parser::Filter, parser::OwnedLiteral, renderer::Walkable}; @@ -30,6 +31,15 @@ impl IterationContext { impl ContextElement for IterationContext {} +impl Truthiness for IterationContext { + fn is_truthy(&self) -> bool { + // 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 `{.}`. + true + } +} + impl Renderable for IterationContext { fn render(&self, _filters: &Vec) -> Result { // TODO: Would this even ever be called? Won't matter, but I'd diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index 3878e18..ff0729b 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -13,6 +13,7 @@ pub use context_element::CompareContextElement; pub use context_element::ContextElement; pub use context_element::Loopable; pub use context_element::Renderable; +pub use context_element::Truthiness; pub use context_element::Walkable; pub use errors::CompileError; pub use errors::RenderError; diff --git a/src/renderer/parameters_context.rs b/src/renderer/parameters_context.rs index 92ee3b1..31d52b8 100644 --- a/src/renderer/parameters_context.rs +++ b/src/renderer/parameters_context.rs @@ -6,6 +6,7 @@ use crate::renderer::walking::walk_path; use crate::renderer::Loopable; use crate::renderer::RenderError; use crate::renderer::Renderable; +use crate::renderer::Truthiness; use crate::renderer::WalkError; use crate::renderer::Walkable; use std::{cmp::Ordering, collections::HashMap}; @@ -67,6 +68,15 @@ impl ParametersContext { impl ContextElement for ParametersContext {} +impl Truthiness for ParametersContext { + fn is_truthy(&self) -> bool { + // 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 `{.}`. + true + } +} + impl Renderable for ParametersContext { fn render(&self, _filters: &Vec) -> Result { // TODO: Would this even ever be called? Won't matter, but I'd @@ -128,6 +138,15 @@ impl CompareContextElement for ParametersContext { impl ContextElement for OwnedLiteral {} +impl Truthiness for OwnedLiteral { + fn is_truthy(&self) -> bool { + match self { + OwnedLiteral::LString(text) => !text.is_empty(), + OwnedLiteral::LPositiveInteger(num) => true, + } + } +} + impl Renderable for OwnedLiteral { fn render(&self, _filters: &Vec) -> Result { match self { diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index 03ff2f4..dbac9f7 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -524,12 +524,19 @@ mod tests { use crate::parser::Filter; use crate::renderer::context_element::Loopable; use crate::renderer::context_element::Renderable; + use crate::renderer::context_element::Truthiness; use crate::renderer::context_element::Walkable; use crate::renderer::CompareContextElement; use std::cmp::Ordering; impl ContextElement for String {} + impl Truthiness for String { + fn is_truthy(&self) -> bool { + !self.is_empty() + } + } + impl Renderable for String { fn render(&self, _filters: &Vec) -> Result { Ok(self.clone()) @@ -569,6 +576,12 @@ mod tests { } impl ContextElement for u64 {} + impl Truthiness for u64 { + fn is_truthy(&self) -> bool { + true + } + } + impl Renderable for u64 { fn render(&self, _filters: &Vec) -> Result { Ok(self.to_string()) @@ -605,6 +618,12 @@ mod tests { impl ContextElement for HashMap {} + impl Truthiness for HashMap { + fn is_truthy(&self) -> bool { + true + } + } + impl Renderable for HashMap { fn render(&self, _filters: &Vec) -> Result { // TODO: handle the filters