From be2cce3598a77eaf4e9931aa1154e02b6b9561e1 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Sat, 18 Feb 2017 13:52:23 +0100 Subject: Add support for filters with multiple arguments --- askama/src/generator.rs | 11 ++++++++--- askama/src/parser.rs | 40 ++++++++++++++++++++++++++++++++++------ 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/askama/src/generator.rs b/askama/src/generator.rs index 4ebc61a..911b860 100644 --- a/askama/src/generator.rs +++ b/askama/src/generator.rs @@ -124,9 +124,14 @@ impl<'a> Generator<'a> { self.write(&format!(".{}", attr)); } - fn visit_filter(&mut self, name: &str, val: &Expr) { + fn visit_filter(&mut self, name: &str, args: &[Expr]) { self.write(&format!("askama::filters::{}(&", name)); - self.visit_expr(val); + for (i, arg) in args.iter().enumerate() { + if i > 0 { + self.write(", &"); + } + self.visit_expr(arg); + } self.write(")"); } @@ -142,7 +147,7 @@ impl<'a> Generator<'a> { Expr::StrLit(s) => self.visit_str_lit(s), Expr::Var(s) => self.visit_var(s), Expr::Attr(ref obj, name) => self.visit_attr(obj, name), - Expr::Filter(name, ref val) => self.visit_filter(name, val), + Expr::Filter(name, ref args) => self.visit_filter(name, args), Expr::BinOp(op, ref left, ref right) => self.visit_binop(op, left, right), } diff --git a/askama/src/parser.rs b/askama/src/parser.rs index b5583c3..f15f973 100644 --- a/askama/src/parser.rs +++ b/askama/src/parser.rs @@ -7,7 +7,7 @@ pub enum Expr<'a> { StrLit(&'a str), Var(&'a str), Attr(Box>, &'a str), - Filter(&'a str, Box>), + Filter(&'a str, Vec>), BinOp(&'a str, Box>, Box>), } @@ -91,6 +91,27 @@ named!(target_single, map!(alphanumeric, |s| Target::Name(str::from_utf8(s).unwrap()) )); +named!(arguments>>, opt!( + do_parse!( + tag_s!("(") >> + arg0: ws!(opt!(expr_any)) >> + args: many0!(do_parse!( + tag_s!(",") >> + argn: ws!(expr_any) >> + (argn) + )) >> + tag_s!(")") >> + ({ + let mut res = Vec::new(); + if arg0.is_some() { + res.push(arg0.unwrap()); + } + res.extend(args); + res + }) + ) +)); + named!(expr_single, alt!( expr_num_lit | expr_str_lit | @@ -106,10 +127,11 @@ named!(expr_attr, alt!( ) | expr_single )); -named!(filter, do_parse!( +named!(filter<(&str, Option>)>, do_parse!( tag_s!("|") >> fname: alphanumeric >> - (fname) + args: arguments >> + (str::from_utf8(fname).unwrap(), args) )); named!(expr_filtered, do_parse!( @@ -117,9 +139,15 @@ named!(expr_filtered, do_parse!( filters: many0!(filter) >> ({ let mut res = obj; - for f in filters { - let fname = str::from_utf8(f).unwrap(); - res = Expr::Filter(fname, Box::new(res)); + for (fname, args) in filters { + res = Expr::Filter(fname, { + let mut args = match args { + Some(inner) => inner, + None => Vec::new(), + }; + args.insert(0, res); + args + }); } res }) -- cgit