-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathbooleans.go
115 lines (109 loc) · 2.55 KB
/
booleans.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
105
106
107
108
109
110
111
112
113
114
115
package typ
import (
"reflect"
"strings"
)
// Bool convert interface value to bool.
// Returns true for any non-zero values
func (t *Type) Bool() BoolAccessor {
nv := &NullBool{}
if nv.Error = t.err; t.err != nil {
return nv
}
return t.toBool(false)
}
// BoolHumanize convert interface value to bool.
// Returns false for string 'false' in case-insensitive mode or string equals '0', for other types
// returns true only for positive values
func (t *Type) BoolHumanize() BoolAccessor {
nv := &NullBool{}
if nv.Error = t.err; t.err != nil {
return nv
}
switch {
case t.IsString(true):
bf := strings.EqualFold("false", t.rv.String()) || t.rv.String() == "0"
bt := strings.EqualFold("true", t.rv.String()) || t.rv.String() == "1"
if !bf && !bt {
nv.Error = ErrUnexpectedValue
}
nv.P = &bt
return nv
case t.IsBool(true):
v := t.rv.Bool()
nv.P = &v
return nv
default:
return t.toBool(true)
}
}
// BoolPositive convert interface value to bool.
// Returns true only for positive values
func (t *Type) BoolPositive() BoolAccessor {
nv := &NullBool{}
if nv.Error = t.err; t.err != nil {
return nv
}
return t.toBool(true)
}
// Convert interface value to bool.
// It check positive values if argument "positive" is true, otherwise always true for any non-zero values
func (t *Type) toBool(positive bool) BoolAccessor {
var (
nv BoolAccessor
v bool
)
switch {
case t.IsBool(true):
v = t.rv.Bool()
goto end
case t.IsString(true):
v = t.rv.Len() != 0
goto end
case t.IsInt(true):
vInt := t.rv.Int()
v = (vInt < 0 && !positive) || vInt > 0
goto end
case t.IsUint(true):
vUint := t.rv.Uint()
v = (vUint < 0 && !positive) || vUint > 0
goto end
case t.IsFloat(true):
vFloat := t.rv.Float()
v = (vFloat != 0 && !positive) || vFloat > 0
goto end
case t.IsComplex(true):
value := t.rv.Complex()
fr := real(value)
v = (fr != 0 && !positive) || fr > 0
goto end
default:
if positive {
switch t.rv.Kind() {
case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
v = t.rv.Len() > 0
goto end
}
}
nv = t.Empty().Clone()
nv.Set(!nv.V())
return nv
}
end:
nv = &NullBool{}
nv.Set(v)
return nv
}
// StringBoolHumanize convert value from string to bool.
// Returns false for string 'false' in case-insensitive mode or string equals '0'
func StringBoolHumanize(from string) BoolAccessor {
nv := &NullBool{}
bf := strings.EqualFold("false", from) || from == "0"
bt := strings.EqualFold("true", from) || from == "1"
if !bf && !bt {
nv.Error = ErrUnexpectedValue
return nv
}
nv.P = &bt
return nv
}