diff options
-rw-r--r-- | askama_derive/src/lib.rs | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/askama_derive/src/lib.rs b/askama_derive/src/lib.rs index 2ddec55..0564ccc 100644 --- a/askama_derive/src/lib.rs +++ b/askama_derive/src/lib.rs @@ -6,7 +6,8 @@ extern crate syn; use proc_macro::TokenStream; -use std::path::Path; +use std::borrow::Cow; +use std::path::PathBuf; mod generator; mod parser; @@ -31,13 +32,19 @@ pub fn derive_template(input: TokenStream) -> TokenStream { /// value as passed to the `template()` attribute. fn build_template(ast: &syn::DeriveInput) -> String { let meta = get_template_meta(ast); - let path = path::find_template_from_path(&meta.path, None); - let src = path::get_template_source(&path); - let nodes = parser::parse(&src); + let (path, src) = match meta.source { + Source::Source(s) => (PathBuf::new(), Cow::Borrowed(s)), + Source::Path(s) => { + let path = path::find_template_from_path(&s, None); + let src = path::get_template_source(&path); + (path, Cow::Owned(src)) + }, + }; + let nodes = parser::parse(src.as_ref()); if meta.print == Print::Ast || meta.print == Print::All { println!("{:?}", nodes); } - let code = generator::generate(ast, Path::new(&meta.path), nodes); + let code = generator::generate(ast, &path, nodes); if meta.print == Print::Code || meta.print == Print::All { println!("{}", code); } @@ -56,7 +63,7 @@ fn get_template_meta<'a>(ast: &'a syn::DeriveInput) -> TemplateMeta<'a> { } let attr = attr.unwrap(); - let mut path = None; + let mut source = None; let mut print = Print::None; if let syn::MetaItem::List(_, ref inner) = attr.value { for nm_item in inner { @@ -64,10 +71,15 @@ fn get_template_meta<'a>(ast: &'a syn::DeriveInput) -> TemplateMeta<'a> { 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.as_ref()); + source = Some(Source::Path(s.as_ref())); } else { panic!("template path must be string literal"); }, + "source" => if let syn::Lit::Str(ref s, _) = *val { + source = Some(Source::Source(s.as_ref())); + } else { + panic!("template source must be string literal"); + }, "print" => if let syn::Lit::Str(ref s, _) = *val { print = s.into(); } else { @@ -79,18 +91,24 @@ fn get_template_meta<'a>(ast: &'a syn::DeriveInput) -> TemplateMeta<'a> { } } } - if path.is_none() { - panic!("template path not found in struct attributes"); + + match source { + Some(s) => TemplateMeta { source: s, print }, + None => panic!("template path or source not found in struct attributes"), } - TemplateMeta { path: path.unwrap(), print: print } } // Holds metadata for the template, based on the `template()` attribute. struct TemplateMeta<'a> { - path: &'a str, + source: Source<'a>, print: Print, } +enum Source<'a> { + Path(&'a str), + Source(&'a str), +} + #[derive(PartialEq)] enum Print { All, |