-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathbool.go
104 lines (92 loc) · 2.06 KB
/
bool.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package cvt
import (
"encoding/json"
"reflect"
"strconv"
"strings"
"time"
)
// Bool convert an interface to a bool type, with default value
func Bool(v interface{}, def ...bool) bool {
if v, err := BoolE(v); err == nil {
return v
}
if len(def) > 0 {
return def[0]
}
return false
}
// BoolP convert and store in a new bool value, and returns a pointer to it
func BoolP(v interface{}, def ...bool) *bool {
i := Bool(v, def...)
return &i
}
// BoolE convert an interface to a bool type
func BoolE(val interface{}) (bool, error) {
// direct type(for improve performance)
switch vv := val.(type) {
case nil:
return false, nil
case bool:
return vv, nil
case
float32, float64:
return Float64(vv) != 0, nil
case
time.Duration,
int, int8, int16, int32, int64:
return Int64(vv) != 0, nil
case uint, uint8, uint16, uint32, uint64:
return Uint64(vv) != 0, nil
case []byte:
return str2bool(string(vv))
case string:
return str2bool(vv)
case json.Number:
vvv, err := vv.Float64()
if err != nil {
return false, newErr(val, "bool")
}
return vvv != 0, nil
}
// indirect type
v, rv := Indirect(val)
switch vv := v.(type) {
case nil:
return false, nil
case bool:
return vv, nil
case int, int8, int16, int32, int64:
return rv.Int() != 0, nil
case uint, uint8, uint16, uint32, uint64:
return rv.Uint() != 0, nil
case float32, float64:
return rv.Float() != 0, nil
case []byte:
return str2bool(string(vv))
case string:
return str2bool(vv)
}
switch rv.Kind() {
// by elem length
case reflect.Array, reflect.Slice, reflect.Map:
return rv.Len() > 0, nil
}
return false, newErr(val, "bool")
}
// returns the boolean value represented by the string
func str2bool(str string) (bool, error) {
if val, err := strconv.ParseBool(str); err == nil {
return val, nil
} else if val, err := strconv.ParseFloat(str, 64); err == nil {
return val != 0, nil
}
switch strings.ToLower(strings.TrimSpace(str)) {
case "on", "yes", "y":
return true, nil
case "off", "no", "n":
return false, nil
default:
return false, newErr(str, "bool")
}
}