aboutsummaryrefslogtreecommitdiffstats
path: root/askama_derive
diff options
context:
space:
mode:
authorLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2020-11-02 14:26:17 +0100
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2020-11-02 16:21:31 +0100
commitac7d9e8031b4df489a0d58dc3459bc931f1ff870 (patch)
treeb19bcab3bbc5725684da896f3bf88d1213f05d68 /askama_derive
parent97509f5a3c93dafc73bbe8f0c35ed5269c155e2b (diff)
downloadaskama-ac7d9e8031b4df489a0d58dc3459bc931f1ff870.tar.gz
askama-ac7d9e8031b4df489a0d58dc3459bc931f1ff870.tar.bz2
askama-ac7d9e8031b4df489a0d58dc3459bc931f1ff870.zip
Improve error handling (see #368)
Diffstat (limited to 'askama_derive')
-rw-r--r--askama_derive/src/lib.rs48
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 {