This commit is contained in:
withchao 2023-01-16 19:14:05 +08:00
parent 21ea555183
commit 38013d272b

View File

@ -6,25 +6,6 @@ import (
"reflect" "reflect"
) )
func setBaseValue(from, to reflect.Value) {
if isBaseNil(from) {
return
}
var l int
t := to.Type()
for t.Kind() == reflect.Ptr {
l++
t = t.Elem()
}
v := baseValue(from)
for i := 0; i < l; i++ {
t := reflect.New(v.Type())
t.Elem().Set(v)
v = t
}
to.Set(v)
}
func CopyAny(from, to interface{}) { func CopyAny(from, to interface{}) {
t := reflect.ValueOf(to) t := reflect.ValueOf(to)
if t.Kind() == reflect.Ptr { if t.Kind() == reflect.Ptr {
@ -50,31 +31,35 @@ func copyAny(from, to reflect.Value) {
if isBaseNil(to) { if isBaseNil(to) {
to.Set(getBaseZeroValue(to.Type())) to.Set(getBaseZeroValue(to.Type()))
} }
btfrom := baseType(from.Type()) btFrom := baseType(from.Type())
btto := baseType(to.Type()) btTo := baseType(to.Type())
if typeEq(btfrom, btto) { if btTo.Kind() == reflect.Interface || typeEq(btFrom, btTo) {
setBaseValue(from, to) setBaseValue(from, to)
return return
} }
if _, ok := wrapType[btto.String()]; ok { // string -> wrapperspb.StringValue if _, ok := wrapType[btTo.String()]; ok { // string -> wrapperspb.StringValue
val := reflect.New(btto).Elem() val := reflect.New(btTo).Elem()
copyAny(from, val.FieldByName("Value")) copyAny(from, val.FieldByName("Value"))
setBaseValue(val, to) setBaseValue(val, to)
return return
} }
if _, ok := wrapType[btfrom.String()]; ok { // wrapperspb.StringValue -> string if _, ok := wrapType[btFrom.String()]; ok { // wrapperspb.StringValue -> string
copyAny(baseValue(from).FieldByName("Value"), to) copyAny(baseValue(from).FieldByName("Value"), to)
return return
} }
if btfrom.Kind() == reflect.Struct && btto.Kind() == reflect.Struct { if btFrom.Kind() == reflect.Struct && btTo.Kind() == reflect.Struct {
copyStruct(baseValue(from), baseValue(to)) copyStruct(baseValue(from), baseValue(to))
return return
} }
if btfrom.Kind() == reflect.Slice && btto.Kind() == reflect.Slice { if btFrom.Kind() == reflect.Slice && btTo.Kind() == reflect.Slice {
copySlice(baseValue(from), baseValue(to)) copySlice(baseValue(from), baseValue(to))
return return
} }
if btto.Kind() == reflect.String { if btFrom.Kind() == reflect.Map && btTo.Kind() == reflect.Map {
copyMap(baseValue(from), baseValue(to))
return
}
if btTo.Kind() == reflect.String {
if isBaseNil(to) { if isBaseNil(to) {
to.Set(getBaseZeroValue(baseType(to.Type()))) to.Set(getBaseZeroValue(baseType(to.Type())))
} }
@ -84,6 +69,26 @@ func copyAny(from, to reflect.Value) {
if toNumber(from, to) { if toNumber(from, to) {
return return
} }
}
func setBaseValue(from, to reflect.Value) {
if isBaseNil(from) {
return
}
var l int
t := to.Type()
for t.Kind() == reflect.Ptr {
l++
t = t.Elem()
}
v := baseValue(from)
for i := 0; i < l; i++ {
t := reflect.New(v.Type())
t.Elem().Set(v)
v = t
}
to.Set(v)
} }
func getBaseZeroValue(t reflect.Type) reflect.Value { func getBaseZeroValue(t reflect.Type) reflect.Value {
@ -121,15 +126,6 @@ func baseType(t reflect.Type) reflect.Type {
return t return t
} }
func baseLayer(t reflect.Type) int {
var layer int
for t.Kind() == reflect.Ptr {
layer++
t = t.Elem()
}
return layer
}
func typeEq(t1, t2 reflect.Type) bool { func typeEq(t1, t2 reflect.Type) bool {
return t1.String() == t2.String() return t1.String() == t2.String()
} }
@ -174,59 +170,72 @@ func copySlice(from, to reflect.Value) {
to.Set(temp) to.Set(temp)
} }
func copyMap(from, to reflect.Value) {
// todo copy map
}
func toString(value reflect.Value) string { func toString(value reflect.Value) string {
if value.Kind() == reflect.Slice { if value.Kind() == reflect.Slice {
switch value.Type().String() { switch value.Type().String() {
case "[]uint8": case "[]uint8": // []byte -> []uint8
return string(value.Interface().([]uint8)) return string(value.Interface().([]uint8))
case "[]int32": case "[]int32": // []rune -> []int32
return string(value.Interface().([]int32)) return string(value.Interface().([]int32))
} }
} }
return fmt.Sprint(value.Interface()) return fmt.Sprint(value.Interface())
} }
func toNumber(from1, to1 reflect.Value) bool { func toNumber(from, to reflect.Value) bool {
if isBaseNil(to1) { initTo := func() {
to1.Set(getBaseZeroValue(to1.Type())) if isBaseNil(to) {
to.Set(getBaseZeroValue(to.Type()))
} }
from := baseValue(from1) }
to := baseValue(to1) switch baseValue(from).Kind() {
switch from.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
switch to.Kind() { switch baseValue(to).Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
to.SetInt(from.Int()) initTo()
baseValue(to).SetInt(baseValue(from).Int())
return true return true
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
to.SetUint(uint64(from.Int())) initTo()
baseValue(to).SetUint(uint64(baseValue(from).Int()))
return true return true
case reflect.Float64, reflect.Float32: case reflect.Float64, reflect.Float32:
to.SetFloat(float64(from.Int())) initTo()
baseValue(to).SetFloat(float64(baseValue(from).Int()))
return true return true
} }
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
switch to.Kind() { switch baseValue(to).Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
to.SetInt(int64(from.Uint())) initTo()
baseValue(to).SetInt(int64(baseValue(from).Uint()))
return true return true
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
to.SetInt(int64(from.Uint())) initTo()
baseValue(to).SetInt(int64(baseValue(from).Uint()))
return true return true
case reflect.Float64, reflect.Float32: case reflect.Float64, reflect.Float32:
to.SetFloat(float64(from.Uint())) initTo()
baseValue(to).SetFloat(float64(baseValue(from).Uint()))
return true return true
} }
case reflect.Float64, reflect.Float32: case reflect.Float64, reflect.Float32:
switch to.Kind() { switch baseValue(to).Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
to.SetInt(int64(from.Float())) initTo()
baseValue(to).SetInt(int64(baseValue(from).Float()))
return true return true
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
to.SetUint(uint64(from.Float())) initTo()
baseValue(to).SetUint(uint64(baseValue(from).Float()))
return true return true
case reflect.Float64, reflect.Float32: case reflect.Float64, reflect.Float32:
to.SetFloat(from.Float()) initTo()
baseValue(to).SetFloat(baseValue(from).Float())
return true return true
} }
} }