diff --git a/askama_shared/src/parser.rs b/askama_shared/src/parser.rs index 275c92b17..e13a54ab2 100644 --- a/askama_shared/src/parser.rs +++ b/askama_shared/src/parser.rs @@ -539,7 +539,7 @@ fn filter(i: &[u8]) -> IResult<&[u8], (&str, Option>)> { } fn expr_filtered(i: &[u8]) -> IResult<&[u8], Expr> { - let (i, (obj, filters)) = tuple((expr_index, many0(filter)))(i)?; + let (i, (obj, filters)) = tuple((expr_unary, many0(filter)))(i)?; let mut res = obj; for (fname, args) in filters { @@ -557,7 +557,7 @@ fn expr_filtered(i: &[u8]) -> IResult<&[u8], Expr> { } fn expr_unary(i: &[u8]) -> IResult<&[u8], Expr> { - let (i, (op, expr)) = tuple((opt(alt((ws(tag("!")), ws(tag("-"))))), expr_filtered))(i)?; + let (i, (op, expr)) = tuple((opt(alt((ws(tag("!")), ws(tag("-"))))), expr_index))(i)?; Ok(( i, match op { @@ -605,7 +605,7 @@ macro_rules! expr_prec_layer { } } -expr_prec_layer!(expr_muldivmod, expr_unary, "*", "/", "%"); +expr_prec_layer!(expr_muldivmod, expr_filtered, "*", "/", "%"); expr_prec_layer!(expr_addsub, expr_muldivmod, "+", "-"); expr_prec_layer!(expr_shifts, expr_addsub, ">>", "<<"); expr_prec_layer!(expr_band, expr_shifts, "&"); @@ -1126,7 +1126,41 @@ mod tests { #[test] fn test_parse_filter() { - super::parse("{{ strvar|e }}", &Syntax::default()).unwrap(); + use Expr::*; + let syntax = Syntax::default(); + assert_eq!( + super::parse("{{ strvar|e }}", &syntax).unwrap(), + vec![Node::Expr( + WS(false, false), + Filter("e", vec![Var("strvar")]), + )], + ); + assert_eq!( + super::parse("{{ 2|abs }}", &syntax).unwrap(), + vec![Node::Expr( + WS(false, false), + Filter("abs", vec![NumLit("2")]), + )], + ); + assert_eq!( + super::parse("{{ -2|abs }}", &syntax).unwrap(), + vec![Node::Expr( + WS(false, false), + Filter("abs", vec![Unary("-", NumLit("2").into())]), + )], + ); + assert_eq!( + super::parse("{{ (1 - 2)|abs }}", &syntax).unwrap(), + vec![Node::Expr( + WS(false, false), + Filter( + "abs", + vec![Group( + BinOp("-", NumLit("1").into(), NumLit("2").into()).into() + )] + ), + )], + ); } #[test]