diff options
author | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2019-01-17 11:30:13 +0100 |
---|---|---|
committer | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2019-01-17 17:24:23 +0100 |
commit | a1b5a9ee2e3ce42c4c5bd52adda2879e902540c6 (patch) | |
tree | 7e59c480edbef1f5b8868e02c3fcfd6530b08bb9 /askama_shared | |
parent | 744127bd1cf8897961f978f088bb2c9ee996362a (diff) | |
download | askama-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.toml | 1 | ||||
-rw-r--r-- | askama_shared/src/error.rs | 16 | ||||
-rw-r--r-- | askama_shared/src/filters/mod.rs | 9 | ||||
-rw-r--r-- | askama_shared/src/filters/yaml.rs | 32 |
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" + ); + } +} |