Path: blob/main/vendor/github.com/spf13/cast/map.go
2875 views
// Copyright © 2014 Steve Francia <[email protected]>.1//2// Use of this source code is governed by an MIT-style3// license that can be found in the LICENSE file.45package cast67import (8"encoding/json"9"fmt"10"reflect"11)1213func toMapE[K comparable, V any](i any, keyFn func(any) K, valFn func(any) V) (map[K]V, error) {14m := map[K]V{}1516if i == nil {17return m, fmt.Errorf(errorMsg, i, i, m)18}1920switch v := i.(type) {21case map[K]V:22return v, nil2324case map[K]any:25for k, val := range v {26m[k] = valFn(val)27}2829return m, nil3031case map[any]V:32for k, val := range v {33m[keyFn(k)] = val34}3536return m, nil3738case map[any]any:39for k, val := range v {40m[keyFn(k)] = valFn(val)41}4243return m, nil4445case string:46err := jsonStringToObject(v, &m)47return m, err4849default:50return m, fmt.Errorf(errorMsg, i, i, m)51}52}5354func toStringMapE[T any](i any, fn func(any) T) (map[string]T, error) {55return toMapE(i, ToString, fn)56}5758// ToStringMapStringE casts any value to a map[string]string type.59func ToStringMapStringE(i any) (map[string]string, error) {60return toStringMapE(i, ToString)61}6263// ToStringMapStringSliceE casts any value to a map[string][]string type.64func ToStringMapStringSliceE(i any) (map[string][]string, error) {65m := map[string][]string{}6667switch v := i.(type) {68case map[string][]string:69return v, nil70case map[string][]any:71for k, val := range v {72m[ToString(k)] = ToStringSlice(val)73}74return m, nil75case map[string]string:76for k, val := range v {77m[ToString(k)] = []string{val}78}79case map[string]any:80for k, val := range v {81switch vt := val.(type) {82case []any:83m[ToString(k)] = ToStringSlice(vt)84case []string:85m[ToString(k)] = vt86default:87m[ToString(k)] = []string{ToString(val)}88}89}90return m, nil91case map[any][]string:92for k, val := range v {93m[ToString(k)] = ToStringSlice(val)94}95return m, nil96case map[any]string:97for k, val := range v {98m[ToString(k)] = ToStringSlice(val)99}100return m, nil101case map[any][]any:102for k, val := range v {103m[ToString(k)] = ToStringSlice(val)104}105return m, nil106case map[any]any:107for k, val := range v {108key, err := ToStringE(k)109if err != nil {110return m, fmt.Errorf(errorMsg, i, i, m)111}112value, err := ToStringSliceE(val)113if err != nil {114return m, fmt.Errorf(errorMsg, i, i, m)115}116m[key] = value117}118case string:119err := jsonStringToObject(v, &m)120return m, err121default:122return m, fmt.Errorf(errorMsg, i, i, m)123}124125return m, nil126}127128// ToStringMapBoolE casts any value to a map[string]bool type.129func ToStringMapBoolE(i any) (map[string]bool, error) {130return toStringMapE(i, ToBool)131}132133// ToStringMapE casts any value to a map[string]any type.134func ToStringMapE(i any) (map[string]any, error) {135fn := func(i any) any { return i }136137return toStringMapE(i, fn)138}139140func toStringMapIntE[T int | int64](i any, fn func(any) T, fnE func(any) (T, error)) (map[string]T, error) {141m := map[string]T{}142143if i == nil {144return nil, fmt.Errorf(errorMsg, i, i, m)145}146147switch v := i.(type) {148case map[string]T:149return v, nil150151case map[string]any:152for k, val := range v {153m[k] = fn(val)154}155156return m, nil157158case map[any]T:159for k, val := range v {160m[ToString(k)] = val161}162163return m, nil164165case map[any]any:166for k, val := range v {167m[ToString(k)] = fn(val)168}169170return m, nil171172case string:173err := jsonStringToObject(v, &m)174return m, err175}176177if reflect.TypeOf(i).Kind() != reflect.Map {178return m, fmt.Errorf(errorMsg, i, i, m)179}180181mVal := reflect.ValueOf(m)182v := reflect.ValueOf(i)183184for _, keyVal := range v.MapKeys() {185val, err := fnE(v.MapIndex(keyVal).Interface())186if err != nil {187return m, fmt.Errorf(errorMsg, i, i, m)188}189190mVal.SetMapIndex(keyVal, reflect.ValueOf(val))191}192193return m, nil194}195196// ToStringMapIntE casts any value to a map[string]int type.197func ToStringMapIntE(i any) (map[string]int, error) {198return toStringMapIntE(i, ToInt, ToIntE)199}200201// ToStringMapInt64E casts any value to a map[string]int64 type.202func ToStringMapInt64E(i any) (map[string]int64, error) {203return toStringMapIntE(i, ToInt64, ToInt64E)204}205206// jsonStringToObject attempts to unmarshall a string as JSON into207// the object passed as pointer.208func jsonStringToObject(s string, v any) error {209data := []byte(s)210return json.Unmarshal(data, v)211}212213214