-
Notifications
You must be signed in to change notification settings - Fork 0
/
val.go
130 lines (116 loc) · 3.12 KB
/
val.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
package check
import (
"fmt"
"golang.org/x/exp/constraints"
)
// ValCk is the type of a check function
type ValCk[T any] func(v T) error
// ValOK always returns a nil error - it can be of use with a
// check.ByPos to allow any value in certain slice positions
func ValOK[T any](_ T) error {
return nil
}
// ValEQ returns a function that will check that the value is
// equal to the limit
func ValEQ[T comparable](limit T) ValCk[T] {
return func(v T) error {
if v == limit {
return nil
}
return fmt.Errorf("the value (%v) must equal %v", v, limit)
}
}
// ValNE returns a function that will check that the value is
// not equal to the limit
func ValNE[T comparable](limit T) ValCk[T] {
return func(v T) error {
if v != limit {
return nil
}
return fmt.Errorf("the value (%v) must not equal %v", v, limit)
}
}
// ValGT returns a function that will check that the value is
// greater than the limit
func ValGT[T constraints.Ordered](limit T) ValCk[T] {
return func(v T) error {
if v > limit {
return nil
}
return fmt.Errorf("the value (%v) must be greater than %v", v, limit)
}
}
// ValGE returns a function that will check that the value is
// greater than or equal to the limit
func ValGE[T constraints.Ordered](limit T) ValCk[T] {
return func(v T) error {
if v >= limit {
return nil
}
return fmt.Errorf("the value (%v) must be greater than or equal to %v",
v, limit)
}
}
// ValLT returns a function that will check that the value is less
// than the limit
func ValLT[T constraints.Ordered](limit T) ValCk[T] {
return func(v T) error {
if v < limit {
return nil
}
return fmt.Errorf("the value (%v) must be less than %v", v, limit)
}
}
// ValLE returns a function that will check that the value is less
// than or equal to the limit
func ValLE[T constraints.Ordered](limit T) ValCk[T] {
return func(v T) error {
if v <= limit {
return nil
}
return fmt.Errorf("the value (%v) must be less than or equal to %v",
v, limit)
}
}
// ValBetween returns a function that will check that the value
// lies between the upper and lower limits (inclusive)
func ValBetween[T constraints.Ordered](low, high T) ValCk[T] {
if low >= high {
panic(fmt.Sprintf("Impossible checks passed to ValBetween:"+
" the lower limit (%v) must be less than the upper limit (%v)",
low, high))
}
return func(v T) error {
if v < low {
return fmt.Errorf(
"the value (%v) must be between %v and %v - too small",
v, low, high)
}
if v > high {
return fmt.Errorf(
"the value (%v) must be between %v and %v - too big",
v, low, high)
}
return nil
}
}
// ValDivides returns a function that will check that the value
// is a divisor of d
func ValDivides[T constraints.Integer](d T) ValCk[T] {
return func(v T) error {
if d%v == 0 {
return nil
}
return fmt.Errorf("the value (%d) must be a divisor of %d", v, d)
}
}
// ValIsAMultiple returns a function that will check that the value
// is a multiple of d
func ValIsAMultiple[T constraints.Integer](d T) ValCk[T] {
return func(v T) error {
if v%d == 0 {
return nil
}
return fmt.Errorf("the value (%d) must be a multiple of %d", v, d)
}
}