aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar René Kijewski <rene.kijewski@fu-berlin.de>2023-07-31 20:58:23 +0200
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2023-07-31 21:29:35 +0200
commit985eb8955f36e909d18f7ea6eaf4c748e7afd17a (patch)
tree01aca3e735d2c5c698495ce0b3a383911f2563f5
parent107bdfdd7658919691948f629adf2254cd6aa367 (diff)
downloadaskama-985eb8955f36e909d18f7ea6eaf4c748e7afd17a.tar.gz
askama-985eb8955f36e909d18f7ea6eaf4c748e7afd17a.tar.bz2
askama-985eb8955f36e909d18f7ea6eaf4c748e7afd17a.zip
Fix parsing arrays
This change * allows using empty arrays `[]` in expessions, * adds a cut when the leading `[` was encountered, and * fixes the interaction between arrays and boolean OR. IMO the restriction that you couldn't use empty arrays is not needed. The missing cut made error messages slictly worse if you forget to add the closing `]`. Filter expressions must not have white spaces before the pipe `|`. The white space is used to tell a filter expressions, and `std::ops::Or` apart.
Diffstat (limited to '')
-rw-r--r--askama_parser/src/expr.rs12
-rw-r--r--askama_parser/src/tests.rs83
-rw-r--r--testing/tests/ui/loop_cycle_empty.rs3
-rw-r--r--testing/tests/ui/loop_cycle_empty.stderr7
4 files changed, 93 insertions, 12 deletions
diff --git a/askama_parser/src/expr.rs b/askama_parser/src/expr.rs
index ab7caff..9610c05 100644
--- a/askama_parser/src/expr.rs
+++ b/askama_parser/src/expr.rs
@@ -5,8 +5,8 @@ use nom::bytes::complete::{tag, take_till};
use nom::character::complete::char;
use nom::combinator::{cut, map, not, opt, peek, recognize};
use nom::error::ErrorKind;
-use nom::multi::{fold_many0, many0, separated_list0, separated_list1};
-use nom::sequence::{delimited, pair, preceded, terminated, tuple};
+use nom::multi::{fold_many0, many0, separated_list0};
+use nom::sequence::{pair, preceded, terminated, tuple};
use nom::{error_position, IResult};
use super::{bool_lit, char_lit, identifier, not_ws, num_lit, path, str_lit, ws};
@@ -177,10 +177,12 @@ impl<'a> Expr<'a> {
}
fn array(i: &'a str) -> IResult<&'a str, Self> {
- delimited(
+ preceded(
ws(char('[')),
- map(separated_list1(ws(char(',')), Self::parse), Self::Array),
- ws(char(']')),
+ cut(terminated(
+ map(separated_list0(char(','), ws(Self::parse)), Self::Array),
+ char(']'),
+ )),
)(i)
}
diff --git a/askama_parser/src/tests.rs b/askama_parser/src/tests.rs
index 2beeb38..61aa279 100644
--- a/askama_parser/src/tests.rs
+++ b/askama_parser/src/tests.rs
@@ -761,3 +761,86 @@ fn test_missing_space_after_kw() {
"unable to parse template:\n\n\"{%leta=b%}\""
));
}
+
+#[test]
+fn test_parse_array() {
+ let syntax = Syntax::default();
+ assert_eq!(
+ Ast::from_str("{{ [] }}", &syntax).unwrap().nodes,
+ vec![Node::Expr(Ws(None, None), Expr::Array(vec![]))],
+ );
+ assert_eq!(
+ Ast::from_str("{{ [1] }}", &syntax).unwrap().nodes,
+ vec![Node::Expr(
+ Ws(None, None),
+ Expr::Array(vec![Expr::NumLit("1")])
+ )],
+ );
+ assert_eq!(
+ Ast::from_str("{{ [ 1] }}", &syntax).unwrap().nodes,
+ vec![Node::Expr(
+ Ws(None, None),
+ Expr::Array(vec![Expr::NumLit("1")])
+ )],
+ );
+ assert_eq!(
+ Ast::from_str("{{ [1 ] }}", &syntax).unwrap().nodes,
+ vec![Node::Expr(
+ Ws(None, None),
+ Expr::Array(vec![Expr::NumLit("1")])
+ )],
+ );
+ assert_eq!(
+ Ast::from_str("{{ [1,2] }}", &syntax).unwrap().nodes,
+ vec![Node::Expr(
+ Ws(None, None),
+ Expr::Array(vec![Expr::NumLit("1"), Expr::NumLit("2")])
+ )],
+ );
+ assert_eq!(
+ Ast::from_str("{{ [1 ,2] }}", &syntax).unwrap().nodes,
+ vec![Node::Expr(
+ Ws(None, None),
+ Expr::Array(vec![Expr::NumLit("1"), Expr::NumLit("2")])
+ )],
+ );
+ assert_eq!(
+ Ast::from_str("{{ [1, 2] }}", &syntax).unwrap().nodes,
+ vec![Node::Expr(
+ Ws(None, None),
+ Expr::Array(vec![Expr::NumLit("1"), Expr::NumLit("2")])
+ )],
+ );
+ assert_eq!(
+ Ast::from_str("{{ [1,2 ] }}", &syntax).unwrap().nodes,
+ vec![Node::Expr(
+ Ws(None, None),
+ Expr::Array(vec![Expr::NumLit("1"), Expr::NumLit("2")])
+ )],
+ );
+ assert_eq!(
+ Ast::from_str("{{ []|foo }}", &syntax).unwrap().nodes,
+ vec![Node::Expr(
+ Ws(None, None),
+ Expr::Filter("foo", vec![Expr::Array(vec![])])
+ )],
+ );
+ assert_eq!(
+ Ast::from_str("{{ []| foo }}", &syntax).unwrap().nodes,
+ vec![Node::Expr(
+ Ws(None, None),
+ Expr::Filter("foo", vec![Expr::Array(vec![])])
+ )],
+ );
+ assert_eq!(
+ Ast::from_str("{{ [] |foo }}", &syntax).unwrap().nodes,
+ vec![Node::Expr(
+ Ws(None, None),
+ Expr::BinOp(
+ "|",
+ Box::new(Expr::Array(vec![])),
+ Box::new(Expr::Var("foo"))
+ ),
+ )],
+ );
+}
diff --git a/testing/tests/ui/loop_cycle_empty.rs b/testing/tests/ui/loop_cycle_empty.rs
index 4aa6010..30d54fa 100644
--- a/testing/tests/ui/loop_cycle_empty.rs
+++ b/testing/tests/ui/loop_cycle_empty.rs
@@ -1,6 +1,3 @@
-// Nb. this test fails because currently an empty array "[]" is always a syntax error in askama,
-// but even if this changes, this test should keep failing, but possibly with another error message
-
use askama::Template;
#[derive(Template)]
diff --git a/testing/tests/ui/loop_cycle_empty.stderr b/testing/tests/ui/loop_cycle_empty.stderr
index 4fc35bb..dd4f0dd 100644
--- a/testing/tests/ui/loop_cycle_empty.stderr
+++ b/testing/tests/ui/loop_cycle_empty.stderr
@@ -1,8 +1,7 @@
-error: problems parsing template source at row 1, column 35 near:
- "[]) }}{{ v }},{% endfor %}"
- --> tests/ui/loop_cycle_empty.rs:6:10
+error: loop.cycle(…) cannot use an empty array
+ --> tests/ui/loop_cycle_empty.rs:3:10
|
-6 | #[derive(Template)]
+3 | #[derive(Template)]
| ^^^^^^^^
|
= note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)