diff options
author | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2017-02-18 13:52:23 +0100 |
---|---|---|
committer | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2017-02-18 13:52:23 +0100 |
commit | be2cce3598a77eaf4e9931aa1154e02b6b9561e1 (patch) | |
tree | f8e44a6a0c3901112ac014348b4aa15a0d7006f4 | |
parent | e449140e0a635453084b502baf22f08e8750d068 (diff) | |
download | askama-be2cce3598a77eaf4e9931aa1154e02b6b9561e1.tar.gz askama-be2cce3598a77eaf4e9931aa1154e02b6b9561e1.tar.bz2 askama-be2cce3598a77eaf4e9931aa1154e02b6b9561e1.zip |
Add support for filters with multiple arguments
Diffstat (limited to '')
-rw-r--r-- | askama/src/generator.rs | 11 | ||||
-rw-r--r-- | 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<Expr<'a>>, &'a str), - Filter(&'a str, Box<Expr<'a>>), + Filter(&'a str, Vec<Expr<'a>>), BinOp(&'a str, Box<Expr<'a>>, Box<Expr<'a>>), } @@ -91,6 +91,27 @@ named!(target_single<Target>, map!(alphanumeric, |s| Target::Name(str::from_utf8(s).unwrap()) )); +named!(arguments<Option<Vec<Expr>>>, 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<Expr>, alt!( expr_num_lit | expr_str_lit | @@ -106,10 +127,11 @@ named!(expr_attr<Expr>, alt!( ) | expr_single )); -named!(filter, do_parse!( +named!(filter<(&str, Option<Vec<Expr>>)>, do_parse!( tag_s!("|") >> fname: alphanumeric >> - (fname) + args: arguments >> + (str::from_utf8(fname).unwrap(), args) )); named!(expr_filtered<Expr>, do_parse!( @@ -117,9 +139,15 @@ named!(expr_filtered<Expr>, 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 }) |