Delete old render functions.
This commit is contained in:
parent
05527377c4
commit
18f9fb7f57
@ -1,9 +1,8 @@
|
|||||||
use crate::parser::Filter;
|
use crate::parser::Filter;
|
||||||
use crate::renderer::errors::RenderError;
|
use crate::renderer::errors::RenderError;
|
||||||
use crate::renderer::renderer::RenderWrapper;
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
pub trait ContextElement: Debug + RenderWrapper + Walkable + Renderable + Loopable {}
|
pub trait ContextElement: Debug + Walkable + Renderable + Loopable {}
|
||||||
|
|
||||||
pub trait Walkable {
|
pub trait Walkable {
|
||||||
fn walk(&self, segment: &str) -> Result<&dyn ContextElement, RenderError>;
|
fn walk(&self, segment: &str) -> Result<&dyn ContextElement, RenderError>;
|
||||||
|
@ -20,24 +20,6 @@ pub struct DustRenderer<'a> {
|
|||||||
templates: HashMap<String, &'a Template<'a>>,
|
templates: HashMap<String, &'a Template<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait RenderWrapper {
|
|
||||||
fn render_body<'a>(
|
|
||||||
&'a self,
|
|
||||||
renderer: &'a DustRenderer,
|
|
||||||
body: &Body,
|
|
||||||
) -> Result<String, RenderError>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C: ContextElement> RenderWrapper for C {
|
|
||||||
fn render_body<'a>(
|
|
||||||
&'a self,
|
|
||||||
renderer: &'a DustRenderer,
|
|
||||||
body: &Body,
|
|
||||||
) -> Result<String, RenderError<'a>> {
|
|
||||||
renderer.render_body(body, self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn compile_template<'a>(
|
pub fn compile_template<'a>(
|
||||||
source: &'a str,
|
source: &'a str,
|
||||||
name: String,
|
name: String,
|
||||||
@ -80,22 +62,6 @@ impl<'a> DustRenderer<'a> {
|
|||||||
self.new_render_body(&main_template.contents, breadcrumbs)
|
self.new_render_body(&main_template.contents, breadcrumbs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render<C>(&'a self, name: &str, context: &'a C) -> Result<String, RenderError<'a>>
|
|
||||||
where
|
|
||||||
C: ContextElement,
|
|
||||||
{
|
|
||||||
let main_template = match self.templates.get(name) {
|
|
||||||
Some(tmpl) => tmpl,
|
|
||||||
None => {
|
|
||||||
return Err(RenderError::Generic(format!(
|
|
||||||
"No template named {} in context",
|
|
||||||
name
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
self.render_body(&main_template.contents, context)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new_render_body(
|
fn new_render_body(
|
||||||
&'a self,
|
&'a self,
|
||||||
body: &'a Body,
|
body: &'a Body,
|
||||||
@ -114,23 +80,6 @@ impl<'a> DustRenderer<'a> {
|
|||||||
Ok(output)
|
Ok(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_body<C>(&'a self, body: &Body, context: &'a C) -> Result<String, RenderError<'a>>
|
|
||||||
where
|
|
||||||
C: ContextElement,
|
|
||||||
{
|
|
||||||
let mut output = String::new();
|
|
||||||
for elem in &body.elements {
|
|
||||||
match elem {
|
|
||||||
TemplateElement::TEIgnoredWhitespace(_) => {}
|
|
||||||
TemplateElement::TESpan(span) => output.push_str(span.contents),
|
|
||||||
TemplateElement::TETag(dt) => {
|
|
||||||
output.push_str(&self.render_tag(dt, context)?);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(output)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new_render_tag(
|
fn new_render_tag(
|
||||||
&'a self,
|
&'a self,
|
||||||
tag: &'a DustTag,
|
tag: &'a DustTag,
|
||||||
@ -195,68 +144,6 @@ impl<'a> DustRenderer<'a> {
|
|||||||
Ok("".to_owned())
|
Ok("".to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_tag<C>(&'a self, tag: &DustTag, context: &'a C) -> Result<String, RenderError<'a>>
|
|
||||||
where
|
|
||||||
C: ContextElement,
|
|
||||||
{
|
|
||||||
match tag {
|
|
||||||
DustTag::DTComment(_comment) => (),
|
|
||||||
DustTag::DTReference(reference) => {
|
|
||||||
let val = walk_path(context, &reference.path.keys);
|
|
||||||
if let Err(RenderError::WontWalk { .. }) = val {
|
|
||||||
// If reference does not exist in the context, it becomes an empty string
|
|
||||||
return Ok("".to_owned());
|
|
||||||
} else if let Err(RenderError::CantWalk { .. }) = val {
|
|
||||||
// If the context type does not support walking, it becomes an empty string
|
|
||||||
return Ok("".to_owned());
|
|
||||||
} else {
|
|
||||||
return val?.render(&reference.filters);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DustTag::DTSection(container) => {
|
|
||||||
let val = walk_path(context, &container.path.keys);
|
|
||||||
let loop_elements: Vec<&dyn ContextElement> = self.get_loop_elements(val)?;
|
|
||||||
if loop_elements.is_empty() {
|
|
||||||
// Oddly enough if the value is falsey (like
|
|
||||||
// an empty array or null), Dust uses the
|
|
||||||
// original context before walking the path as
|
|
||||||
// the context for rendering the else block
|
|
||||||
//
|
|
||||||
// TODO: do filters apply? I don't think so
|
|
||||||
// but I should test
|
|
||||||
return match &container.else_contents {
|
|
||||||
Some(body) => self.render_body(&body, context),
|
|
||||||
None => Ok("".to_owned()),
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
match &container.contents {
|
|
||||||
None => return Ok("".to_owned()),
|
|
||||||
Some(body) => {
|
|
||||||
let rendered_results: Result<Vec<String>, RenderError> = loop_elements
|
|
||||||
.into_iter()
|
|
||||||
.map(|array_elem| array_elem.render_body(self, &body))
|
|
||||||
.collect();
|
|
||||||
let rendered_slice: &[String] = &rendered_results?;
|
|
||||||
return Ok(rendered_slice.join(""));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DustTag::DTSpecial(special) => {
|
|
||||||
return Ok(match special {
|
|
||||||
Special::Space => " ",
|
|
||||||
Special::NewLine => "\n",
|
|
||||||
Special::CarriageReturn => "\r",
|
|
||||||
Special::LeftCurlyBrace => "{",
|
|
||||||
Special::RightCurlyBrace => "}",
|
|
||||||
}
|
|
||||||
.to_owned())
|
|
||||||
}
|
|
||||||
_ => (), // TODO: Implement the rest
|
|
||||||
}
|
|
||||||
Ok("".to_owned())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the elements to loop over for a section.
|
/// Gets the elements to loop over for a section.
|
||||||
///
|
///
|
||||||
/// If the value is falsey, and therefore should render the else
|
/// If the value is falsey, and therefore should render the else
|
||||||
@ -268,12 +155,6 @@ impl<'a> DustRenderer<'a> {
|
|||||||
if let Err(RenderError::NotFound { .. }) = walk_result {
|
if let Err(RenderError::NotFound { .. }) = walk_result {
|
||||||
// If reference does not exist in the context, render the else block
|
// If reference does not exist in the context, render the else block
|
||||||
Ok(vec![])
|
Ok(vec![])
|
||||||
} else if let Err(RenderError::WontWalk { .. }) = walk_result {
|
|
||||||
// If reference does not exist in the context, render the else block
|
|
||||||
Ok(vec![])
|
|
||||||
} else if let Err(RenderError::CantWalk { .. }) = walk_result {
|
|
||||||
// If the context type does not support walking, render the else block
|
|
||||||
Ok(vec![])
|
|
||||||
} else {
|
} else {
|
||||||
Ok(walk_result?.get_loop_elements()?)
|
Ok(walk_result?.get_loop_elements()?)
|
||||||
}
|
}
|
||||||
@ -335,19 +216,6 @@ fn new_walk_path<'a>(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn walk_path<'a>(
|
|
||||||
context: &'a dyn ContextElement,
|
|
||||||
path: &Vec<&str>,
|
|
||||||
) -> Result<&'a dyn ContextElement, RenderError<'a>> {
|
|
||||||
let mut output = context;
|
|
||||||
|
|
||||||
for elem in path.iter() {
|
|
||||||
output = output.walk(elem)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(output)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -432,7 +300,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_new_walk_path() {
|
fn test_walk_path() {
|
||||||
let context: HashMap<&str, &str> =
|
let context: HashMap<&str, &str> =
|
||||||
[("cat", "kitty"), ("dog", "doggy"), ("tiger", "murderkitty")]
|
[("cat", "kitty"), ("dog", "doggy"), ("tiger", "murderkitty")]
|
||||||
.iter()
|
.iter()
|
||||||
@ -479,46 +347,4 @@ mod tests {
|
|||||||
"people".to_owned()
|
"people".to_owned()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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"])
|
|
||||||
.unwrap()
|
|
||||||
.render(&Vec::new())
|
|
||||||
.unwrap(),
|
|
||||||
"kitty".to_owned()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
walk_path(&number_context, &vec!["tiger"])
|
|
||||||
.unwrap()
|
|
||||||
.render(&Vec::new())
|
|
||||||
.unwrap(),
|
|
||||||
"3".to_owned()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
walk_path(&deep_context, &vec!["tiger", "food"])
|
|
||||||
.unwrap()
|
|
||||||
.render(&Vec::new())
|
|
||||||
.unwrap(),
|
|
||||||
"people".to_owned()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user