diff options
| author | 2018-12-12 20:43:36 +0100 | |
|---|---|---|
| committer | 2018-12-12 21:48:41 +0100 | |
| commit | 48c5ebbd2be8f7d89f37f3aa04500b8ad1a3d460 (patch) | |
| tree | b21964dcbce68948ae3dee763ea7c61931ed5167 /askama_derive | |
| parent | 9e1cf8f0dff3bd96db4b25703877db5632267ed2 (diff) | |
| download | askama-48c5ebbd2be8f7d89f37f3aa04500b8ad1a3d460.tar.gz askama-48c5ebbd2be8f7d89f37f3aa04500b8ad1a3d460.tar.bz2 askama-48c5ebbd2be8f7d89f37f3aa04500b8ad1a3d460.zip | |
Allow using brackets for enums in `match`
Diffstat (limited to '')
| -rw-r--r-- | askama_derive/src/generator.rs | 45 | ||||
| -rw-r--r-- | askama_derive/src/parser.rs | 54 | 
2 files changed, 85 insertions, 14 deletions
| diff --git a/askama_derive/src/generator.rs b/askama_derive/src/generator.rs index b30b040..047e975 100644 --- a/askama_derive/src/generator.rs +++ b/askama_derive/src/generator.rs @@ -1,6 +1,6 @@  use super::{get_template_source, Context, Heritage};  use crate::input::TemplateInput; -use crate::parser::{Cond, Expr, MatchParameter, MatchVariant, Node, Target, When, WS}; +use crate::parser::{Cond, Expr, MatchParameter, MatchParameters, MatchVariant, Node, Target, When, WS};  use askama_shared::filters;  use proc_macro2::Span; @@ -399,18 +399,43 @@ impl<'a> Generator<'a> {                  }                  None => buf.write("_"),              }; -            if !params.is_empty() { -                buf.write("("); -                for (i, param) in params.iter().enumerate() { -                    if let MatchParameter::Name(p) = *param { -                        self.locals.insert(p); + +            match params { +                MatchParameters::Simple(params) => { +                    if !params.is_empty() { +                        buf.write("("); +                        for (i, param) in params.iter().enumerate() { +                            if let MatchParameter::Name(p) = *param { +                                self.locals.insert(p); +                            } +                            if i > 0 { +                                buf.write(", "); +                            } +                            self.visit_match_param(buf, param); +                        } +                        buf.write(")");                      } -                    if i > 0 { -                        buf.write(", "); +                } +                MatchParameters::Named(params) => { +                    buf.write("{"); +                    for (i, param) in params.iter().enumerate() { +                        if let Some(MatchParameter::Name(p)) = param.1 { +                            self.locals.insert(p); +                        } else { +                            self.locals.insert(param.0); +                        } + +                        if i > 0 { +                            buf.write(", "); +                        } +                        buf.write(param.0); +                        if let Some(param) = ¶m.1 { +                            buf.write(":"); +                            self.visit_match_param(buf, ¶m); +                        }                      } -                    self.visit_match_param(buf, param); +                    buf.write("}");                  } -                buf.write(")");              }              buf.writeln(" => {");              self.handle_ws(ws); diff --git a/askama_derive/src/parser.rs b/askama_derive/src/parser.rs index e1a7fc0..7968ac1 100644 --- a/askama_derive/src/parser.rs +++ b/askama_derive/src/parser.rs @@ -77,10 +77,22 @@ pub type Cond<'a> = (WS, Option<Expr<'a>>, Vec<Node<'a>>);  pub type When<'a> = (      WS,      Option<MatchVariant<'a>>, -    Vec<MatchParameter<'a>>, +    MatchParameters<'a>,      Vec<Node<'a>>,  ); +#[derive(Debug)] +pub enum MatchParameters<'a> { +    Simple(Vec<MatchParameter<'a>>), +    Named(Vec<(&'a str, Option<MatchParameter<'a>>)>), +} + +impl<'a> Default for MatchParameters<'a> { +    fn default() -> Self { +        MatchParameters::Simple(vec![]) +    } +} +  type Input<'a> = nom::types::CompleteByteSlice<'a>;  #[allow(non_snake_case)]  fn Input(input: &[u8]) -> Input { @@ -309,8 +321,13 @@ named!(parameters<Input, Vec<&str>>, do_parse!(      (vals.unwrap_or_default())  )); -named!(with_parameters<Input, Vec<MatchParameter>>, do_parse!( +named!(with_parameters<Input, MatchParameters>, do_parse!(      tag!("with") >> +    value: alt!(match_simple_parameters | match_named_parameters) >> +    (value) +)); + +named!(match_simple_parameters<Input, MatchParameters>, do_parse!(      ws!(tag!("(")) >>      vals: opt!(do_parse!(          arg0: ws!(match_parameter) >> @@ -326,7 +343,26 @@ named!(with_parameters<Input, Vec<MatchParameter>>, do_parse!(          })      )) >>      tag!(")") >> -    (vals.unwrap_or_default()) +    (MatchParameters::Simple(vals.unwrap_or_default())) +)); + +named!(match_named_parameters<Input, MatchParameters>, do_parse!( +    ws!(tag!("{")) >> +    vals: opt!(do_parse!( +        arg0: ws!(match_named_parameter) >> +        args: many0!(do_parse!( +            tag!(",") >> +            argn: ws!(match_named_parameter) >> +            (argn) +        )) >> +        ({ +            let mut res = vec![arg0]; +            res.extend(args); +            res +        }) +    )) >> +    tag!("}") >> +    (MatchParameters::Named(vals.unwrap_or_default()))  ));  named!(expr_group<Input, Expr>, map!( @@ -356,6 +392,16 @@ named!(match_parameter<Input, MatchParameter>, alt!(      param_str_lit  )); +named!(match_named_parameter<Input, (&str, Option<MatchParameter>)>, do_parse!( +    name: identifier >> +    param: opt!(do_parse!( +        ws!(tag!(":")) >> +        param: match_parameter >> +        (param) +    )) >> +    ((name, param)) +)); +  named!(attr<Input, (&str, Option<Vec<Expr>>)>, do_parse!(      tag!(".") >>      attr: alt!(num_lit | identifier) >> @@ -549,7 +595,7 @@ named_args!(match_else_block<'a>(s: &'a Syntax<'a>) <Input<'a>, When<'a>>, do_pa      nws: opt!(tag!("-")) >>      call!(tag_block_end, s) >>      block: call!(parse_template, s) >> -    (WS(pws.is_some(), nws.is_some()), None, vec![], block) +    (WS(pws.is_some(), nws.is_some()), None, MatchParameters::Simple(vec![]), block)  ));  named_args!(when_block<'a>(s: &'a Syntax<'a>) <Input<'a>, When<'a>>, do_parse!( | 
