aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--askama_derive/src/lib.rs5
-rw-r--r--askama_shared/src/generator.rs44
-rw-r--r--askama_shared/src/input.rs13
-rw-r--r--askama_shared/src/lib.rs32
4 files changed, 45 insertions, 49 deletions
diff --git a/askama_derive/src/lib.rs b/askama_derive/src/lib.rs
index cc50ac8..4d81433 100644
--- a/askama_derive/src/lib.rs
+++ b/askama_derive/src/lib.rs
@@ -86,13 +86,14 @@ fn find_used_templates(
let extends = input.config.find_template(extends, Some(&path))?;
let dependency_path = (path.clone(), extends.clone());
if dependency_graph.contains(&dependency_path) {
- return Err(CompileError::String(format!(
+ return Err(format!(
"cyclic dependecy in graph {:#?}",
dependency_graph
.iter()
.map(|e| format!("{:#?} --> {:#?}", e.0, e.1))
.collect::<Vec<String>>()
- )));
+ )
+ .into());
}
dependency_graph.push(dependency_path);
let source = get_template_source(&extends)?;
diff --git a/askama_shared/src/generator.rs b/askama_shared/src/generator.rs
index daf22ae..924d747 100644
--- a/askama_shared/src/generator.rs
+++ b/askama_shared/src/generator.rs
@@ -665,27 +665,25 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> {
return self.write_block(buf, None, ws);
}
- let (def, own_ctx) = if let Some(s) = scope {
- let path = ctx.imports.get(s).ok_or_else(|| {
- CompileError::String(format!("no import found for scope '{}'", s))
- })?;
- let mctx = self.contexts.get(path.as_path()).ok_or_else(|| {
- CompileError::String(format!("context for '{:?}' not found", path))
- })?;
- (
- mctx.macros.get(name).ok_or_else(|| {
- CompileError::String(format!("macro '{}' not found in scope '{}'", name, s))
- })?,
- mctx,
- )
- } else {
- (
- ctx.macros
+ let (def, own_ctx) =
+ if let Some(s) = scope {
+ let path = ctx.imports.get(s).ok_or_else(|| {
+ CompileError::from(format!("no import found for scope {:?}", s))
+ })?;
+ let mctx = self.contexts.get(path.as_path()).ok_or_else(|| {
+ CompileError::from(format!("context for {:?} not found", path))
+ })?;
+ let def = mctx.macros.get(name).ok_or_else(|| {
+ CompileError::from(format!("macro {:?} not found in scope {:?}", name, s))
+ })?;
+ (def, mctx)
+ } else {
+ let def = ctx
+ .macros
.get(name)
- .ok_or_else(|| CompileError::String(format!("macro '{}' not found", name)))?,
- ctx,
- )
- };
+ .ok_or_else(|| CompileError::from(format!("macro {:?} not found", name)))?;
+ (def, ctx)
+ };
self.flush_ws(ws); // Cannot handle_ws() here: whitespace from macro definition comes first
self.locals.push();
@@ -698,7 +696,7 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> {
let mut is_first_variable = true;
for (i, arg) in def.args.iter().enumerate() {
let expr = args.get(i).ok_or_else(|| {
- CompileError::String(format!("macro '{}' takes more than {} arguments", name, i))
+ CompileError::from(format!("macro {:?} takes more than {} arguments", name, i))
})?;
match expr {
@@ -900,7 +898,7 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> {
let heritage = self
.heritage
.as_ref()
- .ok_or(CompileError::Static("no block ancestors available"))?;
+ .ok_or_else(|| CompileError::from("no block ancestors available"))?;
let (ctx, def) = heritage.blocks[cur.0].get(cur.1).ok_or_else(|| {
CompileError::from(match name {
None => format!("no super() block found for block '{}'", cur.0),
@@ -1170,7 +1168,7 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> {
.escapers
.iter()
.find_map(|(escapers, escaper)| escapers.contains(name).then(|| escaper))
- .ok_or(CompileError::Static("invalid escaper for escape filter"))?,
+ .ok_or_else(|| CompileError::from("invalid escaper for escape filter"))?,
None => self.input.escaper,
};
buf.write("::askama::filters::escape(");
diff --git a/askama_shared/src/input.rs b/askama_shared/src/input.rs
index b9341a2..ef27630 100644
--- a/askama_shared/src/input.rs
+++ b/askama_shared/src/input.rs
@@ -34,7 +34,7 @@ impl TemplateInput<'_> {
for attr in &ast.attrs {
if attr.path.is_ident("template") {
if template_args.is_some() {
- return Err(CompileError::Static("duplicated 'template' attribute"));
+ return Err("duplicated 'template' attribute".into());
}
match attr.parse_meta() {
@@ -47,7 +47,7 @@ impl TemplateInput<'_> {
}
}
let template_args =
- template_args.ok_or(CompileError::Static("no attribute 'template' found"))?;
+ template_args.ok_or_else(|| CompileError::from("no attribute 'template' found"))?;
// Loop over the meta attributes and find everything that we
// understand. Return a CompileError if something is not right.
@@ -157,9 +157,10 @@ impl TemplateInput<'_> {
let syntax = syntax.map_or_else(
|| Ok(config.syntaxes.get(config.default_syntax).unwrap()),
|s| {
- config.syntaxes.get(&s).ok_or_else(|| {
- CompileError::String(format!("attribute syntax {} not exist", s))
- })
+ config
+ .syntaxes
+ .get(&s)
+ .ok_or_else(|| CompileError::from(format!("attribute syntax {} not exist", s)))
},
)?;
@@ -181,7 +182,7 @@ impl TemplateInput<'_> {
}
let escaper = escaper.ok_or_else(|| {
- CompileError::String(format!("no escaper defined for extension '{}'", escaping,))
+ CompileError::from(format!("no escaper defined for extension '{}'", escaping))
})?;
let mime_type =
diff --git a/askama_shared/src/lib.rs b/askama_shared/src/lib.rs
index 911367a..b2bebd0 100644
--- a/askama_shared/src/lib.rs
+++ b/askama_shared/src/lib.rs
@@ -3,6 +3,7 @@
#![deny(elided_lifetimes_in_paths)]
#![deny(unreachable_pub)]
+use std::borrow::Cow;
use std::collections::{BTreeMap, HashSet};
use std::convert::TryFrom;
use std::path::{Path, PathBuf};
@@ -204,9 +205,7 @@ struct RawConfig<'d> {
impl RawConfig<'_> {
#[cfg(feature = "config")]
fn from_toml_str(s: &str) -> std::result::Result<RawConfig<'_>, CompileError> {
- toml::from_str(s).map_err(|e| {
- CompileError::String(format!("invalid TOML in {}: {}", CONFIG_FILE_NAME, e))
- })
+ toml::from_str(s).map_err(|e| format!("invalid TOML in {}: {}", CONFIG_FILE_NAME, e).into())
}
#[cfg(not(feature = "config"))]
@@ -243,9 +242,8 @@ pub fn read_config_file() -> std::result::Result<String, CompileError> {
let root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
let filename = root.join(CONFIG_FILE_NAME);
if filename.exists() {
- fs::read_to_string(&filename).map_err(|_| {
- CompileError::String(format!("unable to read {}", filename.to_str().unwrap()))
- })
+ fs::read_to_string(&filename)
+ .map_err(|_| format!("unable to read {:?}", filename.to_str().unwrap()).into())
} else {
Ok("".to_string())
}
@@ -261,10 +259,11 @@ where
#[allow(clippy::match_wild_err_arm)]
pub fn get_template_source(tpl_path: &Path) -> std::result::Result<String, CompileError> {
match fs::read_to_string(tpl_path) {
- Err(_) => Err(CompileError::String(format!(
+ Err(_) => Err(format!(
"unable to open template file '{}'",
tpl_path.to_str().unwrap()
- ))),
+ )
+ .into()),
Ok(mut source) => {
if source.ends_with('\n') {
let _ = source.pop();
@@ -294,29 +293,26 @@ static DEFAULT_ESCAPERS: &[(&[&str], &str)] = &[
];
#[derive(Debug)]
-pub enum CompileError {
- Static(&'static str),
- String(String),
-}
+pub struct CompileError(Cow<'static, str>);
impl fmt::Display for CompileError {
+ #[inline]
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- CompileError::Static(s) => write!(fmt, "{}", s),
- CompileError::String(s) => write!(fmt, "{}", s),
- }
+ fmt.write_str(&self.0)
}
}
impl From<&'static str> for CompileError {
+ #[inline]
fn from(s: &'static str) -> Self {
- CompileError::Static(s)
+ Self(s.into())
}
}
impl From<String> for CompileError {
+ #[inline]
fn from(s: String) -> Self {
- CompileError::String(s)
+ Self(s.into())
}
}