use crate::parser::Filter;
use crate::renderer::errors::RenderError;
use crate::renderer::renderer::RenderWrapper;
use std::fmt::Debug;

pub trait ContextElement: Debug + RenderWrapper + Walkable + Renderable + Loopable {}

pub trait Walkable {
    fn walk(&self, segment: &str) -> Result<&dyn ContextElement, RenderError>;
}

pub trait Renderable {
    fn render(&self, filters: &Vec<Filter>) -> Result<String, RenderError>;
}

pub trait Loopable {
    /// Return the elements for a Dust section
    ///
    /// Sections in dust are accomplished with the {#path} syntax. A
    /// section has a truthiness check performed on it. If that
    /// truthiness check fails, then it will render the
    /// else-block. Otherwise if its a scalar value it will render
    /// once with the context being the element at that path. Finally,
    /// if its an array-like value then it will render n-times, once
    /// for each element of the array.
    fn get_loop_elements(&self) -> Result<Vec<&dyn ContextElement>, RenderError>;
}