ConvertAssign copies to the '*dest' the value in 'src'. An error is returned if the coping is done between incompatible Value and dest types. 'dest' must be a pointer type. Note that for anything else than *[]byte the value is copied, however if 'dest' is of type *[]byte it will point to same []byte
(src Value, dest interface{})
| 322 | // Note that for anything else than *[]byte the value is copied, however if 'dest' |
| 323 | // is of type *[]byte it will point to same []byte array as 'src.Raw()' (no copying). |
| 324 | func ConvertAssign(src Value, dest interface{}) error { |
| 325 | // TODO(zviad): reflecting might be too slow so common cases |
| 326 | // can probably be handled without reflections |
| 327 | var s String |
| 328 | var n Numeric |
| 329 | var f Fractional |
| 330 | var ok bool |
| 331 | var err error |
| 332 | |
| 333 | if src.Inner == nil { |
| 334 | return errors.Newf("source is null") |
| 335 | } |
| 336 | |
| 337 | switch d := dest.(type) { |
| 338 | case *string: |
| 339 | if s, ok = src.Inner.(String); !ok { |
| 340 | return errors.Newf("source: '%v' is not String", src) |
| 341 | } |
| 342 | *d = string(s.raw()) |
| 343 | return nil |
| 344 | case *[]byte: |
| 345 | if s, ok = src.Inner.(String); !ok { |
| 346 | return errors.Newf("source: '%v' is not String", src) |
| 347 | } |
| 348 | *d = s.raw() |
| 349 | return nil |
| 350 | // TODO(zviad): figure out how to do this without reflections |
| 351 | // because I think reflections are slow? |
| 352 | //case *int, *int8, *int16, *int32, *int64: |
| 353 | // if n, ok := src.Inner.(Numeric); !ok { |
| 354 | // return errors.Newf("source: %v is not Numeric", src) |
| 355 | // } |
| 356 | // if i64, err := strconv.ParseInt(string(n.raw()), 10, 64); err != nil { |
| 357 | // return err |
| 358 | // } |
| 359 | // *d = i64 |
| 360 | // return nil |
| 361 | } |
| 362 | |
| 363 | dpv := reflect.ValueOf(dest) |
| 364 | if dpv.Kind() != reflect.Ptr { |
| 365 | return errors.Newf("destination not a pointer") |
| 366 | } |
| 367 | if dpv.IsNil() { |
| 368 | return errors.Newf("destination pointer is Nil") |
| 369 | } |
| 370 | dv := reflect.Indirect(dpv) |
| 371 | switch dv.Kind() { |
| 372 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: |
| 373 | if n, ok = src.Inner.(Numeric); !ok { |
| 374 | return errors.Newf("source: '%v' is not Numeric", src) |
| 375 | } |
| 376 | var i64 int64 |
| 377 | if i64, err = strconv.ParseInt(string(n.raw()), 10, dv.Type().Bits()); err != nil { |
| 378 | return err |
| 379 | } |
| 380 | dv.SetInt(i64) |
| 381 | return nil |