Skip to content

Commit

Permalink
feat: implement std.splitLimitR (#745)
Browse files Browse the repository at this point in the history
  • Loading branch information
itchyny committed Jun 9, 2024
1 parent e544339 commit fa70aa4
Show file tree
Hide file tree
Showing 22 changed files with 94 additions and 0 deletions.
42 changes: 42 additions & 0 deletions builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -1324,6 +1324,47 @@ func builtinSplitLimit(i *interpreter, strv, cv, maxSplitsV value) (value, error
return makeValueArray(res), nil
}

func builtinSplitLimitR(i *interpreter, strv, cv, maxSplitsV value) (value, error) {
str, err := i.getString(strv)
if err != nil {
return nil, err
}
c, err := i.getString(cv)
if err != nil {
return nil, err
}
maxSplits, err := i.getInt(maxSplitsV)
if err != nil {
return nil, err
}
if maxSplits < -1 {
return nil, i.Error(fmt.Sprintf("std.splitLimitR third parameter should be -1 or non-negative, got %v", maxSplits))
}
sStr := str.getGoString()
sC := c.getGoString()
if len(sC) < 1 {
return nil, i.Error(fmt.Sprintf("std.splitLimitR second parameter should have length 1 or greater, got %v", len(sC)))
}

count := strings.Count(sStr, sC)
if maxSplits > -1 && count > maxSplits {
count = maxSplits
}
strs := make([]string, count+1)
for i := count; i > 0; i-- {
index := strings.LastIndex(sStr, sC)
strs[i] = sStr[index+len(sC):]
sStr = sStr[:index]
}
strs[0] = sStr
res := make([]*cachedThunk, len(strs))
for i := range strs {
res[i] = readyThunk(makeValueString(strs[i]))
}

return makeValueArray(res), nil
}

func builtinStrReplace(i *interpreter, strv, fromv, tov value) (value, error) {
str, err := i.getString(strv)
if err != nil {
Expand Down Expand Up @@ -2511,6 +2552,7 @@ var funcBuiltins = buildBuiltinMap([]builtin{
&binaryBuiltin{name: "stripChars", function: builtinStripChars, params: ast.Identifiers{"str", "chars"}},
&ternaryBuiltin{name: "substr", function: builtinSubstr, params: ast.Identifiers{"str", "from", "len"}},
&ternaryBuiltin{name: "splitLimit", function: builtinSplitLimit, params: ast.Identifiers{"str", "c", "maxsplits"}},
&ternaryBuiltin{name: "splitLimitR", function: builtinSplitLimitR, params: ast.Identifiers{"str", "c", "maxsplits"}},
&ternaryBuiltin{name: "strReplace", function: builtinStrReplace, params: ast.Identifiers{"str", "from", "to"}},
&unaryBuiltin{name: "isEmpty", function: builtinIsEmpty, params: ast.Identifiers{"str"}},
&binaryBuiltin{name: "equalsIgnoreCase", function: builtinEqualsIgnoreCase, params: ast.Identifiers{"str1", "str2"}},
Expand Down
1 change: 1 addition & 0 deletions linter/internal/types/stdlib.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ func prepareStdlib(g *typeGraph) {
"rstripChars": g.newSimpleFuncType(stringType, "str", "chars"),
"split": g.newSimpleFuncType(arrayOfString, "str", "c"),
"splitLimit": g.newSimpleFuncType(arrayOfString, "str", "c", "maxsplits"),
"splitLimitR": g.newSimpleFuncType(arrayOfString, "str", "c", "maxsplits"),
"strReplace": g.newSimpleFuncType(stringType, "str", "from", "to"),
"asciiUpper": g.newSimpleFuncType(stringType, "str"),
"asciiLower": g.newSimpleFuncType(stringType, "str"),
Expand Down
5 changes: 5 additions & 0 deletions testdata/builtinSplitLimitR.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
"foo,bar",
"baz",
"qux"
]
1 change: 1 addition & 0 deletions testdata/builtinSplitLimitR.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
std.splitLimitR('foo,bar,baz,qux', ',', 2)
Empty file.
3 changes: 3 additions & 0 deletions testdata/builtinSplitLimitR2.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[
"foo,bar,baz,qux"
]
1 change: 1 addition & 0 deletions testdata/builtinSplitLimitR2.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
std.splitLimitR('foo,bar,baz,qux', ',', 0)
Empty file.
6 changes: 6 additions & 0 deletions testdata/builtinSplitLimitR3.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
"foo",
"bar",
"baz",
"qux"
]
1 change: 1 addition & 0 deletions testdata/builtinSplitLimitR3.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
std.splitLimitR('foo,bar,baz,qux', ',', -1)
Empty file.
6 changes: 6 additions & 0 deletions testdata/builtinSplitLimitR4.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
"foo",
"bar",
"baz",
"qux"
]
1 change: 1 addition & 0 deletions testdata/builtinSplitLimitR4.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
std.splitLimitR('foo,bar,baz,qux', ',', 4)
Empty file.
10 changes: 10 additions & 0 deletions testdata/builtinSplitLimitR5.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
RUNTIME ERROR: std.splitLimitR third parameter should be -1 or non-negative, got -2
-------------------------------------------------
testdata/builtinSplitLimitR5:1:1-44 $

std.splitLimitR('foo,bar,baz,qux', ',', -2)

-------------------------------------------------
During evaluation


1 change: 1 addition & 0 deletions testdata/builtinSplitLimitR5.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
std.splitLimitR('foo,bar,baz,qux', ',', -2)
Empty file.
10 changes: 10 additions & 0 deletions testdata/builtinSplitLimitR6.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
RUNTIME ERROR: std.splitLimitR second parameter should have length 1 or greater, got 0
-------------------------------------------------
testdata/builtinSplitLimitR6:1:1-43 $

std.splitLimitR('foo,bar,baz,qux', '', -1)

-------------------------------------------------
During evaluation


1 change: 1 addition & 0 deletions testdata/builtinSplitLimitR6.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
std.splitLimitR('foo,bar,baz,qux', '', -1)
Empty file.
4 changes: 4 additions & 0 deletions testdata/stdlib_smoke_test.golden
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,10 @@
"a",
"b,c"
],
"splitLimitR": [
"a,b",
"c"
],
"sqrt": 2.2360679774997898,
"startsWith": true,
"strReplace": "bba",
Expand Down
1 change: 1 addition & 0 deletions testdata/stdlib_smoke_test.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
rstripChars: std.rstripChars(str="aaabbbbcccc", chars="c"),
split: std.split(str="a,b,c", c=","),
splitLimit: std.splitLimit(str="a,b,c", c=",", maxsplits=1),
splitLimitR: std.splitLimitR(str="a,b,c", c=",", maxsplits=1),
strReplace: std.strReplace(str="aaa", from="aa", to="bb"),
asciiUpper: std.asciiUpper(str="Blah"),
asciiLower: std.asciiLower(str="Blah"),
Expand Down

0 comments on commit fa70aa4

Please sign in to comment.