Skip to content

Commit

Permalink
(feat) refactor render api, put Context into RenderContext
Browse files Browse the repository at this point in the history
This make Context mutable in render process, which allows decorators
to modify context.

This is part 1 on implementing #102

Signed-off-by: Ning Sun <[email protected]>
  • Loading branch information
sunng87 committed Dec 17, 2016
1 parent 1ae746f commit e1abdf7
Show file tree
Hide file tree
Showing 17 changed files with 172 additions and 273 deletions.
12 changes: 2 additions & 10 deletions examples/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,14 @@ use std::error::Error;

use handlebars::{Handlebars, RenderError, RenderContext, Helper, Context, JsonRender};

fn format_helper(_: &Context,
h: &Helper,
_: &Handlebars,
rc: &mut RenderContext)
-> Result<(), RenderError> {
fn format_helper(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
let param = try!(h.param(0).ok_or(RenderError::new("Param 0 is required for format helper.")));
let rendered = format!("{} pts", param.value().render());
try!(rc.writer.write(rendered.into_bytes().as_ref()));
Ok(())
}

fn rank_helper(_: &Context,
h: &Helper,
_: &Handlebars,
rc: &mut RenderContext)
-> Result<(), RenderError> {
fn rank_helper(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
let rank = try!(h.param(0)
.and_then(|v| v.value().as_u64())
.ok_or(RenderError::new("Param 0 with u64 type is required for rank helper."))) as usize;
Expand Down
12 changes: 2 additions & 10 deletions examples/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ use std::error::Error;
use handlebars::{Handlebars, RenderError, RenderContext, Helper, Context, JsonRender};

// define a custom helper
fn format_helper(_: &Context,
h: &Helper,
_: &Handlebars,
rc: &mut RenderContext)
-> Result<(), RenderError> {
fn format_helper(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
// get parameter from helper or throw an error
let param = try!(h.param(0).ok_or(RenderError::new("Param 0 is required for format helper.")));
let rendered = format!("{} pts", param.value().render());
Expand All @@ -32,11 +28,7 @@ fn format_helper(_: &Context,
}

// another custom helper
fn rank_helper(_: &Context,
h: &Helper,
_: &Handlebars,
rc: &mut RenderContext)
-> Result<(), RenderError> {
fn rank_helper(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
let rank = try!(h.param(0)
.and_then(|v| v.value().as_u64())
.ok_or(RenderError::new("Param 0 with u64 type is required for rank helper."))) as usize;
Expand Down
14 changes: 3 additions & 11 deletions examples/render_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,15 @@ use std::fs::File;
use handlebars::{Handlebars, RenderError, RenderContext, Helper, Context, JsonRender};

// define a custom helper
fn format_helper(_: &Context,
h: &Helper,
_: &Handlebars,
rc: &mut RenderContext)
-> Result<(), RenderError> {
fn format_helper(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
let param = try!(h.param(0).ok_or(RenderError::new("Param 0 is required for format helper.")));
let rendered = format!("{} pts", param.value().render());
try!(rc.writer.write(rendered.into_bytes().as_ref()));
Ok(())
}

// another custom helper
fn rank_helper(_: &Context,
h: &Helper,
_: &Handlebars,
rc: &mut RenderContext)
-> Result<(), RenderError> {
fn rank_helper(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
let rank = try!(h.param(0)
.and_then(|v| v.value().as_u64())
.ok_or(RenderError::new("Param 0 with u64 type is required for rank helper."))) as usize;
Expand Down Expand Up @@ -144,7 +136,7 @@ fn main() {
// Never use this style in your real-world projects.
let mut source_template = File::open(&"./examples/render_file/template.hbs").unwrap();
let mut output_file = File::create("target/table.html").unwrap();
if let Ok(_) = handlebars.template_renderw2(&mut source_template, &data, &mut output_file) {
if let Ok(_) = handlebars.template_renderw2(&mut source_template, data, &mut output_file) {
println!("target/table.html generated");
} else {
println!("Failed to geneate target/table.html");
Expand Down
17 changes: 3 additions & 14 deletions src/directives/inline.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use directives::DirectiveDef;
use registry::Registry;
use context::Context;
use render::{RenderError, RenderContext, Directive};

#[derive(Clone, Copy)]
Expand Down Expand Up @@ -29,12 +28,7 @@ fn get_name<'a>(d: &'a Directive) -> Result<&'a str, RenderError> {
}

impl DirectiveDef for InlineDirective {
fn call(&self,
_: &Context,
d: &Directive,
_: &Registry,
rc: &mut RenderContext)
-> Result<(), RenderError> {
fn call(&self, d: &Directive, _: &Registry, rc: &mut RenderContext) -> Result<(), RenderError> {
let name = try!(get_name(d));

let template = try!(d.template()
Expand All @@ -56,11 +50,6 @@ mod test {
use render::{RenderContext, Evalable};
use support::str::StringWriter;

#[cfg(all(feature = "rustc_ser_type", not(feature = "serde_type")))]
use serialize::json::Json;
#[cfg(feature = "serde_type")]
use serde_json::value::Value as Json;

#[test]
fn test_inline() {
let t0 =
Expand All @@ -72,8 +61,8 @@ mod test {
let hbs = Registry::new();

let mut sw = StringWriter::new();
let mut rc = RenderContext::new(&mut sw);
t0.elements[0].eval(&Context::wraps(&Json::Null), &hbs, &mut rc).unwrap();
let mut rc = RenderContext::new(Context::null(), &mut sw);
t0.elements[0].eval(&hbs, &mut rc).unwrap();

assert!(rc.get_partial(&"hello".to_owned()).is_some());
}
Expand Down
14 changes: 4 additions & 10 deletions src/directives/mod.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,19 @@
use render::{RenderContext, RenderError, Directive};
use registry::Registry;
use context::Context;

pub use self::inline::INLINE_DIRECTIVE;

/// Directive Definition
///
/// Implement this trait to define your own decorators or directives
pub trait DirectiveDef: Send + Sync {
fn call(&self,
ctx: &Context,
d: &Directive,
r: &Registry,
rc: &mut RenderContext)
-> Result<(), RenderError>;
fn call(&self, d: &Directive, r: &Registry, rc: &mut RenderContext) -> Result<(), RenderError>;
}

/// implement DirectiveDef for bare function so we can use function as directive
impl<F: Send + Sync + for<'a, 'b, 'c, 'd, 'e> Fn(&'a Context, &'b Directive, &'c Registry, &'d mut RenderContext) -> Result<(), RenderError>> DirectiveDef for F {
fn call(&self, ctx: &Context, d: &Directive, r: &Registry, rc: &mut RenderContext) -> Result<(), RenderError>{
(*self)(ctx, d, r, rc)
impl<F: Send + Sync + for<'b, 'c, 'd, 'e> Fn(&'b Directive, &'c Registry, &'d mut RenderContext) -> Result<(), RenderError>> DirectiveDef for F {
fn call(&self, d: &Directive, r: &Registry, rc: &mut RenderContext) -> Result<(), RenderError>{
(*self)(d, r, rc)
}
}

Expand Down
15 changes: 5 additions & 10 deletions src/helpers/helper_each.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,14 @@ use serde_json::value::Value as Json;

use helpers::HelperDef;
use registry::Registry;
use context::{Context, JsonTruthy, to_json};
use context::{JsonTruthy, to_json};
use render::{Renderable, RenderContext, RenderError, Helper};

#[derive(Clone, Copy)]
pub struct EachHelper;

impl HelperDef for EachHelper {
fn call(&self,
c: &Context,
h: &Helper,
r: &Registry,
rc: &mut RenderContext)
-> Result<(), RenderError> {
fn call(&self, h: &Helper, r: &Registry, rc: &mut RenderContext) -> Result<(), RenderError> {
let value = try!(h.param(0)
.ok_or_else(|| RenderError::new("Param not found for helper \"each\"")));

Expand Down Expand Up @@ -60,7 +55,7 @@ impl HelperDef for EachHelper {
local_rc.push_block_context(&map);
}

try!(t.render(c, r, &mut local_rc));
try!(t.render(r, &mut local_rc));

if h.block_param().is_some() {
local_rc.pop_block_context();
Expand Down Expand Up @@ -101,7 +96,7 @@ impl HelperDef for EachHelper {
local_rc.push_block_context(&map);
}

try!(t.render(c, r, &mut local_rc));
try!(t.render(r, &mut local_rc));

if h.block_param().is_some() {
local_rc.pop_block_context();
Expand All @@ -116,7 +111,7 @@ impl HelperDef for EachHelper {
}
(false, _) => {
if let Some(else_template) = h.inverse() {
try!(else_template.render(c, r, rc));
try!(else_template.render(r, rc));
}
Ok(())
}
Expand Down
11 changes: 3 additions & 8 deletions src/helpers/helper_if.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use helpers::HelperDef;
use registry::Registry;
use context::{Context, JsonTruthy};
use context::JsonTruthy;
use render::{Renderable, RenderContext, RenderError, Helper};

#[derive(Clone, Copy)]
Expand All @@ -9,12 +9,7 @@ pub struct IfHelper {
}

impl HelperDef for IfHelper {
fn call(&self,
c: &Context,
h: &Helper,
r: &Registry,
rc: &mut RenderContext)
-> Result<(), RenderError> {
fn call(&self, h: &Helper, r: &Registry, rc: &mut RenderContext) -> Result<(), RenderError> {
let param = try!(h.param(0)
.ok_or_else(|| RenderError::new("Param not found for helper \"if\"")));

Expand All @@ -30,7 +25,7 @@ impl HelperDef for IfHelper {
h.inverse()
};
match tmpl {
Some(ref t) => t.render(c, r, rc),
Some(ref t) => t.render(r, rc),
None => Ok(()),
}
}
Expand Down
9 changes: 2 additions & 7 deletions src/helpers/helper_log.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
use helpers::HelperDef;
use registry::Registry;
use context::{JsonRender, Context};
use context::JsonRender;
use render::{RenderContext, RenderError, Helper};

#[derive(Clone, Copy)]
pub struct LogHelper;

impl HelperDef for LogHelper {
fn call(&self,
_: &Context,
h: &Helper,
_: &Registry,
_: &mut RenderContext)
-> Result<(), RenderError> {
fn call(&self, h: &Helper, _: &Registry, _: &mut RenderContext) -> Result<(), RenderError> {
let param = try!(h.param(0)
.ok_or_else(|| RenderError::new("Param not found for helper \"log\"")));

Expand Down
9 changes: 2 additions & 7 deletions src/helpers/helper_lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,14 @@ use serde_json::value::Value as Json;

use helpers::HelperDef;
use registry::Registry;
use context::{Context, JsonRender};
use context::JsonRender;
use render::{RenderContext, RenderError, Helper};

#[derive(Clone, Copy)]
pub struct LookupHelper;

impl HelperDef for LookupHelper {
fn call(&self,
_: &Context,
h: &Helper,
_: &Registry,
rc: &mut RenderContext)
-> Result<(), RenderError> {
fn call(&self, h: &Helper, _: &Registry, rc: &mut RenderContext) -> Result<(), RenderError> {
let collection_value = try!(h.param(0).ok_or_else(|| {
RenderError::new("Param not found for helper \"lookup\"")
}));
Expand Down
Loading

0 comments on commit e1abdf7

Please sign in to comment.