diff options
Diffstat (limited to '')
-rw-r--r-- | askama_derive/src/lib.rs | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/askama_derive/src/lib.rs b/askama_derive/src/lib.rs index 367f124..fb3bb2d 100644 --- a/askama_derive/src/lib.rs +++ b/askama_derive/src/lib.rs @@ -4,19 +4,33 @@ extern crate syn; use proc_macro::TokenStream; -fn get_path_from_attrs(attrs: &[syn::Attribute]) -> String { +struct TemplateMeta { + path: String, +} + +fn get_path_from_attrs(attrs: &[syn::Attribute]) -> TemplateMeta { + let mut path = None; let attr = attrs.iter().find(|a| a.name() == "template").unwrap(); if let syn::MetaItem::List(_, ref inner) = attr.value { - if let syn::NestedMetaItem::MetaItem(ref item) = inner[0] { - if let &syn::MetaItem::NameValue(ref key, ref val) = item { - assert_eq!(key.as_ref(), "path"); - if let &syn::Lit::Str(ref s, _) = val { - return s.clone(); + for nm_item in inner { + if let &syn::NestedMetaItem::MetaItem(ref item) = nm_item { + if let &syn::MetaItem::NameValue(ref key, ref val) = item { + match key.as_ref() { + "path" => if let &syn::Lit::Str(ref s, _) = val { + path = Some(s.clone()); + } else { + panic!("template path must be string literal"); + }, + _ => { panic!("unsupported annotation key found") } + } } } } } - panic!("template path not found in struct attributes"); + if path.is_none() { + panic!("template path not found in struct attributes"); + } + TemplateMeta { path: path.unwrap() } } #[proc_macro_derive(Template, attributes(template))] @@ -26,6 +40,6 @@ pub fn derive_template(input: TokenStream) -> TokenStream { syn::Body::Struct(ref data) => data, _ => panic!("#[derive(Template)] can only be used with structs"), }; - let path = get_path_from_attrs(&ast.attrs); - askama::build_template(&path, &ast).parse().unwrap() + let meta = get_path_from_attrs(&ast.attrs); + askama::build_template(&meta.path, &ast).parse().unwrap() } |