Skip to content

Commit

Permalink
parser: let State::tag_block_{start,end} return Parser
Browse files Browse the repository at this point in the history
  • Loading branch information
Kijewski committed Dec 27, 2024
1 parent 6bf8918 commit adda27e
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 58 deletions.
53 changes: 26 additions & 27 deletions rinja_parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ 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::stream::{AsChar, Stream as _};
use winnow::stream::{AsChar, Stream};
use winnow::token::{any, one_of, take_till, take_while};

pub mod expr;
Expand Down Expand Up @@ -318,12 +318,7 @@ impl<'a> winnow::error::ParserError<&'a str> for ErrorContext<'a> {
}
}

fn append(
self,
_: &&'a str,
_: &<&str as winnow::stream::Stream>::Checkpoint,
_: ErrorKind,
) -> Self {
fn append(self, _: &&'a str, _: &<&str as Stream>::Checkpoint, _: ErrorKind) -> Self {
self
}
}
Expand Down Expand Up @@ -740,26 +735,30 @@ struct State<'a, 'l> {
level: Level<'l>,
}

impl State<'_, '_> {
fn tag_block_start<'i>(&self, i: &mut &'i str) -> ParseResult<'i, ()> {
self.syntax.block_start.value(()).parse_next(i)
impl<'a> State<'a, '_> {
fn tag_block_start<'i>(&self) -> impl Parser<&'i str, (), ErrorContext<'i>> + 'a {
let block_start = self.syntax.block_start;
|i: &mut _| block_start.value(()).parse_next(i)
}

