diff options
author | bott <mhpoin@gmail.com> | 2018-10-07 17:13:52 +0200 |
---|---|---|
committer | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2018-10-07 17:26:08 +0200 |
commit | 28d76964080f5c6c36d5f6ed72828b679fe352b4 (patch) | |
tree | 7056ea52905791893fd1681fd2297aac13389851 | |
parent | 9edf27d9446da0b6c00550544d37b6da633bd2b6 (diff) | |
download | askama-28d76964080f5c6c36d5f6ed72828b679fe352b4.tar.gz askama-28d76964080f5c6c36d5f6ed72828b679fe352b4.tar.bz2 askama-28d76964080f5c6c36d5f6ed72828b679fe352b4.zip |
Add Rust macro support at templates
-rw-r--r-- | askama_derive/src/generator.rs | 12 | ||||
-rw-r--r-- | askama_derive/src/parser.rs | 13 | ||||
-rw-r--r-- | testing/templates/rust-macros.html | 1 | ||||
-rw-r--r-- | testing/tests/rust_macro.rs | 22 |
4 files changed, 46 insertions, 2 deletions
diff --git a/askama_derive/src/generator.rs b/askama_derive/src/generator.rs index 33fbe4c..41e1647 100644 --- a/askama_derive/src/generator.rs +++ b/askama_derive/src/generator.rs @@ -644,10 +644,20 @@ impl<'a> Generator<'a> { Expr::Group(ref inner) => self.visit_group(buf, inner), Expr::MethodCall(ref obj, method, ref args) => { self.visit_method_call(buf, obj, method, args) - } + }, + Expr::RustMacro(name, ref args) => self.visit_rust_macro(buf, name, args), } } + fn visit_rust_macro(&mut self, buf: &mut Buffer, name: &str, args: &[Expr]) -> DisplayWrap { + buf.write(name); + buf.write("!("); + self._visit_args(buf, args); + buf.write(")"); + + DisplayWrap::Unwrapped + } + fn visit_match_variant(&mut self, buf: &mut Buffer, param: &MatchVariant) -> DisplayWrap { let mut expr_buf = Buffer::new(0); let wrapped = match *param { diff --git a/askama_derive/src/parser.rs b/askama_derive/src/parser.rs index 1c5e28e..742a7a2 100644 --- a/askama_derive/src/parser.rs +++ b/askama_derive/src/parser.rs @@ -21,6 +21,7 @@ pub enum Expr<'a> { Range(&'a str, Option<Box<Expr<'a>>>, Option<Box<Expr<'a>>>), Group(Box<Expr<'a>>), MethodCall(Box<Expr<'a>>, &'a str, Vec<Expr<'a>>), + RustMacro(&'a str, Vec<Expr<'a>>), } #[derive(Debug)] @@ -427,6 +428,14 @@ named!(expr_unary<Input, Expr>, do_parse!( }) )); +named!(rust_macro<Input, Expr>, do_parse!( + mname: identifier >> + tag!("!") >> + args: arguments >> + (Expr::RustMacro(mname, args)) +)); + + macro_rules! expr_prec_layer { ( $name:ident, $inner:ident, $( $op:expr ),* ) => { named!($name<Input, Expr>, do_parse!( @@ -463,6 +472,7 @@ named!(range_right<Input, Expr>, do_parse!( named!(expr_any<Input, Expr>, alt!( range_right | + rust_macro | do_parse!( left: expr_or >> rest: range_right >> (match rest { @@ -776,6 +786,7 @@ mod tests { } } } + #[test] fn test_ws_splitter() { check_ws_split("", &("", "", "")); @@ -784,6 +795,7 @@ mod tests { check_ws_split("b\n", &("", "b", "\n")); check_ws_split(" \t\r\n", &(" \t\r\n", "", "")); } + #[test] #[should_panic] fn test_invalid_block() { @@ -805,5 +817,4 @@ mod tests { super::parse("{~ strvar|e ~}", &syntax); } - } diff --git a/testing/templates/rust-macros.html b/testing/templates/rust-macros.html new file mode 100644 index 0000000..dc0b3de --- /dev/null +++ b/testing/templates/rust-macros.html @@ -0,0 +1 @@ +Hello, {{ hello!(name) }}! diff --git a/testing/tests/rust_macro.rs b/testing/tests/rust_macro.rs new file mode 100644 index 0000000..c6e97ce --- /dev/null +++ b/testing/tests/rust_macro.rs @@ -0,0 +1,22 @@ +#[macro_use] +extern crate askama; + +use askama::Template; + +macro_rules! hello { + ($name:expr) => { + "world" + } +} + +#[derive(Template)] +#[template(path = "rust-macros.html")] +struct RustMacrosTemplate<'a> { + name: &'a str, +} + +#[test] +fn main() { + let template = RustMacrosTemplate { name: "foo" }; + assert_eq!("Hello, world!", template.render().unwrap()); +} |