feat: support uuid.UUID in mapping (#2537)
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package mapping
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -318,6 +319,28 @@ func (u *Unmarshaler) processFieldStructWithMap(field reflect.StructField, value
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *Unmarshaler) processFieldTextUnmarshaler(field reflect.StructField, value reflect.Value,
|
||||
mapValue interface{}) (bool, error) {
|
||||
var tval encoding.TextUnmarshaler
|
||||
var ok bool
|
||||
|
||||
if field.Type.Kind() == reflect.Ptr {
|
||||
tval, ok = value.Interface().(encoding.TextUnmarshaler)
|
||||
} else {
|
||||
tval, ok = value.Addr().Interface().(encoding.TextUnmarshaler)
|
||||
}
|
||||
if ok {
|
||||
switch mv := mapValue.(type) {
|
||||
case string:
|
||||
return true, tval.UnmarshalText([]byte(mv))
|
||||
case []byte:
|
||||
return true, tval.UnmarshalText(mv)
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (u *Unmarshaler) processNamedField(field reflect.StructField, value reflect.Value,
|
||||
m Valuer, fullName string) error {
|
||||
key, opts, err := u.parseOptionsWithContext(field, m, fullName)
|
||||
@@ -348,8 +371,16 @@ func (u *Unmarshaler) processNamedFieldWithValue(field reflect.StructField, valu
|
||||
return fmt.Errorf("field %s mustn't be nil", key)
|
||||
}
|
||||
|
||||
if !value.CanSet() {
|
||||
return fmt.Errorf("field %s is not settable", key)
|
||||
}
|
||||
|
||||
maybeNewValue(field, value)
|
||||
|
||||
if yes, err := u.processFieldTextUnmarshaler(field, value, mapValue); yes {
|
||||
return err
|
||||
}
|
||||
|
||||
fieldKind := Deref(field.Type).Kind()
|
||||
switch fieldKind {
|
||||
case reflect.Array, reflect.Map, reflect.Slice, reflect.Struct:
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/zeromicro/go-zero/core/stringx"
|
||||
)
|
||||
@@ -537,10 +538,12 @@ func TestUnmarshalStringMapFromUnsupportedType(t *testing.T) {
|
||||
|
||||
func TestUnmarshalStringMapFromNotSettableValue(t *testing.T) {
|
||||
var v struct {
|
||||
sort map[string]string `key:"sort"`
|
||||
sort map[string]string `key:"sort"`
|
||||
psort *map[string]string `key:"sort"`
|
||||
}
|
||||
m := map[string]interface{}{
|
||||
"sort": `{"value":"ascend","emptyStr":""}`,
|
||||
"sort": `{"value":"ascend","emptyStr":""}`,
|
||||
"psort": `{"value":"ascend","emptyStr":""}`,
|
||||
}
|
||||
|
||||
ast := assert.New(t)
|
||||
@@ -3018,6 +3021,24 @@ func TestUnmarshalJsonReaderArrayString(t *testing.T) {
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestGoogleUUID(t *testing.T) {
|
||||
var val struct {
|
||||
Uid uuid.UUID `json:"uid,optional"`
|
||||
Uidp *uuid.UUID `json:"uidp,optional"`
|
||||
}
|
||||
assert.NoError(t, UnmarshalJsonBytes([]byte(`{
|
||||
"uid": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
|
||||
"uidp": "6ba7b810-9dad-11d1-80b4-00c04fd430c9"}`), &val))
|
||||
assert.Equal(t, "6ba7b810-9dad-11d1-80b4-00c04fd430c8", val.Uid.String())
|
||||
assert.Equal(t, "6ba7b810-9dad-11d1-80b4-00c04fd430c9", val.Uidp.String())
|
||||
assert.NoError(t, UnmarshalJsonMap(map[string]interface{}{
|
||||
"uid": []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c1"),
|
||||
"uidp": []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c2"),
|
||||
}, &val))
|
||||
assert.Equal(t, "6ba7b810-9dad-11d1-80b4-00c04fd430c1", val.Uid.String())
|
||||
assert.Equal(t, "6ba7b810-9dad-11d1-80b4-00c04fd430c2", val.Uidp.String())
|
||||
}
|
||||
|
||||
func BenchmarkDefaultValue(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
var a struct {
|
||||
|
||||
Reference in New Issue
Block a user