aboutsummaryrefslogtreecommitdiffstats
path: root/askama_parser
diff options
context:
space:
mode:
authorLibravatar René Kijewski <rene.kijewski@fu-berlin.de>2023-08-01 11:30:06 +0200
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2023-08-01 13:04:41 +0200
commit4315773676527c94646315ac2a3475fd6eb2925a (patch)
treef9be7d81305bfc0210249db28c822b6df6ce25f8 /askama_parser
parent32cd2825c4e5be9d0f160f9d112a98dbba24b29d (diff)
downloadaskama-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.rs100
-rw-r--r--askama_parser/src/tests.rs155
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]