diff options
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] | 
