aboutsummaryrefslogtreecommitdiffstats
path: root/askama_parser/src/expr.rs
diff options
context:
space:
mode:
authorLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2023-07-02 11:20:35 +0200
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2023-07-31 10:27:15 +0200
commit2376cc6815a83aec7b0b76a671fabe4c22441aea (patch)
tree665ab6505ca32220cd0abaf6ca3e32c87447cf61 /askama_parser/src/expr.rs
parent1677fd6f57bcbfe1c810b3839bf155b3a0a02b76 (diff)
downloadaskama-2376cc6815a83aec7b0b76a671fabe4c22441aea.tar.gz
askama-2376cc6815a83aec7b0b76a671fabe4c22441aea.tar.bz2
askama-2376cc6815a83aec7b0b76a671fabe4c22441aea.zip
parser: move nested_parenthesis() helper into node module
Diffstat (limited to 'askama_parser/src/expr.rs')
-rw-r--r--askama_parser/src/expr.rs52
1 files changed, 49 insertions, 3 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)
}