aboutsummaryrefslogtreecommitdiffstats
path: root/askama_parser/src/node.rs
diff options
context:
space:
mode:
authorLibravatar René Kijewski <rene.kijewski@fu-berlin.de>2023-08-01 11:16:43 +0200
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2023-08-01 13:04:41 +0200
commit32cd2825c4e5be9d0f160f9d112a98dbba24b29d (patch)
tree9ef0d2fb2f65aaed435bdbe4112ffe5097178fcd /askama_parser/src/node.rs
parentcdfe287b730a748f0601da2bc471d056c72c0559 (diff)
downloadaskama-32cd2825c4e5be9d0f160f9d112a98dbba24b29d.tar.gz
askama-32cd2825c4e5be9d0f160f9d112a98dbba24b29d.tar.bz2
askama-32cd2825c4e5be9d0f160f9d112a98dbba24b29d.zip
parser: add `expr::Loop::parse()`
Diffstat (limited to '')
-rw-r--r--askama_parser/src/node.rs138
1 files changed, 70 insertions, 68 deletions
diff --git a/askama_parser/src/node.rs b/askama_parser/src/node.rs
index 89ffae1..0d7552f 100644
--- a/askama_parser/src/node.rs
+++ b/askama_parser/src/node.rs
@@ -51,7 +51,7 @@ impl<'a> Node<'a> {
map(Call::parse, Self::Call),
map(Let::parse, Self::Let),
map(|i| If::parse(i, s), Self::If),
- |i| Self::r#for(i, s),
+ map(|i| Loop::parse(i, s), Self::Loop),
map(|i| Match::parse(i, s), Self::Match),
map(Extends::parse, Self::Extends),
map(Include::parse, Self::Include),
@@ -68,73 +68,6 @@ impl<'a> Node<'a> {
Ok((i, contents))
}
- fn r#for(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self> {
- fn content<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Vec<Node<'a>>> {
- s.enter_loop();
- let result = Node::many(i, s);
- s.leave_loop();
- result
- }
-
- let if_cond = preceded(ws(keyword("if")), cut(ws(Expr::parse)));
- let else_block = |i| {
- let mut p = preceded(
- ws(keyword("else")),
- cut(tuple((
- opt(Whitespace::parse),
- delimited(
- |i| s.tag_block_end(i),
- |i| Self::many(i, s),
- |i| s.tag_block_start(i),
- ),
- opt(Whitespace::parse),
- ))),
- );
- let (i, (pws, nodes, nws)) = p(i)?;
- Ok((i, (pws, nodes, nws)))
- };
- let mut p = tuple((
- opt(Whitespace::parse),
- ws(keyword("for")),
- cut(tuple((
- ws(Target::parse),
- ws(keyword("in")),
- cut(tuple((
- ws(Expr::parse),
- opt(if_cond),
- opt(Whitespace::parse),
- |i| s.tag_block_end(i),
- cut(tuple((
- |i| content(i, s),
- cut(tuple((
- |i| s.tag_block_start(i),
- opt(Whitespace::parse),
- opt(else_block),
- ws(keyword("endfor")),
- opt(Whitespace::parse),
- ))),
- ))),
- ))),
- ))),
- ));
- let (i, (pws1, _, (var, _, (iter, cond, nws1, _, (body, (_, pws2, else_block, _, nws2)))))) =
- p(i)?;
- let (nws3, else_block, pws3) = else_block.unwrap_or_default();
- Ok((
- i,
- Self::Loop(Loop {
- ws1: Ws(pws1, nws1),
- var,
- iter,
- cond,
- body,
- ws2: Ws(pws2, nws3),
- else_nodes: else_block,
- ws3: Ws(pws3, nws2),
- }),
- ))
- }
-
fn r#break(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self> {
let mut p = tuple((
opt(Whitespace::parse),
@@ -460,6 +393,75 @@ pub struct Loop<'a> {
pub ws3: Ws,
}
+impl<'a> Loop<'a> {
+ fn parse(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self> {
+ fn content<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, Vec<Node<'a>>> {
+ s.enter_loop();
+ let result = Node::many(i, s);
+ s.leave_loop();
+ result
+ }
+
+ let if_cond = preceded(ws(keyword("if")), cut(ws(Expr::parse)));
+ let else_block = |i| {
+ let mut p = preceded(
+ ws(keyword("else")),
+ cut(tuple((
+ opt(Whitespace::parse),
+ delimited(
+ |i| s.tag_block_end(i),
+ |i| Node::many(i, s),
+ |i| s.tag_block_start(i),
+ ),
+ opt(Whitespace::parse),
+ ))),
+ );
+ let (i, (pws, nodes, nws)) = p(i)?;
+ Ok((i, (pws, nodes, nws)))
+ };
+ let mut p = tuple((
+ opt(Whitespace::parse),
+ ws(keyword("for")),
+ cut(tuple((
+ ws(Target::parse),
+ ws(keyword("in")),
+ cut(tuple((
+ ws(Expr::parse),
+ opt(if_cond),
+ opt(Whitespace::parse),
+ |i| s.tag_block_end(i),
+ cut(tuple((
+ |i| content(i, s),
+ cut(tuple((
+ |i| s.tag_block_start(i),
+ opt(Whitespace::parse),
+ opt(else_block),
+ ws(keyword("endfor")),
+ opt(Whitespace::parse),
+ ))),
+ ))),
+ ))),
+ ))),
+ ));
+ let (i, (pws1, _, (var, _, (iter, cond, nws1, _, (body, (_, pws2, else_block, _, nws2)))))) =
+ p(i)?;
+ let (nws3, else_block, pws3) = else_block.unwrap_or_default();
+ Ok((
+ i,
+ Self {
+ ws1: Ws(pws1, nws1),
+ var,
+ iter,
+ cond,
+ body,
+ ws2: Ws(pws2, nws3),
+ else_nodes: else_block,
+ ws3: Ws(pws3, nws2),
+ },
+ ))
+ }
+}
+
#[derive(Debug, PartialEq)]
pub struct Macro<'a> {
pub ws1: Ws,