add validators
Showing
1 changed file
with
270 additions
and
0 deletions
validation/validators.go
0 → 100644
| 1 | package revel | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "fmt" | ||
| 5 | "reflect" | ||
| 6 | "regexp" | ||
| 7 | "time" | ||
| 8 | ) | ||
| 9 | |||
| 10 | type Validator interface { | ||
| 11 | IsSatisfied(interface{}) bool | ||
| 12 | DefaultMessage() string | ||
| 13 | } | ||
| 14 | |||
| 15 | type Required struct{} | ||
| 16 | |||
| 17 | func (r Required) IsSatisfied(obj interface{}) bool { | ||
| 18 | if obj == nil { | ||
| 19 | return false | ||
| 20 | } | ||
| 21 | |||
| 22 | if str, ok := obj.(string); ok { | ||
| 23 | return len(str) > 0 | ||
| 24 | } | ||
| 25 | if b, ok := obj.(bool); ok { | ||
| 26 | return b | ||
| 27 | } | ||
| 28 | if i, ok := obj.(int); ok { | ||
| 29 | return i != 0 | ||
| 30 | } | ||
| 31 | if t, ok := obj.(time.Time); ok { | ||
| 32 | return !t.IsZero() | ||
| 33 | } | ||
| 34 | v := reflect.ValueOf(obj) | ||
| 35 | if v.Kind() == reflect.Slice { | ||
| 36 | return v.Len() > 0 | ||
| 37 | } | ||
| 38 | return true | ||
| 39 | } | ||
| 40 | |||
| 41 | func (r Required) DefaultMessage() string { | ||
| 42 | return "Required" | ||
| 43 | } | ||
| 44 | |||
| 45 | // TODO | ||
| 46 | // type Unique struct {} | ||
| 47 | |||
| 48 | type Min struct { | ||
| 49 | Min int | ||
| 50 | } | ||
| 51 | |||
| 52 | func (m Min) IsSatisfied(obj interface{}) bool { | ||
| 53 | num, ok := obj.(int) | ||
| 54 | if ok { | ||
| 55 | return num >= m.Min | ||
| 56 | } | ||
| 57 | return false | ||
| 58 | } | ||
| 59 | |||
| 60 | func (m Min) DefaultMessage() string { | ||
| 61 | return fmt.Sprintln("Minimum is", m.Min) | ||
| 62 | } | ||
| 63 | |||
| 64 | type Max struct { | ||
| 65 | Max int | ||
| 66 | } | ||
| 67 | |||
| 68 | func (m Max) IsSatisfied(obj interface{}) bool { | ||
| 69 | num, ok := obj.(int) | ||
| 70 | if ok { | ||
| 71 | return num <= m.Max | ||
| 72 | } | ||
| 73 | return false | ||
| 74 | } | ||
| 75 | |||
| 76 | func (m Max) DefaultMessage() string { | ||
| 77 | return fmt.Sprintln("Maximum is", m.Max) | ||
| 78 | } | ||
| 79 | |||
| 80 | // Requires an integer to be within Min, Max inclusive. | ||
| 81 | type Range struct { | ||
| 82 | Min | ||
| 83 | Max | ||
| 84 | } | ||
| 85 | |||
| 86 | func (r Range) IsSatisfied(obj interface{}) bool { | ||
| 87 | return r.Min.IsSatisfied(obj) && r.Max.IsSatisfied(obj) | ||
| 88 | } | ||
| 89 | |||
| 90 | func (r Range) DefaultMessage() string { | ||
| 91 | return fmt.Sprintln("Range is", r.Min.Min, "to", r.Max.Max) | ||
| 92 | } | ||
| 93 | |||
| 94 | // Requires an array or string to be at least a given length. | ||
| 95 | type MinSize struct { | ||
| 96 | Min int | ||
| 97 | } | ||
| 98 | |||
| 99 | func (m MinSize) IsSatisfied(obj interface{}) bool { | ||
| 100 | if str, ok := obj.(string); ok { | ||
| 101 | return len(str) >= m.Min | ||
| 102 | } | ||
| 103 | v := reflect.ValueOf(obj) | ||
| 104 | if v.Kind() == reflect.Slice { | ||
| 105 | return v.Len() >= m.Min | ||
| 106 | } | ||
| 107 | return false | ||
| 108 | } | ||
| 109 | |||
| 110 | func (m MinSize) DefaultMessage() string { | ||
| 111 | return fmt.Sprintln("Minimum size is", m.Min) | ||
| 112 | } | ||
| 113 | |||
| 114 | // Requires an array or string to be at most a given length. | ||
| 115 | type MaxSize struct { | ||
| 116 | Max int | ||
| 117 | } | ||
| 118 | |||
| 119 | func (m MaxSize) IsSatisfied(obj interface{}) bool { | ||
| 120 | if str, ok := obj.(string); ok { | ||
| 121 | return len(str) <= m.Max | ||
| 122 | } | ||
| 123 | v := reflect.ValueOf(obj) | ||
| 124 | if v.Kind() == reflect.Slice { | ||
| 125 | return v.Len() <= m.Max | ||
| 126 | } | ||
| 127 | return false | ||
| 128 | } | ||
| 129 | |||
| 130 | func (m MaxSize) DefaultMessage() string { | ||
| 131 | return fmt.Sprintln("Maximum size is", m.Max) | ||
| 132 | } | ||
| 133 | |||
| 134 | // Requires an array or string to be exactly a given length. | ||
| 135 | type Length struct { | ||
| 136 | N int | ||
| 137 | } | ||
| 138 | |||
| 139 | func (s Length) IsSatisfied(obj interface{}) bool { | ||
| 140 | if str, ok := obj.(string); ok { | ||
| 141 | return len(str) == s.N | ||
| 142 | } | ||
| 143 | v := reflect.ValueOf(obj) | ||
| 144 | if v.Kind() == reflect.Slice { | ||
| 145 | return v.Len() == s.N | ||
| 146 | } | ||
| 147 | return false | ||
| 148 | } | ||
| 149 | |||
| 150 | func (s Length) DefaultMessage() string { | ||
| 151 | return fmt.Sprintln("Required length is", s.N) | ||
| 152 | } | ||
| 153 | |||
| 154 | type Alpha struct{} | ||
| 155 | |||
| 156 | func (a Alpha) IsSatisfied(obj interface{}) bool { | ||
| 157 | if str, ok := obj.(string); ok { | ||
| 158 | for _, v := range str { | ||
| 159 | if ('Z' < v || v < 'A') && ('z' < v || v < 'a') { | ||
| 160 | return false | ||
| 161 | } | ||
| 162 | } | ||
| 163 | } | ||
| 164 | return false | ||
| 165 | } | ||
| 166 | |||
| 167 | func (a Alpha) DefaultMessage() string { | ||
| 168 | return fmt.Sprintln("Must be valid alpha characters") | ||
| 169 | } | ||
| 170 | |||
| 171 | type Numeric struct{} | ||
| 172 | |||
| 173 | func (n Numeric) IsSatisfied(obj interface{}) bool { | ||
| 174 | if str, ok := obj.(string); ok { | ||
| 175 | for _, v := range str { | ||
| 176 | if '9' < v || v < '0' { | ||
| 177 | return false | ||
| 178 | } | ||
| 179 | } | ||
| 180 | } | ||
| 181 | return false | ||
| 182 | } | ||
| 183 | |||
| 184 | func (n Numeric) DefaultMessage() string { | ||
| 185 | return fmt.Sprintln("Must be valid numeric characters") | ||
| 186 | } | ||
| 187 | |||
| 188 | type AlphaNumeric struct{} | ||
| 189 | |||
| 190 | func (a AlphaNumeric) IsSatisfied(obj interface{}) bool { | ||
| 191 | if str, ok := obj.(string); ok { | ||
| 192 | for _, v := range str { | ||
| 193 | if ('Z' < v || v < 'A') && ('z' < v || v < 'a') && ('9' < v || v < '0') { | ||
| 194 | return false | ||
| 195 | } | ||
| 196 | } | ||
| 197 | } | ||
| 198 | return false | ||
| 199 | } | ||
| 200 | |||
| 201 | func (a AlphaNumeric) DefaultMessage() string { | ||
| 202 | return fmt.Sprintln("Must be valid alpha or numeric characters") | ||
| 203 | } | ||
| 204 | |||
| 205 | // Requires a string to match a given regex. | ||
| 206 | type Match struct { | ||
| 207 | Regexp *regexp.Regexp | ||
| 208 | } | ||
| 209 | |||
| 210 | func (m Match) IsSatisfied(obj interface{}) bool { | ||
| 211 | str := obj.(string) | ||
| 212 | return m.Regexp.MatchString(str) | ||
| 213 | } | ||
| 214 | |||
| 215 | func (m Match) DefaultMessage() string { | ||
| 216 | return fmt.Sprintln("Must match", m.Regexp) | ||
| 217 | } | ||
| 218 | |||
| 219 | // Requires a string to not match a given regex. | ||
| 220 | type NoMatch struct { | ||
| 221 | Match | ||
| 222 | } | ||
| 223 | |||
| 224 | func (m NoMatch) IsSatisfied(obj interface{}) bool { | ||
| 225 | return !m.Match.IsSatisfied(obj) | ||
| 226 | } | ||
| 227 | |||
| 228 | func (m NoMatch) DefaultMessage() string { | ||
| 229 | return fmt.Sprintln("Must no match", m.Regexp) | ||
| 230 | } | ||
| 231 | |||
| 232 | var alphaDashPattern = regexp.MustCompile("[^\\d\\w-_]") | ||
| 233 | |||
| 234 | type AlphaDash struct { | ||
| 235 | NoMatch | ||
| 236 | } | ||
| 237 | |||
| 238 | func (a AlphaDash) DefaultMessage() string { | ||
| 239 | return fmt.Sprintln("Must be valid characters") | ||
| 240 | } | ||
| 241 | |||
| 242 | var emailPattern = regexp.MustCompile("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[a-zA-Z0-9](?:[\\w-]*[\\w])?") | ||
| 243 | |||
| 244 | type Email struct { | ||
| 245 | Match | ||
| 246 | } | ||
| 247 | |||
| 248 | func (e Email) DefaultMessage() string { | ||
| 249 | return fmt.Sprintln("Must be a valid email address") | ||
| 250 | } | ||
| 251 | |||
| 252 | var ipPattern = regexp.MustCompile("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)") | ||
| 253 | |||
| 254 | type IP struct { | ||
| 255 | Match | ||
| 256 | } | ||
| 257 | |||
| 258 | func (i IP) DefaultMessage() string { | ||
| 259 | return fmt.Sprintln("Must be a valid ip address") | ||
| 260 | } | ||
| 261 | |||
| 262 | var base64Pattern = regexp.MustCompile("^(?:[A-Za-z0-99+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$") | ||
| 263 | |||
| 264 | type Base64 struct { | ||
| 265 | Match | ||
| 266 | } | ||
| 267 | |||
| 268 | func (b Base64) DefaultMessage() string { | ||
| 269 | return fmt.Sprintln("Must be valid base64 characters") | ||
| 270 | } |
-
Please register or sign in to post a comment