github.com/avenga/couper@v1.12.2/eval/lib/default.go (about) 1 package lib 2 3 import ( 4 "fmt" 5 6 "github.com/zclconf/go-cty/cty" 7 "github.com/zclconf/go-cty/cty/convert" 8 "github.com/zclconf/go-cty/cty/function" 9 ) 10 11 var DefaultFunc = function.New(&function.Spec{ 12 VarParam: &function.Parameter{ 13 Name: "vals", 14 Type: cty.DynamicPseudoType, 15 AllowUnknown: true, 16 AllowDynamicType: true, 17 AllowNull: true, 18 }, 19 Type: func(args []cty.Value) (cty.Type, error) { 20 var argTypes []cty.Type 21 for _, val := range args { 22 // ignore NilType values when determining the unsafe-unified return type 23 if val.Type() == cty.NilType { 24 continue 25 } 26 argTypes = append(argTypes, val.Type()) 27 } 28 if len(argTypes) == 0 { 29 // no non-NilVal arguments 30 return cty.NilType, nil 31 } 32 retType, _ := convert.UnifyUnsafe(argTypes) 33 if retType == cty.NilType { 34 return cty.NilType, fmt.Errorf("all defined arguments must have the same type") 35 } 36 return retType, nil 37 }, 38 Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { 39 for _, argVal := range args { 40 if !argVal.IsKnown() { 41 return cty.UnknownVal(retType), nil 42 } 43 if argVal.IsNull() || argVal.Type() == cty.NilType { 44 continue 45 } 46 47 // If the fallback type is a string and this argument too but an empty one, consider them as unset. 48 if argVal.Type() == cty.String && argVal.AsString() == "" && retType == cty.String { 49 continue 50 } 51 52 return convert.Convert(argVal, retType) 53 } 54 return args[len(args)-1], nil 55 }, 56 })