Skip to content

Commit b96b3e8

Browse files
authored
Merge pull request #541 from reubenmiller/feat-template-recurse-functions
feat: extend jsonnet recurse functions to support user defined predicates and transform functions
2 parents 42091e1 + f997270 commit b96b3e8

File tree

2 files changed

+74
-8
lines changed

2 files changed

+74
-8
lines changed

pkg/mapbuilder/mapbuilder.go

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -521,16 +521,32 @@ func evaluateJsonnet(imports string, snippets ...string) (string, error) {
521521
has_(o[ks[0]], ks[1:]);
522522
has_(o, std.split(f, '.')),
523523
RecurseReplace(any, from, to)::
524+
local apply_(maybeFunc, current) = if std.isFunction(maybeFunc) then maybeFunc(current) else maybeFunc;
525+
local is_match_(maybeFunc, current) = if std.isFunction(maybeFunc) then maybeFunc(current) else maybeFunc == current;
524526
local recurseReplace_(any, from, to) = (
525527
{
526-
object: function(x) { [k]: recurseReplace_(x[k], from, to) for k in std.objectFields(x) },
527-
array: function(x) [recurseReplace_(e, from, to) for e in x],
528-
string: function(x) std.native('ReplacePattern')(x, from, to),
529-
#string: function(x) std.strReplace(x, from, to),
530-
number: function(x) x,
531-
boolean: function(x) x,
532-
'function': function(x) x,
533-
'null': function(x) x,
528+
object: function(x) { [k]: recurseReplace_(x[k], from, to) for k in std.objectFields(x) },
529+
array: function(x) [recurseReplace_(e, from, to) for e in x],
530+
string: function(x) std.native('ReplacePattern')(x, from, to),
531+
number: function(x) if is_match_(from, x) then apply_(to, x) else x,
532+
boolean: function(x) if is_match_(from, x) then apply_(to, x) else x,
533+
'function': function(x) if is_match_(from, x) then apply_(to, x) else x,
534+
'null': function(x) if is_match_(from, x) then apply_(to, x) else x,
535+
}[std.type(any)](any)
536+
);
537+
recurseReplace_(any, from, to),
538+
Recurse(any, from, to)::
539+
local apply_(maybeFunc, current) = if std.isFunction(maybeFunc) then maybeFunc(current) else maybeFunc;
540+
local is_match_(maybeFunc, current) = if std.isFunction(maybeFunc) then maybeFunc(current) else maybeFunc == current;
541+
local recurseReplace_(any, from, to) = (
542+
{
543+
object: function(x) { [k]: recurseReplace_(x[k], from, to) for k in std.objectFields(x) },
544+
array: function(x) [recurseReplace_(e, from, to) for e in x],
545+
string: function(x) if is_match_(from, x) then apply_(to, x) else x,
546+
number: function(x) if is_match_(from, x) then apply_(to, x) else x,
547+
boolean: function(x) if is_match_(from, x) then apply_(to, x) else x,
548+
'function': function(x) if is_match_(from, x) then apply_(to, x) else x,
549+
'null': function(x) if is_match_(from, x) then apply_(to, x) else x,
534550
}[std.type(any)](any)
535551
);
536552
recurseReplace_(any, from, to),

tests/manual/template/template_replace.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,53 @@ tests:
1616
}
1717
}
1818
}
19+
20+
RecurseReplace replaces null values:
21+
command: |
22+
c8y template execute --template '{"value":{"item":null}}' |
23+
c8y template execute --template "_.RecurseReplace(input.value, null, 0)" -o json -c=false
24+
stdout:
25+
exactly: |
26+
{
27+
"value": {
28+
"item": 0
29+
}
30+
}
31+
32+
RecurseReplace replaces boolean values:
33+
command: |
34+
c8y template execute --template '{"value":{"item":false}}' |
35+
c8y template execute --template "_.RecurseReplace(input.value, false, true)" -o json -c=false
36+
stdout:
37+
exactly: |
38+
{
39+
"value": {
40+
"item": true
41+
}
42+
}
43+
44+
Recurse object and replace values matching a function:
45+
command: |
46+
c8y template execute --template '{"value":{"item":false,"item2":2}}' |
47+
c8y template execute --template "_.Recurse(input.value, std.isBoolean, function(x) if x == true then 1 else 0)" -o json -c=false
48+
stdout:
49+
exactly: |
50+
{
51+
"value": {
52+
"item": 0,
53+
"item2": 2
54+
}
55+
}
56+
57+
Recurse object and add 1 to all numbers:
58+
command: |
59+
c8y template execute --template '{"value":{"item":false,"item2":2}}' |
60+
c8y template execute --template "_.Recurse(input.value, std.isNumber, function(x) x + 1)" -o json -c=false
61+
stdout:
62+
exactly: |
63+
{
64+
"value": {
65+
"item": false,
66+
"item2": 3
67+
}
68+
}

0 commit comments

Comments
 (0)