gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

assign.go (12557B)


      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 }