-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvalidator.go
147 lines (136 loc) · 3.36 KB
/
validator.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
145
146
147
package csvlib
import (
"fmt"
"reflect"
"strings"
"unicode/utf8"
"unsafe"
)
// ValidatorLT validates a value to be less than the given value
func ValidatorLT[T LTComparable](val T) ValidatorFunc {
return func(v any) error {
v1, ok := v.(T)
if !ok {
return errValidationConversion(v, v1)
}
if v1 < val {
return nil
}
return ErrValidationLT
}
}
// ValidatorLTE validates a value to be less than or equal to the given value
func ValidatorLTE[T LTComparable](val T) ValidatorFunc {
return func(v any) error {
v1, ok := v.(T)
if !ok {
return errValidationConversion(v, v1)
}
if v1 <= val {
return nil
}
return ErrValidationLTE
}
}
// ValidatorGT validates a value to be greater than the given value
func ValidatorGT[T LTComparable](val T) ValidatorFunc {
return func(v any) error {
v1, ok := v.(T)
if !ok {
return errValidationConversion(v, v1)
}
if v1 > val {
return nil
}
return ErrValidationGT
}
}
// ValidatorGTE validates a value to be greater than or equal to the given value
func ValidatorGTE[T LTComparable](val T) ValidatorFunc {
return func(v any) error {
v1, ok := v.(T)
if !ok {
return errValidationConversion(v, v1)
}
if v1 >= val {
return nil
}
return ErrValidationGTE
}
}
// ValidatorRange validates a value to be in the given range (min and max are inclusive)
func ValidatorRange[T LTComparable](min, max T) ValidatorFunc {
return func(v any) error {
v1, ok := v.(T)
if !ok {
return errValidationConversion(v, v1)
}
if min <= v1 && v1 <= max {
return nil
}
return ErrValidationRange
}
}
// ValidatorIN validates a value to be one of the specific values
func ValidatorIN[T LTComparable](vals ...T) ValidatorFunc {
return func(v any) error {
v1, ok := v.(T)
if !ok {
return errValidationConversion(v, v1)
}
for _, val := range vals {
if v1 == val {
return nil
}
}
return ErrValidationIN
}
}
// ValidatorStrLen validates a string to have length in the given range.
// Pass argument -1 to skip the equivalent validation.
func ValidatorStrLen[T StringEx](minLen, maxLen int, lenFuncs ...func(s string) int) ValidatorFunc {
return func(v any) error {
s, ok := v.(T)
if !ok {
return errValidationConversion(v, s)
}
lenFunc := utf8.RuneCountInString
if len(lenFuncs) > 0 {
lenFunc = lenFuncs[0]
}
length := lenFunc(*(*string)(unsafe.Pointer(&s)))
if (minLen == -1 || minLen <= length) && (maxLen == -1 || length <= maxLen) {
return nil
}
return ErrValidationStrLen
}
}
// ValidatorStrPrefix validates a string to have prefix matching the given one
func ValidatorStrPrefix[T StringEx](prefix string) ValidatorFunc {
return func(v any) error {
s, ok := v.(T)
if !ok {
return errValidationConversion(v, s)
}
if strings.HasPrefix(*(*string)(unsafe.Pointer(&s)), prefix) {
return nil
}
return ErrValidationStrPrefix
}
}
// ValidatorStrSuffix validates a string to have suffix matching the given one
func ValidatorStrSuffix[T StringEx](suffix string) ValidatorFunc {
return func(v any) error {
s, ok := v.(T)
if !ok {
return errValidationConversion(v, s)
}
if strings.HasSuffix(*(*string)(unsafe.Pointer(&s)), suffix) {
return nil
}
return ErrValidationStrSuffix
}
}
func errValidationConversion[T any](v1 any, v2 T) error {
return fmt.Errorf("%w: (%v -> %v)", ErrValidationConversion, reflect.TypeOf(v1), reflect.TypeOf(v2))
}