From 509e2aef2170ad60d5d1be79920f05dd5a371e94 Mon Sep 17 00:00:00 2001 From: czou Date: Wed, 27 Mar 2019 23:51:56 -0400 Subject: [PATCH] entity_unmarshal: Check if type is struct before calling NumField() --- entity_test.go | 4 ++++ entity_unmarshal.go | 44 +++++++++++++++++++++++--------------------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/entity_test.go b/entity_test.go index ddb8ac9..a08e726 100644 --- a/entity_test.go +++ b/entity_test.go @@ -413,6 +413,10 @@ var sampleEntityJSON = `{ "latitude": 38.9243983751914, "longitude": -77.2178385786886 }, + "googleAttributes": { + "wi_fi": ["free_wi_fi"], + "welcomes_dogs": ["true"] + }, "meta": { "accountId": "3549951188342570541", "uid": "b3JxON", diff --git a/entity_unmarshal.go b/entity_unmarshal.go index c5b7ef8..05dad9c 100644 --- a/entity_unmarshal.go +++ b/entity_unmarshal.go @@ -7,32 +7,34 @@ import ( ) func unmarshal(i interface{}, m map[string]interface{}) interface{} { - var jsonTagToKey = map[string]string{} val := Indirect(reflect.ValueOf(i)) - for i := 0; i < val.Type().NumField(); i++ { - field := val.Type().Field(i) - tag := strings.Replace(field.Tag.Get("json"), ",omitempty", "", -1) - jsonTagToKey[tag] = field.Name - } + if val.Kind() == reflect.Struct { + var jsonTagToKey = map[string]string{} + for i := 0; i < val.Type().NumField(); i++ { + field := val.Type().Field(i) + tag := strings.Replace(field.Tag.Get("json"), ",omitempty", "", -1) + jsonTagToKey[tag] = field.Name + } - for tag, val := range m { - if _, ok := jsonTagToKey[tag]; ok { - if val == nil { - v := Indirect(reflect.ValueOf(i)).FieldByName(jsonTagToKey[tag]) + for tag, val := range m { + if _, ok := jsonTagToKey[tag]; ok { + if val == nil { + v := Indirect(reflect.ValueOf(i)).FieldByName(jsonTagToKey[tag]) - // Check if double pointer - if v.Type().Kind() == reflect.Ptr { - t := v.Type() - for t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Ptr { - t = t.Elem() + // Check if double pointer + if v.Type().Kind() == reflect.Ptr { + t := v.Type() + for t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Ptr { + t = t.Elem() + } + typedNil := reflect.New(t) + Indirect(reflect.ValueOf(i)).FieldByName(jsonTagToKey[tag]).Set(reflect.ValueOf(typedNil.Interface())) } - typedNil := reflect.New(t) - Indirect(reflect.ValueOf(i)).FieldByName(jsonTagToKey[tag]).Set(reflect.ValueOf(typedNil.Interface())) + } else if vMap, ok := val.(map[string]interface{}); ok { + v := Indirect(reflect.ValueOf(i)).FieldByName(jsonTagToKey[tag]) + r := unmarshal(v.Interface(), vMap) + Indirect(reflect.ValueOf(i)).FieldByName(jsonTagToKey[tag]).Set(reflect.ValueOf(r)) } - } else if vMap, ok := val.(map[string]interface{}); ok { - v := Indirect(reflect.ValueOf(i)).FieldByName(jsonTagToKey[tag]) - r := unmarshal(v.Interface(), vMap) - Indirect(reflect.ValueOf(i)).FieldByName(jsonTagToKey[tag]).Set(reflect.ValueOf(r)) } } }