Adding optional json filter

This commit is contained in:
Anthony Nowell 2017-08-13 00:46:04 -06:00 committed by Dirkjan Ochtman
parent d0a3d51dcd
commit 2d6785b714
7 changed files with 78 additions and 7 deletions

View File

@ -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" ]

View File

@ -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"
]"#);
}
}

View File

@ -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'&'
}

View File

@ -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")];
}
}
}

View File

@ -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"] }

View File

@ -1 +1,4 @@
{"foo": "{{ foo }}", "bar": "{{ bar }}"}
{
"foo": "{{ foo }}",
"bar": {{ bar|json }}
}

View File

@ -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,15 +149,26 @@ 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")]