From a593aea01def93ca850dcc935abd809a9fa47772 Mon Sep 17 00:00:00 2001 From: Nikita Podshivalov Date: Wed, 19 Oct 2022 09:40:18 +0300 Subject: [PATCH] added allowEmptyMap option --- viper.go | 18 ++++++++++++++++++ viper_test.go | 12 ++++++++++++ 2 files changed, 30 insertions(+) diff --git a/viper.go b/viper.go index 5f76cc0..b4a9ef8 100644 --- a/viper.go +++ b/viper.go @@ -205,6 +205,7 @@ type Viper struct { automaticEnvApplied bool envKeyReplacer StringReplacer allowEmptyEnv bool + allowEmptyMap bool config map[string]interface{} override map[string]interface{} @@ -526,6 +527,15 @@ func (v *Viper) mergeWithEnvPrefix(in string) string { return strings.ToUpper(in) } +// AllowEmptyMap tells Viper to consider set, +// but empty maps as valid values instead of falling back. +// For backward compatibility reasons this is false by default. +func AllowEmptyMap(allowEmptyMap bool) { v.AllowEmptyMap(allowEmptyMap) } + +func (v *Viper) AllowEmptyMap(allowEmptyMap bool) { + v.allowEmptyMap = allowEmptyMap +} + // AllowEmptyEnv tells Viper to consider set, // but empty environment variables as valid values instead of falling back. // For backward compatibility reasons this is false by default. @@ -2011,6 +2021,14 @@ func (v *Viper) flattenAndMergeMap(shadow map[string]bool, m map[string]interfac shadow[strings.ToLower(fullKey)] = true continue } + + if v.allowEmptyMap { + if len(val.(map[string]interface{})) == 0 { + shadow[strings.ToLower(fullKey)] = true + continue + } + } + // recursively merge to shadow map shadow = v.flattenAndMergeMap(shadow, m2, fullKey) } diff --git a/viper_test.go b/viper_test.go index 926ffc2..6ce1d3e 100644 --- a/viper_test.go +++ b/viper_test.go @@ -60,6 +60,8 @@ type testUnmarshalExtra struct { var tomlExample = []byte(` title = "TOML Example" +[empty.map] + [owner] organization = "MongoDB" Bio = "MongoDB Chief Developer Advocate & Hacker at Large" @@ -669,6 +671,16 @@ func TestEmptyEnv_Allowed(t *testing.T) { assert.Equal(t, "Cake", Get("name")) } +func TestEmptyMap_Allowed(t *testing.T) { + initTOML() + AllowEmptyMap(true) + + allkeys := sort.StringSlice(AllKeys()) + allkeys.Sort() + + assert.Equal(t, sort.StringSlice(sort.StringSlice{"empty.map", "owner.bio", "owner.dob", "owner.organization", "title"}), allkeys) +} + func TestEnvPrefix(t *testing.T) { initJSON()