diff --git a/builtins.go b/builtins.go index 9d1b950..2b063c7 100644 --- a/builtins.go +++ b/builtins.go @@ -17,6 +17,7 @@ limitations under the License. package jsonnet import ( + "bytes" "math" "sort" @@ -152,6 +153,19 @@ func builtinLength(e *evaluator, xp potentialValue) (value, error) { return makeValueNumber(float64(num)), nil } +func builtinToString(e *evaluator, xp potentialValue) (value, error) { + x, err := e.evaluate(xp) + if err != nil { + return nil, err + } + var buf bytes.Buffer + err = e.i.manifestJSON(e.trace, x, false, "", &buf) + if err != nil { + return nil, err + } + return makeValueString(buf.String()), nil +} + func builtinMakeArray(e *evaluator, szp potentialValue, funcp potentialValue) (value, error) { sz, err := e.evaluateNumber(szp) if err != nil { @@ -432,6 +446,7 @@ var uopBuiltins = []*UnaryBuiltin{ // TODO(sbarzowski) eliminate duplication in function names (e.g. build map from array or constants) var funcBuiltins = map[string]evalCallable{ "length": &UnaryBuiltin{name: "length", function: builtinLength, parameters: ast.Identifiers{"x"}}, + "toString": &UnaryBuiltin{name: "toString", function: builtinToString, parameters: ast.Identifiers{"x"}}, "makeArray": &BinaryBuiltin{name: "makeArray", function: builtinMakeArray, parameters: ast.Identifiers{"sz", "func"}}, "primitiveEquals": &BinaryBuiltin{name: "primitiveEquals", function: primitiveEquals, parameters: ast.Identifiers{"sz", "func"}}, "objectFieldsEx": &BinaryBuiltin{name: "objectFields", function: builtinObjectFieldsEx, parameters: ast.Identifiers{"obj", "hidden"}}, diff --git a/interpreter.go b/interpreter.go index b5d7604..095ac40 100644 --- a/interpreter.go +++ b/interpreter.go @@ -460,7 +460,7 @@ func unparseString(v string) string { for _, c := range v { switch c { case '"': - buf.WriteString("\n") + buf.WriteString("\\\"") case '\\': buf.WriteString("\\\\") case '\b': diff --git a/testdata/std.toString.golden b/testdata/std.toString.golden new file mode 100644 index 0000000..9458e0f --- /dev/null +++ b/testdata/std.toString.golden @@ -0,0 +1 @@ +"\"xxx\"" diff --git a/testdata/std.toString.input b/testdata/std.toString.input new file mode 100644 index 0000000..b1b09a5 --- /dev/null +++ b/testdata/std.toString.input @@ -0,0 +1 @@ +std.toString("xxx") diff --git a/testdata/std.toString2.golden b/testdata/std.toString2.golden new file mode 100644 index 0000000..1026c25 --- /dev/null +++ b/testdata/std.toString2.golden @@ -0,0 +1 @@ +"2" diff --git a/testdata/std.toString2.input b/testdata/std.toString2.input new file mode 100644 index 0000000..0490c86 --- /dev/null +++ b/testdata/std.toString2.input @@ -0,0 +1 @@ +std.toString(2) diff --git a/testdata/std.toString3.golden b/testdata/std.toString3.golden new file mode 100644 index 0000000..3890492 --- /dev/null +++ b/testdata/std.toString3.golden @@ -0,0 +1 @@ +"{ }" diff --git a/testdata/std.toString3.input b/testdata/std.toString3.input new file mode 100644 index 0000000..01a535e --- /dev/null +++ b/testdata/std.toString3.input @@ -0,0 +1 @@ +std.toString({}) diff --git a/testdata/std.toString4.golden b/testdata/std.toString4.golden new file mode 100644 index 0000000..1b4a823 --- /dev/null +++ b/testdata/std.toString4.golden @@ -0,0 +1 @@ +"[ ]" diff --git a/testdata/std.toString4.input b/testdata/std.toString4.input new file mode 100644 index 0000000..81ec321 --- /dev/null +++ b/testdata/std.toString4.input @@ -0,0 +1 @@ +std.toString([]) diff --git a/testdata/std.toString5.golden b/testdata/std.toString5.golden new file mode 100644 index 0000000..57d4eaa --- /dev/null +++ b/testdata/std.toString5.golden @@ -0,0 +1 @@ +RUNTIME ERROR: x diff --git a/testdata/std.toString5.input b/testdata/std.toString5.input new file mode 100644 index 0000000..8ee592a --- /dev/null +++ b/testdata/std.toString5.input @@ -0,0 +1 @@ +std.toString(error "x") diff --git a/testdata/std.toString6.golden b/testdata/std.toString6.golden new file mode 100644 index 0000000..12ed933 --- /dev/null +++ b/testdata/std.toString6.golden @@ -0,0 +1 @@ +"{\"x\": [{\"y\": [ ]}]}" diff --git a/testdata/std.toString6.input b/testdata/std.toString6.input new file mode 100644 index 0000000..c1853f9 --- /dev/null +++ b/testdata/std.toString6.input @@ -0,0 +1 @@ +std.toString({x: [{y: []}]}) diff --git a/testdata/std.toString7.golden b/testdata/std.toString7.golden new file mode 100644 index 0000000..5e248ae --- /dev/null +++ b/testdata/std.toString7.golden @@ -0,0 +1 @@ +"[{\"a\": [42, 42, { }], \"b\": 1337}, 42, \"text\", 42]" diff --git a/testdata/std.toString7.input b/testdata/std.toString7.input new file mode 100644 index 0000000..0f9a53d --- /dev/null +++ b/testdata/std.toString7.input @@ -0,0 +1 @@ +std.toString([{a: [42, 42, {}], ["b"]: 1337}, 42, "text", 42]) diff --git a/testdata/string.golden b/testdata/string.golden new file mode 100644 index 0000000..93a8e1f --- /dev/null +++ b/testdata/string.golden @@ -0,0 +1 @@ +"xxx" diff --git a/testdata/string.input b/testdata/string.input new file mode 100644 index 0000000..93a8e1f --- /dev/null +++ b/testdata/string.input @@ -0,0 +1 @@ +"xxx" diff --git a/testdata/string2.golden b/testdata/string2.golden new file mode 100644 index 0000000..9458e0f --- /dev/null +++ b/testdata/string2.golden @@ -0,0 +1 @@ +"\"xxx\"" diff --git a/testdata/string2.input b/testdata/string2.input new file mode 100644 index 0000000..9458e0f --- /dev/null +++ b/testdata/string2.input @@ -0,0 +1 @@ +"\"xxx\""