|
// toBool converts all reflect.Value-s into bool. |
|
func toBool(v reflect.Value) bool { |
|
b, _ := tryToBool(v) |
|
return b |
|
} |
|
|
|
// tryToBool attempts to convert the value 'v' to a boolean, returning |
|
// an error if it cannot. When converting a string, the function returns |
|
// true if the string nonempty and does not satisfy the condition for false |
|
// with parseBool https://golang.org/pkg/strconv/#ParseBool |
|
// and is not 0.0 |
|
func tryToBool(v reflect.Value) (bool, error) { |
|
if v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface { |
|
v = v.Elem() |
|
} |
|
switch v.Kind() { |
|
case reflect.Float64, reflect.Float32: |
|
return v.Float() != 0, nil |
|
case reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int: |
|
return v.Int() != 0, nil |
|
case reflect.Bool: |
|
return v.Bool(), nil |
|
case reflect.String: |
|
if v.Len() == 0 { |
|
return false, nil |
|
} |
|
|
|
s := v.String() |
|
if b, err := strconv.ParseBool(s); err == nil && !b { |
|
return false, nil |
|
} |
|
|
|
if f, err := tryToFloat64(v); err == nil && f == 0 { |
|
return false, nil |
|
} |
|
return true, nil |
|
case reflect.Slice, reflect.Map: |
|
if v.Len() > 0 { |
|
return true, nil |
|
} |
|
return false, nil |
|
} |
|
return false, errors.New("unknown type") |
|
} |
|
env.Define("toBool", func(v interface{}) bool { |
|
rv := reflect.ValueOf(v) |
|
if !rv.IsValid() { |
|
return false |
|
} |
|
nt := reflect.TypeOf(true) |
|
if rv.Type().ConvertibleTo(nt) { |
|
return rv.Convert(nt).Bool() |
|
} |
|
if rv.Type().ConvertibleTo(reflect.TypeOf(1.0)) && rv.Convert(reflect.TypeOf(1.0)).Float() > 0.0 { |
|
return true |
|
} |
|
if rv.Kind() == reflect.String { |
|
s := strings.ToLower(v.(string)) |
|
if s == "y" || s == "yes" { |
|
return true |
|
} |
|
b, err := strconv.ParseBool(s) |
|
if err == nil { |
|
return b |
|
} |
|
} |
|
return false |
|
}) |
Should it be unified, or is there any reason, so it needs to be inconsistent?
If so, is it possible to extend these two based on a basic function?
anko/vm/vmToX.go
Lines 28 to 71 in 6707570
anko/core/toX.go
Lines 16 to 39 in 6707570
Should it be unified, or is there any reason, so it needs to be inconsistent?
If so, is it possible to extend these two based on a basic function?