aboutsummaryrefslogtreecommitdiffstats
path: root/askama_parser
diff options
context:
space:
mode:
Diffstat (limited to 'askama_parser')
-rw-r--r--askama_parser/src/expr.rs107
1 files changed, 54 insertions, 53 deletions
diff --git a/askama_parser/src/expr.rs b/askama_parser/src/expr.rs
index 4bed4af..ef5c5e2 100644
--- a/askama_parser/src/expr.rs
+++ b/askama_parser/src/expr.rs
@@ -102,6 +102,12 @@ impl<'a> Expr<'a> {
expr_prec_layer!(muldivmod, filtered, "*", "/", "%");
fn filtered(i: &'a str) -> IResult<&'a str, Self> {
+ fn filter(i: &str) -> IResult<&str, (&str, Option<Vec<Expr<'_>>>)> {
+ let (i, (_, fname, args)) =
+ tuple((char('|'), ws(identifier), opt(Expr::arguments)))(i)?;
+ Ok((i, (fname, args)))
+ }
+
let (i, (obj, filters)) = tuple((Self::prefix, many0(filter)))(i)?;
let mut res = obj;
@@ -242,6 +248,54 @@ impl<'a> Suffix<'a> {
}
fn r#macro(i: &'a str) -> IResult<&'a str, Self> {
+ fn nested_parenthesis(i: &str) -> IResult<&str, ()> {
+ let mut nested = 0;
+ let mut last = 0;
+ let mut in_str = false;
+ let mut escaped = false;
+
+ for (i, b) in i.chars().enumerate() {
+ if !(b == '(' || b == ')') || !in_str {
+ match b {
+ '(' => nested += 1,
+ ')' => {
+ if nested == 0 {
+ last = i;
+ break;
+ }
+ nested -= 1;
+ }
+ '"' => {
+ if in_str {
+ if !escaped {
+ in_str = false;
+ }
+ } else {
+ in_str = true;
+ }
+ }
+ '\\' => {
+ escaped = !escaped;
+ }
+ _ => (),
+ }
+ }
+
+ if escaped && b != '\\' {
+ escaped = false;
+ }
+ }
+
+ if nested == 0 {
+ Ok((&i[last..], ()))
+ } else {
+ Err(nom::Err::Error(error_position!(
+ i,
+ ErrorKind::SeparatedNonEmptyList
+ )))
+ }
+ }
+
preceded(
pair(ws(char('!')), char('(')),
cut(terminated(
@@ -276,56 +330,3 @@ impl<'a> Suffix<'a> {
map(preceded(take_till(not_ws), char('?')), |_| Self::Try)(i)
}
}
-
-fn nested_parenthesis(i: &str) -> IResult<&str, ()> {
- let mut nested = 0;
- let mut last = 0;
- let mut in_str = false;
- let mut escaped = false;
-
- for (i, b) in i.chars().enumerate() {
- if !(b == '(' || b == ')') || !in_str {
- match b {
- '(' => nested += 1,
- ')' => {
- if nested == 0 {
- last = i;
- break;
- }
- nested -= 1;
- }
- '"' => {
- if in_str {
- if !escaped {
- in_str = false;
- }
- } else {
- in_str = true;
- }
- }
- '\\' => {
- escaped = !escaped;
- }
- _ => (),
- }
- }
-
- if escaped && b != '\\' {
- escaped = false;
- }
- }
-
- if nested == 0 {
- Ok((&i[last..], ()))
- } else {
- Err(nom::Err::Error(error_position!(
- i,
- ErrorKind::SeparatedNonEmptyList
- )))
- }
-}
-
-fn filter(i: &str) -> IResult<&str, (&str, Option<Vec<Expr<'_>>>)> {
- let (i, (_, fname, args)) = tuple((char('|'), ws(identifier), opt(Expr::arguments)))(i)?;
- Ok((i, (fname, args)))
-}