Add method to retrieve map[string]map[string]string types

This commit is contained in:
adel121 2024-08-27 13:03:08 +02:00
parent 537f03e453
commit 8a095685e4
No known key found for this signature in database

101
viper.go
View file

@ -120,10 +120,10 @@ type DecoderConfigOption func(*mapstructure.DecoderConfig)
// DecodeHook returns a DecoderConfigOption which overrides the default // DecodeHook returns a DecoderConfigOption which overrides the default
// DecoderConfig.DecodeHook value, the default is: // DecoderConfig.DecodeHook value, the default is:
// //
// mapstructure.ComposeDecodeHookFunc( // mapstructure.ComposeDecodeHookFunc(
// mapstructure.StringToTimeDurationHookFunc(), // mapstructure.StringToTimeDurationHookFunc(),
// mapstructure.StringToSliceHookFunc(","), // mapstructure.StringToSliceHookFunc(","),
// ) // )
func DecodeHook(hook mapstructure.DecodeHookFunc) DecoderConfigOption { func DecodeHook(hook mapstructure.DecodeHookFunc) DecoderConfigOption {
return func(c *mapstructure.DecoderConfig) { return func(c *mapstructure.DecoderConfig) {
c.DecodeHook = hook c.DecodeHook = hook
@ -144,18 +144,18 @@ func DecodeHook(hook mapstructure.DecodeHookFunc) DecoderConfigOption {
// //
// For example, if values from the following sources were loaded: // For example, if values from the following sources were loaded:
// //
// Defaults : { // Defaults : {
// "secret": "", // "secret": "",
// "user": "default", // "user": "default",
// "endpoint": "https://localhost" // "endpoint": "https://localhost"
// } // }
// Config : { // Config : {
// "user": "root" // "user": "root"
// "secret": "defaultsecret" // "secret": "defaultsecret"
// } // }
// Env : { // Env : {
// "secret": "somesecretkey" // "secret": "somesecretkey"
// } // }
// //
// The resulting config will have the following values: // The resulting config will have the following values:
// //
@ -510,7 +510,8 @@ func (v *Viper) searchMapWithPathPrefixes(source map[string]interface{}, path []
// isPathShadowedInDeepMap makes sure the given path is not shadowed somewhere // isPathShadowedInDeepMap makes sure the given path is not shadowed somewhere
// on its path in the map. // on its path in the map.
// e.g., if "foo.bar" has a value in the given map, it “shadows” // e.g., if "foo.bar" has a value in the given map, it “shadows”
// "foo.bar.baz" in a lower-priority map //
// "foo.bar.baz" in a lower-priority map
func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{}) string { func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{}) string {
var parentVal interface{} var parentVal interface{}
for i := 1; i < len(path); i++ { for i := 1; i < len(path); i++ {
@ -535,7 +536,8 @@ func (v *Viper) isPathShadowedInDeepMap(path []string, m map[string]interface{})
// isPathShadowedInFlatMap makes sure the given path is not shadowed somewhere // isPathShadowedInFlatMap makes sure the given path is not shadowed somewhere
// in a sub-path of the map. // in a sub-path of the map.
// e.g., if "foo.bar" has a value in the given map, it “shadows” // e.g., if "foo.bar" has a value in the given map, it “shadows”
// "foo.bar.baz" in a lower-priority map //
// "foo.bar.baz" in a lower-priority map
func (v *Viper) isPathShadowedInFlatMap(path []string, mi interface{}) string { func (v *Viper) isPathShadowedInFlatMap(path []string, mi interface{}) string {
// unify input map // unify input map
var m map[string]interface{} var m map[string]interface{}
@ -560,7 +562,8 @@ func (v *Viper) isPathShadowedInFlatMap(path []string, mi interface{}) string {
// isPathShadowedInAutoEnv makes sure the given path is not shadowed somewhere // isPathShadowedInAutoEnv makes sure the given path is not shadowed somewhere
// in the environment, when automatic env is on. // in the environment, when automatic env is on.
// e.g., if "foo.bar" has a value in the environment, it “shadows” // e.g., if "foo.bar" has a value in the environment, it “shadows”
// "foo.bar.baz" in a lower-priority map //
// "foo.bar.baz" in a lower-priority map
func (v *Viper) isPathShadowedInAutoEnv(path []string) string { func (v *Viper) isPathShadowedInAutoEnv(path []string) string {
var parentKey string var parentKey string
for i := 1; i < len(path); i++ { for i := 1; i < len(path); i++ {
@ -581,11 +584,11 @@ func (v *Viper) isPathShadowedInAutoEnv(path []string) string {
// would return a string slice for the key if the key's type is inferred by // would return a string slice for the key if the key's type is inferred by
// the default value and the Get function would return: // the default value and the Get function would return:
// //
// []string {"a", "b", "c"} // []string {"a", "b", "c"}
// //
// Otherwise the Get function would return: // Otherwise the Get function would return:
// //
// "a b c" // "a b c"
func SetTypeByDefaultValue(enable bool) { v.SetTypeByDefaultValue(enable) } func SetTypeByDefaultValue(enable bool) { v.SetTypeByDefaultValue(enable) }
func (v *Viper) SetTypeByDefaultValue(enable bool) { func (v *Viper) SetTypeByDefaultValue(enable bool) {
v.typeByDefValue = enable v.typeByDefValue = enable
@ -827,6 +830,45 @@ func (v *Viper) GetStringMapStringE(key string) (map[string]string, error) {
return cast.ToStringMapStringE(v.GetRaw(key)) return cast.ToStringMapStringE(v.GetRaw(key))
} }
// GetStringMapStringMapString returns the value associated with the key as a map of strings.
func GetStringMapStringMapString(key string) map[string]map[string]string {
return v.GetStringMapStringMapString(key)
}
func (v *Viper) GetStringMapStringMapString(key string) map[string]map[string]string {
result := map[string]map[string]string{}
interfacesVal := cast.ToStringMap(v.Get(key))
for k, v := range interfacesVal {
result[k] = cast.ToStringMapString(v)
}
return result
}
// GetStringMapStringMapStringE is the same as GetStringMapStringMapString but also returns parsing errors.
func GetStringMapStringMapStringE(key string) (map[string]map[string]string, error) {
return v.GetStringMapStringMapStringE(key)
}
func (v *Viper) GetStringMapStringMapStringE(key string) (map[string]map[string]string, error) {
result := map[string]map[string]string{}
interfacesVal, err := cast.ToStringMapE(v.Get(key))
if err != nil {
return result, err
}
for k, v := range interfacesVal {
result[k], err = cast.ToStringMapStringE(v)
if err != nil {
return nil, err
}
}
return result, nil
}
// GetStringMapStringSlice returns the value associated with the key as a map to a slice of strings. // GetStringMapStringSlice returns the value associated with the key as a map to a slice of strings.
func GetStringMapStringSlice(key string) map[string][]string { return v.GetStringMapStringSlice(key) } func GetStringMapStringSlice(key string) map[string][]string { return v.GetStringMapStringSlice(key) }
func (v *Viper) GetStringMapStringSlice(key string) map[string][]string { func (v *Viper) GetStringMapStringSlice(key string) map[string][]string {
@ -955,9 +997,8 @@ func (v *Viper) BindPFlags(flags *pflag.FlagSet) error {
// BindPFlag binds a specific key to a pflag (as used by cobra). // BindPFlag binds a specific key to a pflag (as used by cobra).
// Example (where serverCmd is a Cobra instance): // Example (where serverCmd is a Cobra instance):
// //
// serverCmd.Flags().Int("port", 1138, "Port to run Application server on") // serverCmd.Flags().Int("port", 1138, "Port to run Application server on")
// Viper.BindPFlag("port", serverCmd.Flags().Lookup("port")) // Viper.BindPFlag("port", serverCmd.Flags().Lookup("port"))
//
func BindPFlag(key string, flag *pflag.Flag) error { return v.BindPFlag(key, flag) } func BindPFlag(key string, flag *pflag.Flag) error { return v.BindPFlag(key, flag) }
func (v *Viper) BindPFlag(key string, flag *pflag.Flag) error { func (v *Viper) BindPFlag(key string, flag *pflag.Flag) error {
return v.BindFlagValue(key, pflagValue{flag}) return v.BindFlagValue(key, pflagValue{flag})
@ -978,9 +1019,8 @@ func (v *Viper) BindFlagValues(flags FlagValueSet) (err error) {
// BindFlagValue binds a specific key to a FlagValue. // BindFlagValue binds a specific key to a FlagValue.
// Example (where serverCmd is a Cobra instance): // Example (where serverCmd is a Cobra instance):
// //
// serverCmd.Flags().Int("port", 1138, "Port to run Application server on") // serverCmd.Flags().Int("port", 1138, "Port to run Application server on")
// Viper.BindFlagValue("port", serverCmd.Flags().Lookup("port")) // Viper.BindFlagValue("port", serverCmd.Flags().Lookup("port"))
//
func BindFlagValue(key string, flag FlagValue) error { return v.BindFlagValue(key, flag) } func BindFlagValue(key string, flag FlagValue) error { return v.BindFlagValue(key, flag) }
func (v *Viper) BindFlagValue(key string, flag FlagValue) error { func (v *Viper) BindFlagValue(key string, flag FlagValue) error {
if flag == nil { if flag == nil {
@ -1806,9 +1846,10 @@ func (v *Viper) AllKeys() []string {
// flattenAndMergeMap recursively flattens the given map into a map[string]bool // flattenAndMergeMap recursively flattens the given map into a map[string]bool
// of key paths (used as a set, easier to manipulate than a []string): // of key paths (used as a set, easier to manipulate than a []string):
// - each path is merged into a single key string, delimited with v.keyDelim (= ".") // - each path is merged into a single key string, delimited with v.keyDelim (= ".")
// - if a path is shadowed by an earlier value in the initial shadow map, // - if a path is shadowed by an earlier value in the initial shadow map,
// it is skipped. // it is skipped.
//
// The resulting set of paths is merged to the given shadow set at the same time. // The resulting set of paths is merged to the given shadow set at the same time.
func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interface{}, prefix string) map[string]bool { func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interface{}, prefix string) map[string]bool {
if shadow != nil && prefix != "" && shadow[prefix] { if shadow != nil && prefix != "" && shadow[prefix] {