diff --git a/stdlib/std.jsonnet b/stdlib/std.jsonnet index 135d7a69c..b27da0872 100644 --- a/stdlib/std.jsonnet +++ b/stdlib/std.jsonnet @@ -98,6 +98,32 @@ limitations under the License. aux(str, delim, i2, arr, v + c) tailstrict; aux(str, c, 0, [], ""), + strReplace(str, from, to):: + assert std.type(str) == "string"; + assert std.type(from) == "string"; + assert std.type(to) == "string"; + assert from != "" : "'from' string must not be zero length."; + + // Cache for performance. + local str_len = std.length(str); + local from_len = std.length(from); + + // True if from is at str[i]. + local found_at(i) = str[i:i + from_len] == from; + + // Return the remainder of 'str' starting with 'start_index' where + // all occurrences of 'from' after 'curr_index' are replaced with 'to'. + local replace_after(start_index, curr_index, acc) = + if curr_index > str_len then + acc + str[start_index:curr_index] + else if found_at(curr_index) then + local new_index = curr_index + std.length(from); + replace_after(new_index, new_index, acc + str[start_index:curr_index] + to) + else + replace_after(start_index, curr_index + 1, acc); + + replace_after(0, 0, ""), + range(from, to):: std.makeArray(to - from + 1, function(i) i + from), diff --git a/test_suite/error.equality_function.jsonnet.golden b/test_suite/error.equality_function.jsonnet.golden index 34ef3a667..91e0559ff 100644 --- a/test_suite/error.equality_function.jsonnet.golden +++ b/test_suite/error.equality_function.jsonnet.golden @@ -1,3 +1,3 @@ RUNTIME ERROR: Cannot test equality of functions - std.jsonnet:1014:17-42 function + std.jsonnet:1040:17-42 function error.equality_function.jsonnet:17:1-33 diff --git a/test_suite/error.inside_equals_array.jsonnet.golden b/test_suite/error.inside_equals_array.jsonnet.golden index af627dde5..abfc719b8 100644 --- a/test_suite/error.inside_equals_array.jsonnet.golden +++ b/test_suite/error.inside_equals_array.jsonnet.golden @@ -1,7 +1,7 @@ RUNTIME ERROR: foobar error.inside_equals_array.jsonnet:18:18-32 thunk - std.jsonnet:994:41-45 thunk - std.jsonnet:994:33-45 function - std.jsonnet:994:33-45 function - std.jsonnet:997:29-45 function - std.jsonnet:998:21-33 + std.jsonnet:1020:41-45 thunk + std.jsonnet:1020:33-45 function + std.jsonnet:1020:33-45 function + std.jsonnet:1023:29-45 function + std.jsonnet:1024:21-33 diff --git a/test_suite/error.inside_equals_object.jsonnet.golden b/test_suite/error.inside_equals_object.jsonnet.golden index 1c4668bf5..62c5590f0 100644 --- a/test_suite/error.inside_equals_object.jsonnet.golden +++ b/test_suite/error.inside_equals_object.jsonnet.golden @@ -1,7 +1,7 @@ RUNTIME ERROR: foobar error.inside_equals_object.jsonnet:18:22-36 object - std.jsonnet:1008:62-66 thunk - std.jsonnet:1008:54-66 function - std.jsonnet:1008:54-66 function - std.jsonnet:1011:29-45 function - std.jsonnet:1012:21-33 + std.jsonnet:1034:62-66 thunk + std.jsonnet:1034:54-66 function + std.jsonnet:1034:54-66 function + std.jsonnet:1037:29-45 function + std.jsonnet:1038:21-33 diff --git a/test_suite/error.invariant.equality.jsonnet.golden b/test_suite/error.invariant.equality.jsonnet.golden index ba83fb45a..1c1c698e8 100644 --- a/test_suite/error.invariant.equality.jsonnet.golden +++ b/test_suite/error.invariant.equality.jsonnet.golden @@ -1,6 +1,6 @@ RUNTIME ERROR: Object assertion failed. error.invariant.equality.jsonnet:17:10-15 thunk - std.jsonnet:1008:54-58 thunk - std.jsonnet:1008:54-66 function - std.jsonnet:1008:54-66 function - std.jsonnet:1012:21-33 + std.jsonnet:1034:54-58 thunk + std.jsonnet:1034:54-66 function + std.jsonnet:1034:54-66 function + std.jsonnet:1038:21-33 diff --git a/test_suite/error.obj_assert.fail1.jsonnet.golden b/test_suite/error.obj_assert.fail1.jsonnet.golden index a7e98ff1a..738a75d4e 100644 --- a/test_suite/error.obj_assert.fail1.jsonnet.golden +++ b/test_suite/error.obj_assert.fail1.jsonnet.golden @@ -1,6 +1,6 @@ RUNTIME ERROR: Object assertion failed. error.obj_assert.fail1.jsonnet:20:23-29 thunk - std.jsonnet:1008:54-58 thunk - std.jsonnet:1008:54-66 function - std.jsonnet:1008:54-66 function - std.jsonnet:1012:21-33 + std.jsonnet:1034:54-58 thunk + std.jsonnet:1034:54-66 function + std.jsonnet:1034:54-66 function + std.jsonnet:1038:21-33 diff --git a/test_suite/error.obj_assert.fail2.jsonnet.golden b/test_suite/error.obj_assert.fail2.jsonnet.golden index ac3d47c5d..1c778023f 100644 --- a/test_suite/error.obj_assert.fail2.jsonnet.golden +++ b/test_suite/error.obj_assert.fail2.jsonnet.golden @@ -1,6 +1,6 @@ RUNTIME ERROR: foo was not equal to bar error.obj_assert.fail2.jsonnet:20:32-65 thunk - std.jsonnet:1008:54-58 thunk - std.jsonnet:1008:54-66 function - std.jsonnet:1008:54-66 function - std.jsonnet:1012:21-33 + std.jsonnet:1034:54-58 thunk + std.jsonnet:1034:54-66 function + std.jsonnet:1034:54-66 function + std.jsonnet:1038:21-33 diff --git a/test_suite/error.sanity.jsonnet.golden b/test_suite/error.sanity.jsonnet.golden index 806ec0a5c..be7659eb0 100644 --- a/test_suite/error.sanity.jsonnet.golden +++ b/test_suite/error.sanity.jsonnet.golden @@ -1,3 +1,3 @@ RUNTIME ERROR: Assertion failed. 1 != 2 - std.jsonnet:651:13-56 function + std.jsonnet:677:13-56 function error.sanity.jsonnet:17:1-22 diff --git a/test_suite/error.std_join_types1.jsonnet.golden b/test_suite/error.std_join_types1.jsonnet.golden index d6483506b..ddbb06e67 100644 --- a/test_suite/error.std_join_types1.jsonnet.golden +++ b/test_suite/error.std_join_types1.jsonnet.golden @@ -1,5 +1,5 @@ RUNTIME ERROR: expected string but arr[1] was array - std.jsonnet:167:17-95 function - std.jsonnet:169:17-57 function - std.jsonnet:175:13-34 function + std.jsonnet:193:17-95 function + std.jsonnet:195:17-57 function + std.jsonnet:201:13-34 function error.std_join_types1.jsonnet:17:1-26 diff --git a/test_suite/error.std_join_types2.jsonnet.golden b/test_suite/error.std_join_types2.jsonnet.golden index f47c11ba6..0616d62f0 100644 --- a/test_suite/error.std_join_types2.jsonnet.golden +++ b/test_suite/error.std_join_types2.jsonnet.golden @@ -1,4 +1,4 @@ RUNTIME ERROR: expected array but arr[0] was string - std.jsonnet:167:17-95 function - std.jsonnet:177:13-34 function + std.jsonnet:193:17-95 function + std.jsonnet:203:13-34 function error.std_join_types2.jsonnet:17:1-31 diff --git a/test_suite/stdlib.jsonnet b/test_suite/stdlib.jsonnet index 87c396e5c..bbbd6078b 100644 --- a/test_suite/stdlib.jsonnet +++ b/test_suite/stdlib.jsonnet @@ -159,6 +159,14 @@ std.assertEqual(std.char(97), "a") && std.assertEqual(std.codepoint("\u0000"), 0) && std.assertEqual(std.char(0), "\u0000") && +std.assertEqual(std.strReplace('A cat walked by', 'cat', 'dog'), 'A dog walked by') && +std.assertEqual(std.strReplace('cat', 'cat', 'dog'), 'dog') && +std.assertEqual(std.strReplace('', 'cat', ''), '') && +std.assertEqual(std.strReplace('xoxoxoxox', 'xoxox3xox', 'A'), 'xoxoxoxox') && +std.assertEqual(std.strReplace('xoxoxox3xox', 'xoxox3xox', 'A'), 'xoA') && +std.assertEqual(std.strReplace('A cat is a cat', 'cat', 'dog'), 'A dog is a dog') && +std.assertEqual(std.strReplace('wishyfishyisishy', 'ish', 'and'), 'wandyfandyisandy') && + std.assertEqual(std.map(function(x) x * x, []), []) && std.assertEqual(std.map(function(x) x * x, [1, 2, 3, 4]), [1, 4, 9, 16]) && std.assertEqual(std.map(function(x) x * x, std.filter(function(x) x > 5, std.range(1, 10))), [36, 49, 64, 81, 100]) &&