github.com/vishnusomank/figtree@v0.1.0/convert.go (about)

     1  package figtree
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  )
     7  
     8  // dst must be a pointer type
     9  func convertString(src string, dst interface{}) (err error) {
    10  	// allow destinations that implement the kingping.Value interface:
    11  	// https://github.com/alecthomas/kingpin/blob/v2.3.2/values.go#L30-L33
    12  	type setter interface {
    13  		Set(string) error
    14  	}
    15  	// allow destinations that implement the kingpin.Setter interface:
    16  	// https://github.com/alecthomas/kingpin/blob/v2.3.2/parsers.go#L12-L14
    17  	type setValuer interface {
    18  		SetValue(any) error
    19  	}
    20  	switch v := dst.(type) {
    21  	case *bool:
    22  		*v, err = strconv.ParseBool(src)
    23  	case *string:
    24  		*v = src
    25  	case *int:
    26  		var tmp int64
    27  		// this is a cheat, we only know int is at least 32 bits
    28  		// but we have to make a compromise here
    29  		tmp, err = strconv.ParseInt(src, 10, 32)
    30  		*v = int(tmp)
    31  	case *int8:
    32  		var tmp int64
    33  		tmp, err = strconv.ParseInt(src, 10, 8)
    34  		*v = int8(tmp)
    35  	case *int16:
    36  		var tmp int64
    37  		tmp, err = strconv.ParseInt(src, 10, 16)
    38  		*v = int16(tmp)
    39  	case *int32:
    40  		var tmp int64
    41  		tmp, err = strconv.ParseInt(src, 10, 32)
    42  		*v = int32(tmp)
    43  	case *int64:
    44  		var tmp int64
    45  		tmp, err = strconv.ParseInt(src, 10, 64)
    46  		*v = tmp
    47  	case *uint:
    48  		var tmp uint64
    49  		// this is a cheat, we only know uint is at least 32 bits
    50  		// but we have to make a compromise here
    51  		tmp, err = strconv.ParseUint(src, 10, 32)
    52  		*v = uint(tmp)
    53  	case *uint8:
    54  		var tmp uint64
    55  		tmp, err = strconv.ParseUint(src, 10, 8)
    56  		*v = uint8(tmp)
    57  	case *uint16:
    58  		var tmp uint64
    59  		tmp, err = strconv.ParseUint(src, 10, 16)
    60  		*v = uint16(tmp)
    61  	case *uint32:
    62  		var tmp uint64
    63  		tmp, err = strconv.ParseUint(src, 10, 32)
    64  		*v = uint32(tmp)
    65  	case *uint64:
    66  		var tmp uint64
    67  		tmp, err = strconv.ParseUint(src, 10, 64)
    68  		*v = tmp
    69  	// hmm, collides with uint8
    70  	// case *byte:
    71  	// 	tmp := []byte(src)
    72  	// 	if len(tmp) == 1 {
    73  	// 		*v = tmp[0]
    74  	// 	} else {
    75  	// 		err = fmt.Errorf("Cannot convert string %q to byte, length: %d", src, len(tmp))
    76  	// 	}
    77  	// hmm, collides with int32
    78  	// case *rune:
    79  	// 	tmp := []rune(src)
    80  	// 	if len(tmp) == 1 {
    81  	// 		*v = tmp[0]
    82  	// 	} else {
    83  	// 		err = fmt.Errorf("Cannot convert string %q to rune, lengt: %d", src, len(tmp))
    84  	// 	}
    85  	case *float32:
    86  		var tmp float64
    87  		tmp, err = strconv.ParseFloat(src, 32)
    88  		*v = float32(tmp)
    89  	case *float64:
    90  		var tmp float64
    91  		tmp, err = strconv.ParseFloat(src, 64)
    92  		*v = tmp
    93  	case *any:
    94  		*v = src
    95  	case setter:
    96  		return v.Set(src)
    97  	case setValuer:
    98  		return v.SetValue(src)
    99  	default:
   100  		err = fmt.Errorf("Cannot convert string %q to type %T", src, dst)
   101  	}
   102  	if err != nil {
   103  		return err
   104  	}
   105  
   106  	return nil
   107  }