aboutsummaryrefslogtreecommitdiffstats
path: root/askama_shared
diff options
context:
space:
mode:
authorLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2019-01-17 11:30:13 +0100
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2019-01-17 17:24:23 +0100
commita1b5a9ee2e3ce42c4c5bd52adda2879e902540c6 (patch)
tree7e59c480edbef1f5b8868e02c3fcfd6530b08bb9 /askama_shared
parent744127bd1cf8897961f978f088bb2c9ee996362a (diff)
downloadaskama-a1b5a9ee2e3ce42c4c5bd52adda2879e902540c6.tar.gz
askama-a1b5a9ee2e3ce42c4c5bd52adda2879e902540c6.tar.bz2
askama-a1b5a9ee2e3ce42c4c5bd52adda2879e902540c6.zip
Add optional support for yaml filter (see #192)
Diffstat (limited to 'askama_shared')
-rw-r--r--askama_shared/Cargo.toml1
-rw-r--r--askama_shared/src/error.rs16
-rw-r--r--askama_shared/src/filters/mod.rs9
-rw-r--r--askama_shared/src/filters/yaml.rs32
4 files changed, 55 insertions, 3 deletions
diff --git a/askama_shared/Cargo.toml b/askama_shared/Cargo.toml
index 19ecffd..5ba1111 100644
--- a/askama_shared/Cargo.toml
+++ b/askama_shared/Cargo.toml
@@ -16,4 +16,5 @@ num-traits = "0.2.6"
serde = "1.0"
serde_derive = "1.0"
serde_json = { version = "1.0", optional = true }
+serde_yaml = { version = "0.8", optional = true }
toml = "0.4"
diff --git a/askama_shared/src/error.rs b/askama_shared/src/error.rs
index bd35126..f3e8b48 100644
--- a/askama_shared/src/error.rs
+++ b/askama_shared/src/error.rs
@@ -32,6 +32,10 @@ pub enum Error {
#[cfg(feature = "serde_json")]
Json(::serde_json::Error),
+ /// yaml conversion error
+ #[cfg(feature = "serde_yaml")]
+ Yaml(::serde_yaml::Error),
+
/// This error needs to be non-exhaustive as
/// the `Json` variants existence depends on
/// a feature.
@@ -54,6 +58,8 @@ impl ErrorTrait for Error {
Error::Fmt(ref err) => err.source(),
#[cfg(feature = "serde_json")]
Error::Json(ref err) => err.source(),
+ #[cfg(feature = "serde_yaml")]
+ Error::Yaml(ref err) => err.source(),
_ => None,
}
}
@@ -63,9 +69,10 @@ impl Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Error::Fmt(ref err) => write!(formatter, "formatting error: {}", err),
-
#[cfg(feature = "serde_json")]
Error::Json(ref err) => write!(formatter, "json conversion error: {}", err),
+ #[cfg(feature = "serde_yaml")]
+ Error::Yaml(ref err) => write!(formatter, "yaml conversion error: {}", err),
_ => write!(formatter, "unknown error: __Nonexhaustive"),
}
}
@@ -84,6 +91,13 @@ impl From<::serde_json::Error> for Error {
}
}
+#[cfg(feature = "serde_yaml")]
+impl From<::serde_yaml::Error> for Error {
+ fn from(err: ::serde_yaml::Error) -> Self {
+ Error::Yaml(err)
+ }
+}
+
#[cfg(test)]
mod tests {
use super::Error;
diff --git a/askama_shared/src/filters/mod.rs b/askama_shared/src/filters/mod.rs
index ea702db..7e7bc40 100644
--- a/askama_shared/src/filters/mod.rs
+++ b/askama_shared/src/filters/mod.rs
@@ -6,10 +6,14 @@
#[cfg(feature = "serde_json")]
mod json;
-
#[cfg(feature = "serde_json")]
pub use self::json::json;
+#[cfg(feature = "serde_yaml")]
+mod yaml;
+#[cfg(feature = "serde_yaml")]
+pub use self::yaml::yaml;
+
use crate::error::Error::Fmt;
use askama_escape::{Escaper, MarkupDisplay};
use humansize::{file_size_opts, FileSize};
@@ -23,7 +27,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; 22] = [
+pub const BUILT_IN_FILTERS: [&str; 23] = [
"abs",
"capitalize",
"center",
@@ -46,6 +50,7 @@ pub const BUILT_IN_FILTERS: [&str; 22] = [
"uppercase",
"wordcount",
"json", // Optional feature; reserve the name anyway
+ "yaml", // Optional feature; reserve the name anyway
];
/// Marks a string (or other `Display` type) as safe
diff --git a/askama_shared/src/filters/yaml.rs b/askama_shared/src/filters/yaml.rs
new file mode 100644
index 0000000..fdd03f6
--- /dev/null
+++ b/askama_shared/src/filters/yaml.rs
@@ -0,0 +1,32 @@
+use crate::error::{Error, Result};
+use askama_escape::{Escaper, MarkupDisplay};
+use serde::Serialize;
+
+/// Serialize to JSON (requires `serde_json` feature)
+///
+/// ## Errors
+///
+/// This will panic if `S`'s implementation of `Serialize` decides to fail,
+/// or if `T` contains a map with non-string keys.
+pub fn yaml<E: Escaper, S: Serialize>(e: E, s: &S) -> Result<MarkupDisplay<E, String>> {
+ match serde_yaml::to_string(s) {
+ Ok(s) => Ok(MarkupDisplay::new_safe(s, e)),
+ Err(e) => Err(Error::from(e)),
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use askama_escape::Html;
+
+ #[test]
+ fn test_yaml() {
+ assert_eq!(yaml(Html, &true).unwrap().to_string(), "---\ntrue");
+ assert_eq!(yaml(Html, &"foo").unwrap().to_string(), "---\nfoo");
+ assert_eq!(
+ yaml(Html, &vec!["foo", "bar"]).unwrap().to_string(),
+ "---\n- foo\n- bar"
+ );
+ }
+}