From 95ff27c087f9fd77e76ed069220d7b32d150a84e Mon Sep 17 00:00:00 2001 From: René Kijewski Date: Fri, 14 Jul 2023 12:46:57 +0200 Subject: 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. --- askama_parser/src/node.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'askama_parser/src/node.rs') diff --git a/askama_parser/src/node.rs b/askama_parser/src/node.rs index 4c21ad1..a1aa7e2 100644 --- a/askama_parser/src/node.rs +++ b/askama_parser/src/node.rs @@ -3,15 +3,17 @@ use std::str; use nom::branch::alt; use nom::bytes::complete::{tag, take_until}; use nom::character::complete::char; -use nom::combinator::{complete, consumed, cut, eof, map, not, opt, peek, recognize, value}; +use nom::combinator::{ + complete, consumed, cut, eof, map, map_res, not, opt, peek, recognize, value, +}; use nom::error::{Error, ErrorKind}; use nom::multi::{fold_many0, many0, many1, separated_list0, separated_list1}; use nom::sequence::{delimited, pair, preceded, terminated, tuple}; use nom::{error_position, IResult}; use super::{ - bool_lit, char_lit, identifier, is_ws, keyword, num_lit, path, skip_till, str_lit, ws, Expr, - State, + bool_lit, char_lit, identifier, is_ws, keyword, num_lit, path_or_identifier, skip_till, + str_lit, ws, Expr, PathOrIdentifier, State, }; #[derive(Debug, PartialEq)] @@ -161,6 +163,13 @@ impl<'a> Target<'a> { return Ok((i, Self::Tuple(Vec::new(), targets))); } + let path = |i| { + map_res(path_or_identifier, |v| match v { + PathOrIdentifier::Path(v) => Ok(v), + PathOrIdentifier::Identifier(v) => Err(v), + })(i) + }; + // match structs let (i, path) = opt(path)(i)?; if let Some(path) = path { -- cgit