diff options
Diffstat (limited to 'askama_parser')
| -rw-r--r-- | askama_parser/src/expr.rs | 52 | ||||
| -rw-r--r-- | askama_parser/src/lib.rs | 71 | ||||
| -rw-r--r-- | askama_parser/src/node.rs | 75 | 
3 files changed, 90 insertions, 108 deletions
| diff --git a/askama_parser/src/expr.rs b/askama_parser/src/expr.rs index 803681e..7760a98 100644 --- a/askama_parser/src/expr.rs +++ b/askama_parser/src/expr.rs @@ -5,18 +5,18 @@ use nom::bytes::complete::{tag, take_till};  use nom::character::complete::char;  use nom::combinator::{cut, map, not, opt, peek, recognize};  use nom::error::ErrorKind; +use nom::error_position;  use nom::multi::{fold_many0, many0, separated_list0};  use nom::sequence::{pair, preceded, terminated, tuple}; -use nom::{error_position, IResult};  use super::{      char_lit, identifier, not_ws, num_lit, path_or_identifier, str_lit, ws, Level, PathOrIdentifier,  }; -use crate::ErrorContext; +use crate::ParseResult;  macro_rules! expr_prec_layer {      ( $name:ident, $inner:ident, $op:expr ) => { -        fn $name(i: &'a str, level: Level) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +        fn $name(i: &'a str, level: Level) -> ParseResult<'a, Self> {              let (_, level) = level.nest(i)?;              let (i, left) = Self::$inner(i, level)?;              let (i, right) = many0(pair( @@ -32,7 +32,7 @@ macro_rules! expr_prec_layer {          }      };      ( $name:ident, $inner:ident, $( $op:expr ),+ ) => { -        fn $name(i: &'a str, level: Level) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +        fn $name(i: &'a str, level: Level) -> ParseResult<'a, Self> {              let (_, level) = level.nest(i)?;              let (i, left) = Self::$inner(i, level)?;              let (i, right) = many0(pair( @@ -72,10 +72,7 @@ pub enum Expr<'a> {  }  impl<'a> Expr<'a> { -    pub(super) fn arguments( -        i: &'a str, -        level: Level, -    ) -> IResult<&'a str, Vec<Self>, ErrorContext<&'a str>> { +    pub(super) fn arguments(i: &'a str, level: Level) -> ParseResult<'a, Vec<Self>> {          let (_, level) = level.nest(i)?;          preceded(              ws(char('(')), @@ -86,7 +83,7 @@ impl<'a> Expr<'a> {          )(i)      } -    pub(super) fn parse(i: &'a str, level: Level) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    pub(super) fn parse(i: &'a str, level: Level) -> ParseResult<'a, Self> {          let (_, level) = level.nest(i)?;          let range_right = move |i| {              pair( @@ -118,13 +115,10 @@ impl<'a> Expr<'a> {      expr_prec_layer!(addsub, muldivmod, "+", "-");      expr_prec_layer!(muldivmod, filtered, "*", "/", "%"); -    fn filtered(i: &'a str, level: Level) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn filtered(i: &'a str, level: Level) -> ParseResult<'a, Self> {          let (_, level) = level.nest(i)?;          #[allow(clippy::type_complexity)] -        fn filter( -            i: &str, -            level: Level, -        ) -> IResult<&str, (&str, Option<Vec<Expr<'_>>>), ErrorContext<&str>> { +        fn filter(i: &str, level: Level) -> ParseResult<'_, (&str, Option<Vec<Expr<'_>>>)> {              let (i, (_, fname, args)) = tuple((                  char('|'),                  ws(identifier), @@ -151,7 +145,7 @@ impl<'a> Expr<'a> {          Ok((i, res))      } -    fn prefix(i: &'a str, level: Level) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn prefix(i: &'a str, level: Level) -> ParseResult<'a, Self> {          let (_, level) = level.nest(i)?;          let (i, (ops, mut expr)) = pair(many0(ws(alt((tag("!"), tag("-"))))), |i| {              Suffix::parse(i, level) @@ -162,7 +156,7 @@ impl<'a> Expr<'a> {          Ok((i, expr))      } -    fn single(i: &'a str, level: Level) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn single(i: &'a str, level: Level) -> ParseResult<'a, Self> {          let (_, level) = level.nest(i)?;          alt((              Self::num, @@ -174,7 +168,7 @@ impl<'a> Expr<'a> {          ))(i)      } -    fn group(i: &'a str, level: Level) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn group(i: &'a str, level: Level) -> ParseResult<'a, Self> {          let (_, level) = level.nest(i)?;          let (i, expr) = preceded(ws(char('(')), opt(|i| Self::parse(i, level)))(i)?;          let expr = match expr { @@ -203,7 +197,7 @@ impl<'a> Expr<'a> {          Ok((i, Self::Tuple(exprs)))      } -    fn array(i: &'a str, level: Level) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn array(i: &'a str, level: Level) -> ParseResult<'a, Self> {          let (_, level) = level.nest(i)?;          preceded(              ws(char('[')), @@ -217,7 +211,7 @@ impl<'a> Expr<'a> {          )(i)      } -    fn path_var_bool(i: &'a str) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn path_var_bool(i: &'a str) -> ParseResult<'a, Self> {          map(path_or_identifier, |v| match v {              PathOrIdentifier::Path(v) => Self::Path(v),              PathOrIdentifier::Identifier(v @ "true") => Self::BoolLit(v), @@ -226,15 +220,15 @@ impl<'a> Expr<'a> {          })(i)      } -    fn str(i: &'a str) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn str(i: &'a str) -> ParseResult<'a, Self> {          map(str_lit, Self::StrLit)(i)      } -    fn num(i: &'a str) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn num(i: &'a str) -> ParseResult<'a, Self> {          map(num_lit, Self::NumLit)(i)      } -    fn char(i: &'a str) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn char(i: &'a str) -> ParseResult<'a, Self> {          map(char_lit, Self::CharLit)(i)      }  } @@ -249,7 +243,7 @@ enum Suffix<'a> {  }  impl<'a> Suffix<'a> { -    fn parse(i: &'a str, level: Level) -> IResult<&'a str, Expr<'a>, ErrorContext<&'a str>> { +    fn parse(i: &'a str, level: Level) -> ParseResult<'a, Expr<'a>> {          let (_, level) = level.nest(i)?;          let (mut i, mut expr) = Expr::single(i, level)?;          loop { @@ -279,8 +273,8 @@ impl<'a> Suffix<'a> {          Ok((i, expr))      } -    fn r#macro(i: &'a str) -> IResult<&'a str, Self, ErrorContext<&'a str>> { -        fn nested_parenthesis(input: &str) -> IResult<&str, (), ErrorContext<&str>> { +    fn r#macro(i: &'a str) -> ParseResult<'a, Self> { +        fn nested_parenthesis(input: &str) -> ParseResult<'_, ()> {              let mut nested = 0;              let mut last = 0;              let mut in_str = false; @@ -337,7 +331,7 @@ impl<'a> Suffix<'a> {          )(i)      } -    fn attr(i: &'a str) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn attr(i: &'a str) -> ParseResult<'a, Self> {          map(              preceded(                  ws(pair(char('.'), not(char('.')))), @@ -347,7 +341,7 @@ impl<'a> Suffix<'a> {          )(i)      } -    fn index(i: &'a str, level: Level) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn index(i: &'a str, level: Level) -> ParseResult<'a, Self> {          let (_, level) = level.nest(i)?;          map(              preceded( @@ -358,12 +352,12 @@ impl<'a> Suffix<'a> {          )(i)      } -    fn call(i: &'a str, level: Level) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn call(i: &'a str, level: Level) -> ParseResult<'a, Self> {          let (_, level) = level.nest(i)?;          map(move |i| Expr::arguments(i, level), Self::Call)(i)      } -    fn r#try(i: &'a str) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn r#try(i: &'a str) -> ParseResult<'a, Self> {          map(preceded(take_till(not_ws), char('?')), |_| Self::Try)(i)      }  } diff --git a/askama_parser/src/lib.rs b/askama_parser/src/lib.rs index 5abc771..ff26483 100644 --- a/askama_parser/src/lib.rs +++ b/askama_parser/src/lib.rs @@ -13,7 +13,7 @@ use nom::combinator::{cut, eof, map, opt, recognize};  use nom::error::{Error, ErrorKind, FromExternalError};  use nom::multi::many1;  use nom::sequence::{delimited, pair, preceded, terminated, tuple}; -use nom::{error_position, AsChar, IResult, InputTakeAtPosition}; +use nom::{error_position, AsChar, InputTakeAtPosition};  pub mod expr;  pub use expr::Expr; @@ -129,32 +129,34 @@ impl fmt::Display for ParseError {      }  } +pub(crate) type ParseResult<'a, T = &'a str> = Result<(&'a str, T), nom::Err<ErrorContext<'a>>>; +  /// This type is used to handle `nom` errors and in particular to add custom error messages.  /// It used to generate `ParserError`.  ///  /// It cannot be used to replace `ParseError` because it expects a generic, which would make  /// `askama`'s users experience less good (since this generic is only needed for `nom`).  #[derive(Debug)] -pub(crate) struct ErrorContext<I> { -    pub(crate) input: I, +pub(crate) struct ErrorContext<'a> { +    pub(crate) input: &'a str,      pub(crate) message: Option<Cow<'static, str>>,  } -impl<I> nom::error::ParseError<I> for ErrorContext<I> { -    fn from_error_kind(input: I, _code: ErrorKind) -> Self { +impl<'a> nom::error::ParseError<&'a str> for ErrorContext<'a> { +    fn from_error_kind(input: &'a str, _code: ErrorKind) -> Self {          Self {              input,              message: None,          }      } -    fn append(_: I, _: ErrorKind, other: Self) -> Self { +    fn append(_: &'a str, _: ErrorKind, other: Self) -> Self {          other      }  } -impl<I, E: std::fmt::Display> FromExternalError<I, E> for ErrorContext<I> { -    fn from_external_error(input: I, _kind: ErrorKind, e: E) -> Self { +impl<'a, E: std::fmt::Display> FromExternalError<&'a str, E> for ErrorContext<'a> { +    fn from_external_error(input: &'a str, _kind: ErrorKind, e: E) -> Self {          Self {              input,              message: Some(Cow::Owned(e.to_string())), @@ -162,8 +164,8 @@ impl<I, E: std::fmt::Display> FromExternalError<I, E> for ErrorContext<I> {      }  } -impl<I> ErrorContext<I> { -    pub(crate) fn from_err(error: nom::Err<Error<I>>) -> nom::Err<Self> { +impl<'a> ErrorContext<'a> { +    pub(crate) fn from_err(error: nom::Err<Error<&'a str>>) -> nom::Err<Self> {          match error {              nom::Err::Incomplete(i) => nom::Err::Incomplete(i),              nom::Err::Failure(Error { input, .. }) => nom::Err::Failure(Self { @@ -187,16 +189,16 @@ fn not_ws(c: char) -> bool {  }  fn ws<'a, O>( -    inner: impl FnMut(&'a str) -> IResult<&'a str, O, ErrorContext<&'a str>>, -) -> impl FnMut(&'a str) -> IResult<&'a str, O, ErrorContext<&'a str>> { +    inner: impl FnMut(&'a str) -> ParseResult<'a, O>, +) -> impl FnMut(&'a str) -> ParseResult<'a, O> {      delimited(take_till(not_ws), inner, take_till(not_ws))  }  /// Skips input until `end` was found, but does not consume it.  /// Returns tuple that would be returned when parsing `end`.  fn skip_till<'a, O>( -    end: impl FnMut(&'a str) -> IResult<&'a str, O, ErrorContext<&'a str>>, -) -> impl FnMut(&'a str) -> IResult<&'a str, (&'a str, O), ErrorContext<&'a str>> { +    end: impl FnMut(&'a str) -> ParseResult<'a, O>, +) -> impl FnMut(&'a str) -> ParseResult<'a, (&'a str, O)> {      enum Next<O> {          IsEnd(O),          NotEnd(char), @@ -214,10 +216,8 @@ fn skip_till<'a, O>(      }  } -fn keyword<'a>( -    k: &'a str, -) -> impl FnMut(&'a str) -> IResult<&'a str, &'a str, ErrorContext<&'a str>> { -    move |i: &'a str| -> IResult<&'a str, &'a str, ErrorContext<&'a str>> { +fn keyword<'a>(k: &'a str) -> impl FnMut(&'a str) -> ParseResult<'_> { +    move |i: &'a str| -> ParseResult<'a> {          let (j, v) = identifier(i)?;          if k == v {              Ok((j, v)) @@ -227,15 +227,15 @@ fn keyword<'a>(      }  } -fn identifier(input: &str) -> IResult<&str, &str, ErrorContext<&str>> { -    fn start(s: &str) -> IResult<&str, &str, ErrorContext<&str>> { +fn identifier(input: &str) -> ParseResult<'_> { +    fn start(s: &str) -> ParseResult<'_> {          s.split_at_position1_complete(              |c| !(c.is_alpha() || c == '_' || c >= '\u{0080}'),              nom::error::ErrorKind::Alpha,          )      } -    fn tail(s: &str) -> IResult<&str, &str, ErrorContext<&str>> { +    fn tail(s: &str) -> ParseResult<'_> {          s.split_at_position1_complete(              |c| !(c.is_alphanum() || c == '_' || c >= '\u{0080}'),              nom::error::ErrorKind::Alpha, @@ -245,11 +245,11 @@ fn identifier(input: &str) -> IResult<&str, &str, ErrorContext<&str>> {      recognize(pair(start, opt(tail)))(input)  } -fn bool_lit(i: &str) -> IResult<&str, &str, ErrorContext<&str>> { +fn bool_lit(i: &str) -> ParseResult<'_> {      alt((keyword("false"), keyword("true")))(i)  } -fn num_lit(i: &str) -> IResult<&str, &str, ErrorContext<&str>> { +fn num_lit(i: &str) -> ParseResult<'_> {      recognize(tuple((          opt(char('-')),          digit1, @@ -257,7 +257,7 @@ fn num_lit(i: &str) -> IResult<&str, &str, ErrorContext<&str>> {      )))(i)  } -fn str_lit(i: &str) -> IResult<&str, &str, ErrorContext<&str>> { +fn str_lit(i: &str) -> ParseResult<'_> {      let (i, s) = delimited(          char('"'),          opt(escaped(is_not("\\\""), '\\', anychar)), @@ -266,7 +266,7 @@ fn str_lit(i: &str) -> IResult<&str, &str, ErrorContext<&str>> {      Ok((i, s.unwrap_or_default()))  } -fn char_lit(i: &str) -> IResult<&str, &str, ErrorContext<&str>> { +fn char_lit(i: &str) -> ParseResult<'_> {      let (i, s) = delimited(          char('\''),          opt(escaped(is_not("\\\'"), '\\', anychar)), @@ -280,7 +280,7 @@ enum PathOrIdentifier<'a> {      Identifier(&'a str),  } -fn path_or_identifier(i: &str) -> IResult<&str, PathOrIdentifier<'_>, ErrorContext<&str>> { +fn path_or_identifier(i: &str) -> ParseResult<'_, PathOrIdentifier<'_>> {      let root = ws(opt(tag("::")));      let tail = opt(many1(preceded(ws(tag("::")), identifier))); @@ -326,7 +326,7 @@ impl<'a> State<'a> {          }      } -    fn nest<'b>(&self, i: &'b str) -> IResult<&'b str, (), ErrorContext<&'b str>> { +    fn nest<'b>(&self, i: &'b str) -> ParseResult<'b, ()> {          let (_, level) = self.level.get().nest(i)?;          self.level.set(level);          Ok((i, ())) @@ -336,30 +336,27 @@ impl<'a> State<'a> {          self.level.set(self.level.get().leave());      } -    fn tag_block_start<'i>(&self, i: &'i str) -> IResult<&'i str, &'i str, ErrorContext<&'i str>> { +    fn tag_block_start<'i>(&self, i: &'i str) -> ParseResult<'i> {          tag(self.syntax.block_start)(i)      } -    fn tag_block_end<'i>(&self, i: &'i str) -> IResult<&'i str, &'i str, ErrorContext<&'i str>> { +    fn tag_block_end<'i>(&self, i: &'i str) -> ParseResult<'i> {          tag(self.syntax.block_end)(i)      } -    fn tag_comment_start<'i>( -        &self, -        i: &'i str, -    ) -> IResult<&'i str, &'i str, ErrorContext<&'i str>> { +    fn tag_comment_start<'i>(&self, i: &'i str) -> ParseResult<'i> {          tag(self.syntax.comment_start)(i)      } -    fn tag_comment_end<'i>(&self, i: &'i str) -> IResult<&'i str, &'i str, ErrorContext<&'i str>> { +    fn tag_comment_end<'i>(&self, i: &'i str) -> ParseResult<'i> {          tag(self.syntax.comment_end)(i)      } -    fn tag_expr_start<'i>(&self, i: &'i str) -> IResult<&'i str, &'i str, ErrorContext<&'i str>> { +    fn tag_expr_start<'i>(&self, i: &'i str) -> ParseResult<'i> {          tag(self.syntax.expr_start)(i)      } -    fn tag_expr_end<'i>(&self, i: &'i str) -> IResult<&'i str, &'i str, ErrorContext<&'i str>> { +    fn tag_expr_end<'i>(&self, i: &'i str) -> ParseResult<'i> {          tag(self.syntax.expr_end)(i)      } @@ -403,7 +400,7 @@ impl Default for Syntax<'static> {  pub(crate) struct Level(u8);  impl Level { -    fn nest(self, i: &str) -> IResult<&str, Level, ErrorContext<&str>> { +    fn nest(self, i: &str) -> ParseResult<'_, Level> {          if self.0 >= Self::MAX_DEPTH {              return Err(ErrorContext::from_err(nom::Err::Failure(error_position!(                  i, diff --git a/askama_parser/src/node.rs b/askama_parser/src/node.rs index dc05f48..69703e6 100644 --- a/askama_parser/src/node.rs +++ b/askama_parser/src/node.rs @@ -8,11 +8,11 @@ use nom::combinator::{      complete, consumed, cut, eof, map, map_res, not, opt, peek, recognize, value,  };  use nom::error::{Error, ErrorKind}; +use nom::error_position;  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 crate::ErrorContext; +use crate::{ErrorContext, ParseResult};  use super::{      bool_lit, char_lit, identifier, is_ws, keyword, num_lit, path_or_identifier, skip_till, @@ -40,10 +40,7 @@ pub enum Node<'a> {  }  impl<'a> Node<'a> { -    pub(super) fn many( -        i: &'a str, -        s: &State<'_>, -    ) -> IResult<&'a str, Vec<Self>, ErrorContext<&'a str>> { +    pub(super) fn many(i: &'a str, s: &State<'_>) -> ParseResult<'a, Vec<Self>> {          complete(many0(alt((              map(|i| Lit::parse(i, s), Self::Lit),              map(|i| Comment::parse(i, s), Self::Comment), @@ -52,7 +49,7 @@ impl<'a> Node<'a> {          ))))(i)      } -    fn parse(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn parse(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> {          let mut p = delimited(              |i| s.tag_block_start(i),              alt(( @@ -80,7 +77,7 @@ impl<'a> Node<'a> {          result      } -    fn r#break(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn r#break(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> {          let mut p = tuple((              opt(Whitespace::parse),              ws(keyword("break")), @@ -93,7 +90,7 @@ impl<'a> Node<'a> {          Ok((j, Self::Break(Ws(pws, nws))))      } -    fn r#continue(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn r#continue(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> {          let mut p = tuple((              opt(Whitespace::parse),              ws(keyword("continue")), @@ -106,7 +103,7 @@ impl<'a> Node<'a> {          Ok((j, Self::Continue(Ws(pws, nws))))      } -    fn expr(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn expr(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> {          let mut p = tuple((              |i| s.tag_expr_start(i),              cut(tuple(( @@ -134,7 +131,7 @@ pub enum Target<'a> {  }  impl<'a> Target<'a> { -    pub(super) fn parse(i: &'a str) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    pub(super) fn parse(i: &'a str) -> ParseResult<'a, Self> {          let mut opt_opening_paren = map(opt(ws(char('('))), |o| o.is_some());          let mut opt_closing_paren = map(opt(ws(char(')'))), |o| o.is_some());          let mut opt_opening_brace = map(opt(ws(char('{'))), |o| o.is_some()); @@ -217,7 +214,7 @@ impl<'a> Target<'a> {          map(identifier, Self::Name)(i)      } -    fn lit(i: &'a str) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn lit(i: &'a str) -> ParseResult<'a, Self> {          alt((              map(str_lit, Self::StrLit),              map(char_lit, Self::CharLit), @@ -226,7 +223,7 @@ impl<'a> Target<'a> {          ))(i)      } -    fn named(i: &'a str) -> IResult<&str, (&str, Self), ErrorContext<&'a str>> { +    fn named(i: &'a str) -> ParseResult<'a, (&str, Self)> {          let (i, (src, target)) = pair(identifier, opt(preceded(ws(char(':')), Self::parse)))(i)?;          Ok((i, (src, target.unwrap_or(Self::Name(src)))))      } @@ -240,7 +237,7 @@ pub struct When<'a> {  }  impl<'a> When<'a> { -    fn r#match(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn r#match(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> {          let mut p = tuple((              |i| s.tag_block_start(i),              opt(Whitespace::parse), @@ -263,7 +260,7 @@ impl<'a> When<'a> {      }      #[allow(clippy::self_named_constructors)] -    fn when(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn when(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> {          let mut p = tuple((              |i| s.tag_block_start(i),              opt(Whitespace::parse), @@ -295,7 +292,7 @@ pub struct Cond<'a> {  }  impl<'a> Cond<'a> { -    fn parse(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn parse(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> {          let mut p = tuple((              |i| s.tag_block_start(i),              opt(Whitespace::parse), @@ -334,7 +331,7 @@ pub struct CondTest<'a> {  }  impl<'a> CondTest<'a> { -    fn parse(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn parse(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> {          let mut p = preceded(              ws(keyword("if")),              cut(tuple(( @@ -359,7 +356,7 @@ pub enum Whitespace {  }  impl Whitespace { -    fn parse(i: &str) -> IResult<&str, Self, ErrorContext<&str>> { +    fn parse(i: &str) -> ParseResult<'_, Self> {          alt((              value(Self::Preserve, char('+')),              value(Self::Suppress, char('-')), @@ -381,11 +378,8 @@ pub struct Loop<'a> {  }  impl<'a> Loop<'a> { -    fn parse(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self, ErrorContext<&'a str>> { -        fn content<'a>( -            i: &'a str, -            s: &State<'_>, -        ) -> IResult<&'a str, Vec<Node<'a>>, ErrorContext<&'a str>> { +    fn parse(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> { +        fn content<'a>(i: &'a str, s: &State<'_>) -> ParseResult<'a, Vec<Node<'a>>> {              s.enter_loop();              let result = Node::many(i, s);              s.leave_loop(); @@ -465,8 +459,8 @@ pub struct Macro<'a> {  }  impl<'a> Macro<'a> { -    fn parse(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self, ErrorContext<&'a str>> { -        fn parameters(i: &str) -> IResult<&str, Vec<&str>, ErrorContext<&str>> { +    fn parse(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> { +        fn parameters(i: &str) -> ParseResult<'_, Vec<&str>> {              delimited(                  ws(char('(')),                  separated_list0(char(','), ws(identifier)), @@ -532,7 +526,7 @@ pub struct Import<'a> {  }  impl<'a> Import<'a> { -    fn parse(i: &'a str) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn parse(i: &'a str) -> ParseResult<'a, Self> {          let mut p = tuple((              opt(Whitespace::parse),              ws(keyword("import")), @@ -563,7 +557,7 @@ pub struct Call<'a> {  }  impl<'a> Call<'a> { -    fn parse(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn parse(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> {          let mut p = tuple((              opt(Whitespace::parse),              ws(keyword("call")), @@ -598,7 +592,7 @@ pub struct Match<'a> {  }  impl<'a> Match<'a> { -    fn parse(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn parse(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> {          let mut p = tuple((              opt(Whitespace::parse),              ws(keyword("match")), @@ -649,7 +643,7 @@ pub struct BlockDef<'a> {  }  impl<'a> BlockDef<'a> { -    fn parse(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn parse(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> {          let mut start = tuple((              opt(Whitespace::parse),              ws(keyword("block")), @@ -694,7 +688,7 @@ fn check_end_name<'a>(      name: &'a str,      end_name: &'a str,      kind: &str, -) -> IResult<&'a str, &'a str, ErrorContext<&'a str>> { +) -> ParseResult<'a> {      if name == end_name {          return Ok((after, end_name));      } @@ -717,7 +711,7 @@ pub struct Lit<'a> {  }  impl<'a> Lit<'a> { -    fn parse(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn parse(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> {          let p_start = alt((              tag(s.syntax.block_start),              tag(s.syntax.comment_start), @@ -757,7 +751,7 @@ pub struct Raw<'a> {  }  impl<'a> Raw<'a> { -    fn parse(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn parse(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> {          let endraw = tuple((              |i| s.tag_block_start(i),              opt(Whitespace::parse), @@ -792,7 +786,7 @@ pub struct Let<'a> {  }  impl<'a> Let<'a> { -    fn parse(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn parse(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> {          let mut p = tuple((              opt(Whitespace::parse),              ws(alt((keyword("let"), keyword("set")))), @@ -825,7 +819,7 @@ pub struct If<'a> {  }  impl<'a> If<'a> { -    fn parse(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn parse(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> {          let mut p = tuple((              opt(Whitespace::parse),              |i| CondTest::parse(i, s), @@ -870,7 +864,7 @@ pub struct Include<'a> {  }  impl<'a> Include<'a> { -    fn parse(i: &'a str) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn parse(i: &'a str) -> ParseResult<'a, Self> {          let mut p = tuple((              opt(Whitespace::parse),              ws(keyword("include")), @@ -893,7 +887,7 @@ pub struct Extends<'a> {  }  impl<'a> Extends<'a> { -    fn parse(i: &'a str) -> IResult<&'a str, Self, ErrorContext<&'a str>> { +    fn parse(i: &'a str) -> ParseResult<'a, Self> {          let (i, path) = preceded(ws(keyword("extends")), cut(ws(str_lit)))(i)?;          Ok((i, Self { path }))      } @@ -906,15 +900,12 @@ pub struct Comment<'a> {  }  impl<'a> Comment<'a> { -    fn parse(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self, ErrorContext<&'a str>> { -        fn body<'a>( -            mut i: &'a str, -            s: &State<'_>, -        ) -> IResult<&'a str, &'a str, ErrorContext<&'a str>> { +    fn parse(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> { +        fn body<'a>(mut i: &'a str, s: &State<'_>) -> ParseResult<'a> {              let mut level = 0;              loop {                  let (end, tail) = take_until(s.syntax.comment_end)(i)?; -                match take_until::<_, _, ErrorContext<_>>(s.syntax.comment_start)(i) { +                match take_until::<_, _, ErrorContext<'_>>(s.syntax.comment_start)(i) {                      Ok((start, _)) if start.as_ptr() < end.as_ptr() => {                          level += 1;                          i = &start[2..]; | 
