mirror of
https://gitee.com/johng/gf
synced 2026-06-06 16:21:40 +08:00
improve gconv.Struct* by doing the converting using json.Unmarshal if given params is json string/bytes
This commit is contained in:
@ -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.
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user