aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--askama/Cargo.toml9
-rw-r--r--askama/src/filters/json.rs30
-rw-r--r--askama/src/filters/mod.rs (renamed from askama/src/filters.rs)8
-rw-r--r--askama/src/lib.rs6
-rw-r--r--testing/Cargo.toml5
-rw-r--r--testing/templates/json.html5
-rw-r--r--testing/tests/simple.rs22
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 {