diff options
-rw-r--r-- | askama_derive/src/generator.rs | 18 | ||||
-rw-r--r-- | askama_derive/src/heritage.rs | 4 | ||||
-rw-r--r-- | askama_parser/src/lib.rs | 2 | ||||
-rw-r--r-- | askama_parser/src/node.rs | 88 |
4 files changed, 67 insertions, 45 deletions
diff --git a/askama_derive/src/generator.rs b/askama_derive/src/generator.rs index d29c4c3..60ffa27 100644 --- a/askama_derive/src/generator.rs +++ b/askama_derive/src/generator.rs @@ -2,7 +2,7 @@ use crate::config::{get_template_source, read_config_file, Config, WhitespaceHan use crate::heritage::{Context, Heritage}; use crate::input::{Print, Source, TemplateInput}; use crate::CompileError; -use parser::{Call, Cond, CondTest, Expr, Loop, Node, Parsed, Target, When, Whitespace, Ws}; +use parser::{Call, Cond, CondTest, Expr, Loop, Match, Node, Parsed, Target, Whitespace, Ws}; use proc_macro::TokenStream; use quote::{quote, ToTokens}; @@ -644,8 +644,8 @@ impl<'a> Generator<'a> { Node::Cond(ref conds, ws) => { size_hint += self.write_cond(ctx, buf, conds, ws)?; } - Node::Match(ws1, ref expr, ref arms, ws2) => { - size_hint += self.write_match(ctx, buf, ws1, expr, arms, ws2)?; + Node::Match(ref m) => { + size_hint += self.write_match(ctx, buf, m)?; } Node::Loop(ref loop_block) => { size_hint += self.write_loop(ctx, buf, loop_block)?; @@ -782,11 +782,15 @@ impl<'a> Generator<'a> { &mut self, ctx: &'a Context<'_>, buf: &mut Buffer, - ws1: Ws, - expr: &Expr<'_>, - arms: &'a [When<'_>], - ws2: Ws, + m: &'a Match<'a>, ) -> Result<usize, CompileError> { + let Match { + ws1, + ref expr, + ref arms, + ws2, + } = *m; + self.flush_ws(ws1); let flushed = self.write_buf_writable(buf)?; let mut arm_sizes = Vec::new(); diff --git a/askama_derive/src/heritage.rs b/askama_derive/src/heritage.rs index 9f642e3..fbbb71f 100644 --- a/askama_derive/src/heritage.rs +++ b/askama_derive/src/heritage.rs @@ -3,7 +3,7 @@ use std::path::{Path, PathBuf}; use crate::config::Config; use crate::CompileError; -use parser::{Loop, Macro, Node}; +use parser::{Loop, Macro, Match, Node}; pub(crate) struct Heritage<'a> { pub(crate) root: &'a Context<'a>, @@ -95,7 +95,7 @@ impl Context<'_> { nested.push(body); nested.push(else_block); } - Node::Match(_, _, arms, _) => { + Node::Match(Match { arms, .. }) => { for arm in arms { nested.push(&arm.nodes); } diff --git a/askama_parser/src/lib.rs b/askama_parser/src/lib.rs index c92adbe..74004cb 100644 --- a/askama_parser/src/lib.rs +++ b/askama_parser/src/lib.rs @@ -16,7 +16,7 @@ use nom::{error_position, AsChar, IResult, InputTakeAtPosition}; pub use self::expr::Expr; pub use self::node::{ - Call, Cond, CondTest, Import, Loop, Macro, Node, Target, When, Whitespace, Ws, + Call, Cond, CondTest, Import, Loop, Macro, Match, Node, Target, When, Whitespace, Ws, }; mod expr; diff --git a/askama_parser/src/node.rs b/askama_parser/src/node.rs index 9cdd451..277d60f 100644 --- a/askama_parser/src/node.rs +++ b/askama_parser/src/node.rs @@ -23,7 +23,7 @@ pub enum Node<'a> { LetDecl(Ws, Target<'a>), Let(Ws, Target<'a>, Expr<'a>), Cond(Vec<Cond<'a>>, Ws), - Match(Ws, Expr<'a>, Vec<When<'a>>, Ws), + Match(Match<'a>), Loop(Loop<'a>), Extends(&'a str), BlockDef(Ws, &'a str, Vec<Node<'a>>, Ws), @@ -73,7 +73,7 @@ impl<'a> Node<'a> { Self::r#let, |i| Self::r#if(i, s), |i| Self::r#for(i, s), - |i| Self::r#match(i, s), + map(|i| Match::parse(i, s), Self::Match), Self::extends, Self::include, map(Import::parse, Self::Import), @@ -209,39 +209,6 @@ impl<'a> Node<'a> { )) } - fn r#match(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self> { - let mut p = tuple(( - opt(Whitespace::parse), - ws(keyword("match")), - cut(tuple(( - ws(Expr::parse), - opt(Whitespace::parse), - |i| s.tag_block_end(i), - cut(tuple(( - ws(many0(ws(value((), |i| Self::comment(i, s))))), - many1(|i| When::when(i, s)), - cut(tuple(( - opt(|i| When::r#match(i, s)), - cut(tuple(( - ws(|i| s.tag_block_start(i)), - opt(Whitespace::parse), - ws(keyword("endmatch")), - opt(Whitespace::parse), - ))), - ))), - ))), - ))), - )); - let (i, (pws1, _, (expr, nws1, _, (_, arms, (else_arm, (_, pws2, _, nws2)))))) = p(i)?; - - let mut arms = arms; - if let Some(arm) = else_arm { - arms.push(arm); - } - - Ok((i, Self::Match(Ws(pws1, nws1), expr, arms, Ws(pws2, nws2)))) - } - fn extends(i: &'a str) -> IResult<&'a str, Self> { let (i, (_, name)) = tuple((ws(keyword("extends")), ws(str_lit)))(i)?; Ok((i, Self::Extends(name))) @@ -762,6 +729,57 @@ impl<'a> Call<'a> { } } +#[derive(Debug, PartialEq)] +pub struct Match<'a> { + pub ws1: Ws, + pub expr: Expr<'a>, + pub arms: Vec<When<'a>>, + pub ws2: Ws, +} + +impl<'a> Match<'a> { + fn parse(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self> { + let mut p = tuple(( + opt(Whitespace::parse), + ws(keyword("match")), + cut(tuple(( + ws(Expr::parse), + opt(Whitespace::parse), + |i| s.tag_block_end(i), + cut(tuple(( + ws(many0(ws(value((), |i| Node::comment(i, s))))), + many1(|i| When::when(i, s)), + cut(tuple(( + opt(|i| When::r#match(i, s)), + cut(tuple(( + ws(|i| s.tag_block_start(i)), + opt(Whitespace::parse), + ws(keyword("endmatch")), + opt(Whitespace::parse), + ))), + ))), + ))), + ))), + )); + let (i, (pws1, _, (expr, nws1, _, (_, arms, (else_arm, (_, pws2, _, nws2)))))) = p(i)?; + + let mut arms = arms; + if let Some(arm) = else_arm { + arms.push(arm); + } + + Ok(( + i, + Self { + ws1: Ws(pws1, nws1), + expr, + arms, + ws2: Ws(pws2, nws2), + }, + )) + } +} + /// First field is "minus/plus sign was used on the left part of the item". /// /// Second field is "minus/plus sign was used on the right part of the item". |