-
Notifications
You must be signed in to change notification settings - Fork 0
/
string.go
186 lines (165 loc) · 5.77 KB
/
string.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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
package valid
import (
"errors"
"net/mail"
"regexp"
)
// StringValidator interface is implemented by all string validators.
type StringValidator interface {
// Validate validates the given parameter and returns a validation error, or nil
// if the input is valid.
Validate(string) error
}
// A StringFunc takes a value to validate and returns a validation error.
//
// This type implements the StringValidator interface, thus any functions with this
// signature can be casted to StringFunc and used as a StringValidator.
type StringFunc func(val string) error
// Validate function of StringFunc
func (s StringFunc) Validate(val string) error {
return s(val)
}
// String applies a list of StringValidators to a string value and returns a list of
// aggregated errors.
func String(val string, v ...StringValidator) []error {
var errors []error
for _, validator := range v {
err := validator.Validate(val)
if err != nil {
errors = append(errors, err)
}
}
return errors
}
// Regexp creates a regular expression validator, using the pattern given as string.
func Regexp(pattern, message string) StringFunc {
reg := regexp.MustCompile(pattern)
return RegexpCompiled(reg, message)
}
// RegexpCompiled creates a regular expression validator, using the given already-compiled *regexp.Regexp.
func RegexpCompiled(reg *regexp.Regexp, message string) StringFunc {
f := func(val string) error {
if reg.MatchString(val) {
return nil
}
return errors.New(message)
}
return StringFunc(f)
}
// Len creates a length validator, that checks if the length of given string is in the closed interval [min, max].
// It includes min and max: all val that satisfy max >= len(val) >= min are considered valid.
func Len(min, max int, message string) StringFunc {
f := func(val string) error {
if max < len(val) || len(val) < min {
return errors.New(message)
}
return nil
}
return StringFunc(f)
}
// MinLen creates a minimum length string validator that consideres all strings val valid if they
// satisfy len(val) >= min.
func MinLen(min int, message string) StringValidator {
f := func(val string) error {
if len(val) < min {
return errors.New(message)
}
return nil
}
return StringFunc(f)
}
// MaxLen creates a maximum length string validator that consideres all strings val valid if they
// satisfy len(val) <= max.
func MaxLen(max int, message string) StringValidator {
f := func(val string) error {
if len(val) > max {
return errors.New(message)
}
return nil
}
return StringFunc(f)
}
// LenStrict creates a length validator, that checks if the length of given string is in the open interval (min, max).
// It does not include min and max: all val that satisfy max > len(val) > min are considered valid.
func LenStrict(min, max int, message string) StringFunc {
f := func(val string) error {
if max <= len(val) || len(val) <= min {
return errors.New(message)
}
return nil
}
return StringFunc(f)
}
// MinLenStrict creates a strict minimum length string validator that consideres all strings val valid if they
// satisfy len(val) > min.
func MinLenStrict(min int, message string) StringValidator {
f := func(val string) error {
if len(val) <= min {
return errors.New(message)
}
return nil
}
return StringFunc(f)
}
// MaxLenStrict creates a maximum length string validator that consideres all strings val valid if they
// satisfy len(val) < max.
func MaxLenStrict(max int, message string) StringValidator {
f := func(val string) error {
if len(val) >= max {
return errors.New(message)
}
return nil
}
return StringFunc(f)
}
// Nonempty creates a validator that checks whether the given string is not empty.
func Nonempty(message string) StringValidator {
f := func(val string) error {
if val == "" {
return errors.New(message)
}
return nil
}
return StringFunc(f)
}
// Common regular expressions used for validation.
var (
// RegAlphanumeric matches alphanumeric characters
RegAlphanumeric = regexp.MustCompile("^[a-zA-Z0-9]*$")
// RegAlphanumericPermissive matches numbers, letters, -, _, and .
RegAlphanumericPermissive = regexp.MustCompile("^[a-zA-Z0-9-_.]*$")
// RegEmail is the HTML5 E-mail address regular expression, according to W3C http://www.w3.org/TR/html-markup/input.email.html#input.email.attrs.value.single
RegEmail = regexp.MustCompile("^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$")
)
// Alphanumeric creates a validator that consideres all alphanumeric inputs (including the empty string) valid.
func Alphanumeric(message string) StringValidator {
return RegexpCompiled(RegAlphanumeric, message)
}
// AlphanumericPermissive creates a validator that consideres all inputs containing only letters (a-z, A-Z), numbers (0-9),
// underscore ("_"), minus sign ("-") and period (".") as valid. (including the empty string) valid.
func AlphanumericPermissive(message string) StringValidator {
return RegexpCompiled(RegAlphanumericPermissive, message)
}
// EmailRFC creates a validator for e-mail address according to the net/mail package. Non-empty Address.Name addresses are
// considered invalid (e.g. "John <john@example.org>" is invalid).
//
// For validation of uniqueness, consider normalising the addresses. (e.g. "john+tag@example.com" is the same as
// "john@example.com".
func EmailRFC(message string) StringValidator {
f := func(val string) error {
addr, err := mail.ParseAddress(val)
if err != nil || addr.Name != "" {
return errors.New(message)
}
return nil
}
return StringFunc(f)
}
// Email creates a validator that uses the HTML5 e-mail field regexp as defined by W3C to
// validate e-mail addresses.
//
// The regular expression is defined by W3C here:
// http://www.w3.org/TR/html-markup/input.email.html#input.email.attrs.value.single
func Email(message string) StringValidator {
return RegexpCompiled(RegEmail, message)
}