fn tag_block_end<'i>(&self, i: &mut &'i str) -> ParseResult<'i, ()> {
let control = alt((
self.syntax.block_end.value(None),
peek(delimited('%', alt(('-', '~', '+')).map(Some), '}')),
fail, // rollback on partial matches in the previous line
))
.parse_next(i)?;
if let Some(control) = control {
let message = format!(
"unclosed block, you likely meant to apply whitespace control: {:?}",
format!("{control}{}", self.syntax.block_end),
);
Err(ParseErr::backtrack(ErrorContext::new(message, *i).into()))
} else {
Ok(())
fn tag_block_end<'i>(&self) -> impl Parser<&'i str, (), ErrorContext<'i>> + 'a {
let block_end = self.syntax.block_end;
move |i: &mut _| {
let control = alt((
block_end.value(None),
peek(delimited('%', alt(('-', '~', '+')).map(Some), '}')),
fail, // rollback on partial matches in the previous line
))
.parse_next(i)?;
if let Some(control) = control {
let message = format!(
"unclosed block, you likely meant to apply whitespace control: {:?}",
format!("{control}{}", block_end),
);
Err(ParseErr::backtrack(ErrorContext::new(message, *i).into()))
} else {
Ok(())
}
}
}

Expand Down Expand Up @@ -1268,7 +1267,7 @@ impl<'a, F, I, O, A> UnboundParser<'a, I, O, A> for F
where
F: FnMut(&mut I, A) -> ParseResult<'a, O>,
A: Clone,
I: winnow::stream::Stream + 'a,
I: Stream + 'a,
{
fn bind(mut self, arg: A) -> impl Parser<I, O, ErrorContext<'a>> {
move |i: &mut _| self(i, arg.clone())
Expand All @@ -1285,7 +1284,7 @@ where
F: FnMut(&mut I, A0, A1) -> ParseResult<'a, O>,
A0: Clone,
A1: Clone,
I: winnow::stream::Stream + 'a,
I: Stream + 'a,
{
fn bind(mut self, a0: A0, a1: A1) -> impl Parser<I, O, ErrorContext<'a>> {
move |i: &mut _| self(i, a0.clone(), a1.clone())
Expand Down
53 changes: 22 additions & 31 deletions rinja_parser/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ impl<'a> Node<'a> {
fn parse(i: &mut &'a str, s: &State<'_, '_>) -> ParseResult<'a, Self> {
let mut start = *i;
let tag = preceded(
|i: &mut _| s.tag_block_start(i),
s.tag_block_start(),
peek(preceded((opt(Whitespace::parse), skip_ws0), identifier)),
)
.parse_next(i)?;
Expand All @@ -113,10 +113,7 @@ impl<'a> Node<'a> {
let node = func(i, s)?;
let closed = cut_node(
None,
alt((
ws(eof).value(false),
(|i: &mut _| s.tag_block_end(i)).value(true),
)),
alt((ws(eof).value(false), s.tag_block_end().value(true))),
)
.parse_next(i)?;
match closed {
Expand Down Expand Up @@ -238,7 +235,7 @@ fn cut_node<'a, O>(

fn unexpected_tag<'a>(i: &mut &'a str, s: &State<'_, '_>) -> ParseResult<'a, ()> {
(
|i: &mut _| s.tag_block_start(i),
s.tag_block_start(),
opt(Whitespace::parse),
unexpected_raw_tag.bind(None),
)
Expand Down Expand Up @@ -271,14 +268,14 @@ pub struct When<'a> {
impl<'a> When<'a> {
fn r#else(i: &mut &'a str, s: &State<'_, '_>) -> ParseResult<'a, WithSpan<'a, Self>> {
let mut p = (
|i: &mut _| s.tag_block_start(i),
s.tag_block_start(),
opt(Whitespace::parse),
ws(keyword("else")),
cut_node(
Some("match-else"),
(
opt(Whitespace::parse),
|i: &mut _| s.tag_block_end(i),
s.tag_block_end(),
cut_node(Some("match-else"), Node::many.bind(s)),
),
),
Expand All @@ -301,15 +298,15 @@ impl<'a> When<'a> {
let start = *i;
let endwhen = ws((
delimited(
|i: &mut _| s.tag_block_start(i),
s.tag_block_start(),
opt(Whitespace::parse),
ws(keyword("endwhen")),
),
cut_node(
Some("match-endwhen"),
(
opt(Whitespace::parse),
|i: &mut _| s.tag_block_end(i),
s.tag_block_end(),
repeat(0.., ws(Comment::parse.bind(s))).map(|()| ()),
),
),
Expand All @@ -329,15 +326,15 @@ impl<'a> When<'a> {
))
});
let mut p = (
|i: &mut _| s.tag_block_start(i),
s.tag_block_start(),
opt(Whitespace::parse),
ws(keyword("when")),
cut_node(
Some("match-when"),
(
separated(1.., ws(Target::parse.bind(s)), '|'),
opt(Whitespace::parse),
|i: &mut _| s.tag_block_end(i),
s.tag_block_end(),
cut_node(Some("match-when"), Node::many.bind(s)),
opt(endwhen),
),
Expand Down Expand Up @@ -369,7 +366,7 @@ impl<'a> Cond<'a> {
fn parse(i: &mut &'a str, s: &State<'_, '_>) -> ParseResult<'a, WithSpan<'a, Self>> {
let start = *i;
let (_, pws, cond, nws, _, nodes) = (
|i: &mut _| s.tag_block_start(i),
s.tag_block_start(),
opt(Whitespace::parse),
alt((
preceded(ws(keyword("else")), opt(CondTest::parse.bind(s))),
Expand All @@ -379,7 +376,7 @@ impl<'a> Cond<'a> {
),
)),
opt(Whitespace::parse),
cut_node(Some("if"), |i: &mut _| s.tag_block_end(i)),
cut_node(Some("if"), s.tag_block_end()),
cut_node(Some("if"), Node::many.bind(s)),
)
.parse_next(i)?;
Expand Down Expand Up @@ -492,7 +489,7 @@ fn check_block_start<'a>(
start,
)));
}
(|i: &mut _| s.tag_block_start(i)).parse_next(i)
s.tag_block_start().parse_next(i)
}

#[derive(Debug, PartialEq)]
Expand Down Expand Up @@ -529,11 +526,7 @@ impl<'a> Loop<'a> {
Some("for-else"),
(
opt(Whitespace::parse),
delimited(
|i: &mut _| s.tag_block_end(i),
Node::many.bind(s),
|i: &mut _| s.tag_block_start(i),
),
delimited(s.tag_block_end(), Node::many.bind(s), s.tag_block_start()),
opt(Whitespace::parse),
),
),
Expand Down Expand Up @@ -577,7 +570,7 @@ impl<'a> Loop<'a> {
ws(Expr::parse.bind(s.level, true)),
opt(if_cond),
opt(Whitespace::parse),
|i: &mut _| s.tag_block_end(i),
s.tag_block_end(),
body_and_end,
),
),
Expand Down Expand Up @@ -670,7 +663,7 @@ impl<'a> Macro<'a> {
ws(identifier),
parameters,
opt(Whitespace::parse),
|i: &mut _| s.tag_block_end(i),
s.tag_block_end(),
),
),
);
Expand Down Expand Up @@ -771,7 +764,7 @@ impl<'a> FilterBlock<'a> {
.map(|v: Vec<_>| v),
ws(empty),
opt(Whitespace::parse),
|i: &mut _| s.tag_block_end(i),
s.tag_block_end(),
),
),
);
Expand Down Expand Up @@ -915,7 +908,7 @@ impl<'a> Match<'a> {
(
ws(Expr::parse.bind(s.level, false)),
opt(Whitespace::parse),
|i: &mut _| s.tag_block_end(i),
s.tag_block_end(),
cut_node(
Some("match"),
(
Expand Down Expand Up @@ -984,9 +977,7 @@ impl<'a> BlockDef<'a> {
ws(keyword("block")),
cut_node(
Some("block"),
(ws(identifier), opt(Whitespace::parse), |i: &mut _| {
s.tag_block_end(i)
}),
(ws(identifier), opt(Whitespace::parse), s.tag_block_end()),
),
);
let (pws1, _, (name, nws1, _)) = start.parse_next(i)?;
Expand Down Expand Up @@ -1107,11 +1098,11 @@ impl<'a> Raw<'a> {
fn parse(i: &mut &'a str, s: &State<'_, '_>) -> ParseResult<'a, WithSpan<'a, Self>> {
let start = *i;
let endraw = (
|i: &mut _| s.tag_block_start(i),
s.tag_block_start(),
opt(Whitespace::parse),
ws(keyword("endraw")), // sic: ignore `{% end %}` in raw blocks
opt(Whitespace::parse),
peek(|i: &mut _| s.tag_block_end(i)),
peek(s.tag_block_end()),
);

let mut p = (
Expand All @@ -1121,7 +1112,7 @@ impl<'a> Raw<'a> {
Some("raw"),
(
opt(Whitespace::parse),
|i: &mut _| s.tag_block_end(i),
s.tag_block_end(),
skip_till(Splitter1::new(s.syntax.block_start), endraw).with_taken(),
),
),
Expand Down Expand Up @@ -1212,7 +1203,7 @@ impl<'a> If<'a> {
Some("if"),
(
opt(Whitespace::parse),
|i: &mut _| s.tag_block_end(i),
s.tag_block_end(),
cut_node(
Some("if"),
(
Expand Down

0 comments on commit adda27e

Please sign in to comment.