diff options
-rw-r--r-- | askama_parser/src/expr.rs | 52 | ||||
-rw-r--r-- | askama_parser/src/lib.rs | 48 |
2 files changed, 49 insertions, 51 deletions
diff --git a/askama_parser/src/expr.rs b/askama_parser/src/expr.rs index 03620e7..c5c2351 100644 --- a/askama_parser/src/expr.rs +++ b/askama_parser/src/expr.rs @@ -9,9 +9,7 @@ use nom::multi::{fold_many0, many0, separated_list0, separated_list1}; use nom::sequence::{delimited, pair, preceded, terminated, tuple}; use nom::{error_position, IResult}; -use super::{ - bool_lit, char_lit, identifier, nested_parenthesis, not_ws, num_lit, path, str_lit, ws, -}; +use super::{bool_lit, char_lit, identifier, not_ws, num_lit, path, str_lit, ws}; #[derive(Debug, PartialEq)] pub enum Expr<'a> { @@ -159,6 +157,54 @@ fn expr_macro(i: &str) -> IResult<&str, Suffix<'_>> { )(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 expr_try(i: &str) -> IResult<&str, Suffix<'_>> { map(preceded(take_till(not_ws), char('?')), |_| Suffix::Try)(i) } diff --git a/askama_parser/src/lib.rs b/askama_parser/src/lib.rs index ac4ebb7..970fb2e 100644 --- a/askama_parser/src/lib.rs +++ b/askama_parser/src/lib.rs @@ -202,54 +202,6 @@ fn char_lit(i: &str) -> IResult<&str, &str> { Ok((i, s.unwrap_or_default())) } -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 path(i: &str) -> IResult<&str, Vec<&str>> { let root = opt(value("", ws(tag("::")))); let tail = separated_list1(ws(tag("::")), identifier); |