From 5e644ed05d5fd28faae52915f06ca0bee66ea51f Mon Sep 17 00:00:00 2001 From: boyned//Kampfkarren Date: Mon, 31 May 2021 21:29:35 -0700 Subject: [PATCH] Add json.toStringPretty (#55) * Add json.toStringPretty * Add optional indentation * Better changelog * Update src/remodel_api/json.rs Co-authored-by: Lucien Greathouse --- CHANGELOG.md | 1 + README.md | 9 +++++++++ src/remodel_api/json.rs | 26 +++++++++++++++++++++++++- test-scripts/json-encode.lua | 32 +++++++++++++++++++++++++++++++- 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c522394..20b12b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Added support for CFrame ([#48](https://github.com/rojo-rbx/remodel/pull/48)) * Added support for Vector3, and improved Vector3int16 ([#46](https://github.com/rojo-rbx/remodel/pull/46)) * Added Color3.fromRGB(red, blue, green) ([#44](https://github.com/rojo-rbx/remodel/pull/44)) +* Added `json.toStringPretty` ([#55](https://github.com/rojo-rbx/remodel/pull/55)) ## 0.8.1 (2021-04-09) * Updated to latest rbx_xml, which should fix `OptionalCoordinateFrame`-related issues. diff --git a/README.md b/README.md index 2d56b21..90edc82 100644 --- a/README.md +++ b/README.md @@ -280,6 +280,15 @@ Encodes a Lua object as a JSON string. Can only encode Lua primitives like table Throws on error, like if the input table cannot be encoded. +### `json.toStringPretty` (Unreleased) +``` +json.toStringPretty(value: any, indent?: string = " "): string +``` + +Encodes a Lua object as a prettified JSON string. If an indent is passed, will use that for indentation, otherwise will default to two spaces. + +Throws on error, like if the input table cannot be encoded. + ## Supported Roblox Types When interacting with Roblox instances, Remodel doesn't support all value types yet and may throw an error. diff --git a/src/remodel_api/json.rs b/src/remodel_api/json.rs index eeaf097..83c83f9 100644 --- a/src/remodel_api/json.rs +++ b/src/remodel_api/json.rs @@ -1,5 +1,9 @@ use rlua::{Context, FromLua, Table, ToLua, UserData, UserDataMethods, Value as LuaValue}; -use serde_json::{Number, Value as JsonValue}; +use serde::Serialize; +use serde_json::{ + ser::{PrettyFormatter, Serializer}, + Number, Value as JsonValue, +}; pub struct Json; @@ -9,6 +13,26 @@ impl UserData for Json { serde_json::to_string(&lua_value.0).map_err(rlua::Error::external) }); + methods.add_function( + "toStringPretty", + |_context, (lua_value, indent): (Value, Option)| { + let pretty_formatter = if let Some(ref indent) = indent { + PrettyFormatter::with_indent(indent.as_bytes()) + } else { + PrettyFormatter::new() + }; + + let mut output = Vec::new(); + let mut serializer = Serializer::with_formatter(&mut output, pretty_formatter); + lua_value + .0 + .serialize(&mut serializer) + .map_err(rlua::Error::external)?; + + String::from_utf8(output).map_err(rlua::Error::external) + }, + ); + methods.add_function("fromString", |_context, source: String| { serde_json::from_str::(&source) .map(Value) diff --git a/test-scripts/json-encode.lua b/test-scripts/json-encode.lua index 8a067fc..3f291f5 100644 --- a/test-scripts/json-encode.lua +++ b/test-scripts/json-encode.lua @@ -17,4 +17,34 @@ assert(encodedSparse == "[1.0,2.0,null,4.0]") local sparser = {1, 2, 3, [1000] = 6} local encodedSparser = json.toString(sparser) -assert(encodedSparser == [[{"1":1.0,"1000":6.0,"2":2.0,"3":3.0}]]) \ No newline at end of file +assert(encodedSparser == [[{"1":1.0,"1000":6.0,"2":2.0,"3":3.0}]]) + +local encodedPretty = json.toStringPretty(baseline) +assert(encodedPretty == [[{ + "w": { + "0": "cool", + "wack": "yo" + }, + "x": 5.0, + "y": "Hello, world!", + "z": [ + 1.0, + 2.0, + 3.0 + ] +}]]) + +local encodedPrettyWithIndent = json.toStringPretty(baseline, "\t") +assert(encodedPrettyWithIndent == [[{ + "w": { + "0": "cool", + "wack": "yo" + }, + "x": 5.0, + "y": "Hello, world!", + "z": [ + 1.0, + 2.0, + 3.0 + ] +}]])