diff options
author | René Kijewski <rene.kijewski@fu-berlin.de> | 2023-08-01 11:30:06 +0200 |
---|---|---|
committer | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2023-08-01 13:04:41 +0200 |
commit | 4315773676527c94646315ac2a3475fd6eb2925a (patch) | |
tree | f9be7d81305bfc0210249db28c822b6df6ce25f8 /askama_parser | |
parent | 32cd2825c4e5be9d0f160f9d112a98dbba24b29d (diff) | |
download | askama-4315773676527c94646315ac2a3475fd6eb2925a.tar.gz askama-4315773676527c94646315ac2a3475fd6eb2925a.tar.bz2 askama-4315773676527c94646315ac2a3475fd6eb2925a.zip |
parser: add type for `Node::Comment`
Diffstat (limited to 'askama_parser')
-rw-r--r-- | askama_parser/src/node.rs | 100 | ||||
-rw-r--r-- | askama_parser/src/tests.rs | 155 |
2 files changed, 109 insertions, 146 deletions
diff --git a/askama_parser/src/node.rs b/askama_parser/src/node.rs index 0d7552f..a45cc89 100644 --- a/askama_parser/src/node.rs +++ b/askama_parser/src/node.rs @@ -17,7 +17,7 @@ use super::{ #[derive(Debug, PartialEq)] pub enum Node<'a> { Lit(Lit<'a>), - Comment(Ws), + Comment(Comment<'a>), Expr(Ws, Expr<'a>), Call(Call<'a>), Let(Let<'a>), @@ -38,7 +38,7 @@ impl<'a> Node<'a> { pub(super) fn many(i: &'a str, s: &State<'_>) -> IResult<&'a str, Vec<Self>> { many0(alt(( map(complete(|i| Lit::parse(i, s)), Self::Lit), - complete(|i| Self::comment(i, s)), + map(complete(|i| Comment::parse(i, s)), Self::Comment), complete(|i| Self::expr(i, s)), complete(|i| Self::parse(i, s)), )))(i) @@ -107,46 +107,6 @@ impl<'a> Node<'a> { let (i, (_, (pws, expr, nws, _))) = p(i)?; Ok((i, Self::Expr(Ws(pws, nws), expr))) } - - fn comment(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self> { - fn body<'a>(mut i: &'a str, s: &State<'_>) -> IResult<&'a str, &'a str> { - let mut level = 0; - loop { - let (end, tail) = take_until(s.syntax.comment_end)(i)?; - match take_until::<_, _, Error<_>>(s.syntax.comment_start)(i) { - Ok((start, _)) if start.as_ptr() < end.as_ptr() => { - level += 1; - i = &start[2..]; - } - _ if level > 0 => { - level -= 1; - i = &end[2..]; - } - _ => return Ok((end, tail)), - } - } - } - - let mut p = tuple(( - |i| s.tag_comment_start(i), - cut(tuple(( - opt(Whitespace::parse), - |i| body(i, s), - |i| s.tag_comment_end(i), - ))), - )); - let (i, (_, (pws, tail, _))) = p(i)?; - let nws = if tail.ends_with('-') { - Some(Whitespace::Suppress) - } else if tail.ends_with('+') { - Some(Whitespace::Preserve) - } else if tail.ends_with('~') { - Some(Whitespace::Minimize) - } else { - None - }; - Ok((i, Self::Comment(Ws(pws, nws)))) - } } #[derive(Debug, PartialEq)] @@ -604,7 +564,7 @@ impl<'a> Match<'a> { opt(Whitespace::parse), |i| s.tag_block_end(i), cut(tuple(( - ws(many0(ws(value((), |i| Node::comment(i, s))))), + ws(many0(ws(value((), |i| Comment::parse(i, s))))), many1(|i| When::when(i, s)), cut(tuple(( opt(|i| When::r#match(i, s)), @@ -866,6 +826,60 @@ impl<'a> Extends<'a> { } } +#[derive(Debug, PartialEq)] +pub struct Comment<'a> { + pub ws: Ws, + pub content: &'a str, +} + +impl<'a> Comment<'a> { + fn parse(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self> { + fn body<'a>(mut i: &'a str, s: &State<'_>) -> IResult<&'a str, &'a str> { + let mut level = 0; + loop { + let (end, tail) = take_until(s.syntax.comment_end)(i)?; + match take_until::<_, _, Error<_>>(s.syntax.comment_start)(i) { + Ok((start, _)) if start.as_ptr() < end.as_ptr() => { + level += 1; + i = &start[2..]; + } + _ if level > 0 => { + level -= 1; + i = &end[2..]; + } + _ => return Ok((end, tail)), + } + } + } + + let mut p = tuple(( + |i| s.tag_comment_start(i), + cut(tuple(( + opt(Whitespace::parse), + |i| body(i, s), + |i| s.tag_comment_end(i), + ))), + )); + let (i, (content, (pws, tail, _))) = p(i)?; + let nws = if tail.ends_with('-') { + Some(Whitespace::Suppress) + } else if tail.ends_with('+') { + Some(Whitespace::Preserve) + } else if tail.ends_with('~') { + Some(Whitespace::Minimize) + } else { + None + }; + Ok(( + i, + Self { + ws: Ws(pws, nws), + content, + }, + )) + } +} + /// 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". diff --git a/askama_parser/src/tests.rs b/askama_parser/src/tests.rs index 9f0fbd1..dde127b 100644 --- a/askama_parser/src/tests.rs +++ b/askama_parser/src/tests.rs @@ -521,112 +521,61 @@ fn test_odd_calls() { #[test] fn test_parse_comments() { - let s = &Syntax::default(); + fn one_comment_ws(source: &str, ws: Ws) { + let s = &Syntax::default(); + let mut nodes = Ast::from_str(source, s).unwrap().nodes; + assert_eq!(nodes.len(), 1, "expected to parse one node"); + match nodes.pop().unwrap() { + Node::Comment(comment) => assert_eq!(comment.ws, ws), + node => panic!("expected a comment not, but parsed {:?}", node), + } + } - assert_eq!( - Ast::from_str("{##}", s).unwrap().nodes, - vec![Node::Comment(Ws(None, None))], - ); - assert_eq!( - Ast::from_str("{#- #}", s).unwrap().nodes, - vec![Node::Comment(Ws(Some(Whitespace::Suppress), None))], - ); - assert_eq!( - Ast::from_str("{# -#}", s).unwrap().nodes, - vec![Node::Comment(Ws(None, Some(Whitespace::Suppress)))], - ); - assert_eq!( - Ast::from_str("{#--#}", s).unwrap().nodes, - vec![Node::Comment(Ws( - Some(Whitespace::Suppress), - Some(Whitespace::Suppress) - ))], - ); - assert_eq!( - Ast::from_str("{#- foo\n bar -#}", s).unwrap().nodes, - vec![Node::Comment(Ws( - Some(Whitespace::Suppress), - Some(Whitespace::Suppress) - ))], - ); - assert_eq!( - Ast::from_str("{#- foo\n {#- bar\n -#} baz -#}", s) - .unwrap() - .nodes, - vec![Node::Comment(Ws( - Some(Whitespace::Suppress), - Some(Whitespace::Suppress) - ))], - ); - assert_eq!( - Ast::from_str("{#+ #}", s).unwrap().nodes, - vec![Node::Comment(Ws(Some(Whitespace::Preserve), None))], - ); - assert_eq!( - Ast::from_str("{# +#}", s).unwrap().nodes, - vec![Node::Comment(Ws(None, Some(Whitespace::Preserve)))], - ); - assert_eq!( - Ast::from_str("{#++#}", s).unwrap().nodes, - vec![Node::Comment(Ws( - Some(Whitespace::Preserve), - Some(Whitespace::Preserve) - ))], - ); - assert_eq!( - Ast::from_str("{#+ foo\n bar +#}", s).unwrap().nodes, - vec![Node::Comment(Ws( - Some(Whitespace::Preserve), - Some(Whitespace::Preserve) - ))], - ); - assert_eq!( - Ast::from_str("{#+ foo\n {#+ bar\n +#} baz -+#}", s) - .unwrap() - .nodes, - vec![Node::Comment(Ws( - Some(Whitespace::Preserve), - Some(Whitespace::Preserve) - ))], - ); - assert_eq!( - Ast::from_str("{#~ #}", s).unwrap().nodes, - vec![Node::Comment(Ws(Some(Whitespace::Minimize), None))], - ); - assert_eq!( - Ast::from_str("{# ~#}", s).unwrap().nodes, - vec![Node::Comment(Ws(None, Some(Whitespace::Minimize)))], - ); - assert_eq!( - Ast::from_str("{#~~#}", s).unwrap().nodes, - vec![Node::Comment(Ws( - Some(Whitespace::Minimize), - Some(Whitespace::Minimize) - ))], - ); - assert_eq!( - Ast::from_str("{#~ foo\n bar ~#}", s).unwrap().nodes, - vec![Node::Comment(Ws( - Some(Whitespace::Minimize), - Some(Whitespace::Minimize) - ))], - ); - assert_eq!( - Ast::from_str("{#~ foo\n {#~ bar\n ~#} baz -~#}", s) - .unwrap() - .nodes, - vec![Node::Comment(Ws( - Some(Whitespace::Minimize), - Some(Whitespace::Minimize) - ))], + one_comment_ws("{##}", Ws(None, None)); + one_comment_ws("{#- #}", Ws(Some(Whitespace::Suppress), None)); + one_comment_ws("{# -#}", Ws(None, Some(Whitespace::Suppress))); + one_comment_ws( + "{#--#}", + Ws(Some(Whitespace::Suppress), Some(Whitespace::Suppress)), + ); + one_comment_ws( + "{#- foo\n bar -#}", + Ws(Some(Whitespace::Suppress), Some(Whitespace::Suppress)), + ); + one_comment_ws( + "{#- foo\n {#- bar\n -#} baz -#}", + Ws(Some(Whitespace::Suppress), Some(Whitespace::Suppress)), + ); + one_comment_ws("{#+ #}", Ws(Some(Whitespace::Preserve), None)); + one_comment_ws("{# +#}", Ws(None, Some(Whitespace::Preserve))); + one_comment_ws( + "{#++#}", + Ws(Some(Whitespace::Preserve), Some(Whitespace::Preserve)), + ); + one_comment_ws( + "{#+ foo\n bar +#}", + Ws(Some(Whitespace::Preserve), Some(Whitespace::Preserve)), + ); + one_comment_ws( + "{#+ foo\n {#+ bar\n +#} baz -+#}", + Ws(Some(Whitespace::Preserve), Some(Whitespace::Preserve)), + ); + one_comment_ws("{#~ #}", Ws(Some(Whitespace::Minimize), None)); + one_comment_ws("{# ~#}", Ws(None, Some(Whitespace::Minimize))); + one_comment_ws( + "{#~~#}", + Ws(Some(Whitespace::Minimize), Some(Whitespace::Minimize)), + ); + one_comment_ws( + "{#~ foo\n bar ~#}", + Ws(Some(Whitespace::Minimize), Some(Whitespace::Minimize)), + ); + one_comment_ws( + "{#~ foo\n {#~ bar\n ~#} baz -~#}", + Ws(Some(Whitespace::Minimize), Some(Whitespace::Minimize)), ); - assert_eq!( - Ast::from_str("{# foo {# bar #} {# {# baz #} qux #} #}", s) - .unwrap() - .nodes, - vec![Node::Comment(Ws(None, None))], - ); + one_comment_ws("{# foo {# bar #} {# {# baz #} qux #} #}", Ws(None, None)); } #[test] |