diff options
Diffstat (limited to 'askama_parser/src')
| -rw-r--r-- | askama_parser/src/lib.rs | 10 | ||||
| -rw-r--r-- | askama_parser/src/node.rs | 77 | ||||
| -rw-r--r-- | askama_parser/src/tests.rs | 16 | 
3 files changed, 54 insertions, 49 deletions
diff --git a/askama_parser/src/lib.rs b/askama_parser/src/lib.rs index d095f65..8138a19 100644 --- a/askama_parser/src/lib.rs +++ b/askama_parser/src/lib.rs @@ -16,7 +16,8 @@ use nom::{error_position, AsChar, IResult, InputTakeAtPosition};  pub use self::expr::Expr;  pub use self::node::{ -    BlockDef, Call, Cond, CondTest, Import, Loop, Macro, Match, Node, Target, When, Whitespace, Ws, +    BlockDef, Call, Cond, CondTest, Import, Lit, Loop, Macro, Match, Node, Target, When, +    Whitespace, Ws,  };  mod expr; @@ -138,13 +139,6 @@ fn ws<'a, O>(      delimited(take_till(not_ws), inner, take_till(not_ws))  } -fn split_ws_parts(s: &str) -> Node<'_> { -    let trimmed_start = s.trim_start_matches(is_ws); -    let len_start = s.len() - trimmed_start.len(); -    let trimmed = trimmed_start.trim_end_matches(is_ws); -    Node::Lit(&s[..len_start], trimmed, &trimmed_start[trimmed.len()..]) -} -  /// Skips input until `end` was found, but does not consume it.  /// Returns tuple that would be returned when parsing `end`.  fn skip_till<'a, O>( diff --git a/askama_parser/src/node.rs b/askama_parser/src/node.rs index a8325ef..a743b53 100644 --- a/askama_parser/src/node.rs +++ b/askama_parser/src/node.rs @@ -10,13 +10,13 @@ use nom::sequence::{delimited, pair, preceded, terminated, tuple};  use nom::{error_position, IResult};  use super::{ -    bool_lit, char_lit, identifier, keyword, num_lit, path, skip_till, split_ws_parts, str_lit, ws, -    Expr, State, +    bool_lit, char_lit, identifier, is_ws, keyword, num_lit, path, skip_till, str_lit, ws, Expr, +    State,  };  #[derive(Debug, PartialEq)]  pub enum Node<'a> { -    Lit(&'a str, &'a str, &'a str), +    Lit(Lit<'a>),      Comment(Ws),      Expr(Ws, Expr<'a>),      Call(Call<'a>), @@ -30,7 +30,7 @@ pub enum Node<'a> {      Include(Ws, &'a str),      Import(Import<'a>),      Macro(Macro<'a>), -    Raw(Ws, &'a str, &'a str, &'a str, Ws), +    Raw(Ws, Lit<'a>, Ws),      Break(Ws),      Continue(Ws),  } @@ -38,33 +38,13 @@ pub enum Node<'a> {  impl<'a> Node<'a> {      pub(super) fn many(i: &'a str, s: &State<'_>) -> IResult<&'a str, Vec<Self>> {          many0(alt(( -            complete(|i| Self::content(i, s)), +            map(complete(|i| Lit::parse(i, s)), Self::Lit),              complete(|i| Self::comment(i, s)),              complete(|i| Self::expr(i, s)),              complete(|i| Self::parse(i, s)),          )))(i)      } -    fn content(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self> { -        let p_start = alt(( -            tag(s.syntax.block_start), -            tag(s.syntax.comment_start), -            tag(s.syntax.expr_start), -        )); - -        let (i, _) = not(eof)(i)?; -        let (i, content) = opt(recognize(skip_till(p_start)))(i)?; -        let (i, content) = match content { -            Some("") => { -                // {block,comment,expr}_start follows immediately. -                return Err(nom::Err::Error(error_position!(i, ErrorKind::TakeUntil))); -            } -            Some(content) => (i, content), -            None => ("", i), // there is no {block,comment,expr}_start: take everything -        }; -        Ok((i, split_ws_parts(content))) -    } -      fn parse(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self> {          let mut p = tuple((              |i| s.tag_block_start(i), @@ -244,13 +224,10 @@ impl<'a> Node<'a> {          ));          let (_, (pws1, _, (nws1, _, (contents, (i, (_, pws2, _, nws2, _)))))) = p(i)?; -        let (lws, val, rws) = match split_ws_parts(contents) { -            Node::Lit(lws, val, rws) => (lws, val, rws), -            _ => unreachable!(), -        }; +        let val = Lit::split_ws_parts(contents);          let ws1 = Ws(pws1, nws1);          let ws2 = Ws(pws2, nws2); -        Ok((i, Self::Raw(ws1, lws, val, rws, ws2))) +        Ok((i, Self::Raw(ws1, val, ws2)))      }      fn r#break(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self> { @@ -795,6 +772,46 @@ impl<'a> BlockDef<'a> {      }  } +#[derive(Debug, PartialEq)] +pub struct Lit<'a> { +    pub lws: &'a str, +    pub val: &'a str, +    pub rws: &'a str, +} + +impl<'a> Lit<'a> { +    fn parse(i: &'a str, s: &State<'_>) -> IResult<&'a str, Self> { +        let p_start = alt(( +            tag(s.syntax.block_start), +            tag(s.syntax.comment_start), +            tag(s.syntax.expr_start), +        )); + +        let (i, _) = not(eof)(i)?; +        let (i, content) = opt(recognize(skip_till(p_start)))(i)?; +        let (i, content) = match content { +            Some("") => { +                // {block,comment,expr}_start follows immediately. +                return Err(nom::Err::Error(error_position!(i, ErrorKind::TakeUntil))); +            } +            Some(content) => (i, content), +            None => ("", i), // there is no {block,comment,expr}_start: take everything +        }; +        Ok((i, Self::split_ws_parts(content))) +    } + +    pub(crate) fn split_ws_parts(s: &'a str) -> Self { +        let trimmed_start = s.trim_start_matches(is_ws); +        let len_start = s.len() - trimmed_start.len(); +        let trimmed = trimmed_start.trim_end_matches(is_ws); +        Self { +            lws: &s[..len_start], +            val: trimmed, +            rws: &trimmed_start[trimmed.len()..], +        } +    } +} +  /// 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 61aa279..4717652 100644 --- a/askama_parser/src/tests.rs +++ b/askama_parser/src/tests.rs @@ -1,16 +1,10 @@ -use super::{Ast, Expr, Node, Syntax, Whitespace, Ws}; +use super::{Ast, Expr, Lit, Node, Syntax, Whitespace, Ws};  fn check_ws_split(s: &str, res: &(&str, &str, &str)) { -    match super::split_ws_parts(s) { -        Node::Lit(lws, s, rws) => { -            assert_eq!(lws, res.0); -            assert_eq!(s, res.1); -            assert_eq!(rws, res.2); -        } -        _ => { -            panic!("fail"); -        } -    } +    let Lit { lws, val, rws } = Lit::split_ws_parts(s); +    assert_eq!(lws, res.0); +    assert_eq!(val, res.1); +    assert_eq!(rws, res.2);  }  #[test]  | 
