ConvertString converts a string value to the destination reflect.Value. - It handles various types including numeric types, booleans, time.Duration, slices (comma-separated or YAML), maps, and structs (YAML). - If the destination implements the Parser interface, it is used for conversion. - Returns
(src string, dst reflect.Value)
| 544 | // - Returns true if conversion was handled (even with error), false if |
| 545 | // conversion is unsupported. |
| 546 | func ConvertString(src string, dst reflect.Value) (convertible bool, convErr error) { |
| 547 | dstT := dst.Type() |
| 548 | if dst.Kind() == reflect.Pointer { |
| 549 | if dst.IsNil() { |
| 550 | // Early return for empty string |
| 551 | if src == "" { |
| 552 | return true, nil |
| 553 | } |
| 554 | initPtr(dst) |
| 555 | } |
| 556 | dst = dst.Elem() |
| 557 | dstT = dst.Type() |
| 558 | } |
| 559 | |
| 560 | // Early return for empty string |
| 561 | if src == "" { |
| 562 | dst.SetZero() |
| 563 | return true, nil |
| 564 | } |
| 565 | |
| 566 | if dst.Kind() == reflect.String { |
| 567 | dst.SetString(src) |
| 568 | return true, nil |
| 569 | } |
| 570 | |
| 571 | // check if (*T).Convertor is implemented |
| 572 | if addr := dst.Addr(); addr.Type().Implements(reflect.TypeFor[strutils.Parser]()) { |
| 573 | parser := addr.Interface().(strutils.Parser) |
| 574 | return true, parser.Parse(src) |
| 575 | } |
| 576 | |
| 577 | switch dstT { |
| 578 | case reflect.TypeFor[time.Duration](): |
| 579 | d, err := time.ParseDuration(src) |
| 580 | if err != nil { |
| 581 | return true, err |
| 582 | } |
| 583 | gi.ReflectValueSet(dst, d) |
| 584 | return true, nil |
| 585 | default: |
| 586 | } |
| 587 | |
| 588 | if gi.ReflectIsNumeric(dst) || dst.Kind() == reflect.Bool { |
| 589 | err := gi.ReflectStrToNumBool(dst, src) |
| 590 | if err != nil { |
| 591 | return true, err |
| 592 | } |
| 593 | return true, nil |
| 594 | } |
| 595 | |
| 596 | // yaml like |
| 597 | switch dst.Kind() { |
| 598 | case reflect.Slice: |
| 599 | // one liner is comma separated list |
| 600 | isMultiline := strings.IndexByte(src, '\n') != -1 |
| 601 | if !isMultiline && src[0] != '-' && src[0] != '[' { |
| 602 | values := strutils.CommaSeperatedList(src) |
| 603 | size := len(values) |