improve gconv.Struct* by doing the converting using json.Unmarshal if given params is json string/bytes

This commit is contained in:
Jack
2020-10-21 14:09:16 +08:00
parent 43441a8218
commit 2eb2b89432
3 changed files with 47 additions and 0 deletions

View File

@ -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 <params> 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.

View File

@ -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 <params> 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 <params> to map slice.
paramsMaps := Maps(params)
// If <params> is an empty slice, no conversion.
if len(paramsMaps) == 0 {

View File

@ -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)
})
}