Skip to content

Commit 8528221

Browse files
committed
feat: implement std.match as standard function
1 parent fed90cd commit 8528221

File tree

8 files changed

+47
-4
lines changed

8 files changed

+47
-4
lines changed

builtins.go

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"io"
3030
"math"
3131
"reflect"
32+
"regexp"
3233
"sort"
3334
"strconv"
3435
"strings"
@@ -259,6 +260,29 @@ func builtinTrace(i *interpreter, x value, y value) (value, error) {
259260
return y, nil
260261
}
261262

263+
func builtinMatch(i *interpreter, strv value, patv value) (value, error) {
264+
str, err := i.getString(strv)
265+
if err != nil {
266+
return nil, err
267+
}
268+
pat, err := i.getString(patv)
269+
if err != nil {
270+
return nil, err
271+
}
272+
273+
r, err := regexp.Compile(pat.getGoString())
274+
if err != nil {
275+
return nil, i.Error(fmt.Sprintf("Pattern %s is not valid", pat.getGoString()))
276+
}
277+
278+
matches := []*cachedThunk{} // to return empty array
279+
for _, a := range r.FindAllString(str.getGoString(), -1) {
280+
matches = append(matches, readyThunk(makeValueString(a)))
281+
}
282+
283+
return makeValueArray(matches), nil
284+
}
285+
262286
// astMakeArrayElement wraps the function argument of std.makeArray so that
263287
// it can be embedded in cachedThunk without needing to execute it ahead of
264288
// time. It is equivalent to `local i = 42; func(i)`. It therefore has no
@@ -2097,12 +2121,12 @@ func builtinAvg(i *interpreter, arrv value) (value, error) {
20972121
if err != nil {
20982122
return nil, err
20992123
}
2100-
2124+
21012125
len := float64(arr.length())
21022126
if len == 0 {
21032127
return nil, i.Error("Cannot calculate average of an empty array.")
21042128
}
2105-
2129+
21062130
sumValue, err := builtinSum(i, arrv)
21072131
if err != nil {
21082132
return nil, err
@@ -2112,7 +2136,7 @@ func builtinAvg(i *interpreter, arrv value) (value, error) {
21122136
return nil, err
21132137
}
21142138

2115-
avg := sum.value/len
2139+
avg := sum.value / len
21162140
return makeValueNumber(avg), nil
21172141
}
21182142

@@ -2515,6 +2539,7 @@ var funcBuiltins = buildBuiltinMap([]builtin{
25152539
&unaryBuiltin{name: "isEmpty", function: builtinIsEmpty, params: ast.Identifiers{"str"}},
25162540
&binaryBuiltin{name: "equalsIgnoreCase", function: builtinEqualsIgnoreCase, params: ast.Identifiers{"str1", "str2"}},
25172541
&unaryBuiltin{name: "trim", function: builtinTrim, params: ast.Identifiers{"str"}},
2542+
&binaryBuiltin{name: "match", function: builtinMatch, params: ast.Identifiers{"str", "pat"}},
25182543
&unaryBuiltin{name: "base64Decode", function: builtinBase64Decode, params: ast.Identifiers{"str"}},
25192544
&unaryBuiltin{name: "base64DecodeBytes", function: builtinBase64DecodeBytes, params: ast.Identifiers{"str"}},
25202545
&unaryBuiltin{name: "parseInt", function: builtinParseInt, params: ast.Identifiers{"str"}},

linter/internal/types/stdlib.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ func prepareStdlib(g *typeGraph) {
9898
"isEmpty": g.newSimpleFuncType(boolType, "str"),
9999
"equalsIgnoreCase": g.newSimpleFuncType(boolType, "str1", "str2"),
100100
"trim": g.newSimpleFuncType(stringType, "str"),
101+
"match": g.newSimpleFuncType(stringType, "str", "pat"),
101102
// TODO(sbarzowski) Fix when they match the documentation
102103
"escapeStringBash": g.newSimpleFuncType(stringType, "str_"),
103104
"escapeStringDollars": g.newSimpleFuncType(stringType, "str_"),
@@ -152,7 +153,7 @@ func prepareStdlib(g *typeGraph) {
152153
"minArray": g.newFuncType(anyArrayType, []ast.Parameter{required("arr"), optional("keyF")}),
153154
"maxArray": g.newFuncType(anyArrayType, []ast.Parameter{required("arr"), optional("keyF")}),
154155
"contains": g.newSimpleFuncType(boolType, "arr", "elem"),
155-
"avg": g.newSimpleFuncType(numberType, "arr"),
156+
"avg": g.newSimpleFuncType(numberType, "arr"),
156157
"all": g.newSimpleFuncType(boolArrayType, "arr"),
157158
"any": g.newSimpleFuncType(boolArrayType, "arr"),
158159
"remove": g.newSimpleFuncType(anyArrayType, "arr", "elem"),

testdata/builtinMatch.golden

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[
2+
"peach",
3+
"punch",
4+
"pinch"
5+
]

testdata/builtinMatch.jsonnet

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
std.match("peach punch pinch", "p([a-z]+)ch")

testdata/builtinMatch.linter.golden

Whitespace-only changes.

testdata/builtinMatch2.golden

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
RUNTIME ERROR: Pattern (a] is not valid
2+
-------------------------------------------------
3+
testdata/builtinMatch2:1:1-24 $
4+
5+
std.match("foo", "(a]")
6+
7+
-------------------------------------------------
8+
During evaluation
9+
10+

testdata/builtinMatch2.jsonnet

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
std.match("foo", "(a]")

testdata/builtinMatch2.linter.golden

Whitespace-only changes.

0 commit comments

Comments
 (0)