From 2d457f54f50de8a9430f1e6e3da42244957911d1 Mon Sep 17 00:00:00 2001 From: René Kijewski Date: Thu, 3 Feb 2022 14:55:33 +0100 Subject: Replace custom Cow with actual Cow --- askama_derive/src/lib.rs | 5 +++-- askama_shared/src/generator.rs | 44 ++++++++++++++++++++---------------------- askama_shared/src/input.rs | 13 +++++++------ askama_shared/src/lib.rs | 32 ++++++++++++++---------------- 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::>() - ))); + ) + .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, 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 { 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 { 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 for CompileError { + #[inline] fn from(s: String) -> Self { - CompileError::String(s) + Self(s.into()) } } -- cgit