From a9a3ea2328484de8028b9d2cfc8a22a498b136d0 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Tue, 30 Jul 2024 17:46:03 +0200 Subject: [PATCH] Implement indent parameter for tojson (#546) --- CHANGELOG.md | 4 +++ minijinja/src/filters.rs | 24 ++++++++++++++--- minijinja/src/lib.rs | 1 - minijinja/tests/inputs/tojson.txt | 7 +++++ .../test_templates__vm@tojson.txt.snap | 27 +++++++++++++++++++ 5 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 minijinja/tests/inputs/tojson.txt create mode 100644 minijinja/tests/snapshots/test_templates__vm@tojson.txt.snap diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e3a9e13..036103c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to MiniJinja are documented here. +## 2.1.1 + +- Added `indent` parameter to `tojson` filter. #546 + ## 2.1.0 - minijinja-cli now supports `.ini` files. #532 diff --git a/minijinja/src/filters.rs b/minijinja/src/filters.rs index eab9f596..68ffc5e9 100644 --- a/minijinja/src/filters.rs +++ b/minijinja/src/filters.rs @@ -1008,9 +1008,27 @@ mod builtins { /// ``` #[cfg_attr(docsrs, doc(cfg(all(feature = "builtins", feature = "json"))))] #[cfg(feature = "json")] - pub fn tojson(value: Value, pretty: Option) -> Result { - if pretty.unwrap_or(false) { - serde_json::to_string_pretty(&value) + pub fn tojson(value: Value, indent: Option, args: Kwargs) -> Result { + let indent = match indent { + Some(indent) => Some(indent), + None => ok!(args.get("indent")), + }; + let indent = match indent { + None => None, + Some(ref val) => match bool::try_from(val.clone()).ok() { + Some(true) => Some(2), + Some(false) => None, + None => Some(ok!(usize::try_from(val.clone()))), + }, + }; + args.assert_all_used()?; + if let Some(indent) = indent { + let mut out = Vec::::new(); + let indentation = " ".repeat(indent); + let formatter = serde_json::ser::PrettyFormatter::with_indent(indentation.as_bytes()); + let mut s = serde_json::Serializer::with_formatter(&mut out, formatter); + serde::Serialize::serialize(&value, &mut s) + .map(|_| unsafe { String::from_utf8_unchecked(out) }) } else { serde_json::to_string(&value) } diff --git a/minijinja/src/lib.rs b/minijinja/src/lib.rs index afb5a429..ee012174 100644 --- a/minijinja/src/lib.rs +++ b/minijinja/src/lib.rs @@ -202,7 +202,6 @@ #![allow(clippy::cognitive_complexity)] #![allow(clippy::get_first)] #![allow(clippy::default_constructed_unit_structs)] -#![allow(where_clauses_object_safety)] #![cfg_attr(docsrs, feature(doc_cfg))] #![deny(missing_docs)] #![doc(html_logo_url = "https://github.com/mitsuhiko/minijinja/raw/main/artwork/logo-square.png")] diff --git a/minijinja/tests/inputs/tojson.txt b/minijinja/tests/inputs/tojson.txt new file mode 100644 index 00000000..bcae5d60 --- /dev/null +++ b/minijinja/tests/inputs/tojson.txt @@ -0,0 +1,7 @@ +{} +--- +{{ [1, 2, 3]|tojson }} +{{ [1, 2, 3]|tojson(true) }} +{{ [1, 2, 3]|tojson(indent=4) }} +{{ [1, 2, 3]|tojson(1) }} +{{ [1, 2, 3]|tojson(8) }} \ No newline at end of file diff --git a/minijinja/tests/snapshots/test_templates__vm@tojson.txt.snap b/minijinja/tests/snapshots/test_templates__vm@tojson.txt.snap new file mode 100644 index 00000000..25b0c051 --- /dev/null +++ b/minijinja/tests/snapshots/test_templates__vm@tojson.txt.snap @@ -0,0 +1,27 @@ +--- +source: minijinja/tests/test_templates.rs +description: "{{ [1, 2, 3]|tojson }}\n{{ [1, 2, 3]|tojson(true) }}\n{{ [1, 2, 3]|tojson(indent=4) }}\n{{ [1, 2, 3]|tojson(1) }}\n{{ [1, 2, 3]|tojson(8) }}" +info: {} +input_file: minijinja/tests/inputs/tojson.txt +--- +[1,2,3] +[ + 1, + 2, + 3 +] +[ + 1, + 2, + 3 +] +[ + 1, + 2, + 3 +] +[ + 1, + 2, + 3 +]