github.com/mattn/anko@v0.1.10/vm/vmToX.go (about) 1 package vm 2 3 import ( 4 "errors" 5 "fmt" 6 "reflect" 7 "strconv" 8 "strings" 9 ) 10 11 // toString converts all reflect.Value-s into string. 12 func toString(v reflect.Value) string { 13 if v.Kind() == reflect.Interface && !v.IsNil() { 14 v = v.Elem() 15 } 16 if v.Kind() == reflect.Ptr { 17 v = v.Elem() 18 } 19 if v.Kind() == reflect.String { 20 return v.String() 21 } 22 return fmt.Sprint(v.Interface()) 23 } 24 25 // toBool converts all reflect.Value-s into bool. 26 func toBool(v reflect.Value) bool { 27 b, _ := tryToBool(v) 28 return b 29 } 30 31 // tryToBool attempts to convert the value 'v' to a boolean, returning 32 // an error if it cannot. When converting a string, the function returns 33 // true if the string nonempty and does not satisfy the condition for false 34 // with parseBool https://golang.org/pkg/strconv/#ParseBool 35 // and is not 0.0 36 func tryToBool(v reflect.Value) (bool, error) { 37 if v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface { 38 v = v.Elem() 39 } 40 switch v.Kind() { 41 case reflect.Float64, reflect.Float32: 42 return v.Float() != 0, nil 43 case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int: 44 return v.Int() != 0, nil 45 case reflect.Bool: 46 return v.Bool(), nil 47 case reflect.String: 48 if v.Len() == 0 { 49 return false, nil 50 } 51 52 s := v.String() 53 if b, err := strconv.ParseBool(s); err == nil && !b { 54 return false, nil 55 } 56 57 if f, err := tryToFloat64(v); err == nil && f == 0 { 58 return false, nil 59 } 60 return true, nil 61 case reflect.Slice, reflect.Map: 62 if v.Len() > 0 { 63 return true, nil 64 } 65 return false, nil 66 } 67 return false, errors.New("unknown type") 68 } 69 70 // toFloat64 converts all reflect.Value-s into float64. 71 func toFloat64(v reflect.Value) float64 { 72 f, _ := tryToFloat64(v) 73 return f 74 } 75 76 // tryToFloat64 attempts to convert a value to a float64. 77 // If it cannot (in the case of a non-numeric string, a struct, etc.) 78 // it returns 0.0 and an error. 79 func tryToFloat64(v reflect.Value) (float64, error) { 80 if v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface { 81 v = v.Elem() 82 } 83 switch v.Kind() { 84 case reflect.Float64, reflect.Float32: 85 return v.Float(), nil 86 case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int: 87 return float64(v.Int()), nil 88 case reflect.Bool: 89 if v.Bool() { 90 return 1, nil 91 } 92 return 0, nil 93 case reflect.String: 94 f, err := strconv.ParseFloat(v.String(), 64) 95 if err == nil { 96 return f, nil 97 } 98 } 99 return 0.0, errors.New("couldn't convert to a float64") 100 } 101 102 // toInt64 converts all reflect.Value-s into int64. 103 func toInt64(v reflect.Value) int64 { 104 i, _ := tryToInt64(v) 105 return i 106 } 107 108 // tryToInt64 attempts to convert a value to an int64. 109 // If it cannot (in the case of a non-numeric string, a struct, etc.) 110 // it returns 0 and an error. 111 func tryToInt64(v reflect.Value) (int64, error) { 112 if v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface { 113 v = v.Elem() 114 } 115 switch v.Kind() { 116 case reflect.Float64, reflect.Float32: 117 return int64(v.Float()), nil 118 case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int: 119 return v.Int(), nil 120 case reflect.Bool: 121 if v.Bool() { 122 return 1, nil 123 } 124 return 0, nil 125 case reflect.String: 126 s := v.String() 127 var i int64 128 var err error 129 if strings.HasPrefix(s, "0x") { 130 i, err = strconv.ParseInt(s, 16, 64) 131 } else { 132 i, err = strconv.ParseInt(s, 10, 64) 133 } 134 if err == nil { 135 return i, nil 136 } 137 } 138 return 0, errors.New("couldn't convert to integer") 139 } 140 141 // toInt converts all reflect.Value-s into int. 142 func toInt(v reflect.Value) int { 143 i, _ := tryToInt(v) 144 return i 145 } 146 147 // tryToInt attempts to convert a value to an int. 148 // If it cannot (in the case of a non-numeric string, a struct, etc.) 149 // it returns 0 and an error. 150 func tryToInt(v reflect.Value) (int, error) { 151 if v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface { 152 v = v.Elem() 153 } 154 switch v.Kind() { 155 case reflect.Float64, reflect.Float32: 156 return int(v.Float()), nil 157 case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int: 158 return int(v.Int()), nil 159 case reflect.Bool: 160 if v.Bool() { 161 return 1, nil 162 } 163 return 0, nil 164 case reflect.String: 165 s := v.String() 166 var i int64 167 var err error 168 if strings.HasPrefix(s, "0x") { 169 i, err = strconv.ParseInt(s, 16, 64) 170 } else { 171 i, err = strconv.ParseInt(s, 10, 64) 172 } 173 if err == nil { 174 return int(i), nil 175 } 176 } 177 return 0, errors.New("couldn't convert to integer") 178 }