diff --git a/maud_macros/src/parse.rs b/maud_macros/src/parse.rs index 68f6003..e575f60 100644 --- a/maud_macros/src/parse.rs +++ b/maud_macros/src/parse.rs @@ -158,6 +158,11 @@ impl<'cx, 'i> Parser<'cx, 'i> { let func = try!(self.splice(sp)); self.render.emit_call(func); }, + [pound!(), ident!(sp, name), ..] if name.name == "call_box" => { + self.shift(2); + let func = try!(self.splice(sp)); + self.render.emit_call_box(func); + }, // Splice [ref tt @ dollar!(), dollar!(), ..] => { self.shift(2); diff --git a/maud_macros/src/render.rs b/maud_macros/src/render.rs index 36add0e..737ae8e 100644 --- a/maud_macros/src/render.rs +++ b/maud_macros/src/render.rs @@ -197,6 +197,16 @@ impl<'cx> Renderer<'cx> { let stmt = self.wrap_try(expr); self.push(stmt); } + + pub fn emit_call_box(&mut self, func: P<Expr>) { + let w = self.writer; + let expr = quote_expr!(self.cx, + ::std::boxed::FnBox::call_box( + $func, + (&mut *$w as &mut ::std::fmt::Write,))); + let stmt = self.wrap_try(expr); + self.push(stmt); + } } fn html_escape(s: &str) -> String { diff --git a/maud_macros/tests/tests.rs b/maud_macros/tests/tests.rs index cbbb8d6..673f026 100644 --- a/maud_macros/tests/tests.rs +++ b/maud_macros/tests/tests.rs @@ -1,10 +1,8 @@ -#![feature(plugin)] +#![feature(fnbox, plugin)] #![plugin(maud_macros)] extern crate maud; -use std::fmt; - #[test] fn literals() { let mut s = String::new(); @@ -274,22 +272,35 @@ mod issue_10 { } } -#[test] -fn call() { +mod subtemplates { + use std::fmt; + fn ducks(w: &mut fmt::Write) -> fmt::Result { write!(w, "Ducks") } - let mut s = String::new(); - let swans = |yes| - if yes { - |w: &mut fmt::Write| write!(w, "Swans") - } else { - panic!("oh noes") - }; - html!(s, { - #call ducks - #call (|w: &mut fmt::Write| write!(w, "Geese")) - #call swans(true) - }).unwrap(); - assert_eq!(s, "DucksGeeseSwans"); + + #[test] + fn call() { + let mut s = String::new(); + let swans = |yes| + if yes { + |w: &mut fmt::Write| write!(w, "Swans") + } else { + panic!("oh noes") + }; + html!(s, { + #call ducks + #call (|w: &mut fmt::Write| write!(w, "Geese")) + #call swans(true) + }).unwrap(); + assert_eq!(s, "DucksGeeseSwans"); + } + + #[test] + fn call_box() { + let mut s = String::new(); + let ducks = Box::new(ducks); + html!(s, #call_box ducks).unwrap(); + assert_eq!(s, "Ducks"); + } }