diff options
Diffstat (limited to '')
| -rw-r--r-- | askama_shared/Cargo.toml | 5 | ||||
| -rw-r--r-- | askama_shared/src/filters/mod.rs | 21 | 
2 files changed, 23 insertions, 3 deletions
| diff --git a/askama_shared/Cargo.toml b/askama_shared/Cargo.toml index d9faf2f..b8ea481 100644 --- a/askama_shared/Cargo.toml +++ b/askama_shared/Cargo.toml @@ -10,7 +10,7 @@ workspace = ".."  edition = "2018"  [features] -default = ["config", "humansize", "num-traits"] +default = ["config", "humansize", "num-traits", "percent-encoding"]  config = ["serde", "toml"]  json = ["serde", "serde_json"]  yaml = ["serde", "serde_yaml"] @@ -30,6 +30,7 @@ serde_json = { version = "1.0", optional = true }  serde_yaml = { version = "0.8", optional = true }  syn = "1"  toml = { version = "0.5", optional = true } +percent-encoding = { version = "2.1.0", optional = true }  [package.metadata.docs.rs] -features = ["config", "humansize", "num-traits", "json", "yaml"] +features = ["config", "humansize", "num-traits", "json", "yaml", "percent-encoding"] diff --git a/askama_shared/src/filters/mod.rs b/askama_shared/src/filters/mod.rs index 1667f40..d5a7c88 100644 --- a/askama_shared/src/filters/mod.rs +++ b/askama_shared/src/filters/mod.rs @@ -24,6 +24,8 @@ use askama_escape::{Escaper, MarkupDisplay};  use humansize::{file_size_opts, FileSize};  #[cfg(feature = "num_traits")]  use num_traits::{cast::NumCast, Signed}; +#[cfg(feature = "percent-encoding")] +use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};  use super::Result; @@ -31,7 +33,7 @@ use super::Result;  // Askama or should refer to a local `filters` module. It should contain all the  // filters shipped with Askama, even the optional ones (since optional inclusion  // in the const vector based on features seems impossible right now). -pub const BUILT_IN_FILTERS: [&str; 23] = [ +pub const BUILT_IN_FILTERS: [&str; 24] = [      "abs",      "capitalize",      "center", @@ -52,6 +54,7 @@ pub const BUILT_IN_FILTERS: [&str; 23] = [      "truncate",      "upper",      "uppercase", +    "urlencode",      "wordcount",      "json", // Optional feature; reserve the name anyway      "yaml", // Optional feature; reserve the name anyway @@ -102,6 +105,13 @@ pub fn filesizeformat(b: usize) -> Result<String> {          .map_err(|_| Fmt(fmt::Error))  } +#[cfg(feature = "percent-encoding")] +/// Returns the the UTF-8 encoded String of the given input. +pub fn urlencode(s: &dyn fmt::Display) -> Result<String> { +    let s = s.to_string(); +    Ok(utf8_percent_encode(&s, NON_ALPHANUMERIC).to_string()) +} +  /// Formats arguments according to the specified format  ///  /// The first argument to this filter must be a string literal (as in normal @@ -308,6 +318,15 @@ mod tests {          assert_eq!(filesizeformat(1024).unwrap(), "1.02 KB");      } +    #[cfg(feature = "percent-encoding")] +    #[test] +    fn test_urlencoding() { +        assert_eq!( +            urlencode(&"/path/to/dir with spaces").unwrap(), +            "%2Fpath%2Fto%2Fdir%20with%20spaces" +        ); +    } +      #[test]      fn test_linebreaks() {          assert_eq!( | 
