diff options
Diffstat (limited to 'askama_derive')
-rw-r--r-- | askama_derive/src/lib.rs | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/askama_derive/src/lib.rs b/askama_derive/src/lib.rs index cbffa07..8844e99 100644 --- a/askama_derive/src/lib.rs +++ b/askama_derive/src/lib.rs @@ -3,7 +3,9 @@ extern crate proc_macro; use askama_shared::heritage::{Context, Heritage}; use askama_shared::input::{Print, Source, TemplateInput}; use askama_shared::parser::{parse, Expr, Node}; -use askama_shared::{generator, get_template_source, read_config_file, Config, Integrations}; +use askama_shared::{ + generator, get_template_source, read_config_file, CompileError, Config, Integrations, +}; use proc_macro::TokenStream; use std::collections::HashMap; @@ -12,7 +14,12 @@ use std::path::PathBuf; #[proc_macro_derive(Template, attributes(template))] pub fn derive_template(input: TokenStream) -> TokenStream { let ast: syn::DeriveInput = syn::parse(input).unwrap(); - build_template(&ast).parse().unwrap() + match build_template(&ast) { + Ok(source) => source, + Err(e) => format!("compile_error!({:?})", e), + } + .parse() + .unwrap() } /// Takes a `syn::DeriveInput` and generates source code for it @@ -22,26 +29,26 @@ pub fn derive_template(input: TokenStream) -> TokenStream { /// parsed, and the parse tree is fed to the code generator. Will print /// the parse tree and/or generated source according to the `print` key's /// value as passed to the `template()` attribute. -fn build_template(ast: &syn::DeriveInput) -> String { - let config_toml = read_config_file(); - let config = Config::new(&config_toml); - let input = TemplateInput::new(ast, &config); +fn build_template(ast: &syn::DeriveInput) -> Result<String, CompileError> { + let config_toml = read_config_file()?; + let config = Config::new(&config_toml)?; + let input = TemplateInput::new(ast, &config)?; let source: String = match input.source { Source::Source(ref s) => s.clone(), - Source::Path(_) => get_template_source(&input.path), + Source::Path(_) => get_template_source(&input.path)?, }; let mut sources = HashMap::new(); - find_used_templates(&input, &mut sources, source); + find_used_templates(&input, &mut sources, source)?; let mut parsed = HashMap::new(); for (path, src) in &sources { - parsed.insert(path, parse(src, input.syntax)); + parsed.insert(path, parse(src, input.syntax)?); } let mut contexts = HashMap::new(); for (path, nodes) in &parsed { - contexts.insert(*path, Context::new(&input.config, path, nodes)); + contexts.insert(*path, Context::new(&input.config, path, nodes)?); } let ctx = &contexts[&input.path]; @@ -55,26 +62,30 @@ fn build_template(ast: &syn::DeriveInput) -> String { eprintln!("{:?}", parsed[&input.path]); } - let code = generator::generate(&input, &contexts, &heritage, INTEGRATIONS); + let code = generator::generate(&input, &contexts, &heritage, INTEGRATIONS)?; if input.print == Print::Code || input.print == Print::All { eprintln!("{}", code); } - code + Ok(code) } -fn find_used_templates(input: &TemplateInput, map: &mut HashMap<PathBuf, String>, source: String) { +fn find_used_templates( + input: &TemplateInput, + map: &mut HashMap<PathBuf, String>, + source: String, +) -> Result<(), CompileError> { let mut check = vec![(input.path.clone(), source)]; while let Some((path, source)) = check.pop() { - for n in parse(&source, input.syntax) { + for n in parse(&source, input.syntax)? { match n { Node::Extends(Expr::StrLit(extends)) => { - let extends = input.config.find_template(extends, Some(&path)); - let source = get_template_source(&extends); + let extends = input.config.find_template(extends, Some(&path))?; + let source = get_template_source(&extends)?; check.push((extends, source)); } Node::Import(_, import, _) => { - let import = input.config.find_template(import, Some(&path)); - let source = get_template_source(&import); + let import = input.config.find_template(import, Some(&path))?; + let source = get_template_source(&import)?; check.push((import, source)); } _ => {} @@ -82,6 +93,7 @@ fn find_used_templates(input: &TemplateInput, map: &mut HashMap<PathBuf, String> } map.insert(path, source); } + Ok(()) } const INTEGRATIONS: Integrations = Integrations { |