aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/go-viper/mapstructure/v2
diff options
context:
space:
mode:
authorTaras Madan <tarasmadan@google.com>2024-11-11 11:41:38 +0100
committerTaras Madan <tarasmadan@google.com>2024-11-11 11:10:48 +0000
commit27e76fae2ee2d84dc7db63af1d9ed7358ba35b7a (patch)
treeed19c0e35e272b3c4cc5a2f2c595e035b2428337 /vendor/github.com/go-viper/mapstructure/v2
parent621e84e063b0e15b23e17780338627c509e1b9e8 (diff)
vendor: update
Diffstat (limited to 'vendor/github.com/go-viper/mapstructure/v2')
-rw-r--r--vendor/github.com/go-viper/mapstructure/v2/decode_hooks.go21
-rw-r--r--vendor/github.com/go-viper/mapstructure/v2/mapstructure.go69
2 files changed, 69 insertions, 21 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 2523c6ad9..1f3c69d4b 100644
--- a/vendor/github.com/go-viper/mapstructure/v2/decode_hooks.go
+++ b/vendor/github.com/go-viper/mapstructure/v2/decode_hooks.go
@@ -6,6 +6,7 @@ import (
"fmt"
"net"
"net/netip"
+ "net/url"
"reflect"
"strconv"
"strings"
@@ -176,6 +177,26 @@ func StringToTimeDurationHookFunc() DecodeHookFunc {
}
}
+// StringToURLHookFunc returns a DecodeHookFunc that converts
+// strings to *url.URL.
+func StringToURLHookFunc() DecodeHookFunc {
+ return func(
+ f reflect.Type,
+ t reflect.Type,
+ data interface{},
+ ) (interface{}, error) {
+ if f.Kind() != reflect.String {
+ return data, nil
+ }
+ if t != reflect.TypeOf(&url.URL{}) {
+ return data, nil
+ }
+
+ // Convert it by parsing
+ return url.Parse(data.(string))
+ }
+}
+
// StringToIPHookFunc returns a DecodeHookFunc that converts
// strings to net.IP
func StringToIPHookFunc() DecodeHookFunc {
diff --git a/vendor/github.com/go-viper/mapstructure/v2/mapstructure.go b/vendor/github.com/go-viper/mapstructure/v2/mapstructure.go
index 1cd6204bb..e77e63ba3 100644
--- a/vendor/github.com/go-viper/mapstructure/v2/mapstructure.go
+++ b/vendor/github.com/go-viper/mapstructure/v2/mapstructure.go
@@ -278,6 +278,10 @@ type DecoderConfig struct {
// field name or tag. Defaults to `strings.EqualFold`. This can be used
// to implement case-sensitive tag values, support snake casing, etc.
MatchName func(mapKey, fieldName string) bool
+
+ // DecodeNil, if set to true, will cause the DecodeHook (if present) to run
+ // even if the input is nil. This can be used to provide default values.
+ DecodeNil bool
}
// A Decoder takes a raw interface value and turns it into structured
@@ -438,19 +442,26 @@ func (d *Decoder) Decode(input interface{}) error {
return err
}
+// isNil returns true if the input is nil or a typed nil pointer.
+func isNil(input interface{}) bool {
+ if input == nil {
+ return true
+ }
+ val := reflect.ValueOf(input)
+ return val.Kind() == reflect.Ptr && val.IsNil()
+}
+
// Decodes an unknown data type into a specific reflection value.
func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) error {
- var inputVal reflect.Value
- if input != nil {
- inputVal = reflect.ValueOf(input)
-
- // We need to check here if input is a typed nil. Typed nils won't
- // match the "input == nil" below so we check that here.
- if inputVal.Kind() == reflect.Ptr && inputVal.IsNil() {
- input = nil
- }
+ var (
+ inputVal = reflect.ValueOf(input)
+ outputKind = getKind(outVal)
+ decodeNil = d.config.DecodeNil && d.cachedDecodeHook != nil
+ )
+ if isNil(input) {
+ // Typed nils won't match the "input == nil" below, so reset input.
+ input = nil
}
-
if input == nil {
// If the data is nil, then we don't set anything, unless ZeroFields is set
// to true.
@@ -461,17 +472,31 @@ func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) e
d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
}
}
- return nil
+ if !decodeNil {
+ return nil
+ }
}
-
if !inputVal.IsValid() {
- // If the input value is invalid, then we just set the value
- // to be the zero value.
- outVal.Set(reflect.Zero(outVal.Type()))
- if d.config.Metadata != nil && name != "" {
- d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
+ if !decodeNil {
+ // If the input value is invalid, then we just set the value
+ // to be the zero value.
+ outVal.Set(reflect.Zero(outVal.Type()))
+ if d.config.Metadata != nil && name != "" {
+ d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
+ }
+ return nil
+ }
+ // Hooks need a valid inputVal, so reset it to zero value of outVal type.
+ switch outputKind {
+ case reflect.Struct, reflect.Map:
+ var mapVal map[string]interface{}
+ inputVal = reflect.ValueOf(mapVal) // create nil map pointer
+ case reflect.Slice, reflect.Array:
+ var sliceVal []interface{}
+ inputVal = reflect.ValueOf(sliceVal) // create nil slice pointer
+ default:
+ inputVal = reflect.Zero(outVal.Type())
}
- return nil
}
if d.cachedDecodeHook != nil {
@@ -482,9 +507,11 @@ func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) e
return fmt.Errorf("error decoding '%s': %w", name, err)
}
}
+ if isNil(input) {
+ return nil
+ }
var err error
- outputKind := getKind(outVal)
addMetaKey := true
switch outputKind {
case reflect.Bool:
@@ -765,8 +792,8 @@ func (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) e
}
default:
return fmt.Errorf(
- "'%s' expected type '%s', got unconvertible type '%s', value: '%v'",
- name, val.Type(), dataVal.Type(), data)
+ "'%s' expected type '%s', got unconvertible type '%#v', value: '%#v'",
+ name, val, dataVal, data)
}
return nil