diff options
Diffstat (limited to '')
-rw-r--r-- | askama_derive/src/generator.rs | 15 | ||||
-rw-r--r-- | askama_derive/src/heritage.rs | 4 | ||||
-rw-r--r-- | askama_parser/src/lib.rs | 4 | ||||
-rw-r--r-- | askama_parser/src/node.rs | 80 |
4 files changed, 58 insertions, 45 deletions
diff --git a/askama_derive/src/generator.rs b/askama_derive/src/generator.rs index 643fb73..4cf972b 100644 --- a/askama_derive/src/generator.rs +++ b/askama_derive/src/generator.rs @@ -3,7 +3,7 @@ use crate::heritage::{Context, Heritage}; use crate::input::{Print, Source, TemplateInput}; use crate::CompileError; use parser::{ - Call, Cond, CondTest, Expr, Let, Lit, Loop, Match, Node, Parsed, Target, Whitespace, Ws, + Call, CondTest, Expr, If, Let, Lit, Loop, Match, Node, Parsed, Target, Whitespace, Ws, }; use proc_macro::TokenStream; @@ -640,8 +640,8 @@ impl<'a> Generator<'a> { Node::Let(ref l) => { self.write_let(buf, l)?; } - Node::Cond(ref conds, ws) => { - size_hint += self.write_cond(ctx, buf, conds, ws)?; + Node::If(ref i) => { + size_hint += self.write_if(ctx, buf, i)?; } Node::Match(ref m) => { size_hint += self.write_match(ctx, buf, m)?; @@ -707,17 +707,16 @@ impl<'a> Generator<'a> { Ok(size_hint) } - fn write_cond( + fn write_if( &mut self, ctx: &'a Context<'_>, buf: &mut Buffer, - conds: &'a [Cond<'_>], - ws: Ws, + i: &'a If<'_>, ) -> Result<usize, CompileError> { let mut flushed = 0; let mut arm_sizes = Vec::new(); let mut has_else = false; - for (i, cond) in conds.iter().enumerate() { + for (i, cond) in i.branches.iter().enumerate() { self.handle_ws(cond.ws); flushed += self.write_buf_writable(buf)?; if i > 0 { @@ -764,7 +763,7 @@ impl<'a> Generator<'a> { arm_size += self.handle(ctx, &cond.nodes, buf, AstLevel::Nested)?; arm_sizes.push(arm_size); } - self.handle_ws(ws); + self.handle_ws(i.ws); flushed += self.write_buf_writable(buf)?; buf.writeln("}")?; diff --git a/askama_derive/src/heritage.rs b/askama_derive/src/heritage.rs index 2a7ef43..1122e39 100644 --- a/askama_derive/src/heritage.rs +++ b/askama_derive/src/heritage.rs @@ -80,8 +80,8 @@ impl Context<'_> { blocks.insert(b.name, b); nested.push(&b.nodes); } - Node::Cond(branches, _) => { - for cond in branches { + Node::If(i) => { + for cond in &i.branches { nested.push(&cond.nodes); } } diff --git a/askama_parser/src/lib.rs b/askama_parser/src/lib.rs index 560507a..8e90802 100644 --- a/askama_parser/src/lib.rs +++ b/askama_parser/src/lib.rs @@ -16,8 +16,8 @@ use nom::{error_position, AsChar, IResult, InputTakeAtPosition}; pub use self::expr::Expr; pub use self::node::{ - BlockDef, Call, Cond, CondTest, Import, Let, Lit, Loop, Macro, Match, Node, Raw, Target, When, - Whitespace, Ws, + BlockDef, Call, Cond, CondTest, If, Import, Let, Lit, Loop, Macro, Match, Node, Raw, Target, + When, Whitespace, Ws, }; mod expr; diff --git a/askama_parser/src/node.rs b/askama_parser/src/node.rs index 9055d99..f7e51de 100644 --- a/askama_parser/src/node.rs +++ b/askama_parser/src/node.rs @@ -21,7 +21,7 @@ pub enum Node<'a> { Expr(Ws, Expr<'a>), Call(Call<'a>), Let(Let<'a>), - Cond(Vec<Cond<'a>>, Ws), + If(If<'a>), Match(Match<'a>), Loop(Loop<'a>), Extends(&'a str), @@ -50,7 +50,7 @@ impl<'a> Node<'a> { alt(( map(Call::parse, Self::Call), map(Let::parse, Self::Let), - |i| Self::r#if(i, s), + map(|i| If::parse(i, s), Self::If), |i| Self::r#for(i, s), map(|i| Match::parse(i, s), Self::Match), Self::extends, @@ -68,37 +68,6 @@ impl<'a> Node<'a> { Ok((i, contents)) } - fn r#if(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self> { - let mut p = tuple(( - opt(Whitespace::parse), - CondTest::parse, - cut(tuple(( - opt(Whitespace::parse), - |i| s.tag_block_end(i), - cut(tuple(( - |i| Node::many(i, s), - many0(|i| Cond::parse(i, s)), - cut(tuple(( - |i| s.tag_block_start(i), - opt(Whitespace::parse), - ws(keyword("endif")), - opt(Whitespace::parse), - ))), - ))), - ))), - )); - - let (i, (pws1, cond, (nws1, _, (nodes, elifs, (_, pws2, _, nws2))))) = p(i)?; - let mut res = vec![Cond { - ws: Ws(pws1, nws1), - cond: Some(cond), - nodes, - }]; - res.extend(elifs); - - Ok((i, Self::Cond(res, Ws(pws2, nws2)))) - } - 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(); @@ -829,6 +798,51 @@ impl<'a> Let<'a> { } } +#[derive(Debug, PartialEq)] +pub struct If<'a> { + pub ws: Ws, + pub branches: Vec<Cond<'a>>, +} + +impl<'a> If<'a> { + fn parse(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self> { + let mut p = tuple(( + opt(Whitespace::parse), + CondTest::parse, + cut(tuple(( + opt(Whitespace::parse), + |i| s.tag_block_end(i), + cut(tuple(( + |i| Node::many(i, s), + many0(|i| Cond::parse(i, s)), + cut(tuple(( + |i| s.tag_block_start(i), + opt(Whitespace::parse), + ws(keyword("endif")), + opt(Whitespace::parse), + ))), + ))), + ))), + )); + + let (i, (pws1, cond, (nws1, _, (nodes, elifs, (_, pws2, _, nws2))))) = p(i)?; + let mut branches = vec![Cond { + ws: Ws(pws1, nws1), + cond: Some(cond), + nodes, + }]; + branches.extend(elifs); + + Ok(( + i, + Self { + ws: Ws(pws2, nws2), + branches, + }, + )) + } +} + /// 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". |