Skip to content

Commit

Permalink
parser: tell user proper keyword to end node
Browse files Browse the repository at this point in the history
  • Loading branch information
Kijewski committed Aug 7, 2024
1 parent 0628afa commit dec67c6
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 24 deletions.
35 changes: 27 additions & 8 deletions rinja_parser/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::str;
use nom::branch::alt;
use nom::bytes::complete::{tag, take_till};
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, fail, map, not, opt, peek, recognize, value};
use nom::error::ErrorKind;
use nom::error_position;
use nom::multi::{many0, many1, separated_list0};
Expand Down Expand Up @@ -377,7 +377,7 @@ impl<'a> Loop<'a> {
|i| s.tag_block_start(i),
opt(Whitespace::parse),
opt(else_block),
ws(keyword("endfor")),
end_node("for", "endfor"),
opt(Whitespace::parse),
))),
))),
Expand Down Expand Up @@ -449,7 +449,7 @@ impl<'a> Macro<'a> {
cut(tuple((
|i| s.tag_block_start(i),
opt(Whitespace::parse),
ws(keyword("endmacro")),
end_node("macro", "endmacro"),
cut(preceded(
opt(|before| {
let (after, end_name) = ws(identifier)(before)?;
Expand Down Expand Up @@ -525,7 +525,7 @@ impl<'a> FilterBlock<'a> {
cut(tuple((
|i| s.tag_block_start(i),
opt(Whitespace::parse),
ws(keyword("endfilter")),
end_node("filter", "endfilter"),
opt(Whitespace::parse),
))),
)));
Expand Down Expand Up @@ -645,7 +645,7 @@ impl<'a> Match<'a> {
cut(tuple((
ws(|i| s.tag_block_start(i)),
opt(Whitespace::parse),
ws(keyword("endmatch")),
end_node("match", "endmatch"),
opt(Whitespace::parse),
))),
))),
Expand Down Expand Up @@ -699,7 +699,7 @@ impl<'a> BlockDef<'a> {
cut(tuple((
|i| s.tag_block_start(i),
opt(Whitespace::parse),
ws(keyword("endblock")),
end_node("block", "endblock"),
cut(tuple((
opt(|before| {
let (after, end_name) = ws(identifier)(before)?;
Expand Down Expand Up @@ -806,7 +806,7 @@ impl<'a> Raw<'a> {
let endraw = tuple((
|i| s.tag_block_start(i),
opt(Whitespace::parse),
ws(keyword("endraw")),
ws(keyword("endraw")), // sic: ignore `{% end %}` in raw blocks
opt(Whitespace::parse),
peek(|i| s.tag_block_end(i)),
));
Expand Down Expand Up @@ -888,7 +888,7 @@ impl<'a> If<'a> {
cut(tuple((
|i| s.tag_block_start(i),
opt(Whitespace::parse),
ws(keyword("endif")),
end_node("if", "endif"),
opt(Whitespace::parse),
))),
))),
Expand Down Expand Up @@ -1057,6 +1057,25 @@ impl<'a> Comment<'a> {
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Ws(pub Option<Whitespace>, pub Option<Whitespace>);

fn end_node<'a, 'g: 'a>(
node: &'g str,
expected: &'g str,
) -> impl Fn(&'a str) -> ParseResult<'a> + 'g {
move |start| {
let (i, actual) = ws(identifier)(start)?;
if actual == expected {
Ok((i, actual))
} else if actual == "end" {
Err(nom::Err::Failure(ErrorContext::new(
format!("expected `{expected}` to terminate `{node}` node, found `{actual}`"),
start,
)))
} else {
fail(start)
}
}
}

#[doc(hidden)]
pub const MAX_KW_LEN: usize = 8;
const MAX_REPL_LEN: usize = MAX_KW_LEN + 2;
Expand Down
32 changes: 16 additions & 16 deletions testing/tests/ui/wrong-end.stderr
Original file line number Diff line number Diff line change
@@ -1,46 +1,46 @@
error: failed to parse template source
--> <source attribute>:1:24
"end %}"
error: expected `endfor` to terminate `for` node, found `end`
--> <source attribute>:1:23
" end %}"
--> tests/ui/wrong-end.rs:4:21
|
4 | #[template(source = "{% for _ in 1..=10 %}{% end %}", ext = "txt")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: failed to parse template source
--> <source attribute>:1:21
"end %}"
error: expected `endmacro` to terminate `macro` node, found `end`
--> <source attribute>:1:20
" end %}"
--> tests/ui/wrong-end.rs:8:21
|
8 | #[template(source = "{% macro test() %}{% end %}", ext = "txt")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: failed to parse template source
--> <source attribute>:1:21
"end %}"
error: expected `endfilter` to terminate `filter` node, found `end`
--> <source attribute>:1:20
" end %}"
--> tests/ui/wrong-end.rs:12:21
|
12 | #[template(source = "{% filter upper %}{% end %}", ext = "txt")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: failed to parse template source
error: expected `endmatch` to terminate `match` node, found `end`
--> <source attribute>:1:30
"end %}"
--> tests/ui/wrong-end.rs:16:21
|
16 | #[template(source = "{% match () %}{% when () %}{% end %}", ext = "txt")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: failed to parse template source
--> <source attribute>:1:19
"end %}"
error: expected `endblock` to terminate `block` node, found `end`
--> <source attribute>:1:18
" end %}"
--> tests/ui/wrong-end.rs:20:21
|
20 | #[template(source = "{% block body %}{% end %}", ext = "txt")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: failed to parse template source
--> <source attribute>:1:16
"end %}"
error: expected `endif` to terminate `if` node, found `end`
--> <source attribute>:1:15
" end %}"
--> tests/ui/wrong-end.rs:24:21
|
24 | #[template(source = "{% if true %}{% end %}", ext = "txt")]
Expand Down

0 comments on commit dec67c6

Please sign in to comment.