diff --git a/core/mapping/utils.go b/core/mapping/utils.go index a793ecbe..a6fff1a1 100644 --- a/core/mapping/utils.go +++ b/core/mapping/utils.go @@ -60,20 +60,6 @@ func Deref(t reflect.Type) reflect.Type { return t } -// DerefVal dereferences a value, if pointer value nil set new a value, returns is not a ptr element value. -func DerefVal(v reflect.Value) reflect.Value { - for { - if v.Kind() != reflect.Ptr { - break - } - if v.IsNil() { - v.Set(reflect.New(v.Type().Elem())) - } - v = v.Elem() - } - return v -} - // Repr returns the string representation of v. func Repr(v interface{}) string { if v == nil { @@ -157,6 +143,23 @@ func doParseKeyAndOptions(field reflect.StructField, value string) (string, *fie return key, &fieldOpts, nil } +// ensureValue ensures nested members not to be nil. +// If pointer value is nil, set to a new value. +func ensureValue(v reflect.Value) reflect.Value { + for { + if v.Kind() != reflect.Ptr { + break + } + + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + v = v.Elem() + } + + return v +} + func implicitValueRequiredStruct(tag string, tp reflect.Type) (bool, error) { numFields := tp.NumField() for i := 0; i < numFields; i++ { @@ -491,8 +494,8 @@ func setValue(kind reflect.Kind, value reflect.Value, str string) error { if !value.CanSet() { return errValueNotSettable } - value = DerefVal(value) + value = ensureValue(value) v, err := convertType(kind, str) if err != nil { return err diff --git a/core/mapping/utils_test.go b/core/mapping/utils_test.go index eac00beb..dec08584 100644 --- a/core/mapping/utils_test.go +++ b/core/mapping/utils_test.go @@ -100,7 +100,7 @@ func TestDerefValInt(t *testing.T) { for _, each := range cases { t.Run(each.t.String(), func(t *testing.T) { - assert.Equal(t, each.expect, DerefVal(each.t).Kind()) + assert.Equal(t, each.expect, ensureValue(each.t).Kind()) }) } }