summaryrefslogtreecommitdiff
path: root/vendor/github.com/spf13/cast/map.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/spf13/cast/map.go')
-rw-r--r--vendor/github.com/spf13/cast/map.go224
1 files changed, 224 insertions, 0 deletions
diff --git a/vendor/github.com/spf13/cast/map.go b/vendor/github.com/spf13/cast/map.go
new file mode 100644
index 000000000..7d6beb56c
--- /dev/null
+++ b/vendor/github.com/spf13/cast/map.go
@@ -0,0 +1,224 @@
+// Copyright © 2014 Steve Francia <spf@spf13.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+package cast
+
+import (
+ "encoding/json"
+ "fmt"
+ "reflect"
+)
+
+func toMapE[K comparable, V any](i any, keyFn func(any) K, valFn func(any) V) (map[K]V, error) {
+ m := map[K]V{}
+
+ if i == nil {
+ return nil, fmt.Errorf(errorMsg, i, i, m)
+ }
+
+ switch v := i.(type) {
+ case map[K]V:
+ return v, nil
+
+ case map[K]any:
+ for k, val := range v {
+ m[k] = valFn(val)
+ }
+
+ return m, nil
+
+ case map[any]V:
+ for k, val := range v {
+ m[keyFn(k)] = val
+ }
+
+ return m, nil
+
+ case map[any]any:
+ for k, val := range v {
+ m[keyFn(k)] = valFn(val)
+ }
+
+ return m, nil
+
+ case string:
+ err := jsonStringToObject(v, &m)
+ if err != nil {
+ return nil, err
+ }
+
+ return m, nil
+
+ default:
+ return nil, fmt.Errorf(errorMsg, i, i, m)
+ }
+}
+
+func toStringMapE[T any](i any, fn func(any) T) (map[string]T, error) {
+ return toMapE(i, ToString, fn)
+}
+
+// ToStringMapStringE casts any value to a map[string]string type.
+func ToStringMapStringE(i any) (map[string]string, error) {
+ return toStringMapE(i, ToString)
+}
+
+// ToStringMapStringSliceE casts any value to a map[string][]string type.
+func ToStringMapStringSliceE(i any) (map[string][]string, error) {
+ m := map[string][]string{}
+
+ switch v := i.(type) {
+ case map[string][]string:
+ return v, nil
+ case map[string][]any:
+ for k, val := range v {
+ m[ToString(k)] = ToStringSlice(val)
+ }
+ return m, nil
+ case map[string]string:
+ for k, val := range v {
+ m[ToString(k)] = []string{val}
+ }
+ case map[string]any:
+ for k, val := range v {
+ switch vt := val.(type) {
+ case []any:
+ m[ToString(k)] = ToStringSlice(vt)
+ case []string:
+ m[ToString(k)] = vt
+ default:
+ m[ToString(k)] = []string{ToString(val)}
+ }
+ }
+ return m, nil
+ case map[any][]string:
+ for k, val := range v {
+ m[ToString(k)] = ToStringSlice(val)
+ }
+ return m, nil
+ case map[any]string:
+ for k, val := range v {
+ m[ToString(k)] = ToStringSlice(val)
+ }
+ return m, nil
+ case map[any][]any:
+ for k, val := range v {
+ m[ToString(k)] = ToStringSlice(val)
+ }
+ return m, nil
+ case map[any]any:
+ for k, val := range v {
+ key, err := ToStringE(k)
+ if err != nil {
+ return nil, fmt.Errorf(errorMsg, i, i, m)
+ }
+ value, err := ToStringSliceE(val)
+ if err != nil {
+ return nil, fmt.Errorf(errorMsg, i, i, m)
+ }
+ m[key] = value
+ }
+ case string:
+ err := jsonStringToObject(v, &m)
+ if err != nil {
+ return nil, err
+ }
+
+ return m, nil
+ default:
+ return nil, fmt.Errorf(errorMsg, i, i, m)
+ }
+
+ return m, nil
+}
+
+// ToStringMapBoolE casts any value to a map[string]bool type.
+func ToStringMapBoolE(i any) (map[string]bool, error) {
+ return toStringMapE(i, ToBool)
+}
+
+// ToStringMapE casts any value to a map[string]any type.
+func ToStringMapE(i any) (map[string]any, error) {
+ fn := func(i any) any { return i }
+
+ return toStringMapE(i, fn)
+}
+
+func toStringMapIntE[T int | int64](i any, fn func(any) T, fnE func(any) (T, error)) (map[string]T, error) {
+ m := map[string]T{}
+
+ if i == nil {
+ return nil, fmt.Errorf(errorMsg, i, i, m)
+ }
+
+ switch v := i.(type) {
+ case map[string]T:
+ return v, nil
+
+ case map[string]any:
+ for k, val := range v {
+ m[k] = fn(val)
+ }
+
+ return m, nil
+
+ case map[any]T:
+ for k, val := range v {
+ m[ToString(k)] = val
+ }
+
+ return m, nil
+
+ case map[any]any:
+ for k, val := range v {
+ m[ToString(k)] = fn(val)
+ }
+
+ return m, nil
+
+ case string:
+ err := jsonStringToObject(v, &m)
+ if err != nil {
+ return nil, err
+ }
+
+ return m, nil
+ }
+
+ if reflect.TypeOf(i).Kind() != reflect.Map {
+ return nil, fmt.Errorf(errorMsg, i, i, m)
+ }
+
+ mVal := reflect.ValueOf(m)
+ v := reflect.ValueOf(i)
+
+ for _, keyVal := range v.MapKeys() {
+ val, err := fnE(v.MapIndex(keyVal).Interface())
+ if err != nil {
+ return m, fmt.Errorf(errorMsg, i, i, m)
+ }
+
+ mVal.SetMapIndex(keyVal, reflect.ValueOf(val))
+ }
+
+ return m, nil
+}
+
+// ToStringMapIntE casts any value to a map[string]int type.
+func ToStringMapIntE(i any) (map[string]int, error) {
+ return toStringMapIntE(i, ToInt, ToIntE)
+}
+
+// ToStringMapInt64E casts any value to a map[string]int64 type.
+func ToStringMapInt64E(i any) (map[string]int64, error) {
+ return toStringMapIntE(i, ToInt64, ToInt64E)
+}
+
+// jsonStringToObject attempts to unmarshall a string as JSON into
+// the object passed as pointer.
+func jsonStringToObject(s string, v any) error {
+ data := []byte(s)
+ return json.Unmarshal(data, v)
+}