mirror of
https://github.com/yusing/godoxy.git
synced 2025-05-19 20:32:35 +02:00
fix: unmarshal
This commit is contained in:
parent
2ec1de96d5
commit
eb7495b02a
2 changed files with 34 additions and 29 deletions
|
@ -308,6 +308,20 @@ func isIntFloat(t reflect.Kind) bool {
|
|||
return t >= reflect.Bool && t <= reflect.Float64
|
||||
}
|
||||
|
||||
func itoa(v reflect.Value) string {
|
||||
switch v.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return strconv.FormatInt(v.Int(), 10)
|
||||
case reflect.Bool:
|
||||
return strconv.FormatBool(v.Bool())
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return strconv.FormatUint(v.Uint(), 10)
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return strconv.FormatFloat(v.Float(), 'f', -1, 64)
|
||||
}
|
||||
panic("invalid call on itoa")
|
||||
}
|
||||
|
||||
// Convert attempts to convert the src to dst.
|
||||
//
|
||||
// If src is a map, it is deserialized into dst.
|
||||
|
@ -365,20 +379,12 @@ func Convert(src reflect.Value, dst reflect.Value) gperr.Error {
|
|||
}
|
||||
case isIntFloat(srcKind):
|
||||
if dst.Kind() == reflect.String {
|
||||
var strV string
|
||||
switch {
|
||||
case src.CanInt():
|
||||
strV = strconv.FormatInt(src.Int(), 10)
|
||||
case srcKind == reflect.Bool:
|
||||
strV = strconv.FormatBool(src.Bool())
|
||||
case src.CanUint():
|
||||
strV = strconv.FormatUint(src.Uint(), 10)
|
||||
case src.CanFloat():
|
||||
strV = strconv.FormatFloat(src.Float(), 'f', -1, 64)
|
||||
}
|
||||
dst.Set(reflect.ValueOf(strV))
|
||||
dst.Set(reflect.ValueOf(itoa(src)))
|
||||
return nil
|
||||
}
|
||||
if dst.Addr().Type().Implements(typeStrParser) {
|
||||
return Convert(reflect.ValueOf(itoa(src)), dst)
|
||||
}
|
||||
if !isIntFloat(dstT.Kind()) || !src.CanConvert(dstT) {
|
||||
return ErrUnsupportedConversion.Subjectf("%s to %s", srcT, dstT)
|
||||
}
|
||||
|
@ -445,7 +451,8 @@ func ConvertString(src string, dst reflect.Value) (convertible bool, convErr gpe
|
|||
dst = dst.Elem()
|
||||
dstT = dst.Type()
|
||||
}
|
||||
if dst.Kind() == reflect.String {
|
||||
dstKind := dst.Kind()
|
||||
if dstKind == reflect.String {
|
||||
dst.SetString(src)
|
||||
return
|
||||
}
|
||||
|
@ -482,7 +489,7 @@ func ConvertString(src string, dst reflect.Value) (convertible bool, convErr gpe
|
|||
setSameOrEmbedddType(reflect.ValueOf(ipnet).Elem(), dst)
|
||||
return
|
||||
}
|
||||
if dstKind := dst.Kind(); isIntFloat(dstKind) {
|
||||
if isIntFloat(dstKind) {
|
||||
var i any
|
||||
var err error
|
||||
switch {
|
||||
|
@ -512,7 +519,14 @@ func ConvertString(src string, dst reflect.Value) (convertible bool, convErr gpe
|
|||
}
|
||||
// yaml like
|
||||
var tmp any
|
||||
switch dst.Kind() {
|
||||
switch dstKind {
|
||||
case reflect.Map, reflect.Struct:
|
||||
rawMap := make(SerializedObject)
|
||||
err := yaml.Unmarshal([]byte(src), &rawMap)
|
||||
if err != nil {
|
||||
return true, gperr.Wrap(err)
|
||||
}
|
||||
tmp = rawMap
|
||||
case reflect.Slice:
|
||||
src = strings.TrimSpace(src)
|
||||
isMultiline := strings.ContainsRune(src, '\n')
|
||||
|
@ -538,13 +552,6 @@ func ConvertString(src string, dst reflect.Value) (convertible bool, convErr gpe
|
|||
return true, gperr.Wrap(err)
|
||||
}
|
||||
tmp = sl
|
||||
case reflect.Map, reflect.Struct:
|
||||
rawMap := make(SerializedObject)
|
||||
err := yaml.Unmarshal([]byte(src), &rawMap)
|
||||
if err != nil {
|
||||
return true, gperr.Wrap(err)
|
||||
}
|
||||
tmp = rawMap
|
||||
default:
|
||||
return false, nil
|
||||
}
|
||||
|
|
|
@ -7,9 +7,7 @@ import (
|
|||
"reflect"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/yusing/go-proxy/internal/utils/strutils"
|
||||
. "github.com/yusing/go-proxy/internal/utils/testing"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
@ -95,12 +93,12 @@ func TestStringIntConvert(t *testing.T) {
|
|||
field := refl.Elem().Field(i)
|
||||
t.Run(fmt.Sprintf("field_%s", field.Type().Name()), func(t *testing.T) {
|
||||
ok, err := ConvertString("127", field)
|
||||
ExpectTrue(t, ok)
|
||||
ExpectNoError(t, err)
|
||||
ExpectTrue(t, ok)
|
||||
ExpectNoError(t, err)
|
||||
ExpectEqualValues(t, field.Interface(), 127)
|
||||
|
||||
err = Convert(reflect.ValueOf(uint8(64)), field)
|
||||
ExpectNoError(t, err)
|
||||
ExpectNoError(t, err)
|
||||
ExpectEqualValues(t, field.Interface(), 64)
|
||||
})
|
||||
}
|
||||
|
@ -212,8 +210,8 @@ func BenchmarkStringToMapYAML(b *testing.B) {
|
|||
|
||||
func TestStringToStruct(t *testing.T) {
|
||||
type T struct {
|
||||
A string
|
||||
B int
|
||||
A string
|
||||
B int
|
||||
}
|
||||
t.Run("yaml-like simple", func(t *testing.T) {
|
||||
var dst T
|
||||
|
|
Loading…
Add table
Reference in a new issue