Start implementing support for multiple errors
diff --git a/mapstructure.go b/mapstructure.go
index d83ad0e..b61070f 100644
--- a/mapstructure.go
+++ b/mapstructure.go
@@ -14,6 +14,16 @@
"strings"
)
+// Error implements the error interface and can represents multiple
+// errors that occur in the course of a single decode.
+type Error struct {
+ Errors []string
+}
+
+func (e *Error) Error() string {
+ return fmt.Sprintf("%d error(s) decoding", len(e.Errors))
+}
+
// Decode takes a map and uses reflection to convert it into the
// given Go native structure. val must be a pointer to a struct.
func Decode(m map[string]interface{}, rawVal interface{}) error {
@@ -169,6 +179,8 @@
name, dataValType.Key().Kind())
}
+ errors := make([]string, 0)
+
valType := val.Type()
for i := 0; i < valType.NumField(); i++ {
fieldType := valType.Field(i)
@@ -202,9 +214,18 @@
fieldName = fmt.Sprintf("%s.%s", name, fieldName)
if err := decode(fieldName, rawMapVal.Interface(), field); err != nil {
- return err
+ switch e := err.(type) {
+ case *Error:
+ errors = append(errors, e.Errors...)
+ default:
+ errors = append(errors, e.Error())
+ }
}
}
+ if len(errors) > 0 {
+ return &Error{errors}
+ }
+
return nil
}
diff --git a/mapstructure_test.go b/mapstructure_test.go
index e913b6c..713e621 100644
--- a/mapstructure_test.go
+++ b/mapstructure_test.go
@@ -287,7 +287,13 @@
t.FailNow()
}
- if err.Error() != "'root.Vstring' expected type 'string', got 'int'" {
+ derr, ok := err.(*Error)
+ if !ok {
+ t.Errorf("error should be kind of Error, instead: %#v", err)
+ t.FailNow()
+ }
+
+ if derr.Errors[0] != "'root.Vstring' expected type 'string', got 'int'" {
t.Errorf("got unexpected error: %s", err)
}
}