diff options
-rw-r--r-- | askama/Cargo.toml | 9 | ||||
-rw-r--r-- | askama/src/filters/json.rs | 30 | ||||
-rw-r--r-- | askama/src/filters/mod.rs (renamed from askama/src/filters.rs) | 8 | ||||
-rw-r--r-- | askama/src/lib.rs | 6 | ||||
-rw-r--r-- | testing/Cargo.toml | 5 | ||||
-rw-r--r-- | testing/templates/json.html | 5 | ||||
-rw-r--r-- | testing/tests/simple.rs | 22 |
7 files changed, 78 insertions, 7 deletions
diff --git a/askama/Cargo.toml b/askama/Cargo.toml index 57708ee..32a8c03 100644 --- a/askama/Cargo.toml +++ b/askama/Cargo.toml @@ -18,3 +18,12 @@ travis-ci = { repository = "djc/askama" } [dependencies] askama_derive = { path = "../askama_derive", version = "0.3.4" } error-chain = "0.10" +serde = { version = "1.0", optional = true } +serde_json = { version = "1.0", optional = true } + +[features] +serde-json = ["serde", "serde_json"] +default = [] + +[package.metadata.docs.rs] +features = [ "serde-json" ] diff --git a/askama/src/filters/json.rs b/askama/src/filters/json.rs new file mode 100644 index 0000000..4443fb4 --- /dev/null +++ b/askama/src/filters/json.rs @@ -0,0 +1,30 @@ +use serde::Serialize; +use serde_json; +use errors::{Error, Result}; + +/// 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 json<S: Serialize>(s: &S) -> Result<String> { + serde_json::to_string_pretty(s).map_err(Error::from) +} + + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_json() { + assert_eq!(json(&true).unwrap(), "true"); + assert_eq!(json(&"foo").unwrap(), r#""foo""#); + assert_eq!(json(&vec!["foo", "bar"]).unwrap(), +r#"[ + "foo", + "bar" +]"#); + } +} diff --git a/askama/src/filters.rs b/askama/src/filters/mod.rs index b8673e6..ca229ca 100644 --- a/askama/src/filters.rs +++ b/askama/src/filters/mod.rs @@ -2,9 +2,17 @@ //! //! Contains all the built-in filter functions for use in templates. //! Currently, there is no way to define filters outside this module. + +#[cfg(feature = "serde-json")] +mod json; + +#[cfg(feature = "serde-json")] +pub use self::json::json; + use std::fmt; use super::Result; + fn escapable(b: &u8) -> bool { *b == b'<' || *b == b'>' || *b == b'&' } diff --git a/askama/src/lib.rs b/askama/src/lib.rs index 9c1d648..1870363 100644 --- a/askama/src/lib.rs +++ b/askama/src/lib.rs @@ -216,6 +216,11 @@ extern crate askama_derive; #[macro_use] extern crate error_chain; +#[cfg(feature = "serde-json")] +extern crate serde; +#[cfg(feature = "serde-json")] +extern crate serde_json; + use std::env; use std::fmt; use std::fs::{self, DirEntry}; @@ -279,6 +284,7 @@ mod errors { error_chain! { foreign_links { Fmt(::std::fmt::Error); + Json(::serde_json::Error) #[cfg(feature = "serde-json")]; } } } diff --git a/testing/Cargo.toml b/testing/Cargo.toml index bb6b534..be9af26 100644 --- a/testing/Cargo.toml +++ b/testing/Cargo.toml @@ -6,7 +6,8 @@ workspace = ".." build = "build.rs" [dependencies] -askama = { path = "../askama", version = "*" } +serde_json = "1.0" +askama = { path = "../askama", version = "*", features = ["serde-json"] } [build-dependencies] -askama = { path = "../askama", version = "*" } +askama = { path = "../askama", version = "*", features = ["serde-json"] } diff --git a/testing/templates/json.html b/testing/templates/json.html index e711c10..250b7be 100644 --- a/testing/templates/json.html +++ b/testing/templates/json.html @@ -1 +1,4 @@ -{"foo": "{{ foo }}", "bar": "{{ bar }}"} +{ + "foo": "{{ foo }}", + "bar": {{ bar|json }} +} diff --git a/testing/tests/simple.rs b/testing/tests/simple.rs index 896e082..93faf50 100644 --- a/testing/tests/simple.rs +++ b/testing/tests/simple.rs @@ -1,7 +1,10 @@ #[macro_use] extern crate askama; +#[macro_use] +extern crate serde_json; use askama::Template; +use serde_json::Value; #[derive(Template)] #[template(path = "simple.html")] @@ -146,16 +149,27 @@ fn test_generics() { #[template(path = "json.html")] struct JsonTemplate<'a> { foo: &'a str, - bar: &'a str, + bar: &'a Value, } #[test] fn test_json() { - let t = JsonTemplate { foo: "a", bar: "b" }; - assert_eq!(t.render().unwrap(), "{\"foo\": \"a\", \"bar\": \"b\"}"); + let val = json!({"arr": [ "one", 2, true, null ]}); + let t = JsonTemplate { foo: "a", bar: &val }; + // Note: the json filter lacks a way to specify initial indentation + assert_eq!(t.render().unwrap(), r#"{ + "foo": "a", + "bar": { + "arr": [ + "one", + 2, + true, + null + ] +} +}"#); } - #[derive(Template)] #[template(path = "composition.html")] struct CompositionTemplate { |