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 }