2020-04-28 19:09:02 -04:00
|
|
|
use crate::parser::Filter;
|
2020-04-12 18:29:40 -04:00
|
|
|
use crate::renderer::errors::RenderError;
|
2020-05-09 14:00:19 -04:00
|
|
|
use crate::renderer::errors::WalkError;
|
2020-05-30 18:16:58 -04:00
|
|
|
use crate::renderer::DustRenderer;
|
2020-05-10 17:12:15 -04:00
|
|
|
use std::any::Any;
|
2020-05-16 13:31:52 -04:00
|
|
|
use std::{cmp::Ordering, fmt::Debug};
|
2020-04-11 20:34:16 -04:00
|
|
|
|
2020-05-10 19:01:02 -04:00
|
|
|
pub trait ContextElement:
|
2020-05-24 16:16:43 -04:00
|
|
|
Debug
|
|
|
|
|
+ Truthiness
|
|
|
|
|
+ Walkable
|
|
|
|
|
+ Renderable
|
|
|
|
|
+ Loopable
|
|
|
|
|
+ CloneIntoBoxedContextElement
|
|
|
|
|
+ CompareContextElement
|
2020-05-30 16:34:32 -04:00
|
|
|
+ FromContextElement
|
2020-05-10 19:01:02 -04:00
|
|
|
{
|
|
|
|
|
}
|
2020-04-11 20:34:16 -04:00
|
|
|
|
2020-05-24 16:16:43 -04:00
|
|
|
pub trait Truthiness {
|
|
|
|
|
fn is_truthy(&self) -> bool;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-11 22:19:54 -04:00
|
|
|
pub trait Walkable {
|
2020-05-30 17:50:27 -04:00
|
|
|
fn walk(&self, segment: &str) -> Result<&dyn IntoContextElement, WalkError>;
|
2020-05-30 11:50:55 -04:00
|
|
|
|
|
|
|
|
/// If an element contains meta information and should not be
|
|
|
|
|
/// returned as the final result of a walk, this function should
|
|
|
|
|
/// return true.
|
|
|
|
|
///
|
|
|
|
|
/// For example, the iteration context contains $idx and $len but
|
|
|
|
|
/// it should not be the result of a dot-reference like `{.}`.
|
|
|
|
|
fn is_pseudo_element(&self) -> bool {
|
|
|
|
|
false
|
|
|
|
|
}
|
2020-04-11 20:34:16 -04:00
|
|
|
}
|
2020-04-28 19:09:02 -04:00
|
|
|
|
|
|
|
|
pub trait Renderable {
|
|
|
|
|
fn render(&self, filters: &Vec<Filter>) -> Result<String, RenderError>;
|
|
|
|
|
}
|
2020-04-28 19:34:52 -04:00
|
|
|
|
|
|
|
|
pub trait Loopable {
|
|
|
|
|
/// Return the elements for a Dust section
|
|
|
|
|
///
|
2020-05-24 16:27:13 -04:00
|
|
|
/// Sections in dust are accomplished with the {#path} syntax. If
|
|
|
|
|
/// its an array-like value then it will render n-times, once for
|
|
|
|
|
/// each element of the array. If this is a scalar value, then
|
|
|
|
|
/// return an empty array. Sections with scalar values will still
|
|
|
|
|
/// be rendered (only once) if their truthiness check comes back
|
|
|
|
|
/// true.
|
2020-05-09 14:14:22 -04:00
|
|
|
fn get_loop_elements(&self) -> Vec<&dyn ContextElement>;
|
2020-04-28 19:34:52 -04:00
|
|
|
}
|
2020-05-10 14:53:12 -04:00
|
|
|
|
2020-05-10 22:04:41 -04:00
|
|
|
pub trait CastToAny {
|
2020-05-10 17:12:15 -04:00
|
|
|
fn to_any(&self) -> &dyn Any;
|
2020-05-10 22:04:41 -04:00
|
|
|
}
|
2020-05-10 19:16:55 -04:00
|
|
|
|
2020-05-10 22:04:41 -04:00
|
|
|
pub trait CompareContextElement: CastToAny {
|
2020-05-10 19:16:55 -04:00
|
|
|
fn equals(&self, other: &dyn ContextElement) -> bool;
|
2020-05-16 13:31:52 -04:00
|
|
|
|
|
|
|
|
fn partial_compare(&self, other: &dyn ContextElement) -> Option<Ordering>;
|
2020-05-10 17:12:15 -04:00
|
|
|
}
|
|
|
|
|
|
2020-05-10 21:07:31 -04:00
|
|
|
pub trait CloneIntoBoxedContextElement {
|
2020-05-30 17:50:27 -04:00
|
|
|
fn clone_to_box(&self) -> Box<dyn IntoContextElement>;
|
2020-05-10 19:01:02 -04:00
|
|
|
}
|
|
|
|
|
|
2020-05-30 17:50:27 -04:00
|
|
|
impl<C: 'static + IntoContextElement + Clone> CloneIntoBoxedContextElement for C {
|
|
|
|
|
fn clone_to_box(&self) -> Box<dyn IntoContextElement> {
|
2020-05-10 21:07:31 -04:00
|
|
|
Box::new(self.clone())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-10 22:05:48 -04:00
|
|
|
impl<C: 'static + ContextElement> CastToAny for C {
|
2020-05-10 21:10:48 -04:00
|
|
|
fn to_any(&self) -> &dyn Any {
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-10 20:58:47 -04:00
|
|
|
impl<'a, 'b> PartialEq<&'b dyn ContextElement> for &'a dyn ContextElement {
|
|
|
|
|
fn eq(&self, other: &&'b dyn ContextElement) -> bool {
|
2020-05-10 21:00:06 -04:00
|
|
|
self.equals(*other)
|
2020-05-10 20:58:47 -04:00
|
|
|
}
|
|
|
|
|
}
|
2020-05-16 13:31:52 -04:00
|
|
|
|
|
|
|
|
impl<'a, 'b> PartialOrd<&'b dyn ContextElement> for &'a dyn ContextElement {
|
|
|
|
|
fn partial_cmp(&self, other: &&'b dyn ContextElement) -> Option<Ordering> {
|
|
|
|
|
self.partial_compare(*other)
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-05-30 16:34:32 -04:00
|
|
|
|
|
|
|
|
pub trait FromContextElement {
|
|
|
|
|
fn from_context_element(&self) -> &dyn IntoContextElement;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<C: ContextElement> FromContextElement for C {
|
|
|
|
|
fn from_context_element(&self) -> &dyn IntoContextElement {
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-30 17:50:27 -04:00
|
|
|
pub trait IntoContextElement: Debug + Walkable + CloneIntoBoxedContextElement {
|
|
|
|
|
fn into_context_element(
|
|
|
|
|
&self,
|
2020-05-30 18:16:58 -04:00
|
|
|
renderer: &DustRenderer,
|
2020-05-30 17:50:27 -04:00
|
|
|
breadcrumbs: &Vec<&dyn IntoContextElement>,
|
|
|
|
|
) -> &dyn ContextElement;
|
2020-05-30 16:34:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<C: ContextElement> IntoContextElement for C {
|
2020-05-30 17:50:27 -04:00
|
|
|
fn into_context_element(
|
|
|
|
|
&self,
|
2020-05-30 18:16:58 -04:00
|
|
|
renderer: &DustRenderer,
|
2020-05-30 17:50:27 -04:00
|
|
|
breadcrumbs: &Vec<&dyn IntoContextElement>,
|
|
|
|
|
) -> &dyn ContextElement {
|
2020-05-30 16:34:32 -04:00
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
}
|