feat: support uuid.UUID in mapping (#2537)

master
Kevin Wan 2 years ago committed by GitHub
parent de5c59aad3
commit f9beab1095
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,6 +1,7 @@
package mapping package mapping
import ( import (
"encoding"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
@ -318,6 +319,28 @@ func (u *Unmarshaler) processFieldStructWithMap(field reflect.StructField, value
return nil 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, func (u *Unmarshaler) processNamedField(field reflect.StructField, value reflect.Value,
m Valuer, fullName string) error { m Valuer, fullName string) error {
key, opts, err := u.parseOptionsWithContext(field, m, fullName) 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) 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) maybeNewValue(field, value)
if yes, err := u.processFieldTextUnmarshaler(field, value, mapValue); yes {
return err
}
fieldKind := Deref(field.Type).Kind() fieldKind := Deref(field.Type).Kind()
switch fieldKind { switch fieldKind {
case reflect.Array, reflect.Map, reflect.Slice, reflect.Struct: case reflect.Array, reflect.Map, reflect.Slice, reflect.Struct:

@ -8,6 +8,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/google/uuid"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/zeromicro/go-zero/core/stringx" "github.com/zeromicro/go-zero/core/stringx"
) )
@ -538,9 +539,11 @@ func TestUnmarshalStringMapFromUnsupportedType(t *testing.T) {
func TestUnmarshalStringMapFromNotSettableValue(t *testing.T) { func TestUnmarshalStringMapFromNotSettableValue(t *testing.T) {
var v struct { 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{}{ m := map[string]interface{}{
"sort": `{"value":"ascend","emptyStr":""}`, "sort": `{"value":"ascend","emptyStr":""}`,
"psort": `{"value":"ascend","emptyStr":""}`,
} }
ast := assert.New(t) ast := assert.New(t)
@ -3018,6 +3021,24 @@ func TestUnmarshalJsonReaderArrayString(t *testing.T) {
assert.NotNil(t, err) 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) { func BenchmarkDefaultValue(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
var a struct { var a struct {

Loading…
Cancel
Save