aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--askama_shared/src/parser.rs62
1 files changed, 19 insertions, 43 deletions
diff --git a/askama_shared/src/parser.rs b/askama_shared/src/parser.rs
index e5d42fc..6c90941 100644
--- a/askama_shared/src/parser.rs
+++ b/askama_shared/src/parser.rs
@@ -2,13 +2,13 @@ use std::cell::Cell;
use std::str;
use nom::branch::alt;
-use nom::bytes::complete::{escaped, is_not, tag, take_until};
+use nom::bytes::complete::{escaped, is_not, tag, take_till, take_until};
use nom::character::complete::{anychar, char, digit1};
use nom::combinator::{complete, cut, map, opt, recognize, value};
-use nom::error::{Error, ErrorKind, ParseError};
+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::{self, error_position, Compare, IResult, InputLength, InputTake};
+use nom::{self, IResult, error_position};
use crate::{CompileError, Syntax};
@@ -140,50 +140,26 @@ pub struct CondTest<'a> {
pub expr: Expr<'a>,
}
-fn ws<F, I, O, E>(mut inner: F) -> impl FnMut(I) -> IResult<I, O, E>
-where
- F: FnMut(I) -> IResult<I, O, E>,
- I: InputLength + InputTake + Clone + PartialEq + for<'a> Compare<&'a [u8; 1]>,
- E: ParseError<I>,
-{
- move |i: I| {
- let mut ws = many0(alt::<_, _, (), _>((
- tag(b" "),
- tag(b"\t"),
- tag(b"\r"),
- tag(b"\n"),
- )));
- let i = ws(i.clone()).map(|(i, _)| i).unwrap_or(i);
- let (i, res) = inner(i)?;
- let i = ws(i.clone()).map(|(i, _)| i).unwrap_or(i);
- Ok((i, res))
- }
+fn is_ws(c: char) -> bool {
+ matches!(c, ' ' | '\t' | '\r' | '\n')
}
-fn split_ws_parts(s: &[u8]) -> Node<'_> {
- if s.is_empty() {
- let rs = str::from_utf8(s).unwrap();
- return Node::Lit(rs, rs, rs);
- }
+fn not_ws(c: u8) -> bool {
+ !is_ws(c as char)
+}
- let is_ws = |c: &u8| *c != b' ' && *c != b'\t' && *c != b'\r' && *c != b'\n';
- let start = s.iter().position(&is_ws);
- let res = if let Some(start) = start {
- let end = s.iter().rposition(&is_ws);
- if let Some(end) = end {
- (&s[..start], &s[start..=end], &s[end + 1..])
- } else {
- (&s[..start], &s[start..], &[] as &[u8])
- }
- } else {
- (s, &[] as &[u8], &[] as &[u8])
- };
+fn ws<'a, O>(
+ inner: impl FnMut(&'a [u8]) -> IResult<&'a [u8], O>,
+) -> impl FnMut(&'a [u8]) -> IResult<&'a [u8], O> {
+ delimited(take_till(not_ws), inner, take_till(not_ws))
+}
- Node::Lit(
- str::from_utf8(res.0).unwrap(),
- str::from_utf8(res.1).unwrap(),
- str::from_utf8(res.2).unwrap(),
- )
+fn split_ws_parts(s: &[u8]) -> Node<'_> {
+ let s = str::from_utf8(s).unwrap();
+ let trimmed_start = s.trim_start_matches(is_ws);
+ let len_start = s.len() - trimmed_start.len();
+ let trimmed = trimmed_start.trim_end_matches(is_ws);
+ Node::Lit(&s[..len_start], trimmed, &trimmed_start[trimmed.len()..])
}
#[derive(Debug)]