rebase: bump k8s.io/kubernetes from 1.26.2 to 1.27.2

Bumps [k8s.io/kubernetes](https://github.com/kubernetes/kubernetes) from 1.26.2 to 1.27.2.
- [Release notes](https://github.com/kubernetes/kubernetes/releases)
- [Commits](https://github.com/kubernetes/kubernetes/compare/v1.26.2...v1.27.2)

---
updated-dependencies:
- dependency-name: k8s.io/kubernetes
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot]
2023-05-29 21:03:29 +00:00
committed by mergify[bot]
parent 0e79135419
commit 07b05616a0
1072 changed files with 208716 additions and 198880 deletions

36
vendor/github.com/google/cel-go/ext/BUILD.bazel generated vendored Normal file
View File

@ -0,0 +1,36 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
package(
licenses = ["notice"], # Apache 2.0
)
go_library(
name = "go_default_library",
srcs = [
"encoders.go",
"guards.go",
"strings.go",
],
importpath = "github.com/google/cel-go/ext",
visibility = ["//visibility:public"],
deps = [
"//cel:go_default_library",
"//common/types:go_default_library",
"//common/types/ref:go_default_library",
],
)
go_test(
name = "go_default_test",
size = "small",
srcs = [
"encoders_test.go",
"strings_test.go",
],
embed = [
":go_default_library",
],
deps = [
"//cel:go_default_library",
],
)

194
vendor/github.com/google/cel-go/ext/README.md generated vendored Normal file
View File

@ -0,0 +1,194 @@
# Extensions
CEL extensions are a related set of constants, functions, macros, or other
features which may not be covered by the core CEL spec.
## Encoders
Encoding utilies for marshalling data into standardized representations.
### Base64.Decode
Decodes base64-encoded string to bytes.
This function will return an error if the string input is not
base64-encoded.
base64.decode(<string>) -> <bytes>
Examples:
base64.decode('aGVsbG8=') // return b'hello'
base64.decode('aGVsbG8') // error
### Base64.Encode
Encodes bytes to a base64-encoded string.
base64.encode(<bytes>) -> <string>
Example:
base64.encode(b'hello') // return 'aGVsbG8='
## Strings
Extended functions for string manipulation. As a general note, all indices are
zero-based.
### CharAt
Returns the character at the given position. If the position is negative, or
greater than the length of the string, the function will produce an error:
<string>.charAt(<int>) -> <string>
Examples:
'hello'.charAt(4) // return 'o'
'hello'.charAt(5) // return ''
'hello'.charAt(-1) // error
### IndexOf
Returns the integer index of the first occurrence of the search string. If the
search string is not found the function returns -1.
The function also accepts an optional position from which to begin the
substring search. If the substring is the empty string, the index where the
search starts is returned (zero or custom).
<string>.indexOf(<string>) -> <int>
<string>.indexOf(<string>, <int>) -> <int>
Examples:
'hello mellow'.indexOf('') // returns 0
'hello mellow'.indexOf('ello') // returns 1
'hello mellow'.indexOf('jello') // returns -1
'hello mellow'.indexOf('', 2) // returns 2
'hello mellow'.indexOf('ello', 2) // returns 7
'hello mellow'.indexOf('ello', 20) // error
### LastIndexOf
Returns the integer index of the last occurrence of the search string. If the
search string is not found the function returns -1.
The function also accepts an optional position which represents the last index
to be considered as the beginning of the substring match. If the substring is
the empty string, the index where the search starts is returned (string length
or custom).
<string>.lastIndexOf(<string>) -> <int>
<string>.lastIndexOf(<string>, <int>) -> <int>
Examples:
'hello mellow'.lastIndexOf('') // returns 12
'hello mellow'.lastIndexOf('ello') // returns 7
'hello mellow'.lastIndexOf('jello') // returns -1
'hello mellow'.lastIndexOf('ello', 6) // returns 1
'hello mellow'.lastIndexOf('ello', -1) // error
### LowerAscii
Returns a new string where all ASCII characters are lower-cased.
This function does not perform Unicode case-mapping for characters outside the
ASCII range.
<string>.lowerAscii() -> <string>
Examples:
'TacoCat'.lowerAscii() // returns 'tacocat'
'TacoCÆt Xii'.lowerAscii() // returns 'tacocÆt xii'
### Replace
Returns a new string based on the target, which replaces the occurrences of a
search string with a replacement string if present. The function accepts an
optional limit on the number of substring replacements to be made.
When the replacement limit is 0, the result is the original string. When the
limit is a negative number, the function behaves the same as replace all.
<string>.replace(<string>, <string>) -> <string>
<string>.replace(<string>, <string>, <int>) -> <string>
Examples:
'hello hello'.replace('he', 'we') // returns 'wello wello'
'hello hello'.replace('he', 'we', -1) // returns 'wello wello'
'hello hello'.replace('he', 'we', 1) // returns 'wello hello'
'hello hello'.replace('he', 'we', 0) // returns 'hello hello'
### Split
Returns a list of strings split from the input by the given separator. The
function accepts an optional argument specifying a limit on the number of
substrings produced by the split.
When the split limit is 0, the result is an empty list. When the limit is 1,
the result is the target string to split. When the limit is a negative
number, the function behaves the same as split all.
<string>.split(<string>) -> <list<string>>
<string>.split(<string>, <int>) -> <list<string>>
Examples:
'hello hello hello'.split(' ') // returns ['hello', 'hello', 'hello']
'hello hello hello'.split(' ', 0) // returns []
'hello hello hello'.split(' ', 1) // returns ['hello hello hello']
'hello hello hello'.split(' ', 2) // returns ['hello', 'hello hello']
'hello hello hello'.split(' ', -1) // returns ['hello', 'hello', 'hello']
### Substring
Returns the substring given a numeric range corresponding to character
positions. Optionally may omit the trailing range for a substring from a given
character position until the end of a string.
Character offsets are 0-based with an inclusive start range and exclusive end
range. It is an error to specify an end range that is lower than the start
range, or for either the start or end index to be negative or exceed the string
length.
<string>.substring(<int>) -> <string>
<string>.substring(<int>, <int>) -> <string>
Examples:
'tacocat'.substring(4) // returns 'cat'
'tacocat'.substring(0, 4) // returns 'taco'
'tacocat'.substring(-1) // error
'tacocat'.substring(2, 1) // error
### Trim
Returns a new string which removes the leading and trailing whitespace in the
target string. The trim function uses the Unicode definition of whitespace
which does not include the zero-width spaces. See:
https://en.wikipedia.org/wiki/Whitespace_character#Unicode
<string>.trim() -> <string>
Examples:
' \ttrim\n '.trim() // returns 'trim'
### UpperAscii
Returns a new string where all ASCII characters are upper-cased.
This function does not perform Unicode case-mapping for characters outside the
ASCII range.
<string>.upperAscii() -> <string>
Examples:
'TacoCat'.upperAscii() // returns 'TACOCAT'
'TacoCÆt Xii'.upperAscii() // returns 'TACOCÆT XII'

88
vendor/github.com/google/cel-go/ext/encoders.go generated vendored Normal file
View File

@ -0,0 +1,88 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package ext
import (
"encoding/base64"
"reflect"
"github.com/google/cel-go/cel"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
)
// Encoders returns a cel.EnvOption to configure extended functions for string, byte, and object
// encodings.
//
// Base64.Decode
//
// Decodes base64-encoded string to bytes.
//
// This function will return an error if the string input is not base64-encoded.
//
// base64.decode(<string>) -> <bytes>
//
// Examples:
//
// base64.decode('aGVsbG8=') // return b'hello'
// base64.decode('aGVsbG8') // error
//
// Base64.Encode
//
// Encodes bytes to a base64-encoded string.
//
// base64.encode(<bytes>) -> <string>
//
// Examples:
//
// base64.encode(b'hello') // return b'aGVsbG8='
func Encoders() cel.EnvOption {
return cel.Lib(encoderLib{})
}
type encoderLib struct{}
func (encoderLib) CompileOptions() []cel.EnvOption {
return []cel.EnvOption{
cel.Function("base64.decode",
cel.Overload("base64_decode_string", []*cel.Type{cel.StringType}, cel.BytesType,
cel.UnaryBinding(func(str ref.Val) ref.Val {
s := str.(types.String)
return bytesOrError(base64DecodeString(string(s)))
}))),
cel.Function("base64.encode",
cel.Overload("base64_encode_bytes", []*cel.Type{cel.BytesType}, cel.StringType,
cel.UnaryBinding(func(bytes ref.Val) ref.Val {
b := bytes.(types.Bytes)
return stringOrError(base64EncodeBytes([]byte(b)))
}))),
}
}
func (encoderLib) ProgramOptions() []cel.ProgramOption {
return []cel.ProgramOption{}
}
func base64DecodeString(str string) ([]byte, error) {
return base64.StdEncoding.DecodeString(str)
}
func base64EncodeBytes(bytes []byte) (string, error) {
return base64.StdEncoding.EncodeToString(bytes), nil
}
var (
bytesListType = reflect.TypeOf([]byte{})
)

50
vendor/github.com/google/cel-go/ext/guards.go generated vendored Normal file
View File

@ -0,0 +1,50 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package ext
import (
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
)
// function invocation guards for common call signatures within extension functions.
func intOrError(i int64, err error) ref.Val {
if err != nil {
return types.NewErr(err.Error())
}
return types.Int(i)
}
func bytesOrError(bytes []byte, err error) ref.Val {
if err != nil {
return types.NewErr(err.Error())
}
return types.Bytes(bytes)
}
func stringOrError(str string, err error) ref.Val {
if err != nil {
return types.NewErr(err.Error())
}
return types.String(str)
}
func listStringOrError(strs []string, err error) ref.Val {
if err != nil {
return types.NewErr(err.Error())
}
return types.DefaultTypeAdapter.NativeToValue(strs)
}

483
vendor/github.com/google/cel-go/ext/strings.go generated vendored Normal file
View File

@ -0,0 +1,483 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package ext contains CEL extension libraries where each library defines a related set of
// constants, functions, macros, or other configuration settings which may not be covered by
// the core CEL spec.
package ext
import (
"fmt"
"reflect"
"strings"
"unicode"
"github.com/google/cel-go/cel"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
)
// Strings returns a cel.EnvOption to configure extended functions for string manipulation.
// As a general note, all indices are zero-based.
//
// CharAt
//
// Returns the character at the given position. If the position is negative, or greater than
// the length of the string, the function will produce an error:
//
// <string>.charAt(<int>) -> <string>
//
// Examples:
//
// 'hello'.charAt(4) // return 'o'
// 'hello'.charAt(5) // return ''
// 'hello'.charAt(-1) // error
//
// IndexOf
//
// Returns the integer index of the first occurrence of the search string. If the search string is
// not found the function returns -1.
//
// The function also accepts an optional position from which to begin the substring search. If the
// substring is the empty string, the index where the search starts is returned (zero or custom).
//
// <string>.indexOf(<string>) -> <int>
// <string>.indexOf(<string>, <int>) -> <int>
//
// Examples:
//
// 'hello mellow'.indexOf('') // returns 0
// 'hello mellow'.indexOf('ello') // returns 1
// 'hello mellow'.indexOf('jello') // returns -1
// 'hello mellow'.indexOf('', 2) // returns 2
// 'hello mellow'.indexOf('ello', 2) // returns 7
// 'hello mellow'.indexOf('ello', 20) // error
//
// Join
//
// Returns a new string where the elements of string list are concatenated.
//
// The function also accepts an optional separator which is placed between elements in the resulting string.
//
// <list<string>>.join() -> <string>
// <list<string>>.join(<string>) -> <string>
//
// Examples:
//
// ['hello', 'mellow'].join() // returns 'hellomellow'
// ['hello', 'mellow'].join(' ') // returns 'hello mellow'
// [].join() // returns ''
// [].join('/') // returns ''
//
// LastIndexOf
//
// Returns the integer index at the start of the last occurrence of the search string. If the
// search string is not found the function returns -1.
//
// The function also accepts an optional position which represents the last index to be
// considered as the beginning of the substring match. If the substring is the empty string,
// the index where the search starts is returned (string length or custom).
//
// <string>.lastIndexOf(<string>) -> <int>
// <string>.lastIndexOf(<string>, <int>) -> <int>
//
// Examples:
//
// 'hello mellow'.lastIndexOf('') // returns 12
// 'hello mellow'.lastIndexOf('ello') // returns 7
// 'hello mellow'.lastIndexOf('jello') // returns -1
// 'hello mellow'.lastIndexOf('ello', 6) // returns 1
// 'hello mellow'.lastIndexOf('ello', -1) // error
//
// LowerAscii
//
// Returns a new string where all ASCII characters are lower-cased.
//
// This function does not perform Unicode case-mapping for characters outside the ASCII range.
//
// <string>.lowerAscii() -> <string>
//
// Examples:
//
// 'TacoCat'.lowerAscii() // returns 'tacocat'
// 'TacoCÆt Xii'.lowerAscii() // returns 'tacocÆt xii'
//
// Replace
//
// Returns a new string based on the target, which replaces the occurrences of a search string
// with a replacement string if present. The function accepts an optional limit on the number of
// substring replacements to be made.
//
// When the replacement limit is 0, the result is the original string. When the limit is a negative
// number, the function behaves the same as replace all.
//
// <string>.replace(<string>, <string>) -> <string>
// <string>.replace(<string>, <string>, <int>) -> <string>
//
// Examples:
//
// 'hello hello'.replace('he', 'we') // returns 'wello wello'
// 'hello hello'.replace('he', 'we', -1) // returns 'wello wello'
// 'hello hello'.replace('he', 'we', 1) // returns 'wello hello'
// 'hello hello'.replace('he', 'we', 0) // returns 'hello hello'
//
// Split
//
// Returns a list of strings split from the input by the given separator. The function accepts
// an optional argument specifying a limit on the number of substrings produced by the split.
//
// When the split limit is 0, the result is an empty list. When the limit is 1, the result is the
// target string to split. When the limit is a negative number, the function behaves the same as
// split all.
//
// <string>.split(<string>) -> <list<string>>
// <string>.split(<string>, <int>) -> <list<string>>
//
// Examples:
//
// 'hello hello hello'.split(' ') // returns ['hello', 'hello', 'hello']
// 'hello hello hello'.split(' ', 0) // returns []
// 'hello hello hello'.split(' ', 1) // returns ['hello hello hello']
// 'hello hello hello'.split(' ', 2) // returns ['hello', 'hello hello']
// 'hello hello hello'.split(' ', -1) // returns ['hello', 'hello', 'hello']
//
// Substring
//
// Returns the substring given a numeric range corresponding to character positions. Optionally
// may omit the trailing range for a substring from a given character position until the end of
// a string.
//
// Character offsets are 0-based with an inclusive start range and exclusive end range. It is an
// error to specify an end range that is lower than the start range, or for either the start or end
// index to be negative or exceed the string length.
//
// <string>.substring(<int>) -> <string>
// <string>.substring(<int>, <int>) -> <string>
//
// Examples:
//
// 'tacocat'.substring(4) // returns 'cat'
// 'tacocat'.substring(0, 4) // returns 'taco'
// 'tacocat'.substring(-1) // error
// 'tacocat'.substring(2, 1) // error
//
// Trim
//
// Returns a new string which removes the leading and trailing whitespace in the target string.
// The trim function uses the Unicode definition of whitespace which does not include the
// zero-width spaces. See: https://en.wikipedia.org/wiki/Whitespace_character#Unicode
//
// <string>.trim() -> <string>
//
// Examples:
//
// ' \ttrim\n '.trim() // returns 'trim'
//
// UpperAscii
//
// Returns a new string where all ASCII characters are upper-cased.
//
// This function does not perform Unicode case-mapping for characters outside the ASCII range.
//
// <string>.upperAscii() -> <string>
//
// Examples:
//
// 'TacoCat'.upperAscii() // returns 'TACOCAT'
// 'TacoCÆt Xii'.upperAscii() // returns 'TACOCÆT XII'
func Strings() cel.EnvOption {
return cel.Lib(stringLib{})
}
type stringLib struct{}
func (stringLib) CompileOptions() []cel.EnvOption {
return []cel.EnvOption{
cel.Function("charAt",
cel.MemberOverload("string_char_at_int", []*cel.Type{cel.StringType, cel.IntType}, cel.StringType,
cel.BinaryBinding(func(str, ind ref.Val) ref.Val {
s := str.(types.String)
i := ind.(types.Int)
return stringOrError(charAt(string(s), int64(i)))
}))),
cel.Function("indexOf",
cel.MemberOverload("string_index_of_string", []*cel.Type{cel.StringType, cel.StringType}, cel.IntType,
cel.BinaryBinding(func(str, substr ref.Val) ref.Val {
s := str.(types.String)
sub := substr.(types.String)
return intOrError(indexOf(string(s), string(sub)))
})),
cel.MemberOverload("string_index_of_string_int", []*cel.Type{cel.StringType, cel.StringType, cel.IntType}, cel.IntType,
cel.FunctionBinding(func(args ...ref.Val) ref.Val {
s := args[0].(types.String)
sub := args[1].(types.String)
offset := args[2].(types.Int)
return intOrError(indexOfOffset(string(s), string(sub), int64(offset)))
}))),
cel.Function("lastIndexOf",
cel.MemberOverload("string_last_index_of_string", []*cel.Type{cel.StringType, cel.StringType}, cel.IntType,
cel.BinaryBinding(func(str, substr ref.Val) ref.Val {
s := str.(types.String)
sub := substr.(types.String)
return intOrError(lastIndexOf(string(s), string(sub)))
})),
cel.MemberOverload("string_last_index_of_string_int", []*cel.Type{cel.StringType, cel.StringType, cel.IntType}, cel.IntType,
cel.FunctionBinding(func(args ...ref.Val) ref.Val {
s := args[0].(types.String)
sub := args[1].(types.String)
offset := args[2].(types.Int)
return intOrError(lastIndexOfOffset(string(s), string(sub), int64(offset)))
}))),
cel.Function("lowerAscii",
cel.MemberOverload("string_lower_ascii", []*cel.Type{cel.StringType}, cel.StringType,
cel.UnaryBinding(func(str ref.Val) ref.Val {
s := str.(types.String)
return stringOrError(lowerASCII(string(s)))
}))),
cel.Function("replace",
cel.MemberOverload(
"string_replace_string_string", []*cel.Type{cel.StringType, cel.StringType, cel.StringType}, cel.StringType,
cel.FunctionBinding(func(args ...ref.Val) ref.Val {
str := args[0].(types.String)
old := args[1].(types.String)
new := args[2].(types.String)
return stringOrError(replace(string(str), string(old), string(new)))
})),
cel.MemberOverload(
"string_replace_string_string_int", []*cel.Type{cel.StringType, cel.StringType, cel.StringType, cel.IntType}, cel.StringType,
cel.FunctionBinding(func(args ...ref.Val) ref.Val {
str := args[0].(types.String)
old := args[1].(types.String)
new := args[2].(types.String)
n := args[3].(types.Int)
return stringOrError(replaceN(string(str), string(old), string(new), int64(n)))
}))),
cel.Function("split",
cel.MemberOverload("string_split_string", []*cel.Type{cel.StringType, cel.StringType}, cel.ListType(cel.StringType),
cel.BinaryBinding(func(str, separator ref.Val) ref.Val {
s := str.(types.String)
sep := separator.(types.String)
return listStringOrError(split(string(s), string(sep)))
})),
cel.MemberOverload("string_split_string_int", []*cel.Type{cel.StringType, cel.StringType, cel.IntType}, cel.ListType(cel.StringType),
cel.FunctionBinding(func(args ...ref.Val) ref.Val {
s := args[0].(types.String)
sep := args[1].(types.String)
n := args[2].(types.Int)
return listStringOrError(splitN(string(s), string(sep), int64(n)))
}))),
cel.Function("substring",
cel.MemberOverload("string_substring_int", []*cel.Type{cel.StringType, cel.IntType}, cel.StringType,
cel.BinaryBinding(func(str, offset ref.Val) ref.Val {
s := str.(types.String)
off := offset.(types.Int)
return stringOrError(substr(string(s), int64(off)))
})),
cel.MemberOverload("string_substring_int_int", []*cel.Type{cel.StringType, cel.IntType, cel.IntType}, cel.StringType,
cel.FunctionBinding(func(args ...ref.Val) ref.Val {
s := args[0].(types.String)
start := args[1].(types.Int)
end := args[2].(types.Int)
return stringOrError(substrRange(string(s), int64(start), int64(end)))
}))),
cel.Function("trim",
cel.MemberOverload("string_trim", []*cel.Type{cel.StringType}, cel.StringType,
cel.UnaryBinding(func(str ref.Val) ref.Val {
s := str.(types.String)
return stringOrError(trimSpace(string(s)))
}))),
cel.Function("upperAscii",
cel.MemberOverload("string_upper_ascii", []*cel.Type{cel.StringType}, cel.StringType,
cel.UnaryBinding(func(str ref.Val) ref.Val {
s := str.(types.String)
return stringOrError(upperASCII(string(s)))
}))),
cel.Function("join",
cel.MemberOverload("list_join", []*cel.Type{cel.ListType(cel.StringType)}, cel.StringType,
cel.UnaryBinding(func(list ref.Val) ref.Val {
l, err := list.ConvertToNative(stringListType)
if err != nil {
return types.NewErr(err.Error())
}
return stringOrError(join(l.([]string)))
})),
cel.MemberOverload("list_join_string", []*cel.Type{cel.ListType(cel.StringType), cel.StringType}, cel.StringType,
cel.BinaryBinding(func(list, delim ref.Val) ref.Val {
l, err := list.ConvertToNative(stringListType)
if err != nil {
return types.NewErr(err.Error())
}
d := delim.(types.String)
return stringOrError(joinSeparator(l.([]string), string(d)))
}))),
}
}
func (stringLib) ProgramOptions() []cel.ProgramOption {
return []cel.ProgramOption{}
}
func charAt(str string, ind int64) (string, error) {
i := int(ind)
runes := []rune(str)
if i < 0 || i > len(runes) {
return "", fmt.Errorf("index out of range: %d", ind)
}
if i == len(runes) {
return "", nil
}
return string(runes[i]), nil
}
func indexOf(str, substr string) (int64, error) {
return indexOfOffset(str, substr, int64(0))
}
func indexOfOffset(str, substr string, offset int64) (int64, error) {
if substr == "" {
return offset, nil
}
off := int(offset)
runes := []rune(str)
subrunes := []rune(substr)
if off < 0 || off >= len(runes) {
return -1, fmt.Errorf("index out of range: %d", off)
}
for i := off; i < len(runes)-(len(subrunes)-1); i++ {
found := true
for j := 0; j < len(subrunes); j++ {
if runes[i+j] != subrunes[j] {
found = false
break
}
}
if found {
return int64(i), nil
}
}
return -1, nil
}
func lastIndexOf(str, substr string) (int64, error) {
runes := []rune(str)
if substr == "" {
return int64(len(runes)), nil
}
return lastIndexOfOffset(str, substr, int64(len(runes)-1))
}
func lastIndexOfOffset(str, substr string, offset int64) (int64, error) {
if substr == "" {
return offset, nil
}
off := int(offset)
runes := []rune(str)
subrunes := []rune(substr)
if off < 0 || off >= len(runes) {
return -1, fmt.Errorf("index out of range: %d", off)
}
if off > len(runes)-len(subrunes) {
off = len(runes) - len(subrunes)
}
for i := off; i >= 0; i-- {
found := true
for j := 0; j < len(subrunes); j++ {
if runes[i+j] != subrunes[j] {
found = false
break
}
}
if found {
return int64(i), nil
}
}
return -1, nil
}
func lowerASCII(str string) (string, error) {
runes := []rune(str)
for i, r := range runes {
if r <= unicode.MaxASCII {
r = unicode.ToLower(r)
runes[i] = r
}
}
return string(runes), nil
}
func replace(str, old, new string) (string, error) {
return strings.ReplaceAll(str, old, new), nil
}
func replaceN(str, old, new string, n int64) (string, error) {
return strings.Replace(str, old, new, int(n)), nil
}
func split(str, sep string) ([]string, error) {
return strings.Split(str, sep), nil
}
func splitN(str, sep string, n int64) ([]string, error) {
return strings.SplitN(str, sep, int(n)), nil
}
func substr(str string, start int64) (string, error) {
runes := []rune(str)
if int(start) < 0 || int(start) > len(runes) {
return "", fmt.Errorf("index out of range: %d", start)
}
return string(runes[start:]), nil
}
func substrRange(str string, start, end int64) (string, error) {
runes := []rune(str)
l := len(runes)
if start > end {
return "", fmt.Errorf("invalid substring range. start: %d, end: %d", start, end)
}
if int(start) < 0 || int(start) > l {
return "", fmt.Errorf("index out of range: %d", start)
}
if int(end) < 0 || int(end) > l {
return "", fmt.Errorf("index out of range: %d", end)
}
return string(runes[int(start):int(end)]), nil
}
func trimSpace(str string) (string, error) {
return strings.TrimSpace(str), nil
}
func upperASCII(str string) (string, error) {
runes := []rune(str)
for i, r := range runes {
if r <= unicode.MaxASCII {
r = unicode.ToUpper(r)
runes[i] = r
}
}
return string(runes), nil
}
func joinSeparator(strs []string, separator string) (string, error) {
return strings.Join(strs, separator), nil
}
func join(strs []string) (string, error) {
return strings.Join(strs, ""), nil
}
var (
stringListType = reflect.TypeOf([]string{})
)