gomu/anko/convert.go
2021-02-15 21:08:39 +08:00

108 lines
1.9 KiB
Go

package anko
import (
"fmt"
"reflect"
"strconv"
"strings"
"github.com/mattn/anko/env"
)
// importToX defines type coercion functions
func importToX(e *env.Env) {
e.Define("bool", 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
})
e.Define("string", func(v interface{}) string {
if b, ok := v.([]byte); ok {
return string(b)
}
return fmt.Sprint(v)
})
e.Define("int", func(v interface{}) int64 {
rv := reflect.ValueOf(v)
if !rv.IsValid() {
return 0
}
nt := reflect.TypeOf(1)
if rv.Type().ConvertibleTo(nt) {
return rv.Convert(nt).Int()
}
if rv.Kind() == reflect.String {
i, err := strconv.ParseInt(v.(string), 10, 64)
if err == nil {
return i
}
f, err := strconv.ParseFloat(v.(string), 64)
if err == nil {
return int64(f)
}
}
if rv.Kind() == reflect.Bool {
if v.(bool) {
return 1
}
}
return 0
})
e.Define("float", func(v interface{}) float64 {
rv := reflect.ValueOf(v)
if !rv.IsValid() {
return 0
}
nt := reflect.TypeOf(1.0)
if rv.Type().ConvertibleTo(nt) {
return rv.Convert(nt).Float()
}
if rv.Kind() == reflect.String {
f, err := strconv.ParseFloat(v.(string), 64)
if err == nil {
return f
}
}
if rv.Kind() == reflect.Bool {
if v.(bool) {
return 1.0
}
}
return 0.0
})
e.Define("char", func(s rune) string {
return string(s)
})
e.Define("rune", func(s string) rune {
if len(s) == 0 {
return 0
}
return []rune(s)[0]
})
}