aboutsummaryrefslogtreecommitdiffstats
path: root/askama_parser/src/expr.rs
diff options
context:
space:
mode:
authorLibravatar René Kijewski <rene.kijewski@fu-berlin.de>2023-07-14 12:46:57 +0200
committerLibravatar René Kijewski <Kijewski@users.noreply.github.com>2023-08-03 00:02:04 +0200
commit95ff27c087f9fd77e76ed069220d7b32d150a84e (patch)
tree49f9037daeec0561960aeadc3c3d4a9503ce0bdb /askama_parser/src/expr.rs
parentd38e2b4e2651b7c8b1a8bf614377011d046250f6 (diff)
downloadaskama-95ff27c087f9fd77e76ed069220d7b32d150a84e.tar.gz
askama-95ff27c087f9fd77e76ed069220d7b32d150a84e.tar.bz2
askama-95ff27c087f9fd77e76ed069220d7b32d150a84e.zip
Parse paths and identifiers only once
In the old implementation each variable in an expression would be parsed up to three times: * Try to parse a path because it contains a leading double colon, or infix double colons. * Try to parse it as path again by scanning for an identifier that contains an upper case character. * Fall back to scanning for any identifier. This PR turns all three steps into one, without the need for backtracking.
Diffstat (limited to '')
-rw-r--r--askama_parser/src/expr.rs20
1 files changed, 10 insertions, 10 deletions
diff --git a/askama_parser/src/expr.rs b/askama_parser/src/expr.rs
index 8331e01..248bc19 100644
--- a/askama_parser/src/expr.rs
+++ b/askama_parser/src/expr.rs
@@ -9,7 +9,10 @@ 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};
+use super::{
+ bool_lit, char_lit, identifier, not_ws, num_lit, path_or_identifier, str_lit, ws,
+ PathOrIdentifier,
+};
macro_rules! expr_prec_layer {
( $name:ident, $inner:ident, $op:expr ) => {
@@ -141,9 +144,8 @@ impl<'a> Expr<'a> {
Self::num,
Self::str,
Self::char,
- Self::path,
+ Self::path_or_var,
Self::array,
- Self::var,
Self::group,
))(i)
}
@@ -186,13 +188,11 @@ impl<'a> Expr<'a> {
)(i)
}
- fn path(i: &'a str) -> IResult<&'a str, Self> {
- let (i, path) = path(i)?;
- Ok((i, Self::Path(path)))
- }
-
- fn var(i: &'a str) -> IResult<&'a str, Self> {
- map(identifier, Self::Var)(i)
+ fn path_or_var(i: &'a str) -> IResult<&'a str, Self> {
+ map(path_or_identifier, |v| match v {
+ PathOrIdentifier::Path(v) => Self::Path(v),
+ PathOrIdentifier::Identifier(v) => Self::Var(v),
+ })(i)
}
fn str(i: &'a str) -> IResult<&'a str, Self> {