diff --git a/util/gconv/gconv_struct.go b/util/gconv/gconv_struct.go index f01d4c759..d08ace23a 100644 --- a/util/gconv/gconv_struct.go +++ b/util/gconv/gconv_struct.go @@ -10,6 +10,7 @@ import ( "fmt" "github.com/gogf/gf/errors/gerror" "github.com/gogf/gf/internal/empty" + "github.com/gogf/gf/internal/json" "reflect" "regexp" "strings" @@ -63,6 +64,18 @@ func doStruct(params interface{}, pointer interface{}, recursive bool, mapping . } }() + // If given is JSON, it then uses json.Unmarshal doing the converting. + switch r := params.(type) { + case []byte: + if json.Valid(r) { + return json.Unmarshal(r, pointer) + } + case string: + if paramsBytes := []byte(r); json.Valid(paramsBytes) { + return json.Unmarshal(paramsBytes, pointer) + } + } + // UnmarshalValue. // Assign value with interface UnmarshalValue. // Note that only pointer can implement interface UnmarshalValue. diff --git a/util/gconv/gconv_structs.go b/util/gconv/gconv_structs.go index 1885acc49..9c8c169de 100644 --- a/util/gconv/gconv_structs.go +++ b/util/gconv/gconv_structs.go @@ -8,6 +8,7 @@ package gconv import ( "github.com/gogf/gf/errors/gerror" + "github.com/gogf/gf/internal/json" "reflect" ) @@ -42,6 +43,18 @@ func doStructs(params interface{}, pointer interface{}, deep bool, mapping ...ma err = gerror.NewfSkip(1, "%v", e) } }() + // If given is JSON, it then uses json.Unmarshal doing the converting. + switch r := params.(type) { + case []byte: + if json.Valid(r) { + return json.Unmarshal(r, pointer) + } + case string: + if paramsBytes := []byte(r); json.Valid(paramsBytes) { + return json.Unmarshal(paramsBytes, pointer) + } + } + // Pointer type check. pointerRv, ok := pointer.(reflect.Value) if !ok { pointerRv = reflect.ValueOf(pointer) @@ -49,6 +62,7 @@ func doStructs(params interface{}, pointer interface{}, deep bool, mapping ...ma return gerror.Newf("pointer should be type of pointer, but got: %v", kind) } } + // Converting to map slice. paramsMaps := Maps(params) // If is an empty slice, no conversion. if len(paramsMaps) == 0 { diff --git a/util/gconv/gconv_z_unit_struct_test.go b/util/gconv/gconv_z_unit_struct_test.go index 1b5e0666b..f423d8010 100644 --- a/util/gconv/gconv_z_unit_struct_test.go +++ b/util/gconv/gconv_z_unit_struct_test.go @@ -981,3 +981,23 @@ func Test_Struct_To_Struct(t *testing.T) { t.Assert(TestA.Date, TestB.Date) }) } + +func Test_Struct_WithJson(t *testing.T) { + type A struct { + Name string + } + type B struct { + A + Score int + } + gtest.C(t, func(t *gtest.T) { + b1 := &B{} + b1.Name = "john" + b1.Score = 100 + b, _ := json.Marshal(b1) + b2 := &B{} + err := gconv.Struct(b, b2) + t.Assert(err, nil) + t.Assert(b2, b1) + }) +}