Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for providing partials in data #80

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use std::collections::HashMap;
use serde::Serialize;

use encoder::Error;
use crate::Template;

use super::{Data, to_data};

/// `MapBuilder` is a helper type that construct `Data` types.
Expand Down Expand Up @@ -150,6 +152,21 @@ impl MapBuilder {
MapBuilder { data: data }
}

/// Adds a template to the `MapBuilder`.
///
/// ```rust
/// use mustache::{MapBuilder, compile_str};
/// let user_template = compile_str("<strong>{{username}}</strong>").unwrap();
/// let data = MapBuilder::new()
/// .insert_template("user", user_template)
/// .build();
/// ```
#[inline]
pub fn insert_template<K: ToString>(mut self, key: K, value: Template) -> MapBuilder {
self.data.insert(key.to_string(), Data::Template(value));
self
}

/// Return the built `Data`.
#[inline]
pub fn build(self) -> Data {
Expand Down
4 changes: 4 additions & 0 deletions src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ use std::fmt;
// for bug!
use log::{log, error};

use crate::Template;

pub enum Data {
Null,
String(String),
Bool(bool),
Vec(Vec<Data>),
Map(HashMap<String, Data>),
Template(Template),
Fun(RefCell<Box<dyn FnMut(String) -> String + Send>>),
}

Expand Down Expand Up @@ -40,6 +43,7 @@ impl fmt::Debug for Data {
Data::Bool(v) => write!(f, "Bool({:?})", v),
Data::Vec(ref v) => write!(f, "VecVal({:?})", v),
Data::Map(ref v) => write!(f, "Map({:?})", v),
Data::Template(ref v) => write!(f, "Template({:?})", v),
Data::Fun(_) => write!(f, "Fun(...)"),
}
}
Expand Down
18 changes: 13 additions & 5 deletions src/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ impl<'a> RenderContext<'a> {
self.render(wr, stack, children)?;
stack.pop();
}
Data::Template(_) => {}
Data::Fun(ref fcell) => {
let f = &mut *fcell.borrow_mut();
let tokens = self.render_fun(src, otag, ctag, f)?;
Expand All @@ -291,9 +292,16 @@ impl<'a> RenderContext<'a> {
stack: &mut Vec<&Data>,
name: &str,
indent: &str) -> Result<()> {
match self.template.partials.get(name) {
match self
.find(&[name], stack)
.and_then(|d| match d {
Data::Template(t) => Some(&t.tokens),
_ => None,
})
.or_else(|| self.template.partials.get(name))
{
None => (),
Some(ref tokens) => {
Some(tokens) => {
let mut indent = self.indent.clone() + indent;

mem::swap(&mut self.indent, &mut indent);
Expand Down Expand Up @@ -323,7 +331,7 @@ impl<'a> RenderContext<'a> {
Ok(tokens)
}

fn find<'c>(&self, path: &[String], stack: &mut Vec<&'c Data>) -> Option<&'c Data> {
fn find<'c>(&self, path: &[impl AsRef<str>], stack: &mut Vec<&'c Data>) -> Option<&'c Data> {
// If we have an empty path, we just want the top value in our stack.
if path.is_empty() {
match stack.last() {
Expand All @@ -342,7 +350,7 @@ impl<'a> RenderContext<'a> {
for data in stack.iter().rev() {
match **data {
Data::Map(ref m) => {
if let Some(v) = m.get(&path[0]) {
if let Some(v) = m.get(path[0].as_ref()) {
value = Some(v);
break;
}
Expand All @@ -362,7 +370,7 @@ impl<'a> RenderContext<'a> {
for part in path[1..].iter() {
match *value {
Data::Map(ref m) => {
match m.get(part) {
match m.get(part.as_ref()) {
Some(v) => {
value = v;
}
Expand Down
9 changes: 9 additions & 0 deletions tests/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,15 @@ fn assert_partials_data(template: Template) {
assert_eq!(render_data(&template, &Data::Map(ctx0)),
"<h2>Names</h2>\n <strong>a</strong>\n\n".to_string());

let mut ctx0 = HashMap::new();
let mut ctx1 = HashMap::new();
ctx1.insert("name".to_string(), Data::String("a".to_string()));
ctx0.insert("names".to_string(), Data::Vec(vec![Data::Map(ctx1)]));
let user_partial = compile_str("<span>{{>username}}</span>\n");
ctx0.insert("user".to_string(), Data::Template(user_partial));
assert_eq!(render_data(&template, &Data::Map(ctx0)),
"<h2>Names</h2>\n <span>a</span>\n\n".to_string());

let mut ctx0 = HashMap::new();
let mut ctx1 = HashMap::new();
ctx1.insert("name".to_string(), Data::String("a".to_string()));
Expand Down