aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2017-02-18 13:52:23 +0100
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2017-02-18 13:52:23 +0100
commitbe2cce3598a77eaf4e9931aa1154e02b6b9561e1 (patch)
treef8e44a6a0c3901112ac014348b4aa15a0d7006f4
parente449140e0a635453084b502baf22f08e8750d068 (diff)
downloadaskama-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.rs11
-rw-r--r--askama/src/parser.rs40
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
})