From 468f376bfc2cf3e09addac37cd144de56b5f93bf Mon Sep 17 00:00:00 2001 From: Anthony Nowell Date: Wed, 27 Sep 2017 01:53:35 -0600 Subject: implement basic match functionality --- askama_shared/src/parser.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'askama_shared/src/parser.rs') diff --git a/askama_shared/src/parser.rs b/askama_shared/src/parser.rs index 5bdcb9b..ec4dcbd 100644 --- a/askama_shared/src/parser.rs +++ b/askama_shared/src/parser.rs @@ -40,6 +40,7 @@ pub enum Node<'a> { LetDecl(WS, Target<'a>), Let(WS, Target<'a>, Expr<'a>), Cond(Vec<(WS, Option>, Vec>)>, WS), + Match(WS, Expr<'a>, &'a str, Vec>, WS), Loop(WS, Target<'a>, Expr<'a>, Vec>, WS), Extends(Expr<'a>), BlockDef(WS, &'a str, Vec>, WS), @@ -49,6 +50,7 @@ pub enum Node<'a> { } pub type Cond<'a> = (WS, Option>, Vec>); +pub type When<'a> = (WS, &'a str, Vec<&'a str>, Vec>); fn split_ws_parts(s: &[u8]) -> Node { if s.is_empty() { @@ -210,6 +212,12 @@ named!(parameters>, do_parse!( (vals.unwrap_or_default()) )); +named!(with_parameters>, do_parse!( + tag_s!("with") >> + params: ws!(parameters) >> + (params) +)); + named!(expr_group, map!( delimited!(char!('('), expr_any, char!(')')), |s| Expr::Group(Box::new(s)) @@ -359,6 +367,51 @@ named!(block_if, do_parse!( }) )); +named!(when_block, do_parse!( + tag_s!("{%") >> + pws: opt!(tag_s!("-")) >> + ws!(tag_s!("when")) >> + variant: ws!(identifier) >> + params: opt!(ws!(with_parameters)) >> + nws: opt!(tag_s!("-")) >> + tag_s!("%}") >> + block: parse_template >> + (WS(pws.is_some(), nws.is_some()), variant, params.unwrap_or_default(), block) +)); + +named!(block_match, do_parse!( + pws1: opt!(tag_s!("-")) >> + ws!(tag_s!("match")) >> + expr: ws!(expr_any) >> + nws1: opt!(tag_s!("-")) >> + tag_s!("%}") >> + inter: take_content >> + arms: many1!(when_block) >> + ws!(tag_s!("{%")) >> + pws2: opt!(tag_s!("-")) >> + ws!(tag_s!("endmatch")) >> + nws2: opt!(tag_s!("-")) >> + ({ + let inter = match inter { + Node::Lit(lws, val, rws) => { + assert!(val.is_empty(), + "only whitespace allowed between match and first when, found {}", val); + assert!(rws.is_empty(), + "only whitespace allowed between match and first when, found {}", rws); + lws + }, + _ => panic!("only literals allowed between match and first when"), + }; + Node::Match( + WS(pws1.is_some(), nws1.is_some()), + expr, + inter, + arms, + WS(pws2.is_some(), nws2.is_some()), + ) + }) +)); + named!(block_let, do_parse!( pws: opt!(tag_s!("-")) >> ws!(tag_s!("let")) >> @@ -471,6 +524,7 @@ named!(block_node, do_parse!( block_let | block_if | block_for | + block_match | block_extends | block_include | block_import | -- cgit