diff options
author | René Kijewski <rene.kijewski@fu-berlin.de> | 2023-08-01 03:09:35 +0200 |
---|---|---|
committer | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2023-08-01 13:04:41 +0200 |
commit | 222c42917aa19162562b8a9c35350e3e992f9823 (patch) | |
tree | 055f247d144e72c0bdd167ce8313f87aadca6b21 | |
parent | ffe267be7a725c776ebc92d6551e8a070aadf254 (diff) | |
download | askama-222c42917aa19162562b8a9c35350e3e992f9823.tar.gz askama-222c42917aa19162562b8a9c35350e3e992f9823.tar.bz2 askama-222c42917aa19162562b8a9c35350e3e992f9823.zip |
parser: let `Macro` know its name
-rw-r--r-- | askama_derive/src/generator.rs | 2 | ||||
-rw-r--r-- | askama_derive/src/heritage.rs | 6 | ||||
-rw-r--r-- | askama_parser/src/node.rs | 105 |
3 files changed, 57 insertions, 56 deletions
diff --git a/askama_derive/src/generator.rs b/askama_derive/src/generator.rs index 5308c02..1c6e722 100644 --- a/askama_derive/src/generator.rs +++ b/askama_derive/src/generator.rs @@ -659,7 +659,7 @@ impl<'a> Generator<'a> { Node::Call(ws, scope, name, ref args) => { size_hint += self.write_call(ctx, buf, ws, scope, name, args)?; } - Node::Macro(_, ref m) => { + Node::Macro(ref m) => { if level != AstLevel::Top { return Err("macro blocks only allowed at the top level".into()); } diff --git a/askama_derive/src/heritage.rs b/askama_derive/src/heritage.rs index 9ef7aeb..801b109 100644 --- a/askama_derive/src/heritage.rs +++ b/askama_derive/src/heritage.rs @@ -64,14 +64,14 @@ impl Context<'_> { extends = Some(config.find_template(extends_path, Some(path))?); } }, - Node::Macro(name, m) if top => { - macros.insert(*name, m); + Node::Macro(m) if top => { + macros.insert(m.name, m); } Node::Import(_, import_path, scope) if top => { let path = config.find_template(import_path, Some(path))?; imports.insert(*scope, path); } - Node::Extends(_) | Node::Macro(_, _) | Node::Import(_, _, _) if !top => { + Node::Extends(_) | Node::Macro(_) | Node::Import(_, _, _) if !top => { return Err( "extends, macro or import blocks not allowed below top level".into(), ); diff --git a/askama_parser/src/node.rs b/askama_parser/src/node.rs index 4a0fa30..f15aa5a 100644 --- a/askama_parser/src/node.rs +++ b/askama_parser/src/node.rs @@ -29,7 +29,7 @@ pub enum Node<'a> { BlockDef(Ws, &'a str, Vec<Node<'a>>, Ws), Include(Ws, &'a str), Import(Ws, &'a str, &'a str), - Macro(&'a str, Macro<'a>), + Macro(Macro<'a>), Raw(Ws, &'a str, &'a str, &'a str, Ws), Break(Ws), Continue(Ws), @@ -78,7 +78,7 @@ impl<'a> Node<'a> { Self::include, Self::import, |i| Self::block(i, s), - |i| Self::r#macro(i, s), + map(|i| Macro::parse(i, s), Self::Macro), |i| Self::raw(i, s), |i| Self::r#break(i, s), |i| Self::r#continue(i, s), @@ -315,56 +315,6 @@ impl<'a> Node<'a> { Ok((i, Self::Import(Ws(pws, nws), name, scope))) } - fn r#macro(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self> { - fn parameters(i: &str) -> IResult<&str, Vec<&str>> { - delimited( - ws(char('(')), - separated_list0(char(','), ws(identifier)), - ws(char(')')), - )(i) - } - - let mut start = tuple(( - opt(Whitespace::parse), - ws(keyword("macro")), - cut(tuple(( - ws(identifier), - opt(ws(parameters)), - opt(Whitespace::parse), - |i| s.tag_block_end(i), - ))), - )); - let (i, (pws1, _, (name, params, nws1, _))) = start(i)?; - - let mut end = cut(tuple(( - |i| Self::many(i, s), - cut(tuple(( - |i| s.tag_block_start(i), - opt(Whitespace::parse), - ws(keyword("endmacro")), - cut(tuple((opt(ws(keyword(name))), opt(Whitespace::parse)))), - ))), - ))); - let (i, (contents, (_, pws2, _, (_, nws2)))) = end(i)?; - - assert_ne!(name, "super", "invalid macro name 'super'"); - - let params = params.unwrap_or_default(); - - Ok(( - i, - Self::Macro( - name, - Macro { - ws1: Ws(pws1, nws1), - args: params, - nodes: contents, - ws2: Ws(pws2, nws2), - }, - ), - )) - } - fn raw(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self> { let endraw = tuple(( |i| s.tag_block_start(i), @@ -722,11 +672,62 @@ pub struct Loop<'a> { #[derive(Debug, PartialEq)] pub struct Macro<'a> { pub ws1: Ws, + pub name: &'a str, pub args: Vec<&'a str>, pub nodes: Vec<Node<'a>>, pub ws2: Ws, } +impl<'a> Macro<'a> { + fn parse(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self> { + fn parameters(i: &str) -> IResult<&str, Vec<&str>> { + delimited( + ws(char('(')), + separated_list0(char(','), ws(identifier)), + ws(char(')')), + )(i) + } + + let mut start = tuple(( + opt(Whitespace::parse), + ws(keyword("macro")), + cut(tuple(( + ws(identifier), + opt(ws(parameters)), + opt(Whitespace::parse), + |i| s.tag_block_end(i), + ))), + )); + let (i, (pws1, _, (name, params, nws1, _))) = start(i)?; + + let mut end = cut(tuple(( + |i| Node::many(i, s), + cut(tuple(( + |i| s.tag_block_start(i), + opt(Whitespace::parse), + ws(keyword("endmacro")), + cut(tuple((opt(ws(keyword(name))), opt(Whitespace::parse)))), + ))), + ))); + let (i, (contents, (_, pws2, _, (_, nws2)))) = end(i)?; + + assert_ne!(name, "super", "invalid macro name 'super'"); + + let params = params.unwrap_or_default(); + + Ok(( + i, + Self { + ws1: Ws(pws1, nws1), + name, + args: params, + nodes: contents, + 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". |