github.com/3JoB/go-json@v0.10.4/internal/decoder/assign.go (about)

     1  package decoder
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strconv"
     7  
     8  	"github.com/3JoB/go-reflect"
     9  )
    10  
    11  var (
    12  	nilValue = reflect.ValueOf(nil)
    13  )
    14  
    15  func AssignValue(src, dst reflect.Value) error {
    16  	if dst.Type().Kind() != reflect.Ptr {
    17  		return fmt.Errorf("invalid dst type. required pointer type: %T", dst.Type())
    18  	}
    19  	casted, err := castValue(dst.Elem().Type(), src)
    20  	if err != nil {
    21  		return err
    22  	}
    23  	dst.Elem().Set(casted)
    24  	return nil
    25  }
    26  
    27  func castValue(t reflect.Type, v reflect.Value) (reflect.Value, error) {
    28  	switch t.Kind() {
    29  	case reflect.Int:
    30  		vv, err := castInt(v)
    31  		if err != nil {
    32  			return nilValue, err
    33  		}
    34  		return reflect.ValueOf(int(vv.Int())), nil
    35  	case reflect.Int8:
    36  		vv, err := castInt(v)
    37  		if err != nil {
    38  			return nilValue, err
    39  		}
    40  		return reflect.ValueOf(int8(vv.Int())), nil
    41  	case reflect.Int16:
    42  		vv, err := castInt(v)
    43  		if err != nil {
    44  			return nilValue, err
    45  		}
    46  		return reflect.ValueOf(int16(vv.Int())), nil
    47  	case reflect.Int32:
    48  		vv, err := castInt(v)
    49  		if err != nil {
    50  			return nilValue, err
    51  		}
    52  		return reflect.ValueOf(int32(vv.Int())), nil
    53  	case reflect.Int64:
    54  		return castInt(v)
    55  	case reflect.Uint:
    56  		vv, err := castUint(v)
    57  		if err != nil {
    58  			return nilValue, err
    59  		}
    60  		return reflect.ValueOf(uint(vv.Uint())), nil
    61  	case reflect.Uint8:
    62  		vv, err := castUint(v)
    63  		if err != nil {
    64  			return nilValue, err
    65  		}
    66  		return reflect.ValueOf(uint8(vv.Uint())), nil
    67  	case reflect.Uint16:
    68  		vv, err := castUint(v)
    69  		if err != nil {
    70  			return nilValue, err
    71  		}
    72  		return reflect.ValueOf(uint16(vv.Uint())), nil
    73  	case reflect.Uint32:
    74  		vv, err := castUint(v)
    75  		if err != nil {
    76  			return nilValue, err
    77  		}
    78  		return reflect.ValueOf(uint32(vv.Uint())), nil
    79  	case reflect.Uint64:
    80  		return castUint(v)
    81  	case reflect.Uintptr:
    82  		vv, err := castUint(v)
    83  		if err != nil {
    84  			return nilValue, err
    85  		}
    86  		return reflect.ValueOf(uintptr(vv.Uint())), nil
    87  	case reflect.String:
    88  		return castString(v)
    89  	case reflect.Bool:
    90  		return castBool(v)
    91  	case reflect.Float32:
    92  		vv, err := castFloat(v)
    93  		if err != nil {
    94  			return nilValue, err
    95  		}
    96  		return reflect.ValueOf(float32(vv.Float())), nil
    97  	case reflect.Float64:
    98  		return castFloat(v)
    99  	case reflect.Array:
   100  		return castArray(t, v)
   101  	case reflect.Slice:
   102  		return castSlice(t, v)
   103  	case reflect.Map:
   104  		return castMap(t, v)
   105  	case reflect.Struct:
   106  		return castStruct(t, v)
   107  	}
   108  	return v, nil
   109  }
   110  
   111  func castInt(v reflect.Value) (reflect.Value, error) {
   112  	switch v.Type().Kind() {
   113  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   114  		return v, nil
   115  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   116  		return reflect.ValueOf(int64(v.Uint())), nil
   117  	case reflect.String:
   118  		i64, err := strconv.ParseInt(v.String(), 10, 64)
   119  		if err != nil {
   120  			return nilValue, err
   121  		}
   122  		return reflect.ValueOf(i64), nil
   123  	case reflect.Bool:
   124  		if v.Bool() {
   125  			return reflect.ValueOf(int64(1)), nil
   126  		}
   127  		return reflect.ValueOf(int64(0)), nil
   128  	case reflect.Float32, reflect.Float64:
   129  		return reflect.ValueOf(int64(v.Float())), nil
   130  	case reflect.Array:
   131  		if v.Len() > 0 {
   132  			return castInt(v.Index(0))
   133  		}
   134  		return nilValue, errors.New("failed to cast to int64 from empty array")
   135  	case reflect.Slice:
   136  		if v.Len() > 0 {
   137  			return castInt(v.Index(0))
   138  		}
   139  		return nilValue, errors.New("failed to cast to int64 from empty slice")
   140  	case reflect.Interface:
   141  		return castInt(reflect.ValueOf(v.Interface()))
   142  	case reflect.Map:
   143  		return nilValue, errors.New("failed to cast to int64 from map")
   144  	case reflect.Struct:
   145  		return nilValue, errors.New("failed to cast to int64 from struct")
   146  	case reflect.Ptr:
   147  		return castInt(v.Elem())
   148  	}
   149  	return nilValue, fmt.Errorf("failed to cast to int64 from %s", v.Type().Kind())
   150  }
   151  
   152  func castUint(v reflect.Value) (reflect.Value, error) {
   153  	switch v.Type().Kind() {
   154  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   155  		return reflect.ValueOf(uint64(v.Int())), nil
   156  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   157  		return v, nil
   158  	case reflect.String:
   159  		u64, err := strconv.ParseUint(v.String(), 10, 64)
   160  		if err != nil {
   161  			return nilValue, err
   162  		}
   163  		return reflect.ValueOf(u64), nil
   164  	case reflect.Bool:
   165  		if v.Bool() {
   166  			return reflect.ValueOf(uint64(1)), nil
   167  		}
   168  		return reflect.ValueOf(uint64(0)), nil
   169  	case reflect.Float32, reflect.Float64:
   170  		return reflect.ValueOf(uint64(v.Float())), nil
   171  	case reflect.Array:
   172  		if v.Len() > 0 {
   173  			return castUint(v.Index(0))
   174  		}
   175  		return nilValue, errors.New("failed to cast to uint64 from empty array")
   176  	case reflect.Slice:
   177  		if v.Len() > 0 {
   178  			return castUint(v.Index(0))
   179  		}
   180  		return nilValue, errors.New("failed to cast to uint64 from empty slice")
   181  	case reflect.Interface:
   182  		return castUint(reflect.ValueOf(v.Interface()))
   183  	case reflect.Map:
   184  		return nilValue, errors.New("failed to cast to uint64 from map")
   185  	case reflect.Struct:
   186  		return nilValue, errors.New("failed to cast to uint64 from struct")
   187  	case reflect.Ptr:
   188  		return castUint(v.Elem())
   189  	}
   190  	return nilValue, fmt.Errorf("failed to cast to uint64 from %s", v.Type().Kind())
   191  }
   192  
   193  func castString(v reflect.Value) (reflect.Value, error) {
   194  	switch v.Type().Kind() {
   195  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   196  		return reflect.ValueOf(fmt.Sprint(v.Int())), nil
   197  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   198  		return reflect.ValueOf(fmt.Sprint(v.Uint())), nil
   199  	case reflect.String:
   200  		return v, nil
   201  	case reflect.Bool:
   202  		if v.Bool() {
   203  			return reflect.ValueOf("true"), nil
   204  		}
   205  		return reflect.ValueOf("false"), nil
   206  	case reflect.Float32, reflect.Float64:
   207  		return reflect.ValueOf(fmt.Sprint(v.Float())), nil
   208  	case reflect.Array:
   209  		if v.Len() > 0 {
   210  			return castString(v.Index(0))
   211  		}
   212  		return nilValue, errors.New("failed to cast to string from empty array")
   213  	case reflect.Slice:
   214  		if v.Len() > 0 {
   215  			return castString(v.Index(0))
   216  		}
   217  		return nilValue, errors.New("failed to cast to string from empty slice")
   218  	case reflect.Interface:
   219  		return castString(reflect.ValueOf(v.Interface()))
   220  	case reflect.Map:
   221  		return nilValue, errors.New("failed to cast to string from map")
   222  	case reflect.Struct:
   223  		return nilValue, errors.New("failed to cast to string from struct")
   224  	case reflect.Ptr:
   225  		return castString(v.Elem())
   226  	}
   227  	return nilValue, fmt.Errorf("failed to cast to string from %s", v.Type().Kind())
   228  }
   229  
   230  func castBool(v reflect.Value) (reflect.Value, error) {
   231  	switch v.Type().Kind() {
   232  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   233  		switch v.Int() {
   234  		case 0:
   235  			return reflect.ValueOf(false), nil
   236  		case 1:
   237  			return reflect.ValueOf(true), nil
   238  		}
   239  		return nilValue, fmt.Errorf("failed to cast to bool from %d", v.Int())
   240  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   241  		switch v.Uint() {
   242  		case 0:
   243  			return reflect.ValueOf(false), nil
   244  		case 1:
   245  			return reflect.ValueOf(true), nil
   246  		}
   247  		return nilValue, fmt.Errorf("failed to cast to bool from %d", v.Uint())
   248  	case reflect.String:
   249  		b, err := strconv.ParseBool(v.String())
   250  		if err != nil {
   251  			return nilValue, err
   252  		}
   253  		return reflect.ValueOf(b), nil
   254  	case reflect.Bool:
   255  		return v, nil
   256  	case reflect.Float32, reflect.Float64:
   257  		switch v.Float() {
   258  		case 0:
   259  			return reflect.ValueOf(false), nil
   260  		case 1:
   261  			return reflect.ValueOf(true), nil
   262  		}
   263  		return nilValue, fmt.Errorf("failed to cast to bool from %f", v.Float())
   264  	case reflect.Array:
   265  		if v.Len() > 0 {
   266  			return castBool(v.Index(0))
   267  		}
   268  		return nilValue, errors.New("failed to cast to string from empty array")
   269  	case reflect.Slice:
   270  		if v.Len() > 0 {
   271  			return castBool(v.Index(0))
   272  		}
   273  		return nilValue, errors.New("failed to cast to string from empty slice")
   274  	case reflect.Interface:
   275  		return castBool(reflect.ValueOf(v.Interface()))
   276  	case reflect.Map:
   277  		return nilValue, errors.New("failed to cast to string from map")
   278  	case reflect.Struct:
   279  		return nilValue, errors.New("failed to cast to string from struct")
   280  	case reflect.Ptr:
   281  		return castBool(v.Elem())
   282  	}
   283  	return nilValue, fmt.Errorf("failed to cast to bool from %s", v.Type().Kind())
   284  }
   285  
   286  func castFloat(v reflect.Value) (reflect.Value, error) {
   287  	switch v.Type().Kind() {
   288  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   289  		return reflect.ValueOf(float64(v.Int())), nil
   290  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   291  		return reflect.ValueOf(float64(v.Uint())), nil
   292  	case reflect.String:
   293  		f64, err := strconv.ParseFloat(v.String(), 64)
   294  		if err != nil {
   295  			return nilValue, err
   296  		}
   297  		return reflect.ValueOf(f64), nil
   298  	case reflect.Bool:
   299  		if v.Bool() {
   300  			return reflect.ValueOf(float64(1)), nil
   301  		}
   302  		return reflect.ValueOf(float64(0)), nil
   303  	case reflect.Float32, reflect.Float64:
   304  		return v, nil
   305  	case reflect.Array:
   306  		if v.Len() > 0 {
   307  			return castFloat(v.Index(0))
   308  		}
   309  		return nilValue, errors.New("failed to cast to float64 from empty array")
   310  	case reflect.Slice:
   311  		if v.Len() > 0 {
   312  			return castFloat(v.Index(0))
   313  		}
   314  		return nilValue, errors.New("failed to cast to float64 from empty slice")
   315  	case reflect.Interface:
   316  		return castFloat(reflect.ValueOf(v.Interface()))
   317  	case reflect.Map:
   318  		return nilValue, errors.New("failed to cast to float64 from map")
   319  	case reflect.Struct:
   320  		return nilValue, errors.New("failed to cast to float64 from struct")
   321  	case reflect.Ptr:
   322  		return castFloat(v.Elem())
   323  	}
   324  	return nilValue, fmt.Errorf("failed to cast to float64 from %s", v.Type().Kind())
   325  }
   326  
   327  func castArray(t reflect.Type, v reflect.Value) (reflect.Value, error) {
   328  	kind := v.Type().Kind()
   329  	if kind == reflect.Interface {
   330  		return castArray(t, reflect.ValueOf(v.Interface()))
   331  	}
   332  	if kind != reflect.Slice && kind != reflect.Array {
   333  		return nilValue, fmt.Errorf("failed to cast to array from %s", kind)
   334  	}
   335  	if t.Elem() == v.Type().Elem() {
   336  		return v, nil
   337  	}
   338  	if t.Len() != v.Len() {
   339  		return nilValue, fmt.Errorf("failed to cast [%d]array from slice of %d length", t.Len(), v.Len())
   340  	}
   341  	ret := reflect.New(t).Elem()
   342  	for i := 0; i < v.Len(); i++ {
   343  		vv, err := castValue(t.Elem(), v.Index(i))
   344  		if err != nil {
   345  			return nilValue, err
   346  		}
   347  		ret.Index(i).Set(vv)
   348  	}
   349  	return ret, nil
   350  }
   351  
   352  func castSlice(t reflect.Type, v reflect.Value) (reflect.Value, error) {
   353  	kind := v.Type().Kind()
   354  	if kind == reflect.Interface {
   355  		return castSlice(t, reflect.ValueOf(v.Interface()))
   356  	}
   357  	if kind != reflect.Slice && kind != reflect.Array {
   358  		return nilValue, fmt.Errorf("failed to cast to slice from %s", kind)
   359  	}
   360  	if t.Elem() == v.Type().Elem() {
   361  		return v, nil
   362  	}
   363  	ret := reflect.MakeSlice(t, v.Len(), v.Len())
   364  	for i := 0; i < v.Len(); i++ {
   365  		vv, err := castValue(t.Elem(), v.Index(i))
   366  		if err != nil {
   367  			return nilValue, err
   368  		}
   369  		ret.Index(i).Set(vv)
   370  	}
   371  	return ret, nil
   372  }
   373  
   374  func castMap(t reflect.Type, v reflect.Value) (reflect.Value, error) {
   375  	ret := reflect.MakeMap(t)
   376  	switch v.Type().Kind() {
   377  	case reflect.Map:
   378  		iter := v.MapRange()
   379  		for iter.Next() {
   380  			key, err := castValue(t.Key(), reflect.ToV(iter.Key()))
   381  			if err != nil {
   382  				return nilValue, err
   383  			}
   384  			value, err := castValue(t.Elem(), reflect.ToV(iter.Value()))
   385  			if err != nil {
   386  				return nilValue, err
   387  			}
   388  			ret.SetMapIndex(key, value)
   389  		}
   390  		return ret, nil
   391  	case reflect.Interface:
   392  		return castMap(t, reflect.ValueOf(v.Interface()))
   393  	case reflect.Slice:
   394  		if v.Len() > 0 {
   395  			return castMap(t, v.Index(0))
   396  		}
   397  		return nilValue, errors.New("failed to cast to map from empty slice")
   398  	}
   399  	return nilValue, fmt.Errorf("failed to cast to map from %s", v.Type().Kind())
   400  }
   401  
   402  func castStruct(t reflect.Type, v reflect.Value) (reflect.Value, error) {
   403  	ret := reflect.New(t).Elem()
   404  	switch v.Type().Kind() {
   405  	case reflect.Map:
   406  		iter := v.MapRange()
   407  		for iter.Next() {
   408  			key := reflect.ToV(iter.Key())
   409  			k, err := castString(key)
   410  			if err != nil {
   411  				return nilValue, err
   412  			}
   413  			fieldName := k.String()
   414  			field, ok := t.FieldByName(fieldName)
   415  			if ok {
   416  				value, err := castValue(field.Type, reflect.ToV(iter.Value()))
   417  				if err != nil {
   418  					return nilValue, err
   419  				}
   420  				ret.FieldByName(fieldName).Set(value)
   421  			}
   422  		}
   423  		return ret, nil
   424  	case reflect.Struct:
   425  		for i := 0; i < v.Type().NumField(); i++ {
   426  			name := v.Type().Field(i).Name
   427  			ret.FieldByName(name).Set(v.FieldByName(name))
   428  		}
   429  		return ret, nil
   430  	case reflect.Interface:
   431  		return castStruct(t, reflect.ValueOf(v.Interface()))
   432  	case reflect.Slice:
   433  		if v.Len() > 0 {
   434  			return castStruct(t, v.Index(0))
   435  		}
   436  		return nilValue, errors.New("failed to cast to struct from empty slice")
   437  	default:
   438  		return nilValue, fmt.Errorf("failed to cast to struct from %s", v.Type().Kind())
   439  	}
   440  }