From 8a5ff3b41298ebbdd32ac6e74421704d06864a94 Mon Sep 17 00:00:00 2001 From: vallentin Date: Thu, 18 Nov 2021 08:10:28 +0100 Subject: Added support for optional escaper for escape filter (resolves #556) --- askama_shared/src/filters/mod.rs | 9 --------- askama_shared/src/generator.rs | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 11 deletions(-) (limited to 'askama_shared') diff --git a/askama_shared/src/filters/mod.rs b/askama_shared/src/filters/mod.rs index 8406dee..7009f58 100644 --- a/askama_shared/src/filters/mod.rs +++ b/askama_shared/src/filters/mod.rs @@ -106,15 +106,6 @@ where Ok(MarkupDisplay::new_unsafe(v, e)) } -/// Alias for the `escape()` filter -pub fn e(e: E, v: T) -> Result> -where - E: Escaper, - T: fmt::Display, -{ - escape(e, v) -} - #[cfg(feature = "humansize")] /// Returns adequate string representation (in KB, ..) of number of bytes pub fn filesizeformat(b: &B) -> Result { diff --git a/askama_shared/src/generator.rs b/askama_shared/src/generator.rs index 5c72934..78ada4b 100644 --- a/askama_shared/src/generator.rs +++ b/askama_shared/src/generator.rs @@ -1091,7 +1091,10 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { mut name: &str, args: &[Expr<'_>], ) -> Result { - if name == "format" { + if matches!(name, "escape" | "e") { + self._visit_escape_filter(buf, args)?; + return Ok(DisplayWrap::Wrapped); + } else if name == "format" { self._visit_format_filter(buf, args)?; return Ok(DisplayWrap::Unwrapped); } else if name == "fmt" { @@ -1115,7 +1118,7 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { return Err("the `yaml` filter requires the `serde-yaml` feature to be enabled".into()); } - const FILTERS: [&str; 5] = ["safe", "escape", "e", "json", "yaml"]; + const FILTERS: [&str; 3] = ["safe", "json", "yaml"]; if FILTERS.contains(&name) { buf.write(&format!( "::askama::filters::{}({}, ", @@ -1135,6 +1138,37 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { }) } + fn _visit_escape_filter( + &mut self, + buf: &mut Buffer, + args: &[Expr<'_>], + ) -> Result<(), CompileError> { + if args.len() > 2 { + return Err("only two arguments allowed to escape filter".into()); + } + let opt_escaper = match args.get(1) { + Some(Expr::StrLit(name)) => Some(*name), + Some(_) => return Err("invalid escaper type for escape filter".into()), + None => None, + }; + let escaper = match opt_escaper { + Some(name) => self + .input + .config + .escapers + .iter() + .find_map(|(escapers, escaper)| escapers.contains(name).then(|| escaper)) + .ok_or(CompileError::Static("invalid escaper for escape filter"))?, + None => self.input.escaper, + }; + buf.write("::askama::filters::escape("); + buf.write(escaper); + buf.write(", "); + self._visit_args(buf, &args[..1])?; + buf.write(")?"); + Ok(()) + } + fn _visit_format_filter( &mut self, buf: &mut Buffer, -- cgit