diff options
Diffstat (limited to '')
-rw-r--r-- | askama_shared/Cargo.toml | 2 | ||||
-rw-r--r-- | askama_shared/src/filters/json.rs | 39 | ||||
-rw-r--r-- | askama_shared/src/generator.rs | 2 |
3 files changed, 25 insertions, 18 deletions
diff --git a/askama_shared/Cargo.toml b/askama_shared/Cargo.toml index e19ad35..ea9e968 100644 --- a/askama_shared/Cargo.toml +++ b/askama_shared/Cargo.toml @@ -12,7 +12,7 @@ edition = "2018" [features] default = ["config", "humansize", "num-traits", "percent-encoding"] config = ["serde", "toml"] -json = ["serde", "serde_json"] +json = ["serde", "serde_json", "askama_escape/json"] markdown = ["comrak"] yaml = ["serde", "serde_yaml"] diff --git a/askama_shared/src/filters/json.rs b/askama_shared/src/filters/json.rs index c0df707..e94e50c 100644 --- a/askama_shared/src/filters/json.rs +++ b/askama_shared/src/filters/json.rs @@ -1,33 +1,40 @@ use crate::error::{Error, Result}; -use askama_escape::{Escaper, MarkupDisplay}; +use askama_escape::JsonEscapeBuffer; use serde::Serialize; +use serde_json::to_writer_pretty; -/// Serialize to JSON (requires `serde_json` feature) +/// Serialize to JSON (requires `json` feature) /// -/// ## Errors +/// The generated string does not contain ampersands `&`, chevrons `< >`, or apostrophes `'`. +/// To use it in a `<script>` you can combine it with the safe filter: /// -/// 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<E: Escaper, S: Serialize>(e: E, s: S) -> Result<MarkupDisplay<E, String>> { - match serde_json::to_string_pretty(&s) { - Ok(s) => Ok(MarkupDisplay::new_safe(s, e)), - Err(e) => Err(Error::from(e)), - } +/// ``` html +/// <script> +/// var data = {{data|json|safe}}; +/// </script> +/// ``` +/// +/// To use it in HTML attributes, you can either use it in quotation marks `"{{data|json}}"` as is, +/// or in apostrophes with the (optional) safe filter `'{{data|json|safe}}'`. +/// In HTML texts the output of e.g. `<pre>{{data|json|safe}}</pre>` is safe, too. +pub fn json<S: Serialize>(s: S) -> Result<String> { + let mut writer = JsonEscapeBuffer::new(); + to_writer_pretty(&mut writer, &s).map_err(Error::from)?; + Ok(writer.finish()) } #[cfg(test)] mod tests { use super::*; - use askama_escape::Html; #[test] fn test_json() { - assert_eq!(json(Html, true).unwrap().to_string(), "true"); - assert_eq!(json(Html, "foo").unwrap().to_string(), r#""foo""#); - assert_eq!(json(Html, &true).unwrap().to_string(), "true"); - assert_eq!(json(Html, &"foo").unwrap().to_string(), r#""foo""#); + assert_eq!(json(true).unwrap(), "true"); + assert_eq!(json("foo").unwrap(), r#""foo""#); + assert_eq!(json(&true).unwrap(), "true"); + assert_eq!(json(&"foo").unwrap(), r#""foo""#); assert_eq!( - json(Html, &vec!["foo", "bar"]).unwrap().to_string(), + json(&vec!["foo", "bar"]).unwrap(), r#"[ "foo", "bar" diff --git a/askama_shared/src/generator.rs b/askama_shared/src/generator.rs index 6024436..ea22a83 100644 --- a/askama_shared/src/generator.rs +++ b/askama_shared/src/generator.rs @@ -1171,7 +1171,7 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> { return Err("the `yaml` filter requires the `serde-yaml` feature to be enabled".into()); } - const FILTERS: [&str; 3] = ["safe", "json", "yaml"]; + const FILTERS: [&str; 2] = ["safe", "yaml"]; if FILTERS.contains(&name) { buf.write(&format!( "::askama::filters::{}({}, ", |