diff --git a/stdlib/std.jsonnet b/stdlib/std.jsonnet index 14fee32b8..07babbaa0 100644 --- a/stdlib/std.jsonnet +++ b/stdlib/std.jsonnet @@ -677,15 +677,13 @@ limitations under the License. "\\r" else if ch == "\t" then "\\t" - else if ch == "\u0000" then - "\\u0000" else local cp = std.codepoint(ch); - if cp < 32 || cp > 126 then + if cp < 32 || (cp >= 126 && cp <= 159) then "\\u%04x" % [cp] else ch; - "\"%s\"" % std.foldl(function(a, b) a + trans(b), std.stringChars(str), ""), + "\"%s\"" % std.join("", [trans(ch) for ch in std.stringChars(str)]), escapeStringPython(str):: std.escapeStringJson(str), @@ -697,7 +695,7 @@ limitations under the License. "'\"'\"'" else ch; - "'%s'" % std.foldl(function(a, b) a + trans(b), std.stringChars(str), ""), + "'%s'" % std.join("", [trans(ch) for ch in std.stringChars(str)]), escapeStringDollars(str_):: local str = std.toString(str_); @@ -708,6 +706,47 @@ limitations under the License. ch; std.foldl(function(a, b) a + trans(b), std.stringChars(str), ""), + manifestJson(value):: std.manifestJsonEx(value, " "), + + manifestJsonEx(value, indent):: + local aux(v, path, cindent) = + if v == true then + "true" + else if v == false then + "false" + else if v == null then + "null" + else if std.type(v) == "number" then + "" + v + else if std.type(v) == "string" then + std.escapeStringJson(v) + else if std.type(v) == "function" then + error "Tried to manifest function at " + path + else if std.type(v) == "array" then + local range = std.range(0, std.length(v) - 1); + local lines = ["[\n" + cindent] + + std.join([",\n" + cindent], + [[indent + aux(v[i], path + [i], cindent + indent)] for i +in range]) + + ["\n" + cindent + "]"]; + std.join("", lines) + else if std.type(v) == "object" then + local lines = ["{\n" + cindent] + + std.join([",\n" + cindent], + [[indent + "\"" + k + "\": " + + aux(v[k], path + [k], cindent + indent)] + for k in std.objectFields(v)]) + + ["\n" + cindent + "}"]; + std.join("", lines); + aux(value, [], ""), + + manifestYamlStream(value):: + if std.type(value) != "array" then + error "manifestYamlStream only takes arrays, got " + std.type(value) + else + "---\n" + std.join("\n---\n", [std.manifestJson(e) for e in value]) + '\n...\n', + + manifestPython(o):: if std.type(o) == "object" then local fields = ["%s: %s" % [std.escapeStringPython(k), std.manifestPython(o[k])] diff --git a/test_suite/error.equality_function.jsonnet.golden b/test_suite/error.equality_function.jsonnet.golden index 0aec2a705..8cc0c9f57 100644 --- a/test_suite/error.equality_function.jsonnet.golden +++ b/test_suite/error.equality_function.jsonnet.golden @@ -1,3 +1,3 @@ RUNTIME ERROR: Cannot test equality of functions - std.jsonnet:941:17-41 function + std.jsonnet:980:17-41 function error.equality_function.jsonnet:17:1-32 diff --git a/test_suite/error.inside_equals_array.jsonnet.golden b/test_suite/error.inside_equals_array.jsonnet.golden index 2afd3a498..3f01439a4 100644 --- a/test_suite/error.inside_equals_array.jsonnet.golden +++ b/test_suite/error.inside_equals_array.jsonnet.golden @@ -1,7 +1,7 @@ RUNTIME ERROR: foobar error.inside_equals_array.jsonnet:18:18-31 thunk - std.jsonnet:921:41-44 thunk - std.jsonnet:921:33-44 function - std.jsonnet:921:33-44 function - std.jsonnet:924:29-44 function - std.jsonnet:925:21-32 + std.jsonnet:960:41-44 thunk + std.jsonnet:960:33-44 function + std.jsonnet:960:33-44 function + std.jsonnet:963:29-44 function + std.jsonnet:964:21-32 diff --git a/test_suite/error.inside_equals_object.jsonnet.golden b/test_suite/error.inside_equals_object.jsonnet.golden index d46e04fb5..26655d6bc 100644 --- a/test_suite/error.inside_equals_object.jsonnet.golden +++ b/test_suite/error.inside_equals_object.jsonnet.golden @@ -1,7 +1,7 @@ RUNTIME ERROR: foobar error.inside_equals_object.jsonnet:18:22-35 object - std.jsonnet:935:62-65 thunk - std.jsonnet:935:54-65 function - std.jsonnet:935:54-65 function - std.jsonnet:938:29-44 function - std.jsonnet:939:21-32 + std.jsonnet:974:62-65 thunk + std.jsonnet:974:54-65 function + std.jsonnet:974:54-65 function + std.jsonnet:977:29-44 function + std.jsonnet:978:21-32 diff --git a/test_suite/error.invariant.equality.jsonnet.golden b/test_suite/error.invariant.equality.jsonnet.golden index d623810e6..6e1e9c382 100644 --- a/test_suite/error.invariant.equality.jsonnet.golden +++ b/test_suite/error.invariant.equality.jsonnet.golden @@ -1,6 +1,6 @@ RUNTIME ERROR: Object assertion failed. error.invariant.equality.jsonnet:17:10-14 thunk - std.jsonnet:935:54-57 thunk - std.jsonnet:935:54-65 function - std.jsonnet:935:54-65 function - std.jsonnet:939:21-32 + std.jsonnet:974:54-57 thunk + std.jsonnet:974:54-65 function + std.jsonnet:974:54-65 function + std.jsonnet:978:21-32 diff --git a/test_suite/stdlib.jsonnet b/test_suite/stdlib.jsonnet index 423906f78..859c9373c 100644 --- a/test_suite/stdlib.jsonnet +++ b/test_suite/stdlib.jsonnet @@ -338,4 +338,30 @@ std.assertEqual(std.split("/foo/", "/"), ["", "foo", ""]) && std.assertEqual(std.splitLimit("foo/bar", "/", 1), ["foo", "bar"]) && std.assertEqual(std.splitLimit("/foo/", "/", 1), ["", "foo/"]) && +std.assertEqual(std.manifestJsonEx({ + x: [1, 2, 3, true, false, null, "string\nstring"], + y: { a: 1, b: 2, c: [1, 2] }, +}, " ") + "\n", ||| + { + "x": [ + 1, + 2, + 3, + true, + false, + null, + "string\nstring" + ], + "y": { + "a": 1, + "b": 2, + "c": [ + 1, + 2 + ] + } + } +||| +) && + true