mirror of
https://github.com/yusing/godoxy.git
synced 2025-05-20 12:42:34 +02:00
support deserialize into anonymous fields
This commit is contained in:
parent
e53d6d216d
commit
8a9cb2527e
2 changed files with 76 additions and 36 deletions
|
@ -141,6 +141,28 @@ func Serialize(data any) (SerializedObject, error) {
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func extractFields(t reflect.Type) []reflect.StructField {
|
||||||
|
for t.Kind() == reflect.Ptr {
|
||||||
|
t = t.Elem()
|
||||||
|
}
|
||||||
|
if t.Kind() != reflect.Struct {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var fields []reflect.StructField
|
||||||
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
field := t.Field(i)
|
||||||
|
if !field.IsExported() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if field.Anonymous {
|
||||||
|
fields = append(fields, extractFields(field.Type)...)
|
||||||
|
} else {
|
||||||
|
fields = append(fields, field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fields
|
||||||
|
}
|
||||||
|
|
||||||
// Deserialize takes a SerializedObject and a target value, and assigns the values in the SerializedObject to the target value.
|
// Deserialize takes a SerializedObject and a target value, and assigns the values in the SerializedObject to the target value.
|
||||||
// Deserialize ignores case differences between the field names in the SerializedObject and the target.
|
// Deserialize ignores case differences between the field names in the SerializedObject and the target.
|
||||||
//
|
//
|
||||||
|
@ -183,7 +205,8 @@ func Deserialize(src SerializedObject, dst any) E.Error {
|
||||||
needValidate := false
|
needValidate := false
|
||||||
mapping := make(map[string]reflect.Value)
|
mapping := make(map[string]reflect.Value)
|
||||||
fieldName := make(map[string]string)
|
fieldName := make(map[string]string)
|
||||||
for _, field := range reflect.VisibleFields(dstT) {
|
fields := extractFields(dstT)
|
||||||
|
for _, field := range fields {
|
||||||
var key string
|
var key string
|
||||||
if jsonTag, ok := field.Tag.Lookup("json"); ok {
|
if jsonTag, ok := field.Tag.Lookup("json"); ok {
|
||||||
key = strings.Split(jsonTag, ",")[0]
|
key = strings.Split(jsonTag, ",")[0]
|
||||||
|
|
|
@ -9,44 +9,61 @@ import (
|
||||||
. "github.com/yusing/go-proxy/internal/utils/testing"
|
. "github.com/yusing/go-proxy/internal/utils/testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
type S = struct {
|
func TestSerializeDeserialize(t *testing.T) {
|
||||||
I int
|
type S struct {
|
||||||
S string
|
I int
|
||||||
IS []int
|
S string
|
||||||
SS []string
|
IS []int
|
||||||
MSI map[string]int
|
SS []string
|
||||||
MIS map[int]string
|
MSI map[string]int
|
||||||
|
MIS map[int]string
|
||||||
|
}
|
||||||
|
|
||||||
|
var testStruct = S{
|
||||||
|
I: 1,
|
||||||
|
S: "hello",
|
||||||
|
IS: []int{1, 2, 3},
|
||||||
|
SS: []string{"a", "b", "c"},
|
||||||
|
MSI: map[string]int{"a": 1, "b": 2, "c": 3},
|
||||||
|
MIS: map[int]string{1: "a", 2: "b", 3: "c"},
|
||||||
|
}
|
||||||
|
|
||||||
|
var testStructSerialized = map[string]any{
|
||||||
|
"I": 1,
|
||||||
|
"S": "hello",
|
||||||
|
"IS": []int{1, 2, 3},
|
||||||
|
"SS": []string{"a", "b", "c"},
|
||||||
|
"MSI": map[string]int{"a": 1, "b": 2, "c": 3},
|
||||||
|
"MIS": map[int]string{1: "a", 2: "b", 3: "c"},
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("serialize", func(t *testing.T) {
|
||||||
|
s, err := Serialize(testStruct)
|
||||||
|
ExpectNoError(t, err)
|
||||||
|
ExpectDeepEqual(t, s, testStructSerialized)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("deserialize", func(t *testing.T) {
|
||||||
|
var s2 S
|
||||||
|
err := Deserialize(testStructSerialized, &s2)
|
||||||
|
ExpectNoError(t, err)
|
||||||
|
ExpectDeepEqual(t, s2, testStruct)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var testStruct = S{
|
func TestDeserializeAnonymousField(t *testing.T) {
|
||||||
I: 1,
|
type Anon struct {
|
||||||
S: "hello",
|
A, B int
|
||||||
IS: []int{1, 2, 3},
|
}
|
||||||
SS: []string{"a", "b", "c"},
|
var s struct {
|
||||||
MSI: map[string]int{"a": 1, "b": 2, "c": 3},
|
Anon
|
||||||
MIS: map[int]string{1: "a", 2: "b", 3: "c"},
|
C int
|
||||||
}
|
}
|
||||||
|
err := Deserialize(map[string]any{"a": 1, "b": 2, "c": 3}, &s)
|
||||||
var testStructSerialized = map[string]any{
|
|
||||||
"I": 1,
|
|
||||||
"S": "hello",
|
|
||||||
"IS": []int{1, 2, 3},
|
|
||||||
"SS": []string{"a", "b", "c"},
|
|
||||||
"MSI": map[string]int{"a": 1, "b": 2, "c": 3},
|
|
||||||
"MIS": map[int]string{1: "a", 2: "b", 3: "c"},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSerialize(t *testing.T) {
|
|
||||||
s, err := Serialize(testStruct)
|
|
||||||
ExpectNoError(t, err)
|
ExpectNoError(t, err)
|
||||||
ExpectDeepEqual(t, s, testStructSerialized)
|
ExpectEqual(t, s.A, 1)
|
||||||
}
|
ExpectEqual(t, s.B, 2)
|
||||||
|
ExpectEqual(t, s.C, 3)
|
||||||
func TestDeserialize(t *testing.T) {
|
|
||||||
var s S
|
|
||||||
err := Deserialize(testStructSerialized, &s)
|
|
||||||
ExpectNoError(t, err)
|
|
||||||
ExpectDeepEqual(t, s, testStruct)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStringIntConvert(t *testing.T) {
|
func TestStringIntConvert(t *testing.T) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue