Skip to content

Commit

Permalink
chore: Upgrade to Winnow 0.7 (#330)
Browse files Browse the repository at this point in the history
* chore: Upgrade to Winnow 0.6.26

* refactor: Resolve deprecations

* refactor: Switch from Parser to ModalParser

* chore: Upgrade to Winnow 0.7

I am not thrilled with the fact that annotations of some kind (I used
no-op `map_err`s here) are needed for the errors and will be digging
into this to better understand why.  The code in `toml_edit` is very
similar and yet it doesn't need them.

* refactor: Remove From impl for ErrMode

* refactor: Remove map_err's added to work around 'impl From for ErrMode'
  • Loading branch information
epage authored Jan 31, 2025
1 parent c0cb411 commit 08bc972
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 41 deletions.
2 changes: 1 addition & 1 deletion rinja_parser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ harness = false
[dependencies]
memchr = "2"
serde = { version = "1.0", optional = true, features = ["derive"] }
winnow = "0.6.23"
winnow = "0.7.0"

[dev-dependencies]
criterion = "0.5"
Expand Down
8 changes: 2 additions & 6 deletions rinja_parser/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use winnow::ascii::digit1;
use winnow::combinator::{
alt, cut_err, fail, not, opt, peek, preceded, repeat, separated, terminated,
};
use winnow::error::{ErrorKind, ParserError as _};
use winnow::error::ParserError as _;
use winnow::stream::Stream as _;

use crate::node::CondTest;
Expand Down Expand Up @@ -625,11 +625,7 @@ impl<'a> Suffix<'a> {
expr = WithSpan::new(Expr::RustMacro(vec![name], args), before_suffix)
}
_ => {
return Err(winnow::error::ErrMode::from_error_kind(
&before_suffix,
ErrorKind::Tag,
)
.cut());
return Err(winnow::error::ErrMode::from_input(&before_suffix).cut());
}
},
}
Expand Down
48 changes: 24 additions & 24 deletions rinja_parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ use std::path::Path;
use std::sync::Arc;
use std::{fmt, str};

use winnow::Parser;
use winnow::ascii::take_escaped;
use winnow::combinator::{alt, cut_err, delimited, fail, not, opt, peek, preceded, repeat};
use winnow::error::{ErrorKind, FromExternalError};
use winnow::error::FromExternalError;
use winnow::stream::{AsChar, Stream as _};
use winnow::token::{any, one_of, take_till, take_while};
use winnow::{ModalParser, Parser};

pub mod expr;
pub use expr::{Attr, Expr, Filter, TyGenerics};
Expand Down Expand Up @@ -308,41 +308,41 @@ impl<'a> ErrorContext<'a> {
message: Some(message.into()),
}
}

fn backtrack(self) -> winnow::error::ErrMode<Self> {
winnow::error::ErrMode::Backtrack(self)
}

fn cut(self) -> winnow::error::ErrMode<Self> {
winnow::error::ErrMode::Cut(self)
}
}

impl<'a> winnow::error::ParserError<&'a str> for ErrorContext<'a> {
fn from_error_kind(input: &&'a str, _code: ErrorKind) -> Self {
type Inner = Self;

fn from_input(input: &&'a str) -> Self {
Self {
span: (*input).into(),
message: None,
}
}

fn append(
self,
_: &&'a str,
_: &<&str as winnow::stream::Stream>::Checkpoint,
_: ErrorKind,
) -> Self {
self
#[inline(always)]
fn into_inner(self) -> Result<Self::Inner, Self> {
Ok(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 {
fn from_external_error(input: &&'a str, e: E) -> Self {
Self {
span: (*input).into(),
message: Some(Cow::Owned(e.to_string())),
}
}
}

impl<'a> From<ErrorContext<'a>> for winnow::error::ErrMode<ErrorContext<'a>> {
fn from(cx: ErrorContext<'a>) -> Self {
Self::Cut(cx)
}
}

#[inline]
fn skip_ws0<'a>(i: &mut &'a str) -> ParseResult<'a, ()> {
*i = i.trim_ascii_start();
Expand All @@ -361,17 +361,17 @@ fn skip_ws1<'a>(i: &mut &'a str) -> ParseResult<'a, ()> {
}

fn ws<'a, O>(
inner: impl Parser<&'a str, O, ErrorContext<'a>>,
) -> impl Parser<&'a str, O, ErrorContext<'a>> {
inner: impl ModalParser<&'a str, O, ErrorContext<'a>>,
) -> impl ModalParser<&'a str, O, ErrorContext<'a>> {
delimited(skip_ws0, inner, skip_ws0)
}

/// Skips input until `end` was found, but does not consume it.
/// Returns tuple that would be returned when parsing `end`.
fn skip_till<'a, 'b, O>(
candidate_finder: impl crate::memchr_splitter::Splitter,
end: impl Parser<&'a str, O, ErrorContext<'a>>,
) -> impl Parser<&'a str, (&'a str, O), ErrorContext<'a>> {
end: impl ModalParser<&'a str, O, ErrorContext<'a>>,
) -> impl ModalParser<&'a str, (&'a str, O), ErrorContext<'a>> {
let mut next = alt((end.map(Some), any.map(|_| None)));
move |i: &mut &'a str| loop {
*i = match candidate_finder.split(i) {
Expand All @@ -392,7 +392,7 @@ fn skip_till<'a, 'b, O>(
}
}

