github.com/grbit/go-json@v0.11.0/internal/decoder/assign.go (about)

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