git.delta.rocks / jrsonnet / refs/commits / ce6eeacd9f76

difftreelog

feat minify json

Lach2020-08-22parent: #4dbbc6e.patch.diff
in: master

2 files changed

modifiedcrates/jrsonnet-evaluator/src/builtin/manifest.rsdiffbeforeafterboth
before · crates/jrsonnet-evaluator/src/builtin/manifest.rs
1use crate::error::Error::*;2use crate::error::Result;3use crate::{throw, Val};45#[derive(PartialEq)]6pub enum ManifestType {7	// Applied in manifestification8	Manifest,9	/// Used for std.manifestJson10	/// Empty array/objects extends to "[\n\n]" instead of "[ ]" as in manifest11	Std,12	// No line breaks, used in `obj+''`13	ToString,14}1516pub struct ManifestJsonOptions<'s> {17	pub padding: &'s str,18	pub mtype: ManifestType,19}2021pub(crate) fn manifest_json_ex(val: &Val, options: &ManifestJsonOptions<'_>) -> Result<String> {22	let mut out = String::new();23	manifest_json_ex_buf(val, &mut out, &mut String::new(), options)?;24	Ok(out)25}26fn manifest_json_ex_buf(27	val: &Val,28	buf: &mut String,29	cur_padding: &mut String,30	options: &ManifestJsonOptions<'_>,31) -> Result<()> {32	use std::fmt::Write;33	match val.unwrap_if_lazy()? {34		Val::Bool(v) => {35			if v {36				buf.push_str("true");37			} else {38				buf.push_str("false");39			}40		}41		Val::Null => buf.push_str("null"),42		Val::Str(s) => buf.push_str(&escape_string_json(&s)),43		Val::Num(n) => write!(buf, "{}", n).unwrap(),44		Val::Arr(items) => {45			buf.push('[');46			if !items.is_empty() {47				if options.mtype != ManifestType::ToString {48					buf.push('\n');49				}5051				let old_len = cur_padding.len();52				cur_padding.push_str(options.padding);53				for (i, item) in items.iter().enumerate() {54					if i != 0 {55						buf.push(',');56						if options.mtype == ManifestType::ToString {57							buf.push(' ');58						} else {59							buf.push('\n');60						}61					}62					buf.push_str(cur_padding);63					manifest_json_ex_buf(item, buf, cur_padding, options)?;64				}65				cur_padding.truncate(old_len);6667				if options.mtype != ManifestType::ToString {68					buf.push('\n');69					buf.push_str(cur_padding);70				}71			} else if options.mtype == ManifestType::Std {72				buf.push_str("\n\n");73				buf.push_str(cur_padding);74			} else if options.mtype == ManifestType::ToString {75				buf.push(' ');76			}77			buf.push(']');78		}79		Val::Obj(obj) => {80			buf.push('{');81			let fields = obj.visible_fields();82			if !fields.is_empty() {83				if options.mtype != ManifestType::ToString {84					buf.push('\n');85				}8687				let old_len = cur_padding.len();88				cur_padding.push_str(options.padding);89				for (i, field) in fields.into_iter().enumerate() {90					if i != 0 {91						buf.push(',');92						if options.mtype == ManifestType::ToString {93							buf.push(' ');94						} else {95							buf.push('\n');96						}97					}98					buf.push_str(cur_padding);99					buf.push_str(&escape_string_json(&field));100					buf.push_str(": ");101					manifest_json_ex_buf(&obj.get(field)?.unwrap(), buf, cur_padding, options)?;102				}103				cur_padding.truncate(old_len);104105				if options.mtype != ManifestType::ToString {106					buf.push('\n');107					buf.push_str(cur_padding);108				}109			} else if options.mtype == ManifestType::Std {110				buf.push_str("\n\n");111				buf.push_str(cur_padding);112			} else if options.mtype == ManifestType::ToString {113				buf.push(' ');114			}115			buf.push('}');116		}117		Val::Func(_) | Val::Intristic(_, _) => {118			throw!(RuntimeError("tried to manifest function".into()))119		}120		Val::Lazy(_) => unreachable!(),121	};122	Ok(())123}124pub fn escape_string_json(s: &str) -> String {125	use std::fmt::Write;126	let mut out = String::new();127	out.push('"');128	for c in s.chars() {129		match c {130			'"' => out.push_str("\\\""),131			'\\' => out.push_str("\\\\"),132			'\u{0008}' => out.push_str("\\b"),133			'\u{000c}' => out.push_str("\\f"),134			'\n' => out.push_str("\\n"),135			'\r' => out.push_str("\\r"),136			'\t' => out.push_str("\\t"),137			c if c < 32 as char || (c >= 127 as char && c <= 159 as char) => {138				write!(out, "\\u{:04x}", c as u32).unwrap()139			}140			c => out.push(c),141		}142	}143	out.push('"');144	out145}146147#[test]148fn json_test() {149	assert_eq!(escape_string_json("\u{001f}"), "\"\\u001f\"")150}
modifiedcrates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/val.rs
+++ b/crates/jrsonnet-evaluator/src/val.rs
@@ -227,7 +227,11 @@
 			&self,
 			&ManifestJsonOptions {
 				padding: &" ".repeat(padding),
-				mtype: ManifestType::Manifest,
+				mtype: if padding == 0 {
+					ManifestType::Minify
+				} else {
+					ManifestType::Manifest
+				},
 			},
 		)
 		.map(|s| s.into())