forked from pengux/check
-
Notifications
You must be signed in to change notification settings - Fork 0
/
number.go
144 lines (99 loc) · 2.91 KB
/
number.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package check
import (
"strconv"
)
type Number []Validator
func (validators Number) Validate(v interface{}) error {
switch v.(type) {
case int, float64:
return And(validators).Validate(v)
default:
return ValidationErr("number.type", "%T not a number", v)
}
return nil
}
type Integer []Validator
func (validators Integer) Validate(v interface{}) error {
val, ok := v.(int)
if !ok {
return ValidationErr("integer.type", " %T not an integer", v)
}
return And(validators).Validate(val)
}
type Float []Validator
func (validators Float) Validate(v interface{}) error {
val, ok := v.(float64)
if !ok {
return ValidationErr("float.type", "%T not a float", v)
}
return And(validators).Validate(val)
}
func LowerThan(v float64) LowerThanNumber {
return LowerThanNumber{v, false}
}
func LowerThanOrEqual(v float64) LowerThanNumber {
return LowerThanNumber{v, true}
}
// LowerThanNumber validates that a number must be lower than its value
type LowerThanNumber struct {
Constraint float64
Inclusive bool
}
func (validator LowerThanNumber) Validate(v interface{}) error {
switch val := v.(type) {
case float64:
diff := validator.Constraint - val
if (validator.Inclusive && diff == 0) || diff > 0 {
return nil
}
return ValidationErr("number.lower", "%v is not lower than %v", strconv.FormatFloat(val, 'f', -1, 64), strconv.FormatFloat(validator.Constraint, 'f', -1, 64))
case int:
diff := validator.Constraint - float64(val)
if (validator.Inclusive && diff == 0) || diff > 0 {
return nil
}
return ValidationErr("number.lower", "%v is not lower than %v", strconv.Itoa(val), strconv.FormatFloat(validator.Constraint, 'f', -1, 64))
}
return nil
}
func GreaterThan(v float64) GreaterThanNumber {
return GreaterThanNumber{v, false}
}
func GreaterThanOrEqual(v float64) GreaterThanNumber {
return GreaterThanNumber{v, true}
}
// GreaterThanNumber validates that a number must be greater than its value
type GreaterThanNumber struct {
Constraint float64
Inclusive bool
}
// Validate check value against constraint
func (validator GreaterThanNumber) Validate(v interface{}) error {
switch val := v.(type) {
case float64:
diff := val - validator.Constraint
if (validator.Inclusive && diff == 0) || diff > 0 {
return nil
}
return ValidationErr("number.greater", "%v is not greater than %v", strconv.FormatFloat(val, 'f', -1, 64), strconv.FormatFloat(validator.Constraint, 'f', -1, 64))
case int:
diff := float64(val) - validator.Constraint
if (validator.Inclusive && diff == 0) || diff > 0 {
return nil
}
return ValidationErr("number.greater", "%v is not greater than %v", strconv.Itoa(val), strconv.FormatFloat(validator.Constraint, 'f', -1, 64))
}
return nil
}
func Between(min, max float64) And {
return And{
GreaterThan(min),
LowerThan(max),
}
}
func BetweenInclusive(min, max float64) And {
return And{
GreaterThanOrEqual(min),
LowerThanOrEqual(max),
}
}