Convert attempts to convert the src to dst. If src is a map, it is deserialized into dst. If src is a slice, each of its elements are converted and stored in dst. For any other type, it is converted using the reflect.Value.Convert function (if possible). If dst is not settable, an error is returne
(src reflect.Value, dst reflect.Value, checkValidateTag bool)
| 391 | // Returns: |
| 392 | // - error: the error occurred during conversion, or nil if no error occurred. |
| 393 | func Convert(src reflect.Value, dst reflect.Value, checkValidateTag bool) error { |
| 394 | if !dst.IsValid() { |
| 395 | return fmt.Errorf("convert: dst is %w", ErrNilValue) |
| 396 | } |
| 397 | |
| 398 | if (src.Kind() == reflect.Pointer && src.IsNil()) || !src.IsValid() { |
| 399 | if !dst.CanSet() { |
| 400 | return fmt.Errorf("convert: src is %w", ErrNilValue) |
| 401 | } |
| 402 | dst.SetZero() |
| 403 | return nil |
| 404 | } |
| 405 | |
| 406 | if src.IsZero() { |
| 407 | if !dst.CanSet() { |
| 408 | return fmt.Errorf("convert: src is %w", ErrNilValue) |
| 409 | } |
| 410 | switch dst.Kind() { |
| 411 | case reflect.Pointer: |
| 412 | initPtr(dst) |
| 413 | default: |
| 414 | dst.SetZero() |
| 415 | } |
| 416 | return nil |
| 417 | } |
| 418 | |
| 419 | srcT := src.Type() |
| 420 | dstT := dst.Type() |
| 421 | |
| 422 | if src.Kind() == reflect.Interface { |
| 423 | src = src.Elem() |
| 424 | srcT = src.Type() |
| 425 | } |
| 426 | |
| 427 | if dst.Kind() == reflect.Pointer { |
| 428 | if dst.IsNil() { |
| 429 | if !dst.CanSet() { |
| 430 | return fmt.Errorf("convert: dst is %w", ErrUnsettable) |
| 431 | } |
| 432 | initPtr(dst) |
| 433 | } |
| 434 | dst = dst.Elem() |
| 435 | dstT = dst.Type() |
| 436 | } |
| 437 | |
| 438 | srcKind := srcT.Kind() |
| 439 | |
| 440 | switch { |
| 441 | case srcT == dstT, srcT.AssignableTo(dstT): |
| 442 | if !dst.CanSet() { |
| 443 | return fmt.Errorf("convert: dst is %w", ErrUnsettable) |
| 444 | } |
| 445 | dst.Set(src) |
| 446 | return nil |
| 447 | case srcKind == reflect.String: |
| 448 | if !dst.CanSet() { |
| 449 | return fmt.Errorf("convert: dst is %w", ErrUnsettable) |
| 450 | } |