1package validator 2 3import ( 4 "fmt" 5 "net" 6 "net/url" 7 "reflect" 8 "strings" 9 "time" 10 "unicode/utf8" 11) 12 13// BakedInAliasValidators is a default mapping of a single validationstag that 14// defines a common or complex set of validation(s) to simplify 15// adding validation to structs. i.e. set key "_ageok" and the tags 16// are "gt=0,lte=130" or key "_preferredname" and tags "omitempty,gt=0,lte=60" 17var bakedInAliasValidators = map[string]string{ 18 "iscolor": "hexcolor|rgb|rgba|hsl|hsla", 19} 20 21// BakedInValidators is the default map of ValidationFunc 22// you can add, remove or even replace items to suite your needs, 23// or even disregard and use your own map if so desired. 24var bakedInValidators = map[string]Func{ 25 "required": HasValue, 26 "len": HasLengthOf, 27 "min": HasMinOf, 28 "max": HasMaxOf, 29 "eq": IsEq, 30 "ne": IsNe, 31 "lt": IsLt, 32 "lte": IsLte, 33 "gt": IsGt, 34 "gte": IsGte, 35 "eqfield": IsEqField, 36 "eqcsfield": IsEqCrossStructField, 37 "necsfield": IsNeCrossStructField, 38 "gtcsfield": IsGtCrossStructField, 39 "gtecsfield": IsGteCrossStructField, 40 "ltcsfield": IsLtCrossStructField, 41 "ltecsfield": IsLteCrossStructField, 42 "nefield": IsNeField, 43 "gtefield": IsGteField, 44 "gtfield": IsGtField, 45 "ltefield": IsLteField, 46 "ltfield": IsLtField, 47 "alpha": IsAlpha, 48 "alphanum": IsAlphanum, 49 "numeric": IsNumeric, 50 "number": IsNumber, 51 "hexadecimal": IsHexadecimal, 52 "hexcolor": IsHEXColor, 53 "rgb": IsRGB, 54 "rgba": IsRGBA, 55 "hsl": IsHSL, 56 "hsla": IsHSLA, 57 "email": IsEmail, 58 "url": IsURL, 59 "uri": IsURI, 60 "base64": IsBase64, 61 "contains": Contains, 62 "containsany": ContainsAny, 63 "containsrune": ContainsRune, 64 "excludes": Excludes, 65 "excludesall": ExcludesAll, 66 "excludesrune": ExcludesRune, 67 "isbn": IsISBN, 68 "isbn10": IsISBN10, 69 "isbn13": IsISBN13, 70 "uuid": IsUUID, 71 "uuid3": IsUUID3, 72 "uuid4": IsUUID4, 73 "uuid5": IsUUID5, 74 "ascii": IsASCII, 75 "printascii": IsPrintableASCII, 76 "multibyte": HasMultiByteCharacter, 77 "datauri": IsDataURI, 78 "latitude": IsLatitude, 79 "longitude": IsLongitude, 80 "ssn": IsSSN, 81 "ipv4": IsIPv4, 82 "ipv6": IsIPv6, 83 "ip": IsIP, 84 "cidrv4": IsCIDRv4, 85 "cidrv6": IsCIDRv6, 86 "cidr": IsCIDR, 87 "tcp4_addr": IsTCP4AddrResolvable, 88 "tcp6_addr": IsTCP6AddrResolvable, 89 "tcp_addr": IsTCPAddrResolvable, 90 "udp4_addr": IsUDP4AddrResolvable, 91 "udp6_addr": IsUDP6AddrResolvable, 92 "udp_addr": IsUDPAddrResolvable, 93 "ip4_addr": IsIP4AddrResolvable, 94 "ip6_addr": IsIP6AddrResolvable, 95 "ip_addr": IsIPAddrResolvable, 96 "unix_addr": IsUnixAddrResolvable, 97 "mac": IsMAC, 98} 99 100// IsMAC is the validation function for validating if the field's value is a valid MAC address. 101// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 102func IsMAC(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 103 _, err := net.ParseMAC(field.String()) 104 return err == nil 105} 106 107// IsCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address. 108// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 109func IsCIDRv4(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 110 111 ip, _, err := net.ParseCIDR(field.String()) 112 113 return err == nil && ip.To4() != nil 114} 115 116// IsCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address. 117// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 118func IsCIDRv6(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 119 120 ip, _, err := net.ParseCIDR(field.String()) 121 122 return err == nil && ip.To4() == nil 123} 124 125// IsCIDR is the validation function for validating if the field's value is a valid v4 or v6 CIDR address. 126// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 127func IsCIDR(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 128 129 _, _, err := net.ParseCIDR(field.String()) 130 131 return err == nil 132} 133 134// IsIPv4 is the validation function for validating if a value is a valid v4 IP address. 135// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 136func IsIPv4(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 137 138 ip := net.ParseIP(field.String()) 139 140 return ip != nil && ip.To4() != nil 141} 142 143// IsIPv6 is the validation function for validating if the field's value is a valid v6 IP address. 144// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 145func IsIPv6(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 146 ip := net.ParseIP(field.String()) 147 148 return ip != nil && ip.To4() == nil 149} 150 151// IsIP is the validation function for validating if the field's value is a valid v4 or v6 IP address. 152// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 153func IsIP(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 154 155 ip := net.ParseIP(field.String()) 156 157 return ip != nil 158} 159 160// IsSSN is the validation function for validating if the field's value is a valid SSN. 161// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 162func IsSSN(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 163 164 if field.Len() != 11 { 165 return false 166 } 167 168 return sSNRegex.MatchString(field.String()) 169} 170 171// IsLongitude is the validation function for validating if the field's value is a valid longitude coordinate. 172// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 173func IsLongitude(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 174 return longitudeRegex.MatchString(field.String()) 175} 176 177// IsLatitude is the validation function for validating if the field's value is a valid latitude coordinate. 178// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 179func IsLatitude(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 180 return latitudeRegex.MatchString(field.String()) 181} 182 183// IsDataURI is the validation function for validating if the field's value is a valid data URI. 184// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 185func IsDataURI(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 186 187 uri := strings.SplitN(field.String(), ",", 2) 188 189 if len(uri) != 2 { 190 return false 191 } 192 193 if !dataURIRegex.MatchString(uri[0]) { 194 return false 195 } 196 197 fld := reflect.ValueOf(uri[1]) 198 199 return IsBase64(v, topStruct, currentStructOrField, fld, fld.Type(), fld.Kind(), param) 200} 201 202// HasMultiByteCharacter is the validation function for validating if the field's value has a multi byte character. 203// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 204func HasMultiByteCharacter(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 205 206 if field.Len() == 0 { 207 return true 208 } 209 210 return multibyteRegex.MatchString(field.String()) 211} 212 213// IsPrintableASCII is the validation function for validating if the field's value is a valid printable ASCII character. 214// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 215func IsPrintableASCII(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 216 return printableASCIIRegex.MatchString(field.String()) 217} 218 219// IsASCII is the validation function for validating if the field's value is a valid ASCII character. 220// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 221func IsASCII(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 222 return aSCIIRegex.MatchString(field.String()) 223} 224 225// IsUUID5 is the validation function for validating if the field's value is a valid v5 UUID. 226// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 227func IsUUID5(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 228 return uUID5Regex.MatchString(field.String()) 229} 230 231// IsUUID4 is the validation function for validating if the field's value is a valid v4 UUID. 232// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 233func IsUUID4(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 234 return uUID4Regex.MatchString(field.String()) 235} 236 237// IsUUID3 is the validation function for validating if the field's value is a valid v3 UUID. 238// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 239func IsUUID3(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 240 return uUID3Regex.MatchString(field.String()) 241} 242 243// IsUUID is the validation function for validating if the field's value is a valid UUID of any version. 244// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 245func IsUUID(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 246 return uUIDRegex.MatchString(field.String()) 247} 248 249// IsISBN is the validation function for validating if the field's value is a valid v10 or v13 ISBN. 250// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 251func IsISBN(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 252 return IsISBN10(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) || IsISBN13(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) 253} 254 255// IsISBN13 is the validation function for validating if the field's value is a valid v13 ISBN. 256// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 257func IsISBN13(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 258 259 s := strings.Replace(strings.Replace(field.String(), "-", "", 4), " ", "", 4) 260 261 if !iSBN13Regex.MatchString(s) { 262 return false 263 } 264 265 var checksum int32 266 var i int32 267 268 factor := []int32{1, 3} 269 270 for i = 0; i < 12; i++ { 271 checksum += factor[i%2] * int32(s[i]-'0') 272 } 273 274 return (int32(s[12]-'0'))-((10-(checksum%10))%10) == 0 275} 276 277// IsISBN10 is the validation function for validating if the field's value is a valid v10 ISBN. 278// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 279func IsISBN10(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 280 281 s := strings.Replace(strings.Replace(field.String(), "-", "", 3), " ", "", 3) 282 283 if !iSBN10Regex.MatchString(s) { 284 return false 285 } 286 287 var checksum int32 288 var i int32 289 290 for i = 0; i < 9; i++ { 291 checksum += (i + 1) * int32(s[i]-'0') 292 } 293 294 if s[9] == 'X' { 295 checksum += 10 * 10 296 } else { 297 checksum += 10 * int32(s[9]-'0') 298 } 299 300 return checksum%11 == 0 301} 302 303// ExcludesRune is the validation function for validating that the field's value does not contain the rune specified within the param. 304// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 305func ExcludesRune(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 306 return !ContainsRune(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) 307} 308 309// ExcludesAll is the validation function for validating that the field's value does not contain any of the characters specified within the param. 310// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 311func ExcludesAll(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 312 return !ContainsAny(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) 313} 314 315// Excludes is the validation function for validating that the field's value does not contain the text specified within the param. 316// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 317func Excludes(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 318 return !Contains(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) 319} 320 321// ContainsRune is the validation function for validating that the field's value contains the rune specified within the param. 322// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 323func ContainsRune(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 324 r, _ := utf8.DecodeRuneInString(param) 325 326 return strings.ContainsRune(field.String(), r) 327} 328 329// ContainsAny is the validation function for validating that the field's value contains any of the characters specified within the param. 330// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 331func ContainsAny(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 332 return strings.ContainsAny(field.String(), param) 333} 334 335// Contains is the validation function for validating that the field's value contains the text specified within the param. 336// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 337func Contains(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 338 return strings.Contains(field.String(), param) 339} 340 341// IsNeField is the validation function for validating if the current field's value is not equal to the field specified by the param's value. 342// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 343func IsNeField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 344 345 currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param) 346 347 if !ok || currentKind != fieldKind { 348 return true 349 } 350 351 switch fieldKind { 352 353 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 354 return field.Int() != currentField.Int() 355 356 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 357 return field.Uint() != currentField.Uint() 358 359 case reflect.Float32, reflect.Float64: 360 return field.Float() != currentField.Float() 361 362 case reflect.Slice, reflect.Map, reflect.Array: 363 return int64(field.Len()) != int64(currentField.Len()) 364 365 case reflect.Struct: 366 367 // Not Same underlying type i.e. struct and time 368 if fieldType != currentField.Type() { 369 return true 370 } 371 372 if fieldType == timeType { 373 374 t := currentField.Interface().(time.Time) 375 fieldTime := field.Interface().(time.Time) 376 377 return !fieldTime.Equal(t) 378 } 379 380 } 381 382 // default reflect.String: 383 return field.String() != currentField.String() 384} 385 386// IsNe is the validation function for validating that the field's value does not equal the provided param value. 387// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 388func IsNe(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 389 return !IsEq(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) 390} 391 392// IsLteCrossStructField is the validation function for validating if the current field's value is less than or equal to the field, within a separate struct, specified by the param's value. 393// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 394func IsLteCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 395 396 topField, topKind, ok := v.GetStructFieldOK(topStruct, param) 397 if !ok || topKind != fieldKind { 398 return false 399 } 400 401 switch fieldKind { 402 403 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 404 return field.Int() <= topField.Int() 405 406 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 407 return field.Uint() <= topField.Uint() 408 409 case reflect.Float32, reflect.Float64: 410 return field.Float() <= topField.Float() 411 412 case reflect.Slice, reflect.Map, reflect.Array: 413 return int64(field.Len()) <= int64(topField.Len()) 414 415 case reflect.Struct: 416 417 // Not Same underlying type i.e. struct and time 418 if fieldType != topField.Type() { 419 return false 420 } 421 422 if fieldType == timeType { 423 424 fieldTime := field.Interface().(time.Time) 425 topTime := topField.Interface().(time.Time) 426 427 return fieldTime.Before(topTime) || fieldTime.Equal(topTime) 428 } 429 } 430 431 // default reflect.String: 432 return field.String() <= topField.String() 433} 434 435// IsLtCrossStructField is the validation function for validating if the current field's value is less than the field, within a separate struct, specified by the param's value. 436// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 437func IsLtCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 438 439 topField, topKind, ok := v.GetStructFieldOK(topStruct, param) 440 if !ok || topKind != fieldKind { 441 return false 442 } 443 444 switch fieldKind { 445 446 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 447 return field.Int() < topField.Int() 448 449 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 450 return field.Uint() < topField.Uint() 451 452 case reflect.Float32, reflect.Float64: 453 return field.Float() < topField.Float() 454 455 case reflect.Slice, reflect.Map, reflect.Array: 456 return int64(field.Len()) < int64(topField.Len()) 457 458 case reflect.Struct: 459 460 // Not Same underlying type i.e. struct and time 461 if fieldType != topField.Type() { 462 return false 463 } 464 465 if fieldType == timeType { 466 467 fieldTime := field.Interface().(time.Time) 468 topTime := topField.Interface().(time.Time) 469 470 return fieldTime.Before(topTime) 471 } 472 } 473 474 // default reflect.String: 475 return field.String() < topField.String() 476} 477 478// IsGteCrossStructField is the validation function for validating if the current field's value is greater than or equal to the field, within a separate struct, specified by the param's value. 479// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 480func IsGteCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 481 482 topField, topKind, ok := v.GetStructFieldOK(topStruct, param) 483 if !ok || topKind != fieldKind { 484 return false 485 } 486 487 switch fieldKind { 488 489 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 490 return field.Int() >= topField.Int() 491 492 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 493 return field.Uint() >= topField.Uint() 494 495 case reflect.Float32, reflect.Float64: 496 return field.Float() >= topField.Float() 497 498 case reflect.Slice, reflect.Map, reflect.Array: 499 return int64(field.Len()) >= int64(topField.Len()) 500 501 case reflect.Struct: 502 503 // Not Same underlying type i.e. struct and time 504 if fieldType != topField.Type() { 505 return false 506 } 507 508 if fieldType == timeType { 509 510 fieldTime := field.Interface().(time.Time) 511 topTime := topField.Interface().(time.Time) 512 513 return fieldTime.After(topTime) || fieldTime.Equal(topTime) 514 } 515 } 516 517 // default reflect.String: 518 return field.String() >= topField.String() 519} 520 521// IsGtCrossStructField is the validation function for validating if the current field's value is greater than the field, within a separate struct, specified by the param's value. 522// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 523func IsGtCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 524 525 topField, topKind, ok := v.GetStructFieldOK(topStruct, param) 526 if !ok || topKind != fieldKind { 527 return false 528 } 529 530 switch fieldKind { 531 532 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 533 return field.Int() > topField.Int() 534 535 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 536 return field.Uint() > topField.Uint() 537 538 case reflect.Float32, reflect.Float64: 539 return field.Float() > topField.Float() 540 541 case reflect.Slice, reflect.Map, reflect.Array: 542 return int64(field.Len()) > int64(topField.Len()) 543 544 case reflect.Struct: 545 546 // Not Same underlying type i.e. struct and time 547 if fieldType != topField.Type() { 548 return false 549 } 550 551 if fieldType == timeType { 552 553 fieldTime := field.Interface().(time.Time) 554 topTime := topField.Interface().(time.Time) 555 556 return fieldTime.After(topTime) 557 } 558 } 559 560 // default reflect.String: 561 return field.String() > topField.String() 562} 563 564// IsNeCrossStructField is the validation function for validating that the current field's value is not equal to the field, within a separate struct, specified by the param's value. 565// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 566func IsNeCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 567 568 topField, currentKind, ok := v.GetStructFieldOK(topStruct, param) 569 if !ok || currentKind != fieldKind { 570 return true 571 } 572 573 switch fieldKind { 574 575 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 576 return topField.Int() != field.Int() 577 578 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 579 return topField.Uint() != field.Uint() 580 581 case reflect.Float32, reflect.Float64: 582 return topField.Float() != field.Float() 583 584 case reflect.Slice, reflect.Map, reflect.Array: 585 return int64(topField.Len()) != int64(field.Len()) 586 587 case reflect.Struct: 588 589 // Not Same underlying type i.e. struct and time 590 if fieldType != topField.Type() { 591 return true 592 } 593 594 if fieldType == timeType { 595 596 t := field.Interface().(time.Time) 597 fieldTime := topField.Interface().(time.Time) 598 599 return !fieldTime.Equal(t) 600 } 601 } 602 603 // default reflect.String: 604 return topField.String() != field.String() 605} 606 607// IsEqCrossStructField is the validation function for validating that the current field's value is equal to the field, within a separate struct, specified by the param's value. 608// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 609func IsEqCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 610 611 topField, topKind, ok := v.GetStructFieldOK(topStruct, param) 612 if !ok || topKind != fieldKind { 613 return false 614 } 615 616 switch fieldKind { 617 618 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 619 return topField.Int() == field.Int() 620 621 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 622 return topField.Uint() == field.Uint() 623 624 case reflect.Float32, reflect.Float64: 625 return topField.Float() == field.Float() 626 627 case reflect.Slice, reflect.Map, reflect.Array: 628 return int64(topField.Len()) == int64(field.Len()) 629 630 case reflect.Struct: 631 632 // Not Same underlying type i.e. struct and time 633 if fieldType != topField.Type() { 634 return false 635 } 636 637 if fieldType == timeType { 638 639 t := field.Interface().(time.Time) 640 fieldTime := topField.Interface().(time.Time) 641 642 return fieldTime.Equal(t) 643 } 644 } 645 646 // default reflect.String: 647 return topField.String() == field.String() 648} 649 650// IsEqField is the validation function for validating if the current field's value is equal to the field specified by the param's value. 651// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 652func IsEqField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 653 654 currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param) 655 if !ok || currentKind != fieldKind { 656 return false 657 } 658 659 switch fieldKind { 660 661 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 662 return field.Int() == currentField.Int() 663 664 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 665 return field.Uint() == currentField.Uint() 666 667 case reflect.Float32, reflect.Float64: 668 return field.Float() == currentField.Float() 669 670 case reflect.Slice, reflect.Map, reflect.Array: 671 return int64(field.Len()) == int64(currentField.Len()) 672 673 case reflect.Struct: 674 675 // Not Same underlying type i.e. struct and time 676 if fieldType != currentField.Type() { 677 return false 678 } 679 680 if fieldType == timeType { 681 682 t := currentField.Interface().(time.Time) 683 fieldTime := field.Interface().(time.Time) 684 685 return fieldTime.Equal(t) 686 } 687 688 } 689 690 // default reflect.String: 691 return field.String() == currentField.String() 692} 693 694// IsEq is the validation function for validating if the current field's value is equal to the param's value. 695// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 696func IsEq(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 697 698 switch fieldKind { 699 700 case reflect.String: 701 return field.String() == param 702 703 case reflect.Slice, reflect.Map, reflect.Array: 704 p := asInt(param) 705 706 return int64(field.Len()) == p 707 708 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 709 p := asInt(param) 710 711 return field.Int() == p 712 713 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 714 p := asUint(param) 715 716 return field.Uint() == p 717 718 case reflect.Float32, reflect.Float64: 719 p := asFloat(param) 720 721 return field.Float() == p 722 } 723 724 panic(fmt.Sprintf("Bad field type %T", field.Interface())) 725} 726 727// IsBase64 is the validation function for validating if the current field's value is a valid base 64. 728// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 729func IsBase64(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 730 return base64Regex.MatchString(field.String()) 731} 732 733// IsURI is the validation function for validating if the current field's value is a valid URI. 734// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 735func IsURI(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 736 737 switch fieldKind { 738 739 case reflect.String: 740 741 s := field.String() 742 743 // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195 744 // emulate browser and strip the '#' suffix prior to validation. see issue-#237 745 if i := strings.Index(s, "#"); i > -1 { 746 s = s[:i] 747 } 748 749 if s == blank { 750 return false 751 } 752 753 _, err := url.ParseRequestURI(s) 754 755 return err == nil 756 } 757 758 panic(fmt.Sprintf("Bad field type %T", field.Interface())) 759} 760 761// IsURL is the validation function for validating if the current field's value is a valid URL. 762// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 763func IsURL(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 764 765 switch fieldKind { 766 767 case reflect.String: 768 769 var i int 770 s := field.String() 771 772 // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195 773 // emulate browser and strip the '#' suffix prior to validation. see issue-#237 774 if i = strings.Index(s, "#"); i > -1 { 775 s = s[:i] 776 } 777 778 if s == blank { 779 return false 780 } 781 782 url, err := url.ParseRequestURI(s) 783 784 if err != nil || url.Scheme == blank { 785 return false 786 } 787 788 return err == nil 789 } 790 791 panic(fmt.Sprintf("Bad field type %T", field.Interface())) 792} 793 794// IsEmail is the validation function for validating if the current field's value is a valid email address. 795// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 796func IsEmail(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 797 return emailRegex.MatchString(field.String()) 798} 799 800// IsHSLA is the validation function for validating if the current field's value is a valid HSLA color. 801// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 802func IsHSLA(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 803 return hslaRegex.MatchString(field.String()) 804} 805 806// IsHSL is the validation function for validating if the current field's value is a valid HSL color. 807// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 808func IsHSL(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 809 return hslRegex.MatchString(field.String()) 810} 811 812// IsRGBA is the validation function for validating if the current field's value is a valid RGBA color. 813// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 814func IsRGBA(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 815 return rgbaRegex.MatchString(field.String()) 816} 817 818// IsRGB is the validation function for validating if the current field's value is a valid RGB color. 819// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 820func IsRGB(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 821 return rgbRegex.MatchString(field.String()) 822} 823 824// IsHEXColor is the validation function for validating if the current field's value is a valid HEX color. 825// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 826func IsHEXColor(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 827 return hexcolorRegex.MatchString(field.String()) 828} 829 830// IsHexadecimal is the validation function for validating if the current field's value is a valid hexadecimal. 831// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 832func IsHexadecimal(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 833 return hexadecimalRegex.MatchString(field.String()) 834} 835 836// IsNumber is the validation function for validating if the current field's value is a valid number. 837// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 838func IsNumber(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 839 return numberRegex.MatchString(field.String()) 840} 841 842// IsNumeric is the validation function for validating if the current field's value is a valid numeric value. 843// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 844func IsNumeric(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 845 return numericRegex.MatchString(field.String()) 846} 847 848// IsAlphanum is the validation function for validating if the current field's value is a valid alphanumeric value. 849// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 850func IsAlphanum(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 851 return alphaNumericRegex.MatchString(field.String()) 852} 853 854// IsAlpha is the validation function for validating if the current field's value is a valid alpha value. 855// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 856func IsAlpha(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 857 return alphaRegex.MatchString(field.String()) 858} 859 860// HasValue is the validation function for validating if the current field's value is not the default static value. 861// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 862func HasValue(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 863 864 switch fieldKind { 865 case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func: 866 return !field.IsNil() 867 default: 868 return field.IsValid() && field.Interface() != reflect.Zero(fieldType).Interface() 869 } 870} 871 872// IsGteField is the validation function for validating if the current field's value is greater than or equal to the field specified by the param's value. 873// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 874func IsGteField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 875 876 currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param) 877 if !ok || currentKind != fieldKind { 878 return false 879 } 880 881 switch fieldKind { 882 883 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 884 885 return field.Int() >= currentField.Int() 886 887 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 888 889 return field.Uint() >= currentField.Uint() 890 891 case reflect.Float32, reflect.Float64: 892 893 return field.Float() >= currentField.Float() 894 895 case reflect.Struct: 896 897 // Not Same underlying type i.e. struct and time 898 if fieldType != currentField.Type() { 899 return false 900 } 901 902 if fieldType == timeType { 903 904 t := currentField.Interface().(time.Time) 905 fieldTime := field.Interface().(time.Time) 906 907 return fieldTime.After(t) || fieldTime.Equal(t) 908 } 909 } 910 911 // default reflect.String 912 return len(field.String()) >= len(currentField.String()) 913} 914 915// IsGtField is the validation function for validating if the current field's value is greater than the field specified by the param's value. 916// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 917func IsGtField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 918 919 currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param) 920 if !ok || currentKind != fieldKind { 921 return false 922 } 923 924 switch fieldKind { 925 926 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 927 928 return field.Int() > currentField.Int() 929 930 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 931 932 return field.Uint() > currentField.Uint() 933 934 case reflect.Float32, reflect.Float64: 935 936 return field.Float() > currentField.Float() 937 938 case reflect.Struct: 939 940 // Not Same underlying type i.e. struct and time 941 if fieldType != currentField.Type() { 942 return false 943 } 944 945 if fieldType == timeType { 946 947 t := currentField.Interface().(time.Time) 948 fieldTime := field.Interface().(time.Time) 949 950 return fieldTime.After(t) 951 } 952 } 953 954 // default reflect.String 955 return len(field.String()) > len(currentField.String()) 956} 957 958// IsGte is the validation function for validating if the current field's value is greater than or equal to the param's value. 959// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 960func IsGte(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 961 962 switch fieldKind { 963 964 case reflect.String: 965 p := asInt(param) 966 967 return int64(utf8.RuneCountInString(field.String())) >= p 968 969 case reflect.Slice, reflect.Map, reflect.Array: 970 p := asInt(param) 971 972 return int64(field.Len()) >= p 973 974 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 975 p := asInt(param) 976 977 return field.Int() >= p 978 979 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 980 p := asUint(param) 981 982 return field.Uint() >= p 983 984 case reflect.Float32, reflect.Float64: 985 p := asFloat(param) 986 987 return field.Float() >= p 988 989 case reflect.Struct: 990 991 if fieldType == timeType || fieldType == timePtrType { 992 993 now := time.Now().UTC() 994 t := field.Interface().(time.Time) 995 996 return t.After(now) || t.Equal(now) 997 } 998 } 999 1000 panic(fmt.Sprintf("Bad field type %T", field.Interface())) 1001} 1002 1003// IsGt is the validation function for validating if the current field's value is greater than the param's value. 1004// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 1005func IsGt(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 1006 1007 switch fieldKind { 1008 1009 case reflect.String: 1010 p := asInt(param) 1011 1012 return int64(utf8.RuneCountInString(field.String())) > p 1013 1014 case reflect.Slice, reflect.Map, reflect.Array: 1015 p := asInt(param) 1016 1017 return int64(field.Len()) > p 1018 1019 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 1020 p := asInt(param) 1021 1022 return field.Int() > p 1023 1024 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 1025 p := asUint(param) 1026 1027 return field.Uint() > p 1028 1029 case reflect.Float32, reflect.Float64: 1030 p := asFloat(param) 1031 1032 return field.Float() > p 1033 case reflect.Struct: 1034 1035 if fieldType == timeType || fieldType == timePtrType { 1036 1037 return field.Interface().(time.Time).After(time.Now().UTC()) 1038 } 1039 } 1040 1041 panic(fmt.Sprintf("Bad field type %T", field.Interface())) 1042} 1043 1044// HasLengthOf is the validation function for validating if the current field's value is equal to the param's value. 1045// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 1046func HasLengthOf(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 1047 1048 switch fieldKind { 1049 1050 case reflect.String: 1051 p := asInt(param) 1052 1053 return int64(utf8.RuneCountInString(field.String())) == p 1054 1055 case reflect.Slice, reflect.Map, reflect.Array: 1056 p := asInt(param) 1057 1058 return int64(field.Len()) == p 1059 1060 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 1061 p := asInt(param) 1062 1063 return field.Int() == p 1064 1065 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 1066 p := asUint(param) 1067 1068 return field.Uint() == p 1069 1070 case reflect.Float32, reflect.Float64: 1071 p := asFloat(param) 1072 1073 return field.Float() == p 1074 } 1075 1076 panic(fmt.Sprintf("Bad field type %T", field.Interface())) 1077} 1078 1079// HasMinOf is the validation function for validating if the current field's value is greater than or equal to the param's value. 1080// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 1081func HasMinOf(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 1082 1083 return IsGte(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) 1084} 1085 1086// IsLteField is the validation function for validating if the current field's value is less than or equal to the field specified by the param's value. 1087// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 1088func IsLteField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 1089 1090 currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param) 1091 if !ok || currentKind != fieldKind { 1092 return false 1093 } 1094 1095 switch fieldKind { 1096 1097 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 1098 1099 return field.Int() <= currentField.Int() 1100 1101 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 1102 1103 return field.Uint() <= currentField.Uint() 1104 1105 case reflect.Float32, reflect.Float64: 1106 1107 return field.Float() <= currentField.Float() 1108 1109 case reflect.Struct: 1110 1111 // Not Same underlying type i.e. struct and time 1112 if fieldType != currentField.Type() { 1113 return false 1114 } 1115 1116 if fieldType == timeType { 1117 1118 t := currentField.Interface().(time.Time) 1119 fieldTime := field.Interface().(time.Time) 1120 1121 return fieldTime.Before(t) || fieldTime.Equal(t) 1122 } 1123 } 1124 1125 // default reflect.String 1126 return len(field.String()) <= len(currentField.String()) 1127} 1128 1129// IsLtField is the validation function for validating if the current field's value is less than the field specified by the param's value. 1130// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 1131func IsLtField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 1132 1133 currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param) 1134 if !ok || currentKind != fieldKind { 1135 return false 1136 } 1137 1138 switch fieldKind { 1139 1140 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 1141 1142 return field.Int() < currentField.Int() 1143 1144 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 1145 1146 return field.Uint() < currentField.Uint() 1147 1148 case reflect.Float32, reflect.Float64: 1149 1150 return field.Float() < currentField.Float() 1151 1152 case reflect.Struct: 1153 1154 // Not Same underlying type i.e. struct and time 1155 if fieldType != currentField.Type() { 1156 return false 1157 } 1158 1159 if fieldType == timeType { 1160 1161 t := currentField.Interface().(time.Time) 1162 fieldTime := field.Interface().(time.Time) 1163 1164 return fieldTime.Before(t) 1165 } 1166 } 1167 1168 // default reflect.String 1169 return len(field.String()) < len(currentField.String()) 1170} 1171 1172// IsLte is the validation function for validating if the current field's value is less than or equal to the param's value. 1173// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 1174func IsLte(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 1175 1176 switch fieldKind { 1177 1178 case reflect.String: 1179 p := asInt(param) 1180 1181 return int64(utf8.RuneCountInString(field.String())) <= p 1182 1183 case reflect.Slice, reflect.Map, reflect.Array: 1184 p := asInt(param) 1185 1186 return int64(field.Len()) <= p 1187 1188 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 1189 p := asInt(param) 1190 1191 return field.Int() <= p 1192 1193 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 1194 p := asUint(param) 1195 1196 return field.Uint() <= p 1197 1198 case reflect.Float32, reflect.Float64: 1199 p := asFloat(param) 1200 1201 return field.Float() <= p 1202 1203 case reflect.Struct: 1204 1205 if fieldType == timeType || fieldType == timePtrType { 1206 1207 now := time.Now().UTC() 1208 t := field.Interface().(time.Time) 1209 1210 return t.Before(now) || t.Equal(now) 1211 } 1212 } 1213 1214 panic(fmt.Sprintf("Bad field type %T", field.Interface())) 1215} 1216 1217// IsLt is the validation function for validating if the current field's value is less than the param's value. 1218// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 1219func IsLt(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 1220 1221 switch fieldKind { 1222 1223 case reflect.String: 1224 p := asInt(param) 1225 1226 return int64(utf8.RuneCountInString(field.String())) < p 1227 1228 case reflect.Slice, reflect.Map, reflect.Array: 1229 p := asInt(param) 1230 1231 return int64(field.Len()) < p 1232 1233 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 1234 p := asInt(param) 1235 1236 return field.Int() < p 1237 1238 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 1239 p := asUint(param) 1240 1241 return field.Uint() < p 1242 1243 case reflect.Float32, reflect.Float64: 1244 p := asFloat(param) 1245 1246 return field.Float() < p 1247 1248 case reflect.Struct: 1249 1250 if fieldType == timeType || fieldType == timePtrType { 1251 1252 return field.Interface().(time.Time).Before(time.Now().UTC()) 1253 } 1254 } 1255 1256 panic(fmt.Sprintf("Bad field type %T", field.Interface())) 1257} 1258 1259// HasMaxOf is the validation function for validating if the current field's value is less than or equal to the param's value. 1260// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 1261func HasMaxOf(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 1262 return IsLte(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) 1263} 1264 1265// IsTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address. 1266// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 1267func IsTCP4AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 1268 1269 if !isIP4Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) { 1270 return false 1271 } 1272 1273 _, err := net.ResolveTCPAddr("tcp4", field.String()) 1274 return err == nil 1275} 1276 1277// IsTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address. 1278// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 1279func IsTCP6AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 1280 1281 if !isIP6Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) { 1282 return false 1283 } 1284 1285 _, err := net.ResolveTCPAddr("tcp6", field.String()) 1286 return err == nil 1287} 1288 1289// IsTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address. 1290// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 1291func IsTCPAddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 1292 1293 if !isIP4Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) && 1294 !isIP6Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) { 1295 return false 1296 } 1297 1298 _, err := net.ResolveTCPAddr("tcp", field.String()) 1299 return err == nil 1300} 1301 1302// IsUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address. 1303// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 1304func IsUDP4AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 1305 1306 if !isIP4Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) { 1307 return false 1308 } 1309 1310 _, err := net.ResolveUDPAddr("udp4", field.String()) 1311 return err == nil 1312} 1313 1314// IsUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address. 1315// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 1316func IsUDP6AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 1317 1318 if !isIP6Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) { 1319 return false 1320 } 1321 1322 _, err := net.ResolveUDPAddr("udp6", field.String()) 1323 return err == nil 1324} 1325 1326// IsUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address. 1327// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 1328func IsUDPAddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 1329 1330 if !isIP4Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) && 1331 !isIP6Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) { 1332 return false 1333 } 1334 1335 _, err := net.ResolveUDPAddr("udp", field.String()) 1336 return err == nil 1337} 1338 1339// IsIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address. 1340// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 1341func IsIP4AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 1342 1343 if !IsIPv4(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) { 1344 return false 1345 } 1346 1347 _, err := net.ResolveIPAddr("ip4", field.String()) 1348 return err == nil 1349} 1350 1351// IsIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address. 1352// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 1353func IsIP6AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 1354 1355 if !IsIPv6(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) { 1356 return false 1357 } 1358 1359 _, err := net.ResolveIPAddr("ip6", field.String()) 1360 return err == nil 1361} 1362 1363// IsIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address. 1364// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 1365func IsIPAddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 1366 1367 if !IsIP(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) { 1368 return false 1369 } 1370 1371 _, err := net.ResolveIPAddr("ip", field.String()) 1372 return err == nil 1373} 1374 1375// IsUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address. 1376// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. 1377func IsUnixAddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 1378 _, err := net.ResolveUnixAddr("unix", field.String()) 1379 return err == nil 1380} 1381 1382func isIP4Addr(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 1383 val := field.String() 1384 1385 if idx := strings.LastIndex(val, ":"); idx != -1 { 1386 val = val[0:idx] 1387 } 1388 1389 if !IsIPv4(v, topStruct, currentStructOrField, reflect.ValueOf(val), fieldType, fieldKind, param) { 1390 return false 1391 } 1392 1393 return true 1394} 1395 1396func isIP6Addr(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { 1397 val := field.String() 1398 1399 if idx := strings.LastIndex(val, ":"); idx != -1 { 1400 if idx != 0 && val[idx-1:idx] == "]" { 1401 val = val[1 : idx-1] 1402 } 1403 } 1404 1405 if !IsIPv6(v, topStruct, currentStructOrField, reflect.ValueOf(val), fieldType, fieldKind, param) { 1406 return false 1407 } 1408 1409 return true 1410} 1411