aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/go-viper/mapstructure/v2/decode_hooks.go
diff options
context:
space:
mode:
authorTaras Madan <tarasmadan@google.com>2024-09-10 12:16:33 +0200
committerTaras Madan <tarasmadan@google.com>2024-09-10 14:05:26 +0000
commitc97c816133b42257d0bcf1ee4bd178bb2a7a2b9e (patch)
tree0bcbc2e540bbf8f62f6c17887cdd53b8c2cee637 /vendor/github.com/go-viper/mapstructure/v2/decode_hooks.go
parent54e657429ab892ad06c90cd7c1a4eb33ba93a3dc (diff)
vendor: update
Diffstat (limited to 'vendor/github.com/go-viper/mapstructure/v2/decode_hooks.go')
-rw-r--r--vendor/github.com/go-viper/mapstructure/v2/decode_hooks.go283
1 files changed, 279 insertions, 4 deletions
diff --git a/vendor/github.com/go-viper/mapstructure/v2/decode_hooks.go b/vendor/github.com/go-viper/mapstructure/v2/decode_hooks.go
index 840d6adce..2523c6ad9 100644
--- a/vendor/github.com/go-viper/mapstructure/v2/decode_hooks.go
+++ b/vendor/github.com/go-viper/mapstructure/v2/decode_hooks.go
@@ -36,6 +36,30 @@ func typedDecodeHook(h DecodeHookFunc) DecodeHookFunc {
return nil
}
+// cachedDecodeHook takes a raw DecodeHookFunc (an interface{}) and turns
+// it into a closure to be used directly
+// if the type fails to convert we return a closure always erroring to keep the previous behaviour
+func cachedDecodeHook(raw DecodeHookFunc) func(from reflect.Value, to reflect.Value) (interface{}, error) {
+ switch f := typedDecodeHook(raw).(type) {
+ case DecodeHookFuncType:
+ return func(from reflect.Value, to reflect.Value) (interface{}, error) {
+ return f(from.Type(), to.Type(), from.Interface())
+ }
+ case DecodeHookFuncKind:
+ return func(from reflect.Value, to reflect.Value) (interface{}, error) {
+ return f(from.Kind(), to.Kind(), from.Interface())
+ }
+ case DecodeHookFuncValue:
+ return func(from reflect.Value, to reflect.Value) (interface{}, error) {
+ return f(from, to)
+ }
+ default:
+ return func(from reflect.Value, to reflect.Value) (interface{}, error) {
+ return nil, errors.New("invalid decode hook signature")
+ }
+ }
+}
+
// DecodeHookExec executes the given decode hook. This should be used
// since it'll naturally degrade to the older backwards compatible DecodeHookFunc
// that took reflect.Kind instead of reflect.Type.
@@ -61,13 +85,17 @@ func DecodeHookExec(
// The composed funcs are called in order, with the result of the
// previous transformation.
func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc {
+ cached := make([]func(from reflect.Value, to reflect.Value) (interface{}, error), 0, len(fs))
+ for _, f := range fs {
+ cached = append(cached, cachedDecodeHook(f))
+ }
return func(f reflect.Value, t reflect.Value) (interface{}, error) {
var err error
data := f.Interface()
newFrom := f
- for _, f1 := range fs {
- data, err = DecodeHookExec(f1, newFrom, t)
+ for _, c := range cached {
+ data, err = c(newFrom, t)
if err != nil {
return nil, err
}
@@ -81,13 +109,17 @@ func ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc {
// OrComposeDecodeHookFunc executes all input hook functions until one of them returns no error. In that case its value is returned.
// If all hooks return an error, OrComposeDecodeHookFunc returns an error concatenating all error messages.
func OrComposeDecodeHookFunc(ff ...DecodeHookFunc) DecodeHookFunc {
+ cached := make([]func(from reflect.Value, to reflect.Value) (interface{}, error), 0, len(ff))
+ for _, f := range ff {
+ cached = append(cached, cachedDecodeHook(f))
+ }
return func(a, b reflect.Value) (interface{}, error) {
var allErrs string
var out interface{}
var err error
- for _, f := range ff {
- out, err = DecodeHookExec(f, a, b)
+ for _, c := range cached {
+ out, err = c(a, b)
if err != nil {
allErrs += err.Error() + "\n"
continue
@@ -332,3 +364,246 @@ func StringToNetIPAddrPortHookFunc() DecodeHookFunc {
return netip.ParseAddrPort(data.(string))
}
}
+
+// StringToBasicTypeHookFunc returns a DecodeHookFunc that converts
+// strings to basic types.
+// int8, uint8, int16, uint16, int32, uint32, int64, uint64, int, uint, float32, float64, bool, byte, rune, complex64, complex128
+func StringToBasicTypeHookFunc() DecodeHookFunc {
+ return ComposeDecodeHookFunc(
+ StringToInt8HookFunc(),
+ StringToUint8HookFunc(),
+ StringToInt16HookFunc(),
+ StringToUint16HookFunc(),
+ StringToInt32HookFunc(),
+ StringToUint32HookFunc(),
+ StringToInt64HookFunc(),
+ StringToUint64HookFunc(),
+ StringToIntHookFunc(),
+ StringToUintHookFunc(),
+ StringToFloat32HookFunc(),
+ StringToFloat64HookFunc(),
+ StringToBoolHookFunc(),
+ // byte and rune are aliases for uint8 and int32 respectively
+ // StringToByteHookFunc(),
+ // StringToRuneHookFunc(),
+ StringToComplex64HookFunc(),
+ StringToComplex128HookFunc(),
+ )
+}
+
+// StringToInt8HookFunc returns a DecodeHookFunc that converts
+// strings to int8.
+func StringToInt8HookFunc() DecodeHookFunc {
+ return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
+ if f.Kind() != reflect.String || t.Kind() != reflect.Int8 {
+ return data, nil
+ }
+
+ // Convert it by parsing
+ i64, err := strconv.ParseInt(data.(string), 0, 8)
+ return int8(i64), err
+ }
+}
+
+// StringToUint8HookFunc returns a DecodeHookFunc that converts
+// strings to uint8.
+func StringToUint8HookFunc() DecodeHookFunc {
+ return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
+ if f.Kind() != reflect.String || t.Kind() != reflect.Uint8 {
+ return data, nil
+ }
+
+ // Convert it by parsing
+ u64, err := strconv.ParseUint(data.(string), 0, 8)
+ return uint8(u64), err
+ }
+}
+
+// StringToInt16HookFunc returns a DecodeHookFunc that converts
+// strings to int16.
+func StringToInt16HookFunc() DecodeHookFunc {
+ return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
+ if f.Kind() != reflect.String || t.Kind() != reflect.Int16 {
+ return data, nil
+ }
+
+ // Convert it by parsing
+ i64, err := strconv.ParseInt(data.(string), 0, 16)
+ return int16(i64), err
+ }
+}
+
+// StringToUint16HookFunc returns a DecodeHookFunc that converts
+// strings to uint16.
+func StringToUint16HookFunc() DecodeHookFunc {
+ return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
+ if f.Kind() != reflect.String || t.Kind() != reflect.Uint16 {
+ return data, nil
+ }
+
+ // Convert it by parsing
+ u64, err := strconv.ParseUint(data.(string), 0, 16)
+ return uint16(u64), err
+ }
+}
+
+// StringToInt32HookFunc returns a DecodeHookFunc that converts
+// strings to int32.
+func StringToInt32HookFunc() DecodeHookFunc {
+ return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
+ if f.Kind() != reflect.String || t.Kind() != reflect.Int32 {
+ return data, nil
+ }
+
+ // Convert it by parsing
+ i64, err := strconv.ParseInt(data.(string), 0, 32)
+ return int32(i64), err
+ }
+}
+
+// StringToUint32HookFunc returns a DecodeHookFunc that converts
+// strings to uint32.
+func StringToUint32HookFunc() DecodeHookFunc {
+ return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
+ if f.Kind() != reflect.String || t.Kind() != reflect.Uint32 {
+ return data, nil
+ }
+
+ // Convert it by parsing
+ u64, err := strconv.ParseUint(data.(string), 0, 32)
+ return uint32(u64), err
+ }
+}
+
+// StringToInt64HookFunc returns a DecodeHookFunc that converts
+// strings to int64.
+func StringToInt64HookFunc() DecodeHookFunc {
+ return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
+ if f.Kind() != reflect.String || t.Kind() != reflect.Int64 {
+ return data, nil
+ }
+
+ // Convert it by parsing
+ return strconv.ParseInt(data.(string), 0, 64)
+ }
+}
+
+// StringToUint64HookFunc returns a DecodeHookFunc that converts
+// strings to uint64.
+func StringToUint64HookFunc() DecodeHookFunc {
+ return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
+ if f.Kind() != reflect.String || t.Kind() != reflect.Uint64 {
+ return data, nil
+ }
+
+ // Convert it by parsing
+ return strconv.ParseUint(data.(string), 0, 64)
+ }
+}
+
+// StringToIntHookFunc returns a DecodeHookFunc that converts
+// strings to int.
+func StringToIntHookFunc() DecodeHookFunc {
+ return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
+ if f.Kind() != reflect.String || t.Kind() != reflect.Int {
+ return data, nil
+ }
+
+ // Convert it by parsing
+ i64, err := strconv.ParseInt(data.(string), 0, 0)
+ return int(i64), err
+ }
+}
+
+// StringToUintHookFunc returns a DecodeHookFunc that converts
+// strings to uint.
+func StringToUintHookFunc() DecodeHookFunc {
+ return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
+ if f.Kind() != reflect.String || t.Kind() != reflect.Uint {
+ return data, nil
+ }
+
+ // Convert it by parsing
+ u64, err := strconv.ParseUint(data.(string), 0, 0)
+ return uint(u64), err
+ }
+}
+
+// StringToFloat32HookFunc returns a DecodeHookFunc that converts
+// strings to float32.
+func StringToFloat32HookFunc() DecodeHookFunc {
+ return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
+ if f.Kind() != reflect.String || t.Kind() != reflect.Float32 {
+ return data, nil
+ }
+
+ // Convert it by parsing
+ f64, err := strconv.ParseFloat(data.(string), 32)
+ return float32(f64), err
+ }
+}
+
+// StringToFloat64HookFunc returns a DecodeHookFunc that converts
+// strings to float64.
+func StringToFloat64HookFunc() DecodeHookFunc {
+ return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
+ if f.Kind() != reflect.String || t.Kind() != reflect.Float64 {
+ return data, nil
+ }
+
+ // Convert it by parsing
+ return strconv.ParseFloat(data.(string), 64)
+ }
+}
+
+// StringToBoolHookFunc returns a DecodeHookFunc that converts
+// strings to bool.
+func StringToBoolHookFunc() DecodeHookFunc {
+ return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
+ if f.Kind() != reflect.String || t.Kind() != reflect.Bool {
+ return data, nil
+ }
+
+ // Convert it by parsing
+ return strconv.ParseBool(data.(string))
+ }
+}
+
+// StringToByteHookFunc returns a DecodeHookFunc that converts
+// strings to byte.
+func StringToByteHookFunc() DecodeHookFunc {
+ return StringToUint8HookFunc()
+}
+
+// StringToRuneHookFunc returns a DecodeHookFunc that converts
+// strings to rune.
+func StringToRuneHookFunc() DecodeHookFunc {
+ return StringToInt32HookFunc()
+}
+
+// StringToComplex64HookFunc returns a DecodeHookFunc that converts
+// strings to complex64.
+func StringToComplex64HookFunc() DecodeHookFunc {
+ return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
+ if f.Kind() != reflect.String || t.Kind() != reflect.Complex64 {
+ return data, nil
+ }
+
+ // Convert it by parsing
+ c128, err := strconv.ParseComplex(data.(string), 64)
+ return complex64(c128), err
+ }
+}
+
+// StringToComplex128HookFunc returns a DecodeHookFunc that converts
+// strings to complex128.
+func StringToComplex128HookFunc() DecodeHookFunc {
+ return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) {
+ if f.Kind() != reflect.String || t.Kind() != reflect.Complex128 {
+ return data, nil
+ }
+
+ // Convert it by parsing
+ return strconv.ParseComplex(data.(string), 128)
+ }
+}