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 }