summaryrefslogtreecommitdiff
path: root/vendor/github.com/goccy/go-json/internal/decoder/assign.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/goccy/go-json/internal/decoder/assign.go')
-rw-r--r--vendor/github.com/goccy/go-json/internal/decoder/assign.go438
1 files changed, 438 insertions, 0 deletions
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/assign.go b/vendor/github.com/goccy/go-json/internal/decoder/assign.go
new file mode 100644
index 000000000..c53e6ad9f
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/assign.go
@@ -0,0 +1,438 @@
+package decoder
+
+import (
+ "fmt"
+ "reflect"
+ "strconv"
+)
+
+var (
+ nilValue = reflect.ValueOf(nil)
+)
+
+func AssignValue(src, dst reflect.Value) error {
+ if dst.Type().Kind() != reflect.Ptr {
+ return fmt.Errorf("invalid dst type. required pointer type: %T", dst.Type())
+ }
+ casted, err := castValue(dst.Elem().Type(), src)
+ if err != nil {
+ return err
+ }
+ dst.Elem().Set(casted)
+ return nil
+}
+
+func castValue(t reflect.Type, v reflect.Value) (reflect.Value, error) {
+ switch t.Kind() {
+ case reflect.Int:
+ vv, err := castInt(v)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(int(vv.Int())), nil
+ case reflect.Int8:
+ vv, err := castInt(v)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(int8(vv.Int())), nil
+ case reflect.Int16:
+ vv, err := castInt(v)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(int16(vv.Int())), nil
+ case reflect.Int32:
+ vv, err := castInt(v)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(int32(vv.Int())), nil
+ case reflect.Int64:
+ return castInt(v)
+ case reflect.Uint:
+ vv, err := castUint(v)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(uint(vv.Uint())), nil
+ case reflect.Uint8:
+ vv, err := castUint(v)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(uint8(vv.Uint())), nil
+ case reflect.Uint16:
+ vv, err := castUint(v)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(uint16(vv.Uint())), nil
+ case reflect.Uint32:
+ vv, err := castUint(v)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(uint32(vv.Uint())), nil
+ case reflect.Uint64:
+ return castUint(v)
+ case reflect.Uintptr:
+ vv, err := castUint(v)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(uintptr(vv.Uint())), nil
+ case reflect.String:
+ return castString(v)
+ case reflect.Bool:
+ return castBool(v)
+ case reflect.Float32:
+ vv, err := castFloat(v)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(float32(vv.Float())), nil
+ case reflect.Float64:
+ return castFloat(v)
+ case reflect.Array:
+ return castArray(t, v)
+ case reflect.Slice:
+ return castSlice(t, v)
+ case reflect.Map:
+ return castMap(t, v)
+ case reflect.Struct:
+ return castStruct(t, v)
+ }
+ return v, nil
+}
+
+func castInt(v reflect.Value) (reflect.Value, error) {
+ switch v.Type().Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return v, nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return reflect.ValueOf(int64(v.Uint())), nil
+ case reflect.String:
+ i64, err := strconv.ParseInt(v.String(), 10, 64)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(i64), nil
+ case reflect.Bool:
+ if v.Bool() {
+ return reflect.ValueOf(int64(1)), nil
+ }
+ return reflect.ValueOf(int64(0)), nil
+ case reflect.Float32, reflect.Float64:
+ return reflect.ValueOf(int64(v.Float())), nil
+ case reflect.Array:
+ if v.Len() > 0 {
+ return castInt(v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to int64 from empty array")
+ case reflect.Slice:
+ if v.Len() > 0 {
+ return castInt(v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to int64 from empty slice")
+ case reflect.Interface:
+ return castInt(reflect.ValueOf(v.Interface()))
+ case reflect.Map:
+ return nilValue, fmt.Errorf("failed to cast to int64 from map")
+ case reflect.Struct:
+ return nilValue, fmt.Errorf("failed to cast to int64 from struct")
+ case reflect.Ptr:
+ return castInt(v.Elem())
+ }
+ return nilValue, fmt.Errorf("failed to cast to int64 from %s", v.Type().Kind())
+}
+
+func castUint(v reflect.Value) (reflect.Value, error) {
+ switch v.Type().Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return reflect.ValueOf(uint64(v.Int())), nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return v, nil
+ case reflect.String:
+ u64, err := strconv.ParseUint(v.String(), 10, 64)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(u64), nil
+ case reflect.Bool:
+ if v.Bool() {
+ return reflect.ValueOf(uint64(1)), nil
+ }
+ return reflect.ValueOf(uint64(0)), nil
+ case reflect.Float32, reflect.Float64:
+ return reflect.ValueOf(uint64(v.Float())), nil
+ case reflect.Array:
+ if v.Len() > 0 {
+ return castUint(v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to uint64 from empty array")
+ case reflect.Slice:
+ if v.Len() > 0 {
+ return castUint(v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to uint64 from empty slice")
+ case reflect.Interface:
+ return castUint(reflect.ValueOf(v.Interface()))
+ case reflect.Map:
+ return nilValue, fmt.Errorf("failed to cast to uint64 from map")
+ case reflect.Struct:
+ return nilValue, fmt.Errorf("failed to cast to uint64 from struct")
+ case reflect.Ptr:
+ return castUint(v.Elem())
+ }
+ return nilValue, fmt.Errorf("failed to cast to uint64 from %s", v.Type().Kind())
+}
+
+func castString(v reflect.Value) (reflect.Value, error) {
+ switch v.Type().Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return reflect.ValueOf(fmt.Sprint(v.Int())), nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return reflect.ValueOf(fmt.Sprint(v.Uint())), nil
+ case reflect.String:
+ return v, nil
+ case reflect.Bool:
+ if v.Bool() {
+ return reflect.ValueOf("true"), nil
+ }
+ return reflect.ValueOf("false"), nil
+ case reflect.Float32, reflect.Float64:
+ return reflect.ValueOf(fmt.Sprint(v.Float())), nil
+ case reflect.Array:
+ if v.Len() > 0 {
+ return castString(v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to string from empty array")
+ case reflect.Slice:
+ if v.Len() > 0 {
+ return castString(v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to string from empty slice")
+ case reflect.Interface:
+ return castString(reflect.ValueOf(v.Interface()))
+ case reflect.Map:
+ return nilValue, fmt.Errorf("failed to cast to string from map")
+ case reflect.Struct:
+ return nilValue, fmt.Errorf("failed to cast to string from struct")
+ case reflect.Ptr:
+ return castString(v.Elem())
+ }
+ return nilValue, fmt.Errorf("failed to cast to string from %s", v.Type().Kind())
+}
+
+func castBool(v reflect.Value) (reflect.Value, error) {
+ switch v.Type().Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ switch v.Int() {
+ case 0:
+ return reflect.ValueOf(false), nil
+ case 1:
+ return reflect.ValueOf(true), nil
+ }
+ return nilValue, fmt.Errorf("failed to cast to bool from %d", v.Int())
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ switch v.Uint() {
+ case 0:
+ return reflect.ValueOf(false), nil
+ case 1:
+ return reflect.ValueOf(true), nil
+ }
+ return nilValue, fmt.Errorf("failed to cast to bool from %d", v.Uint())
+ case reflect.String:
+ b, err := strconv.ParseBool(v.String())
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(b), nil
+ case reflect.Bool:
+ return v, nil
+ case reflect.Float32, reflect.Float64:
+ switch v.Float() {
+ case 0:
+ return reflect.ValueOf(false), nil
+ case 1:
+ return reflect.ValueOf(true), nil
+ }
+ return nilValue, fmt.Errorf("failed to cast to bool from %f", v.Float())
+ case reflect.Array:
+ if v.Len() > 0 {
+ return castBool(v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to string from empty array")
+ case reflect.Slice:
+ if v.Len() > 0 {
+ return castBool(v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to string from empty slice")
+ case reflect.Interface:
+ return castBool(reflect.ValueOf(v.Interface()))
+ case reflect.Map:
+ return nilValue, fmt.Errorf("failed to cast to string from map")
+ case reflect.Struct:
+ return nilValue, fmt.Errorf("failed to cast to string from struct")
+ case reflect.Ptr:
+ return castBool(v.Elem())
+ }
+ return nilValue, fmt.Errorf("failed to cast to bool from %s", v.Type().Kind())
+}
+
+func castFloat(v reflect.Value) (reflect.Value, error) {
+ switch v.Type().Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return reflect.ValueOf(float64(v.Int())), nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return reflect.ValueOf(float64(v.Uint())), nil
+ case reflect.String:
+ f64, err := strconv.ParseFloat(v.String(), 64)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(f64), nil
+ case reflect.Bool:
+ if v.Bool() {
+ return reflect.ValueOf(float64(1)), nil
+ }
+ return reflect.ValueOf(float64(0)), nil
+ case reflect.Float32, reflect.Float64:
+ return v, nil
+ case reflect.Array:
+ if v.Len() > 0 {
+ return castFloat(v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to float64 from empty array")
+ case reflect.Slice:
+ if v.Len() > 0 {
+ return castFloat(v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to float64 from empty slice")
+ case reflect.Interface:
+ return castFloat(reflect.ValueOf(v.Interface()))
+ case reflect.Map:
+ return nilValue, fmt.Errorf("failed to cast to float64 from map")
+ case reflect.Struct:
+ return nilValue, fmt.Errorf("failed to cast to float64 from struct")
+ case reflect.Ptr:
+ return castFloat(v.Elem())
+ }
+ return nilValue, fmt.Errorf("failed to cast to float64 from %s", v.Type().Kind())
+}
+
+func castArray(t reflect.Type, v reflect.Value) (reflect.Value, error) {
+ kind := v.Type().Kind()
+ if kind == reflect.Interface {
+ return castArray(t, reflect.ValueOf(v.Interface()))
+ }
+ if kind != reflect.Slice && kind != reflect.Array {
+ return nilValue, fmt.Errorf("failed to cast to array from %s", kind)
+ }
+ if t.Elem() == v.Type().Elem() {
+ return v, nil
+ }
+ if t.Len() != v.Len() {
+ return nilValue, fmt.Errorf("failed to cast [%d]array from slice of %d length", t.Len(), v.Len())
+ }
+ ret := reflect.New(t).Elem()
+ for i := 0; i < v.Len(); i++ {
+ vv, err := castValue(t.Elem(), v.Index(i))
+ if err != nil {
+ return nilValue, err
+ }
+ ret.Index(i).Set(vv)
+ }
+ return ret, nil
+}
+
+func castSlice(t reflect.Type, v reflect.Value) (reflect.Value, error) {
+ kind := v.Type().Kind()
+ if kind == reflect.Interface {
+ return castSlice(t, reflect.ValueOf(v.Interface()))
+ }
+ if kind != reflect.Slice && kind != reflect.Array {
+ return nilValue, fmt.Errorf("failed to cast to slice from %s", kind)
+ }
+ if t.Elem() == v.Type().Elem() {
+ return v, nil
+ }
+ ret := reflect.MakeSlice(t, v.Len(), v.Len())
+ for i := 0; i < v.Len(); i++ {
+ vv, err := castValue(t.Elem(), v.Index(i))
+ if err != nil {
+ return nilValue, err
+ }
+ ret.Index(i).Set(vv)
+ }
+ return ret, nil
+}
+
+func castMap(t reflect.Type, v reflect.Value) (reflect.Value, error) {
+ ret := reflect.MakeMap(t)
+ switch v.Type().Kind() {
+ case reflect.Map:
+ iter := v.MapRange()
+ for iter.Next() {
+ key, err := castValue(t.Key(), iter.Key())
+ if err != nil {
+ return nilValue, err
+ }
+ value, err := castValue(t.Elem(), iter.Value())
+ if err != nil {
+ return nilValue, err
+ }
+ ret.SetMapIndex(key, value)
+ }
+ return ret, nil
+ case reflect.Interface:
+ return castMap(t, reflect.ValueOf(v.Interface()))
+ case reflect.Slice:
+ if v.Len() > 0 {
+ return castMap(t, v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to map from empty slice")
+ }
+ return nilValue, fmt.Errorf("failed to cast to map from %s", v.Type().Kind())
+}
+
+func castStruct(t reflect.Type, v reflect.Value) (reflect.Value, error) {
+ ret := reflect.New(t).Elem()
+ switch v.Type().Kind() {
+ case reflect.Map:
+ iter := v.MapRange()
+ for iter.Next() {
+ key := iter.Key()
+ k, err := castString(key)
+ if err != nil {
+ return nilValue, err
+ }
+ fieldName := k.String()
+ field, ok := t.FieldByName(fieldName)
+ if ok {
+ value, err := castValue(field.Type, iter.Value())
+ if err != nil {
+ return nilValue, err
+ }
+ ret.FieldByName(fieldName).Set(value)
+ }
+ }
+ return ret, nil
+ case reflect.Struct:
+ for i := 0; i < v.Type().NumField(); i++ {
+ name := v.Type().Field(i).Name
+ ret.FieldByName(name).Set(v.FieldByName(name))
+ }
+ return ret, nil
+ case reflect.Interface:
+ return castStruct(t, reflect.ValueOf(v.Interface()))
+ case reflect.Slice:
+ if v.Len() > 0 {
+ return castStruct(t, v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to struct from empty slice")
+ default:
+ return nilValue, fmt.Errorf("failed to cast to struct from %s", v.Type().Kind())
+ }
+}