diff --git a/utils/reflect.go b/utils/reflect.go index 3f2bba7fd..a54afcabc 100644 --- a/utils/reflect.go +++ b/utils/reflect.go @@ -104,3 +104,20 @@ func ReflectFieldAsString(intf interface{}, fldName, extraFieldsLabel string) (s return "", fmt.Errorf("Cannot convert to string field type: %s", field.Kind().String()) } } + +// AsMapStringIface converts an item (mostly struct) as map[string]interface{} +func AsMapStringIface(item interface{}) (map[string]interface{}, error) { + out := make(map[string]interface{}) + v := reflect.ValueOf(item) + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + if v.Kind() != reflect.Struct { // Only structs for now + return nil, fmt.Errorf("AsMapStringIface only accepts structs; got %T", v) + } + typ := v.Type() + for i := 0; i < v.NumField(); i++ { + out[typ.Field(i).Name] = v.Field(i).Interface() + } + return out, nil +} diff --git a/utils/reflect_test.go b/utils/reflect_test.go index 12061b269..39785019d 100644 --- a/utils/reflect_test.go +++ b/utils/reflect_test.go @@ -19,6 +19,7 @@ along with this program. If not, see package utils import ( + "reflect" "testing" ) @@ -116,3 +117,25 @@ func TestReflectFieldAsStringOnMap(t *testing.T) { t.Error("Received: %s", strVal) } } + +func TestReflectAsMapStringIface(t *testing.T) { + mystruct := struct { + Title string + Count int + Count64 int64 + Val float64 + ExtraFields map[string]interface{} + }{"Title1", 5, 6, 7.3, map[string]interface{}{"a": "Title2", "b": 15, "c": int64(16), "d": 17.3}} + expectOutMp := map[string]interface{}{ + "Title": "Title1", + "Count": 5, + "Count64": int64(6), + "Val": 7.3, + "ExtraFields": map[string]interface{}{"a": "Title2", "b": 15, "c": int64(16), "d": 17.3}, + } + if outMp, err := AsMapStringIface(mystruct); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(expectOutMp, outMp) { + t.Errorf("Expecting: %+v, received: %+v", expectOutMp, outMp) + } +}