aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar bott <mhpoin@gmail.com>2018-10-07 17:13:52 +0200
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2018-10-07 17:26:08 +0200
commit28d76964080f5c6c36d5f6ed72828b679fe352b4 (patch)
tree7056ea52905791893fd1681fd2297aac13389851
parent9edf27d9446da0b6c00550544d37b6da633bd2b6 (diff)
downloadaskama-28d76964080f5c6c36d5f6ed72828b679fe352b4.tar.gz
askama-28d76964080f5c6c36d5f6ed72828b679fe352b4.tar.bz2
askama-28d76964080f5c6c36d5f6ed72828b679fe352b4.zip
Add Rust macro support at templates
-rw-r--r--askama_derive/src/generator.rs12
-rw-r--r--askama_derive/src/parser.rs13
-rw-r--r--testing/templates/rust-macros.html1
-rw-r--r--testing/tests/rust_macro.rs22
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());
+}