mirror of
https://github.com/google/go-jsonnet.git
synced 2025-08-07 14:57:24 +02:00
Efficient native implementation of std.join
It changes the behavior slightly - mixing strings and arrays in join is no longer allowed.
This commit is contained in:
parent
3481c9c698
commit
8ade994928
54
builtins.go
54
builtins.go
@ -285,6 +285,59 @@ func builtinFlatMap(e *evaluator, funcp potentialValue, arrp potentialValue) (va
|
||||
return makeValueArray(elems), nil
|
||||
}
|
||||
|
||||
func joinArrays(e *evaluator, sep *valueArray, arr *valueArray) (value, error) {
|
||||
result := make([]potentialValue, 0, arr.length())
|
||||
for i, elem := range arr.elements {
|
||||
if i != 0 {
|
||||
for _, subElem := range sep.elements {
|
||||
result = append(result, subElem)
|
||||
}
|
||||
}
|
||||
elemArr, err := e.evaluateArray(elem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, subElem := range elemArr.elements {
|
||||
result = append(result, subElem)
|
||||
}
|
||||
}
|
||||
return makeValueArray(result), nil
|
||||
}
|
||||
|
||||
func joinStrings(e *evaluator, sep *valueString, arr *valueArray) (value, error) {
|
||||
result := make([]rune, 0, arr.length())
|
||||
for i, elem := range arr.elements {
|
||||
if i != 0 {
|
||||
result = append(result, sep.value...)
|
||||
}
|
||||
elemString, err := e.evaluateString(elem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, elemString.value...)
|
||||
}
|
||||
return &valueString{value: result}, nil
|
||||
}
|
||||
|
||||
func builtinJoin(e *evaluator, sepp potentialValue, arrp potentialValue) (value, error) {
|
||||
arr, err := e.evaluateArray(arrp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sep, err := e.evaluate(sepp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch sep := sep.(type) {
|
||||
case *valueString:
|
||||
return joinStrings(e, sep, arr)
|
||||
case *valueArray:
|
||||
return joinArrays(e, sep, arr)
|
||||
default:
|
||||
return nil, e.Error("join first parameter should be string or array, got " + sep.getType().name)
|
||||
}
|
||||
}
|
||||
|
||||
func builtinFilter(e *evaluator, funcp potentialValue, arrp potentialValue) (value, error) {
|
||||
arr, err := e.evaluateArray(arrp)
|
||||
if err != nil {
|
||||
@ -771,6 +824,7 @@ var funcBuiltins = buildBuiltinMap([]builtin{
|
||||
&UnaryBuiltin{name: "toString", function: builtinToString, parameters: ast.Identifiers{"a"}},
|
||||
&BinaryBuiltin{name: "makeArray", function: builtinMakeArray, parameters: ast.Identifiers{"sz", "func"}},
|
||||
&BinaryBuiltin{name: "flatMap", function: builtinFlatMap, parameters: ast.Identifiers{"func", "arr"}},
|
||||
&BinaryBuiltin{name: "join", function: builtinJoin, parameters: ast.Identifiers{"sep", "arr"}},
|
||||
&BinaryBuiltin{name: "filter", function: builtinFilter, parameters: ast.Identifiers{"func", "arr"}},
|
||||
&BinaryBuiltin{name: "range", function: builtinRange, parameters: ast.Identifiers{"from", "to"}},
|
||||
&BinaryBuiltin{name: "primitiveEquals", function: primitiveEquals, parameters: ast.Identifiers{"sz", "func"}},
|
||||
|
1
testdata/std.join.golden
vendored
Normal file
1
testdata/std.join.golden
vendored
Normal file
@ -0,0 +1 @@
|
||||
[ ]
|
1
testdata/std.join.jsonnet
vendored
Normal file
1
testdata/std.join.jsonnet
vendored
Normal file
@ -0,0 +1 @@
|
||||
std.join([], [])
|
1
testdata/std.join2.golden
vendored
Normal file
1
testdata/std.join2.golden
vendored
Normal file
@ -0,0 +1 @@
|
||||
[ ]
|
1
testdata/std.join2.jsonnet
vendored
Normal file
1
testdata/std.join2.jsonnet
vendored
Normal file
@ -0,0 +1 @@
|
||||
std.join([42], [])
|
3
testdata/std.join3.golden
vendored
Normal file
3
testdata/std.join3.golden
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[
|
||||
1
|
||||
]
|
1
testdata/std.join3.jsonnet
vendored
Normal file
1
testdata/std.join3.jsonnet
vendored
Normal file
@ -0,0 +1 @@
|
||||
std.join([42], [[1]])
|
5
testdata/std.join4.golden
vendored
Normal file
5
testdata/std.join4.golden
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
[
|
||||
1,
|
||||
42,
|
||||
2
|
||||
]
|
1
testdata/std.join4.jsonnet
vendored
Normal file
1
testdata/std.join4.jsonnet
vendored
Normal file
@ -0,0 +1 @@
|
||||
std.join([42], [[1], [2]])
|
7
testdata/std.join5.golden
vendored
Normal file
7
testdata/std.join5.golden
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
[
|
||||
1,
|
||||
42,
|
||||
2,
|
||||
42,
|
||||
3
|
||||
]
|
1
testdata/std.join5.jsonnet
vendored
Normal file
1
testdata/std.join5.jsonnet
vendored
Normal file
@ -0,0 +1 @@
|
||||
std.join([42], [[1], [2], [3]])
|
1
testdata/std.join6.golden
vendored
Normal file
1
testdata/std.join6.golden
vendored
Normal file
@ -0,0 +1 @@
|
||||
"aaxxxbb"
|
1
testdata/std.join6.jsonnet
vendored
Normal file
1
testdata/std.join6.jsonnet
vendored
Normal file
@ -0,0 +1 @@
|
||||
std.join("xxx", ["aa", "bb"])
|
8
testdata/std.join7.golden
vendored
Normal file
8
testdata/std.join7.golden
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
RUNTIME ERROR: Unexpected type array, expected string
|
||||
-------------------------------------------------
|
||||
<builtin> builtin function <join>
|
||||
|
||||
-------------------------------------------------
|
||||
During evaluation
|
||||
|
||||
|
1
testdata/std.join7.jsonnet
vendored
Normal file
1
testdata/std.join7.jsonnet
vendored
Normal file
@ -0,0 +1 @@
|
||||
std.join("aa", [[1], [2]])
|
8
testdata/std.join8.golden
vendored
Normal file
8
testdata/std.join8.golden
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
RUNTIME ERROR: Unexpected type string, expected array
|
||||
-------------------------------------------------
|
||||
<builtin> builtin function <join>
|
||||
|
||||
-------------------------------------------------
|
||||
During evaluation
|
||||
|
||||
|
1
testdata/std.join8.jsonnet
vendored
Normal file
1
testdata/std.join8.jsonnet
vendored
Normal file
@ -0,0 +1 @@
|
||||
std.join([3, 4], [[1, 2], "56"])
|
Loading…
Reference in New Issue
Block a user