rebase: bump the golang-dependencies group with 1 update

Bumps the golang-dependencies group with 1 update: [golang.org/x/crypto](https://github.com/golang/crypto).


Updates `golang.org/x/crypto` from 0.16.0 to 0.17.0
- [Commits](https://github.com/golang/crypto/compare/v0.16.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: golang-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot]
2023-12-18 20:31:00 +00:00
committed by mergify[bot]
parent 1ad79314f9
commit e5d9b68d36
398 changed files with 33924 additions and 10753 deletions

View File

@ -9,6 +9,7 @@ go_library(
srcs = [
"encoders.go",
"guards.go",
"lists.go",
"math.go",
"native.go",
"protos.go",
@ -19,8 +20,8 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//cel:go_default_library",
"//checker:go_default_library",
"//checker/decls:go_default_library",
"//common:go_default_library",
"//common/overloads:go_default_library",
"//common/types:go_default_library",
"//common/types/pb:go_default_library",
@ -41,6 +42,7 @@ go_test(
size = "small",
srcs = [
"encoders_test.go",
"lists_test.go",
"math_test.go",
"native_test.go",
"protos_test.go",
@ -53,7 +55,6 @@ go_test(
deps = [
"//cel:go_default_library",
"//checker:go_default_library",
"//common:go_default_library",
"//common/types:go_default_library",
"//common/types/ref:go_default_library",
"//common/types/traits:go_default_library",

View File

@ -149,6 +149,23 @@ Example:
proto.hasExt(msg, google.expr.proto2.test.int32_ext) // returns true || false
## Lists
Extended functions for list manipulation. As a general note, all indices are
zero-based.
### Slice
Returns a new sub-list using the indexes provided.
<list>.slice(<int>, <int>) -> <list>
Examples:
[1,2,3,4].slice(1, 3) // return [2, 3]
[1,2,3,4].slice(2, 4) // return [3 ,4]
## Sets
Sets provides set relationship tests.

View File

@ -16,7 +16,6 @@ package ext
import (
"github.com/google/cel-go/cel"
"github.com/google/cel-go/common"
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
)
@ -71,7 +70,7 @@ func (celBindings) ProgramOptions() []cel.ProgramOption {
return []cel.ProgramOption{}
}
func celBind(meh cel.MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
func celBind(meh cel.MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *cel.Error) {
if !macroTargetMatchesNamespace(celNamespace, target) {
return nil, nil
}
@ -81,10 +80,7 @@ func celBind(meh cel.MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr)
case *exprpb.Expr_IdentExpr:
varName = varIdent.GetIdentExpr().GetName()
default:
return nil, &common.Error{
Message: "cel.bind() variable names must be simple identifers",
Location: meh.OffsetLocation(varIdent.GetId()),
}
return nil, meh.NewError(varIdent.GetId(), "cel.bind() variable names must be simple identifiers")
}
varInit := args[1]
resultExpr := args[2]

View File

@ -16,7 +16,6 @@ package ext
import (
"encoding/base64"
"reflect"
"github.com/google/cel-go/cel"
"github.com/google/cel-go/common/types"
@ -86,7 +85,3 @@ func base64DecodeString(str string) ([]byte, error) {
func base64EncodeBytes(bytes []byte) (string, error) {
return base64.StdEncoding.EncodeToString(bytes), nil
}
var (
bytesListType = reflect.TypeOf([]byte{})
)

View File

@ -17,6 +17,7 @@ package ext
import (
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
)

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

@ -0,0 +1,94 @@
// Copyright 2023 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 (
"fmt"
"github.com/google/cel-go/cel"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
"github.com/google/cel-go/common/types/traits"
)
// Lists returns a cel.EnvOption to configure extended functions for list manipulation.
// As a general note, all indices are zero-based.
// # Slice
//
// Returns a new sub-list using the indexes provided.
//
// <list>.slice(<int>, <int>) -> <list>
//
// Examples:
//
// [1,2,3,4].slice(1, 3) // return [2, 3]
// [1,2,3,4].slice(2, 4) // return [3 ,4]
func Lists() cel.EnvOption {
return cel.Lib(listsLib{})
}
type listsLib struct{}
// LibraryName implements the SingletonLibrary interface method.
func (listsLib) LibraryName() string {
return "cel.lib.ext.lists"
}
// CompileOptions implements the Library interface method.
func (listsLib) CompileOptions() []cel.EnvOption {
listType := cel.ListType(cel.TypeParamType("T"))
return []cel.EnvOption{
cel.Function("slice",
cel.MemberOverload("list_slice",
[]*cel.Type{listType, cel.IntType, cel.IntType}, listType,
cel.FunctionBinding(func(args ...ref.Val) ref.Val {
list := args[0].(traits.Lister)
start := args[1].(types.Int)
end := args[2].(types.Int)
result, err := slice(list, start, end)
if err != nil {
return types.WrapErr(err)
}
return result
}),
),
),
}
}
// ProgramOptions implements the Library interface method.
func (listsLib) ProgramOptions() []cel.ProgramOption {
return []cel.ProgramOption{}
}
func slice(list traits.Lister, start, end types.Int) (ref.Val, error) {
listLength := list.Size().(types.Int)
if start < 0 || end < 0 {
return nil, fmt.Errorf("cannot slice(%d, %d), negative indexes not supported", start, end)
}
if start > end {
return nil, fmt.Errorf("cannot slice(%d, %d), start index must be less than or equal to end index", start, end)
}
if listLength < end {
return nil, fmt.Errorf("cannot slice(%d, %d), list is length %d", start, end, listLength)
}
var newList []ref.Val
for i := types.Int(start); i < end; i++ {
val := list.Get(i)
newList = append(newList, val)
}
return types.DefaultTypeAdapter.NativeToValue(newList), nil
}

View File

@ -19,10 +19,10 @@ import (
"strings"
"github.com/google/cel-go/cel"
"github.com/google/cel-go/common"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
"github.com/google/cel-go/common/types/traits"
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
)
@ -187,24 +187,18 @@ func (mathLib) ProgramOptions() []cel.ProgramOption {
return []cel.ProgramOption{}
}
func mathLeast(meh cel.MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
func mathLeast(meh cel.MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *cel.Error) {
if !macroTargetMatchesNamespace(mathNamespace, target) {
return nil, nil
}
switch len(args) {
case 0:
return nil, &common.Error{
Message: "math.least() requires at least one argument",
Location: meh.OffsetLocation(target.GetId()),
}
return nil, meh.NewError(target.GetId(), "math.least() requires at least one argument")
case 1:
if isListLiteralWithValidArgs(args[0]) || isValidArgType(args[0]) {
return meh.GlobalCall(minFunc, args[0]), nil
}
return nil, &common.Error{
Message: "math.least() invalid single argument value",
Location: meh.OffsetLocation(args[0].GetId()),
}
return nil, meh.NewError(args[0].GetId(), "math.least() invalid single argument value")
case 2:
err := checkInvalidArgs(meh, "math.least()", args)
if err != nil {
@ -220,24 +214,18 @@ func mathLeast(meh cel.MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr
}
}
func mathGreatest(meh cel.MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
func mathGreatest(meh cel.MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *cel.Error) {
if !macroTargetMatchesNamespace(mathNamespace, target) {
return nil, nil
}
switch len(args) {
case 0:
return nil, &common.Error{
Message: "math.greatest() requires at least one argument",
Location: meh.OffsetLocation(target.GetId()),
}
return nil, meh.NewError(target.GetId(), "math.greatest() requires at least one argument")
case 1:
if isListLiteralWithValidArgs(args[0]) || isValidArgType(args[0]) {
return meh.GlobalCall(maxFunc, args[0]), nil
}
return nil, &common.Error{
Message: "math.greatest() invalid single argument value",
Location: meh.OffsetLocation(args[0].GetId()),
}
return nil, meh.NewError(args[0].GetId(), "math.greatest() invalid single argument value")
case 2:
err := checkInvalidArgs(meh, "math.greatest()", args)
if err != nil {
@ -323,14 +311,11 @@ func maxList(numList ref.Val) ref.Val {
}
}
func checkInvalidArgs(meh cel.MacroExprHelper, funcName string, args []*exprpb.Expr) *common.Error {
func checkInvalidArgs(meh cel.MacroExprHelper, funcName string, args []*exprpb.Expr) *cel.Error {
for _, arg := range args {
err := checkInvalidArgLiteral(funcName, arg)
if err != nil {
return &common.Error{
Message: err.Error(),
Location: meh.OffsetLocation(arg.GetId()),
}
return meh.NewError(arg.GetId(), err.Error())
}
}
return nil

View File

@ -24,13 +24,11 @@ import (
"google.golang.org/protobuf/reflect/protoreflect"
"github.com/google/cel-go/cel"
"github.com/google/cel-go/checker/decls"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/pb"
"github.com/google/cel-go/common/types/ref"
"github.com/google/cel-go/common/types/traits"
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
structpb "google.golang.org/protobuf/types/known/structpb"
)
@ -81,7 +79,7 @@ var (
// the time that it is invoked.
func NativeTypes(refTypes ...any) cel.EnvOption {
return func(env *cel.Env) (*cel.Env, error) {
tp, err := newNativeTypeProvider(env.TypeAdapter(), env.TypeProvider(), refTypes...)
tp, err := newNativeTypeProvider(env.CELTypeAdapter(), env.CELTypeProvider(), refTypes...)
if err != nil {
return nil, err
}
@ -93,7 +91,7 @@ func NativeTypes(refTypes ...any) cel.EnvOption {
}
}
func newNativeTypeProvider(adapter ref.TypeAdapter, provider ref.TypeProvider, refTypes ...any) (*nativeTypeProvider, error) {
func newNativeTypeProvider(adapter types.Adapter, provider types.Provider, refTypes ...any) (*nativeTypeProvider, error) {
nativeTypes := make(map[string]*nativeType, len(refTypes))
for _, refType := range refTypes {
switch rt := refType.(type) {
@ -122,18 +120,18 @@ func newNativeTypeProvider(adapter ref.TypeAdapter, provider ref.TypeProvider, r
type nativeTypeProvider struct {
nativeTypes map[string]*nativeType
baseAdapter ref.TypeAdapter
baseProvider ref.TypeProvider
baseAdapter types.Adapter
baseProvider types.Provider
}
// EnumValue proxies to the ref.TypeProvider configured at the times the NativeTypes
// EnumValue proxies to the types.Provider configured at the times the NativeTypes
// option was configured.
func (tp *nativeTypeProvider) EnumValue(enumName string) ref.Val {
return tp.baseProvider.EnumValue(enumName)
}
// FindIdent looks up natives type instances by qualified identifier, and if not found
// proxies to the composed ref.TypeProvider.
// proxies to the composed types.Provider.
func (tp *nativeTypeProvider) FindIdent(typeName string) (ref.Val, bool) {
if t, found := tp.nativeTypes[typeName]; found {
return t, true
@ -141,32 +139,35 @@ func (tp *nativeTypeProvider) FindIdent(typeName string) (ref.Val, bool) {
return tp.baseProvider.FindIdent(typeName)
}
// FindType looks up CEL type-checker type definition by qualified identifier, and if not found
// proxies to the composed ref.TypeProvider.
func (tp *nativeTypeProvider) FindType(typeName string) (*exprpb.Type, bool) {
// FindStructType looks up the CEL type definition by qualified identifier, and if not found
// proxies to the composed types.Provider.
func (tp *nativeTypeProvider) FindStructType(typeName string) (*types.Type, bool) {
if _, found := tp.nativeTypes[typeName]; found {
return decls.NewTypeType(decls.NewObjectType(typeName)), true
return types.NewTypeTypeWithParam(types.NewObjectType(typeName)), true
}
return tp.baseProvider.FindType(typeName)
if celType, found := tp.baseProvider.FindStructType(typeName); found {
return celType, true
}
return tp.baseProvider.FindStructType(typeName)
}
// FindFieldType looks up a native type's field definition, and if the type name is not a native
// type then proxies to the composed ref.TypeProvider
func (tp *nativeTypeProvider) FindFieldType(typeName, fieldName string) (*ref.FieldType, bool) {
// FindStructFieldType looks up a native type's field definition, and if the type name is not a native
// type then proxies to the composed types.Provider
func (tp *nativeTypeProvider) FindStructFieldType(typeName, fieldName string) (*types.FieldType, bool) {
t, found := tp.nativeTypes[typeName]
if !found {
return tp.baseProvider.FindFieldType(typeName, fieldName)
return tp.baseProvider.FindStructFieldType(typeName, fieldName)
}
refField, isDefined := t.hasField(fieldName)
if !found || !isDefined {
return nil, false
}
exprType, ok := convertToExprType(refField.Type)
celType, ok := convertToCelType(refField.Type)
if !ok {
return nil, false
}
return &ref.FieldType{
Type: exprType,
return &types.FieldType{
Type: celType,
IsSet: func(obj any) bool {
refVal := reflect.Indirect(reflect.ValueOf(obj))
refField := refVal.FieldByName(fieldName)
@ -243,75 +244,74 @@ func (tp *nativeTypeProvider) NativeToValue(val any) ref.Val {
}
}
// convertToExprType converts the Golang reflect.Type to a protobuf exprpb.Type.
func convertToExprType(refType reflect.Type) (*exprpb.Type, bool) {
func convertToCelType(refType reflect.Type) (*cel.Type, bool) {
switch refType.Kind() {
case reflect.Bool:
return decls.Bool, true
return cel.BoolType, true
case reflect.Float32, reflect.Float64:
return decls.Double, true
return cel.DoubleType, true
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
if refType == durationType {
return decls.Duration, true
return cel.DurationType, true
}
return decls.Int, true
return cel.IntType, true
case reflect.String:
return decls.String, true
return cel.StringType, true
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return decls.Uint, true
return cel.UintType, true
case reflect.Array, reflect.Slice:
refElem := refType.Elem()
if refElem == reflect.TypeOf(byte(0)) {
return decls.Bytes, true
return cel.BytesType, true
}
elemType, ok := convertToExprType(refElem)
elemType, ok := convertToCelType(refElem)
if !ok {
return nil, false
}
return decls.NewListType(elemType), true
return cel.ListType(elemType), true
case reflect.Map:
keyType, ok := convertToExprType(refType.Key())
keyType, ok := convertToCelType(refType.Key())
if !ok {
return nil, false
}
// Ensure the key type is a int, bool, uint, string
elemType, ok := convertToExprType(refType.Elem())
elemType, ok := convertToCelType(refType.Elem())
if !ok {
return nil, false
}
return decls.NewMapType(keyType, elemType), true
return cel.MapType(keyType, elemType), true
case reflect.Struct:
if refType == timestampType {
return decls.Timestamp, true
return cel.TimestampType, true
}
return decls.NewObjectType(
return cel.ObjectType(
fmt.Sprintf("%s.%s", simplePkgAlias(refType.PkgPath()), refType.Name()),
), true
case reflect.Pointer:
if refType.Implements(pbMsgInterfaceType) {
pbMsg := reflect.New(refType.Elem()).Interface().(protoreflect.ProtoMessage)
return decls.NewObjectType(string(pbMsg.ProtoReflect().Descriptor().FullName())), true
return cel.ObjectType(string(pbMsg.ProtoReflect().Descriptor().FullName())), true
}
return convertToExprType(refType.Elem())
return convertToCelType(refType.Elem())
}
return nil, false
}
func newNativeObject(adapter ref.TypeAdapter, val any, refValue reflect.Value) ref.Val {
func newNativeObject(adapter types.Adapter, val any, refValue reflect.Value) ref.Val {
valType, err := newNativeType(refValue.Type())
if err != nil {
return types.NewErr(err.Error())
}
return &nativeObj{
TypeAdapter: adapter,
val: val,
valType: valType,
refValue: refValue,
Adapter: adapter,
val: val,
valType: valType,
refValue: refValue,
}
}
type nativeObj struct {
ref.TypeAdapter
types.Adapter
val any
valType *nativeType
refValue reflect.Value
@ -520,11 +520,11 @@ func (t *nativeType) hasField(fieldName string) (reflect.StructField, bool) {
return f, true
}
func adaptFieldValue(adapter ref.TypeAdapter, refField reflect.Value) ref.Val {
func adaptFieldValue(adapter types.Adapter, refField reflect.Value) ref.Val {
return adapter.NativeToValue(getFieldValue(adapter, refField))
}
func getFieldValue(adapter ref.TypeAdapter, refField reflect.Value) any {
func getFieldValue(adapter types.Adapter, refField reflect.Value) any {
if refField.IsZero() {
switch refField.Kind() {
case reflect.Array, reflect.Slice:

View File

@ -16,7 +16,6 @@ package ext
import (
"github.com/google/cel-go/cel"
"github.com/google/cel-go/common"
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
)
@ -86,7 +85,7 @@ func (protoLib) ProgramOptions() []cel.ProgramOption {
}
// hasProtoExt generates a test-only select expression for a fully-qualified extension name on a protobuf message.
func hasProtoExt(meh cel.MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
func hasProtoExt(meh cel.MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *cel.Error) {
if !macroTargetMatchesNamespace(protoNamespace, target) {
return nil, nil
}
@ -98,7 +97,7 @@ func hasProtoExt(meh cel.MacroExprHelper, target *exprpb.Expr, args []*exprpb.Ex
}
// getProtoExt generates a select expression for a fully-qualified extension name on a protobuf message.
func getProtoExt(meh cel.MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
func getProtoExt(meh cel.MacroExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *cel.Error) {
if !macroTargetMatchesNamespace(protoNamespace, target) {
return nil, nil
}
@ -109,7 +108,7 @@ func getProtoExt(meh cel.MacroExprHelper, target *exprpb.Expr, args []*exprpb.Ex
return meh.Select(args[0], extFieldName), nil
}
func getExtFieldName(meh cel.MacroExprHelper, expr *exprpb.Expr) (string, *common.Error) {
func getExtFieldName(meh cel.MacroExprHelper, expr *exprpb.Expr) (string, *cel.Error) {
isValid := false
extensionField := ""
switch expr.GetExprKind().(type) {
@ -117,10 +116,7 @@ func getExtFieldName(meh cel.MacroExprHelper, expr *exprpb.Expr) (string, *commo
extensionField, isValid = validateIdentifier(expr)
}
if !isValid {
return "", &common.Error{
Message: "invalid extension field",
Location: meh.OffsetLocation(expr.GetId()),
}
return "", meh.NewError(expr.GetId(), "invalid extension field")
}
return extensionField, nil
}

View File

@ -15,10 +15,14 @@
package ext
import (
"math"
"github.com/google/cel-go/cel"
"github.com/google/cel-go/checker"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
"github.com/google/cel-go/common/types/traits"
"github.com/google/cel-go/interpreter"
)
// Sets returns a cel.EnvOption to configure namespaced set relationship
@ -95,12 +99,24 @@ func (setsLib) CompileOptions() []cel.EnvOption {
cel.Function("sets.intersects",
cel.Overload("list_sets_intersects_list", []*cel.Type{listType, listType}, cel.BoolType,
cel.BinaryBinding(setsIntersects))),
cel.CostEstimatorOptions(
checker.OverloadCostEstimate("list_sets_contains_list", estimateSetsCost(1)),
checker.OverloadCostEstimate("list_sets_intersects_list", estimateSetsCost(1)),
// equivalence requires potentially two m*n comparisons to ensure each list is contained by the other
checker.OverloadCostEstimate("list_sets_equivalent_list", estimateSetsCost(2)),
),
}
}
// ProgramOptions implements the Library interface method.
func (setsLib) ProgramOptions() []cel.ProgramOption {
return []cel.ProgramOption{}
return []cel.ProgramOption{
cel.CostTrackerOptions(
interpreter.OverloadCostTracker("list_sets_contains_list", trackSetsCost(1)),
interpreter.OverloadCostTracker("list_sets_intersects_list", trackSetsCost(1)),
interpreter.OverloadCostTracker("list_sets_equivalent_list", trackSetsCost(2)),
),
}
}
func setsIntersects(listA, listB ref.Val) ref.Val {
@ -136,3 +152,46 @@ func setsEquivalent(listA, listB ref.Val) ref.Val {
}
return setsContains(listB, listA)
}
func estimateSetsCost(costFactor float64) checker.FunctionEstimator {
return func(estimator checker.CostEstimator, target *checker.AstNode, args []checker.AstNode) *checker.CallEstimate {
if len(args) == 2 {
arg0Size := estimateSize(estimator, args[0])
arg1Size := estimateSize(estimator, args[1])
costEstimate := arg0Size.Multiply(arg1Size).MultiplyByCostFactor(costFactor).Add(callCostEstimate)
return &checker.CallEstimate{CostEstimate: costEstimate}
}
return nil
}
}
func estimateSize(estimator checker.CostEstimator, node checker.AstNode) checker.SizeEstimate {
if l := node.ComputedSize(); l != nil {
return *l
}
if l := estimator.EstimateSize(node); l != nil {
return *l
}
return checker.SizeEstimate{Min: 0, Max: math.MaxUint64}
}
func trackSetsCost(costFactor float64) interpreter.FunctionTracker {
return func(args []ref.Val, _ ref.Val) *uint64 {
lhsSize := actualSize(args[0])
rhsSize := actualSize(args[1])
cost := callCost + uint64(float64(lhsSize*rhsSize)*costFactor)
return &cost
}
}
func actualSize(value ref.Val) uint64 {
if sz, ok := value.(traits.Sizer); ok {
return uint64(sz.Size().(types.Int))
}
return 1
}
var (
callCostEstimate = checker.CostEstimate{Min: 1, Max: 1}
callCost = uint64(1)
)

View File

@ -173,7 +173,7 @@ const (
// 'TacoCat'.lowerAscii() // returns 'tacocat'
// 'TacoCÆt Xii'.lowerAscii() // returns 'tacocÆt xii'
//
// # Quote
// # Strings.Quote
//
// Introduced in version: 1
//
@ -301,26 +301,28 @@ func StringsLocale(locale string) StringsOption {
}
}
// StringsVersion configures the version of the string library. The version limits which
// functions are available. Only functions introduced below or equal to the given
// version included in the library. See the library documentation to determine
// which version a function was introduced at. If the documentation does not
// state which version a function was introduced at, it can be assumed to be
// introduced at version 0, when the library was first created.
// If this option is not set, all functions are available.
func StringsVersion(version uint32) func(lib *stringLib) *stringLib {
return func(sl *stringLib) *stringLib {
sl.version = version
return sl
// StringsVersion configures the version of the string library.
//
// The version limits which functions are available. Only functions introduced
// below or equal to the given version included in the library. If this option
// is not set, all functions are available.
//
// See the library documentation to determine which version a function was introduced.
// If the documentation does not state which version a function was introduced, it can
// be assumed to be introduced at version 0, when the library was first created.
func StringsVersion(version uint32) StringsOption {
return func(lib *stringLib) *stringLib {
lib.version = version
return lib
}
}
// CompileOptions implements the Library interface method.
func (sl *stringLib) CompileOptions() []cel.EnvOption {
func (lib *stringLib) CompileOptions() []cel.EnvOption {
formatLocale := "en_US"
if sl.locale != "" {
if lib.locale != "" {
// ensure locale is properly-formed if set
_, err := language.Parse(sl.locale)
_, err := language.Parse(lib.locale)
if err != nil {
return []cel.EnvOption{
func(e *cel.Env) (*cel.Env, error) {
@ -328,7 +330,7 @@ func (sl *stringLib) CompileOptions() []cel.EnvOption {
},
}
}
formatLocale = sl.locale
formatLocale = lib.locale
}
opts := []cel.EnvOption{
@ -432,7 +434,7 @@ func (sl *stringLib) CompileOptions() []cel.EnvOption {
return stringOrError(upperASCII(string(s)))
}))),
}
if sl.version >= 1 {
if lib.version >= 1 {
opts = append(opts, cel.Function("format",
cel.MemberOverload("string_format", []*cel.Type{cel.StringType, cel.ListType(cel.DynType)}, cel.StringType,
cel.FunctionBinding(func(args ...ref.Val) ref.Val {
@ -447,7 +449,7 @@ func (sl *stringLib) CompileOptions() []cel.EnvOption {
}))))
}
if sl.version >= 2 {
if lib.version >= 2 {
opts = append(opts,
cel.Function("join",
cel.MemberOverload("list_join", []*cel.Type{cel.ListType(cel.StringType)}, cel.StringType,