fn keyword(k: &str) -> impl Parser<&str, &str, ErrorContext<'_>> {
fn keyword(k: &str) -> impl ModalParser<&str, &str, ErrorContext<'_>> {
identifier.verify(move |v: &str| v == k)
}

Expand Down Expand Up @@ -508,7 +508,7 @@ fn num_lit<'a>(i: &mut &'a str) -> ParseResult<'a, Num<'a>> {
fn separated_digits<'a>(
radix: u32,
start: bool,
) -> impl Parser<&'a str, &'a str, ErrorContext<'a>> {
) -> impl ModalParser<&'a str, &'a str, ErrorContext<'a>> {
(
move |i: &mut &'a _| match start {
true => Ok(()),
Expand Down Expand Up @@ -758,7 +758,7 @@ impl State<'_, '_> {
control.escape_default(),
self.syntax.block_end.escape_default(),
);
Err(ParseErr::backtrack(ErrorContext::new(message, *i).into()))
Err(ErrorContext::new(message, *i).backtrack())
} else {
Ok(())
}
Expand Down
16 changes: 8 additions & 8 deletions rinja_parser/src/node.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use std::collections::HashSet;
use std::str::{self, FromStr};

use winnow::Parser;
use winnow::combinator::{
alt, cut_err, delimited, empty, eof, fail, not, opt, peek, preceded, repeat, separated,
terminated,
};
use winnow::stream::Stream as _;
use winnow::token::{any, literal, rest};
use winnow::{ModalParser, Parser};

use crate::memchr_splitter::{Splitter1, Splitter2, Splitter3};
use crate::{
Expand Down Expand Up @@ -120,7 +120,7 @@ impl<'a> Node<'a> {
.parse_next(i)?;
match closed {
true => Ok(node),
false => Err(ErrorContext::unclosed("block", s.syntax.block_end, start).into()),
false => Err(ErrorContext::unclosed("block", s.syntax.block_end, start).cut()),
}
}

Expand Down Expand Up @@ -188,7 +188,7 @@ impl<'a> Node<'a> {
.parse_next(i)?;
match closed {
true => Ok(Self::Expr(Ws(pws, nws), expr)),
false => Err(ErrorContext::unclosed("expression", s.syntax.expr_end, start).into()),
false => Err(ErrorContext::unclosed("expression", s.syntax.expr_end, start).cut()),
}
}

Expand Down Expand Up @@ -218,8 +218,8 @@ impl<'a> Node<'a> {

fn cut_node<'a, O>(
kind: Option<&'static str>,
inner: impl Parser<&'a str, O, ErrorContext<'a>>,
) -> impl Parser<&'a str, O, ErrorContext<'a>> {
inner: impl ModalParser<&'a str, O, ErrorContext<'a>>,
) -> impl ModalParser<&'a str, O, ErrorContext<'a>> {
let mut inner = cut_err(inner);
move |i: &mut &'a str| {
let start = *i;
Expand Down Expand Up @@ -1096,7 +1096,7 @@ impl<'a> Lit<'a> {
return fail.parse_next(i);
}
Some(content) => content,
None => rest.parse_next(i)?, // there is no {block,comment,expr}_start: take everything
None => rest.parse_next(i)?, /* there is no {block,comment,expr}_start: take everything */
};
Ok(WithSpan::new(Self::split_ws_parts(content), start))
}
Expand Down Expand Up @@ -1352,7 +1352,7 @@ impl<'a> Comment<'a> {
let tag = opt(skip_till(splitter, |i: &mut _| tag(i, s))).parse_next(i)?;
let Some((inclusive, tag)) = tag else {
return Err(
ErrorContext::unclosed("comment", s.syntax.comment_end, start).into(),
ErrorContext::unclosed("comment", s.syntax.comment_end, start).cut(),
);
};
match tag {
Expand Down Expand Up @@ -1414,7 +1414,7 @@ pub struct Ws(pub Option<Whitespace>, pub Option<Whitespace>);
fn end_node<'a, 'g: 'a>(
node: &'g str,
expected: &'g str,
) -> impl Parser<&'a str, &'a str, ErrorContext<'a>> + 'g {
) -> impl ModalParser<&'a str, &'a str, ErrorContext<'a>> + 'g {
move |i: &mut &'a str| {
let start = i.checkpoint();
let actual = ws(identifier).parse_next(i)?;
Expand Down
4 changes: 2 additions & 2 deletions rinja_parser/src/target.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use winnow::Parser;
use winnow::combinator::{alt, opt, peek, preceded, separated};
use winnow::token::one_of;
use winnow::{ModalParser, Parser};

use crate::{
CharLit, ErrorContext, Num, ParseErr, ParseResult, PathOrIdentifier, State, StrLit, WithSpan,
Expand Down Expand Up @@ -217,7 +217,7 @@ fn verify_name<'a>(
fn collect_targets<'a, T>(
i: &mut &'a str,
delim: char,
one: impl Parser<&'a str, T, ErrorContext<'a>>,
one: impl ModalParser<&'a str, T, ErrorContext<'a>>,
) -> ParseResult<'a, (bool, Vec<T>)> {
let opt_comma = ws(opt(',')).map(|o| o.is_some());
let mut opt_end = ws(opt(one_of(delim))).map(|o| o.is_some());
Expand Down

0 comments on commit 08bc972

Please sign in to comment.