aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--askama/Cargo.toml3
-rw-r--r--askama_shared/Cargo.toml5
-rw-r--r--askama_shared/src/filters/mod.rs21
3 files changed, 25 insertions, 4 deletions
diff --git a/askama/Cargo.toml b/askama/Cargo.toml
index 47da465..d97bf34 100644
--- a/askama/Cargo.toml
+++ b/askama/Cargo.toml
@@ -18,9 +18,10 @@ azure-devops = { project = "dochtman/Projects", pipeline = "Askama", build = "2"
maintenance = { status = "actively-developed" }
[features]
-default = ["config", "humansize", "num-traits"]
+default = ["config", "humansize", "num-traits", "urlencode"]
config = ["askama_shared/config"]
humansize = ["askama_shared/humansize"]
+urlencode = ["askama_shared/percent-encoding"]
serde-json = ["askama_shared/json"]
serde-yaml = ["askama_shared/yaml"]
num-traits = ["askama_shared/num-traits"]
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!(