Add ErrorUnused config where it is an error if there are unused keys
diff --git a/mapstructure.go b/mapstructure.go
index 151741c..231df40 100644
--- a/mapstructure.go
+++ b/mapstructure.go
@@ -11,12 +11,18 @@
"errors"
"fmt"
"reflect"
+ "sort"
"strings"
)
// DecoderConfig is the configuration that is used to create a new decoder
// and allows customization of various aspects of decoding.
type DecoderConfig struct {
+ // If ErrorUnused is true, then it is an error for there to exist
+ // keys in the original map that were unused in the decoding process
+ // (extra keys).
+ ErrorUnused bool
+
// Metadata is the struct that will contain extra metadata about
// the decoding. If this is nil, then no metadata will be tracked.
Metadata *Metadata
@@ -372,6 +378,17 @@
}
}
+ if d.config.ErrorUnused && len(dataValKeysUnused) > 0 {
+ keys := make([]string, 0, len(dataValKeysUnused))
+ for rawKey, _ := range dataValKeysUnused {
+ keys = append(keys, rawKey.(string))
+ }
+ sort.Strings(keys)
+
+ err := fmt.Errorf("'%s' has invalid keys: %s", name, strings.Join(keys, ", "))
+ errors = appendErrors(errors, err)
+ }
+
if len(errors) > 0 {
return &Error{errors}
}
diff --git a/mapstructure_test.go b/mapstructure_test.go
index cc1f249..b3e1363 100644
--- a/mapstructure_test.go
+++ b/mapstructure_test.go
@@ -123,6 +123,31 @@
}
}
+func TestDecoder_ErrorUnused(t *testing.T) {
+ t.Parallel()
+
+ input := map[string]interface{}{
+ "vstring": "hello",
+ "foo": "bar",
+ }
+
+ var result Basic
+ config := &DecoderConfig{
+ ErrorUnused: true,
+ Result: &result,
+ }
+
+ decoder, err := NewDecoder(config)
+ if err != nil {
+ t.Fatalf("err: %s", err)
+ }
+
+ err = decoder.Decode(input)
+ if err == nil {
+ t.Fatal("expected error")
+ }
+}
+
func TestMap(t *testing.T) {
t.Parallel()