diff options
Diffstat (limited to 'askama_derive/src')
| -rw-r--r-- | askama_derive/src/generator.rs | 53 | 
1 files changed, 26 insertions, 27 deletions
| diff --git a/askama_derive/src/generator.rs b/askama_derive/src/generator.rs index 2101feb..6637698 100644 --- a/askama_derive/src/generator.rs +++ b/askama_derive/src/generator.rs @@ -6,6 +6,7 @@ use crate::CompileError;  use proc_macro::TokenStream;  use quote::{quote, ToTokens}; +use syn::punctuated::Punctuated;  use std::collections::hash_map::{Entry, HashMap};  use std::path::{Path, PathBuf}; @@ -92,25 +93,17 @@ impl TemplateArgs {          // the proper type (list).          let mut template_args = None;          for attr in &ast.attrs { -            let ident = match attr.path.get_ident() { -                Some(ident) => ident, -                None => continue, -            }; - -            if ident == "template" { -                if template_args.is_some() { -                    return Err("duplicated 'template' attribute".into()); -                } - -                match attr.parse_meta() { -                    Ok(syn::Meta::List(syn::MetaList { nested, .. })) => { -                        template_args = Some(nested); -                    } -                    Ok(_) => return Err("'template' attribute must be a list".into()), -                    Err(e) => return Err(format!("unable to parse attribute: {e}").into()), -                } +            if !attr.path().is_ident("template") { +                continue;              } + +            match attr.parse_args_with(Punctuated::<syn::Meta, syn::Token![,]>::parse_terminated) { +                Ok(args) if template_args.is_none() => template_args = Some(args), +                Ok(_) => return Err("duplicated 'template' attribute".into()), +                Err(e) => return Err(format!("unable to parse template arguments: {e}").into()), +            };          } +          let template_args =              template_args.ok_or_else(|| CompileError::from("no attribute 'template' found"))?; @@ -120,7 +113,7 @@ impl TemplateArgs {          // `source` contains an enum that can represent `path` or `source`.          for item in template_args {              let pair = match item { -                syn::NestedMeta::Meta(syn::Meta::NameValue(ref pair)) => pair, +                syn::Meta::NameValue(pair) => pair,                  _ => {                      return Err(format!(                          "unsupported attribute argument {:?}", @@ -129,13 +122,19 @@ impl TemplateArgs {                      .into())                  }              }; +              let ident = match pair.path.get_ident() {                  Some(ident) => ident,                  None => unreachable!("not possible in syn::Meta::NameValue(…)"),              }; +            let value = match pair.value { +                syn::Expr::Lit(lit) => lit, +                _ => return Err(format!("unsupported argument value type for {ident:?}").into()), +            }; +              if ident == "path" { -                if let syn::Lit::Str(ref s) = pair.lit { +                if let syn::Lit::Str(s) = value.lit {                      if args.source.is_some() {                          return Err("must specify 'source' or 'path', not both".into());                      } @@ -144,7 +143,7 @@ impl TemplateArgs {                      return Err("template path must be string literal".into());                  }              } else if ident == "source" { -                if let syn::Lit::Str(ref s) = pair.lit { +                if let syn::Lit::Str(s) = value.lit {                      if args.source.is_some() {                          return Err("must specify 'source' or 'path', not both".into());                      } @@ -153,37 +152,37 @@ impl TemplateArgs {                      return Err("template source must be string literal".into());                  }              } else if ident == "print" { -                if let syn::Lit::Str(ref s) = pair.lit { +                if let syn::Lit::Str(s) = value.lit {                      args.print = s.value().parse()?;                  } else {                      return Err("print value must be string literal".into());                  }              } else if ident == "escape" { -                if let syn::Lit::Str(ref s) = pair.lit { +                if let syn::Lit::Str(s) = value.lit {                      args.escaping = Some(s.value());                  } else {                      return Err("escape value must be string literal".into());                  }              } else if ident == "ext" { -                if let syn::Lit::Str(ref s) = pair.lit { +                if let syn::Lit::Str(s) = value.lit {                      args.ext = Some(s.value());                  } else {                      return Err("ext value must be string literal".into());                  }              } else if ident == "syntax" { -                if let syn::Lit::Str(ref s) = pair.lit { +                if let syn::Lit::Str(s) = value.lit {                      args.syntax = Some(s.value())                  } else {                      return Err("syntax value must be string literal".into());                  }              } else if ident == "config" { -                if let syn::Lit::Str(ref s) = pair.lit { +                if let syn::Lit::Str(s) = value.lit {                      args.config_path = Some(s.value())                  } else {                      return Err("config value must be string literal".into());                  }              } else if ident == "whitespace" { -                if let syn::Lit::Str(ref s) = pair.lit { +                if let syn::Lit::Str(s) = value.lit {                      args.whitespace = Some(s.value())                  } else {                      return Err("whitespace value must be string literal".into()); @@ -528,7 +527,7 @@ impl<'a> Generator<'a> {      #[cfg(feature = "with-rocket")]      fn impl_rocket_responder(&mut self, buf: &mut Buffer) -> Result<(), CompileError> {          let lifetime = syn::Lifetime::new("'askama", proc_macro2::Span::call_site()); -        let param = syn::GenericParam::Lifetime(syn::LifetimeDef::new(lifetime)); +        let param = syn::GenericParam::Lifetime(syn::LifetimeParam::new(lifetime));          self.write_header(              buf,              "::askama_rocket::Responder<'askama, 'askama>", | 
