5991a21818
* First batch of changes for the refactor Added the support of gin in routes and other services/utils Begining implementation of JetHTML * Remove os folder * Move scrapers to own repo * Second batch of changes All .jet.html are the working templates. You can now test this PR, the index Page and upload works. If you want to complete the other html templates, you're welcome * Move captcha to util * Move uploadService to utils * Use govalidator instead of regex * Third batch of changes All the front end should as previously. I also fixed some minor things unrelated to the refactor (mostly style issues on static pages) Now errors can be accessed by importing the "errors" helpers and using the `yield errors(name="xxx")` command in templates. Same for infos. Templates are now more hierarchized with a base template "base.jet.html" which is extended depending on the context in "index_site" or "index_admin" layouts. Those layouts are extended than in every pages. Other helpers are captcha to render a captcha `yield captcha(captchaid="xxx")` And also csrf, with the command `yield csrf_field()` To translate, you don't have anymore to do `call $.T "xxx"`, you just have to do `T("xxx")`. Pages for the website part are in folders in the folder "templates/site". Pages for the admin part are in "templates/admin". Layouts are separated in "templates/layouts". Helpers and menu are in "templates/layouts/helpers" and "templates/layouts/menu". Error pages should be put in "templates/errors" * Added test on templates When adding a new template, you have to tell to template_test.go, the context of the new template (if it doesn't use the common context) * Panel admin works Now the templating part should work. The PR can now be fully tested. I think we should push the templating PR and do the routes/controllers/removal of services in another branch. So we know that this one is functional * Updated dependencies * Fixed test for modelhelper * Fix testing for commentlist * Fix travis :') * Just renamed router and removed network * Applying same SEO fix * Update form_validator.go * Added back regexp package
1410 lignes
55 Kio
Go
1410 lignes
55 Kio
Go
package validator
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"net/url"
|
|
"reflect"
|
|
"strings"
|
|
"time"
|
|
"unicode/utf8"
|
|
)
|
|
|
|
// BakedInAliasValidators is a default mapping of a single validationstag that
|
|
// defines a common or complex set of validation(s) to simplify
|
|
// adding validation to structs. i.e. set key "_ageok" and the tags
|
|
// are "gt=0,lte=130" or key "_preferredname" and tags "omitempty,gt=0,lte=60"
|
|
var bakedInAliasValidators = map[string]string{
|
|
"iscolor": "hexcolor|rgb|rgba|hsl|hsla",
|
|
}
|
|
|
|
// BakedInValidators is the default map of ValidationFunc
|
|
// you can add, remove or even replace items to suite your needs,
|
|
// or even disregard and use your own map if so desired.
|
|
var bakedInValidators = map[string]Func{
|
|
"required": HasValue,
|
|
"len": HasLengthOf,
|
|
"min": HasMinOf,
|
|
"max": HasMaxOf,
|
|
"eq": IsEq,
|
|
"ne": IsNe,
|
|
"lt": IsLt,
|
|
"lte": IsLte,
|
|
"gt": IsGt,
|
|
"gte": IsGte,
|
|
"eqfield": IsEqField,
|
|
"eqcsfield": IsEqCrossStructField,
|
|
"necsfield": IsNeCrossStructField,
|
|
"gtcsfield": IsGtCrossStructField,
|
|
"gtecsfield": IsGteCrossStructField,
|
|
"ltcsfield": IsLtCrossStructField,
|
|
"ltecsfield": IsLteCrossStructField,
|
|
"nefield": IsNeField,
|
|
"gtefield": IsGteField,
|
|
"gtfield": IsGtField,
|
|
"ltefield": IsLteField,
|
|
"ltfield": IsLtField,
|
|
"alpha": IsAlpha,
|
|
"alphanum": IsAlphanum,
|
|
"numeric": IsNumeric,
|
|
"number": IsNumber,
|
|
"hexadecimal": IsHexadecimal,
|
|
"hexcolor": IsHEXColor,
|
|
"rgb": IsRGB,
|
|
"rgba": IsRGBA,
|
|
"hsl": IsHSL,
|
|
"hsla": IsHSLA,
|
|
"email": IsEmail,
|
|
"url": IsURL,
|
|
"uri": IsURI,
|
|
"base64": IsBase64,
|
|
"contains": Contains,
|
|
"containsany": ContainsAny,
|
|
"containsrune": ContainsRune,
|
|
"excludes": Excludes,
|
|
"excludesall": ExcludesAll,
|
|
"excludesrune": ExcludesRune,
|
|
"isbn": IsISBN,
|
|
"isbn10": IsISBN10,
|
|
"isbn13": IsISBN13,
|
|
"uuid": IsUUID,
|
|
"uuid3": IsUUID3,
|
|
"uuid4": IsUUID4,
|
|
"uuid5": IsUUID5,
|
|
"ascii": IsASCII,
|
|
"printascii": IsPrintableASCII,
|
|
"multibyte": HasMultiByteCharacter,
|
|
"datauri": IsDataURI,
|
|
"latitude": IsLatitude,
|
|
"longitude": IsLongitude,
|
|
"ssn": IsSSN,
|
|
"ipv4": IsIPv4,
|
|
"ipv6": IsIPv6,
|
|
"ip": IsIP,
|
|
"cidrv4": IsCIDRv4,
|
|
"cidrv6": IsCIDRv6,
|
|
"cidr": IsCIDR,
|
|
"tcp4_addr": IsTCP4AddrResolvable,
|
|
"tcp6_addr": IsTCP6AddrResolvable,
|
|
"tcp_addr": IsTCPAddrResolvable,
|
|
"udp4_addr": IsUDP4AddrResolvable,
|
|
"udp6_addr": IsUDP6AddrResolvable,
|
|
"udp_addr": IsUDPAddrResolvable,
|
|
"ip4_addr": IsIP4AddrResolvable,
|
|
"ip6_addr": IsIP6AddrResolvable,
|
|
"ip_addr": IsIPAddrResolvable,
|
|
"unix_addr": IsUnixAddrResolvable,
|
|
"mac": IsMAC,
|
|
}
|
|
|
|
// IsMAC is the validation function for validating if the field's value is a valid MAC address.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsMAC(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
_, err := net.ParseMAC(field.String())
|
|
return err == nil
|
|
}
|
|
|
|
// IsCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsCIDRv4(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
ip, _, err := net.ParseCIDR(field.String())
|
|
|
|
return err == nil && ip.To4() != nil
|
|
}
|
|
|
|
// IsCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsCIDRv6(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
ip, _, err := net.ParseCIDR(field.String())
|
|
|
|
return err == nil && ip.To4() == nil
|
|
}
|
|
|
|
// IsCIDR is the validation function for validating if the field's value is a valid v4 or v6 CIDR address.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsCIDR(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
_, _, err := net.ParseCIDR(field.String())
|
|
|
|
return err == nil
|
|
}
|
|
|
|
// IsIPv4 is the validation function for validating if a value is a valid v4 IP address.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsIPv4(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
ip := net.ParseIP(field.String())
|
|
|
|
return ip != nil && ip.To4() != nil
|
|
}
|
|
|
|
// IsIPv6 is the validation function for validating if the field's value is a valid v6 IP address.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsIPv6(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
ip := net.ParseIP(field.String())
|
|
|
|
return ip != nil && ip.To4() == nil
|
|
}
|
|
|
|
// IsIP is the validation function for validating if the field's value is a valid v4 or v6 IP address.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsIP(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
ip := net.ParseIP(field.String())
|
|
|
|
return ip != nil
|
|
}
|
|
|
|
// IsSSN is the validation function for validating if the field's value is a valid SSN.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsSSN(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
if field.Len() != 11 {
|
|
return false
|
|
}
|
|
|
|
return sSNRegex.MatchString(field.String())
|
|
}
|
|
|
|
// IsLongitude is the validation function for validating if the field's value is a valid longitude coordinate.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsLongitude(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return longitudeRegex.MatchString(field.String())
|
|
}
|
|
|
|
// IsLatitude is the validation function for validating if the field's value is a valid latitude coordinate.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsLatitude(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return latitudeRegex.MatchString(field.String())
|
|
}
|
|
|
|
// IsDataURI is the validation function for validating if the field's value is a valid data URI.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsDataURI(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
uri := strings.SplitN(field.String(), ",", 2)
|
|
|
|
if len(uri) != 2 {
|
|
return false
|
|
}
|
|
|
|
if !dataURIRegex.MatchString(uri[0]) {
|
|
return false
|
|
}
|
|
|
|
fld := reflect.ValueOf(uri[1])
|
|
|
|
return IsBase64(v, topStruct, currentStructOrField, fld, fld.Type(), fld.Kind(), param)
|
|
}
|
|
|
|
// HasMultiByteCharacter is the validation function for validating if the field's value has a multi byte character.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func HasMultiByteCharacter(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
if field.Len() == 0 {
|
|
return true
|
|
}
|
|
|
|
return multibyteRegex.MatchString(field.String())
|
|
}
|
|
|
|
// IsPrintableASCII is the validation function for validating if the field's value is a valid printable ASCII character.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsPrintableASCII(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return printableASCIIRegex.MatchString(field.String())
|
|
}
|
|
|
|
// IsASCII is the validation function for validating if the field's value is a valid ASCII character.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsASCII(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return aSCIIRegex.MatchString(field.String())
|
|
}
|
|
|
|
// IsUUID5 is the validation function for validating if the field's value is a valid v5 UUID.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsUUID5(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return uUID5Regex.MatchString(field.String())
|
|
}
|
|
|
|
// IsUUID4 is the validation function for validating if the field's value is a valid v4 UUID.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsUUID4(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return uUID4Regex.MatchString(field.String())
|
|
}
|
|
|
|
// IsUUID3 is the validation function for validating if the field's value is a valid v3 UUID.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsUUID3(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return uUID3Regex.MatchString(field.String())
|
|
}
|
|
|
|
// IsUUID is the validation function for validating if the field's value is a valid UUID of any version.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsUUID(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return uUIDRegex.MatchString(field.String())
|
|
}
|
|
|
|
// IsISBN is the validation function for validating if the field's value is a valid v10 or v13 ISBN.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsISBN(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return IsISBN10(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) || IsISBN13(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param)
|
|
}
|
|
|
|
// IsISBN13 is the validation function for validating if the field's value is a valid v13 ISBN.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsISBN13(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
s := strings.Replace(strings.Replace(field.String(), "-", "", 4), " ", "", 4)
|
|
|
|
if !iSBN13Regex.MatchString(s) {
|
|
return false
|
|
}
|
|
|
|
var checksum int32
|
|
var i int32
|
|
|
|
factor := []int32{1, 3}
|
|
|
|
for i = 0; i < 12; i++ {
|
|
checksum += factor[i%2] * int32(s[i]-'0')
|
|
}
|
|
|
|
return (int32(s[12]-'0'))-((10-(checksum%10))%10) == 0
|
|
}
|
|
|
|
// IsISBN10 is the validation function for validating if the field's value is a valid v10 ISBN.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsISBN10(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
s := strings.Replace(strings.Replace(field.String(), "-", "", 3), " ", "", 3)
|
|
|
|
if !iSBN10Regex.MatchString(s) {
|
|
return false
|
|
}
|
|
|
|
var checksum int32
|
|
var i int32
|
|
|
|
for i = 0; i < 9; i++ {
|
|
checksum += (i + 1) * int32(s[i]-'0')
|
|
}
|
|
|
|
if s[9] == 'X' {
|
|
checksum += 10 * 10
|
|
} else {
|
|
checksum += 10 * int32(s[9]-'0')
|
|
}
|
|
|
|
return checksum%11 == 0
|
|
}
|
|
|
|
// ExcludesRune is the validation function for validating that the field's value does not contain the rune specified within the param.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func ExcludesRune(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return !ContainsRune(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param)
|
|
}
|
|
|
|
// ExcludesAll is the validation function for validating that the field's value does not contain any of the characters specified within the param.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func ExcludesAll(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return !ContainsAny(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param)
|
|
}
|
|
|
|
// Excludes is the validation function for validating that the field's value does not contain the text specified within the param.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func Excludes(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return !Contains(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param)
|
|
}
|
|
|
|
// ContainsRune is the validation function for validating that the field's value contains the rune specified within the param.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func ContainsRune(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
r, _ := utf8.DecodeRuneInString(param)
|
|
|
|
return strings.ContainsRune(field.String(), r)
|
|
}
|
|
|
|
// ContainsAny is the validation function for validating that the field's value contains any of the characters specified within the param.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func ContainsAny(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return strings.ContainsAny(field.String(), param)
|
|
}
|
|
|
|
// Contains is the validation function for validating that the field's value contains the text specified within the param.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func Contains(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return strings.Contains(field.String(), param)
|
|
}
|
|
|
|
// 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.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsNeField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param)
|
|
|
|
if !ok || currentKind != fieldKind {
|
|
return true
|
|
}
|
|
|
|
switch fieldKind {
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
return field.Int() != currentField.Int()
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
return field.Uint() != currentField.Uint()
|
|
|
|
case reflect.Float32, reflect.Float64:
|
|
return field.Float() != currentField.Float()
|
|
|
|
case reflect.Slice, reflect.Map, reflect.Array:
|
|
return int64(field.Len()) != int64(currentField.Len())
|
|
|
|
case reflect.Struct:
|
|
|
|
// Not Same underlying type i.e. struct and time
|
|
if fieldType != currentField.Type() {
|
|
return true
|
|
}
|
|
|
|
if fieldType == timeType {
|
|
|
|
t := currentField.Interface().(time.Time)
|
|
fieldTime := field.Interface().(time.Time)
|
|
|
|
return !fieldTime.Equal(t)
|
|
}
|
|
|
|
}
|
|
|
|
// default reflect.String:
|
|
return field.String() != currentField.String()
|
|
}
|
|
|
|
// IsNe is the validation function for validating that the field's value does not equal the provided param value.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsNe(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return !IsEq(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param)
|
|
}
|
|
|
|
// 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.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsLteCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
topField, topKind, ok := v.GetStructFieldOK(topStruct, param)
|
|
if !ok || topKind != fieldKind {
|
|
return false
|
|
}
|
|
|
|
switch fieldKind {
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
return field.Int() <= topField.Int()
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
return field.Uint() <= topField.Uint()
|
|
|
|
case reflect.Float32, reflect.Float64:
|
|
return field.Float() <= topField.Float()
|
|
|
|
case reflect.Slice, reflect.Map, reflect.Array:
|
|
return int64(field.Len()) <= int64(topField.Len())
|
|
|
|
case reflect.Struct:
|
|
|
|
// Not Same underlying type i.e. struct and time
|
|
if fieldType != topField.Type() {
|
|
return false
|
|
}
|
|
|
|
if fieldType == timeType {
|
|
|
|
fieldTime := field.Interface().(time.Time)
|
|
topTime := topField.Interface().(time.Time)
|
|
|
|
return fieldTime.Before(topTime) || fieldTime.Equal(topTime)
|
|
}
|
|
}
|
|
|
|
// default reflect.String:
|
|
return field.String() <= topField.String()
|
|
}
|
|
|
|
// 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.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsLtCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
topField, topKind, ok := v.GetStructFieldOK(topStruct, param)
|
|
if !ok || topKind != fieldKind {
|
|
return false
|
|
}
|
|
|
|
switch fieldKind {
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
return field.Int() < topField.Int()
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
return field.Uint() < topField.Uint()
|
|
|
|
case reflect.Float32, reflect.Float64:
|
|
return field.Float() < topField.Float()
|
|
|
|
case reflect.Slice, reflect.Map, reflect.Array:
|
|
return int64(field.Len()) < int64(topField.Len())
|
|
|
|
case reflect.Struct:
|
|
|
|
// Not Same underlying type i.e. struct and time
|
|
if fieldType != topField.Type() {
|
|
return false
|
|
}
|
|
|
|
if fieldType == timeType {
|
|
|
|
fieldTime := field.Interface().(time.Time)
|
|
topTime := topField.Interface().(time.Time)
|
|
|
|
return fieldTime.Before(topTime)
|
|
}
|
|
}
|
|
|
|
// default reflect.String:
|
|
return field.String() < topField.String()
|
|
}
|
|
|
|
// 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.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsGteCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
topField, topKind, ok := v.GetStructFieldOK(topStruct, param)
|
|
if !ok || topKind != fieldKind {
|
|
return false
|
|
}
|
|
|
|
switch fieldKind {
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
return field.Int() >= topField.Int()
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
return field.Uint() >= topField.Uint()
|
|
|
|
case reflect.Float32, reflect.Float64:
|
|
return field.Float() >= topField.Float()
|
|
|
|
case reflect.Slice, reflect.Map, reflect.Array:
|
|
return int64(field.Len()) >= int64(topField.Len())
|
|
|
|
case reflect.Struct:
|
|
|
|
// Not Same underlying type i.e. struct and time
|
|
if fieldType != topField.Type() {
|
|
return false
|
|
}
|
|
|
|
if fieldType == timeType {
|
|
|
|
fieldTime := field.Interface().(time.Time)
|
|
topTime := topField.Interface().(time.Time)
|
|
|
|
return fieldTime.After(topTime) || fieldTime.Equal(topTime)
|
|
}
|
|
}
|
|
|
|
// default reflect.String:
|
|
return field.String() >= topField.String()
|
|
}
|
|
|
|
// 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.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsGtCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
topField, topKind, ok := v.GetStructFieldOK(topStruct, param)
|
|
if !ok || topKind != fieldKind {
|
|
return false
|
|
}
|
|
|
|
switch fieldKind {
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
return field.Int() > topField.Int()
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
return field.Uint() > topField.Uint()
|
|
|
|
case reflect.Float32, reflect.Float64:
|
|
return field.Float() > topField.Float()
|
|
|
|
case reflect.Slice, reflect.Map, reflect.Array:
|
|
return int64(field.Len()) > int64(topField.Len())
|
|
|
|
case reflect.Struct:
|
|
|
|
// Not Same underlying type i.e. struct and time
|
|
if fieldType != topField.Type() {
|
|
return false
|
|
}
|
|
|
|
if fieldType == timeType {
|
|
|
|
fieldTime := field.Interface().(time.Time)
|
|
topTime := topField.Interface().(time.Time)
|
|
|
|
return fieldTime.After(topTime)
|
|
}
|
|
}
|
|
|
|
// default reflect.String:
|
|
return field.String() > topField.String()
|
|
}
|
|
|
|
// 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.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsNeCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
topField, currentKind, ok := v.GetStructFieldOK(topStruct, param)
|
|
if !ok || currentKind != fieldKind {
|
|
return true
|
|
}
|
|
|
|
switch fieldKind {
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
return topField.Int() != field.Int()
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
return topField.Uint() != field.Uint()
|
|
|
|
case reflect.Float32, reflect.Float64:
|
|
return topField.Float() != field.Float()
|
|
|
|
case reflect.Slice, reflect.Map, reflect.Array:
|
|
return int64(topField.Len()) != int64(field.Len())
|
|
|
|
case reflect.Struct:
|
|
|
|
// Not Same underlying type i.e. struct and time
|
|
if fieldType != topField.Type() {
|
|
return true
|
|
}
|
|
|
|
if fieldType == timeType {
|
|
|
|
t := field.Interface().(time.Time)
|
|
fieldTime := topField.Interface().(time.Time)
|
|
|
|
return !fieldTime.Equal(t)
|
|
}
|
|
}
|
|
|
|
// default reflect.String:
|
|
return topField.String() != field.String()
|
|
}
|
|
|
|
// 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.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsEqCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
topField, topKind, ok := v.GetStructFieldOK(topStruct, param)
|
|
if !ok || topKind != fieldKind {
|
|
return false
|
|
}
|
|
|
|
switch fieldKind {
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
return topField.Int() == field.Int()
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
return topField.Uint() == field.Uint()
|
|
|
|
case reflect.Float32, reflect.Float64:
|
|
return topField.Float() == field.Float()
|
|
|
|
case reflect.Slice, reflect.Map, reflect.Array:
|
|
return int64(topField.Len()) == int64(field.Len())
|
|
|
|
case reflect.Struct:
|
|
|
|
// Not Same underlying type i.e. struct and time
|
|
if fieldType != topField.Type() {
|
|
return false
|
|
}
|
|
|
|
if fieldType == timeType {
|
|
|
|
t := field.Interface().(time.Time)
|
|
fieldTime := topField.Interface().(time.Time)
|
|
|
|
return fieldTime.Equal(t)
|
|
}
|
|
}
|
|
|
|
// default reflect.String:
|
|
return topField.String() == field.String()
|
|
}
|
|
|
|
// IsEqField is the validation function for validating if the current field's value is equal to the field specified by the param's value.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsEqField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param)
|
|
if !ok || currentKind != fieldKind {
|
|
return false
|
|
}
|
|
|
|
switch fieldKind {
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
return field.Int() == currentField.Int()
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
return field.Uint() == currentField.Uint()
|
|
|
|
case reflect.Float32, reflect.Float64:
|
|
return field.Float() == currentField.Float()
|
|
|
|
case reflect.Slice, reflect.Map, reflect.Array:
|
|
return int64(field.Len()) == int64(currentField.Len())
|
|
|
|
case reflect.Struct:
|
|
|
|
// Not Same underlying type i.e. struct and time
|
|
if fieldType != currentField.Type() {
|
|
return false
|
|
}
|
|
|
|
if fieldType == timeType {
|
|
|
|
t := currentField.Interface().(time.Time)
|
|
fieldTime := field.Interface().(time.Time)
|
|
|
|
return fieldTime.Equal(t)
|
|
}
|
|
|
|
}
|
|
|
|
// default reflect.String:
|
|
return field.String() == currentField.String()
|
|
}
|
|
|
|
// IsEq is the validation function for validating if the current field's value is equal to the param's value.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsEq(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
switch fieldKind {
|
|
|
|
case reflect.String:
|
|
return field.String() == param
|
|
|
|
case reflect.Slice, reflect.Map, reflect.Array:
|
|
p := asInt(param)
|
|
|
|
return int64(field.Len()) == p
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
p := asInt(param)
|
|
|
|
return field.Int() == p
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
p := asUint(param)
|
|
|
|
return field.Uint() == p
|
|
|
|
case reflect.Float32, reflect.Float64:
|
|
p := asFloat(param)
|
|
|
|
return field.Float() == p
|
|
}
|
|
|
|
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
|
|
}
|
|
|
|
// IsBase64 is the validation function for validating if the current field's value is a valid base 64.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsBase64(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return base64Regex.MatchString(field.String())
|
|
}
|
|
|
|
// IsURI is the validation function for validating if the current field's value is a valid URI.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsURI(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
switch fieldKind {
|
|
|
|
case reflect.String:
|
|
|
|
s := field.String()
|
|
|
|
// checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195
|
|
// emulate browser and strip the '#' suffix prior to validation. see issue-#237
|
|
if i := strings.Index(s, "#"); i > -1 {
|
|
s = s[:i]
|
|
}
|
|
|
|
if s == blank {
|
|
return false
|
|
}
|
|
|
|
_, err := url.ParseRequestURI(s)
|
|
|
|
return err == nil
|
|
}
|
|
|
|
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
|
|
}
|
|
|
|
// IsURL is the validation function for validating if the current field's value is a valid URL.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsURL(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
switch fieldKind {
|
|
|
|
case reflect.String:
|
|
|
|
var i int
|
|
s := field.String()
|
|
|
|
// checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195
|
|
// emulate browser and strip the '#' suffix prior to validation. see issue-#237
|
|
if i = strings.Index(s, "#"); i > -1 {
|
|
s = s[:i]
|
|
}
|
|
|
|
if s == blank {
|
|
return false
|
|
}
|
|
|
|
url, err := url.ParseRequestURI(s)
|
|
|
|
if err != nil || url.Scheme == blank {
|
|
return false
|
|
}
|
|
|
|
return err == nil
|
|
}
|
|
|
|
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
|
|
}
|
|
|
|
// IsEmail is the validation function for validating if the current field's value is a valid email address.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsEmail(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return emailRegex.MatchString(field.String())
|
|
}
|
|
|
|
// IsHSLA is the validation function for validating if the current field's value is a valid HSLA color.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsHSLA(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return hslaRegex.MatchString(field.String())
|
|
}
|
|
|
|
// IsHSL is the validation function for validating if the current field's value is a valid HSL color.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsHSL(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return hslRegex.MatchString(field.String())
|
|
}
|
|
|
|
// IsRGBA is the validation function for validating if the current field's value is a valid RGBA color.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsRGBA(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return rgbaRegex.MatchString(field.String())
|
|
}
|
|
|
|
// IsRGB is the validation function for validating if the current field's value is a valid RGB color.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsRGB(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return rgbRegex.MatchString(field.String())
|
|
}
|
|
|
|
// IsHEXColor is the validation function for validating if the current field's value is a valid HEX color.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsHEXColor(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return hexcolorRegex.MatchString(field.String())
|
|
}
|
|
|
|
// IsHexadecimal is the validation function for validating if the current field's value is a valid hexadecimal.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsHexadecimal(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return hexadecimalRegex.MatchString(field.String())
|
|
}
|
|
|
|
// IsNumber is the validation function for validating if the current field's value is a valid number.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsNumber(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return numberRegex.MatchString(field.String())
|
|
}
|
|
|
|
// IsNumeric is the validation function for validating if the current field's value is a valid numeric value.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsNumeric(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return numericRegex.MatchString(field.String())
|
|
}
|
|
|
|
// IsAlphanum is the validation function for validating if the current field's value is a valid alphanumeric value.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsAlphanum(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return alphaNumericRegex.MatchString(field.String())
|
|
}
|
|
|
|
// IsAlpha is the validation function for validating if the current field's value is a valid alpha value.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsAlpha(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return alphaRegex.MatchString(field.String())
|
|
}
|
|
|
|
// HasValue is the validation function for validating if the current field's value is not the default static value.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func HasValue(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
switch fieldKind {
|
|
case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
|
|
return !field.IsNil()
|
|
default:
|
|
return field.IsValid() && field.Interface() != reflect.Zero(fieldType).Interface()
|
|
}
|
|
}
|
|
|
|
// 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.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsGteField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param)
|
|
if !ok || currentKind != fieldKind {
|
|
return false
|
|
}
|
|
|
|
switch fieldKind {
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
|
|
return field.Int() >= currentField.Int()
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
|
|
return field.Uint() >= currentField.Uint()
|
|
|
|
case reflect.Float32, reflect.Float64:
|
|
|
|
return field.Float() >= currentField.Float()
|
|
|
|
case reflect.Struct:
|
|
|
|
// Not Same underlying type i.e. struct and time
|
|
if fieldType != currentField.Type() {
|
|
return false
|
|
}
|
|
|
|
if fieldType == timeType {
|
|
|
|
t := currentField.Interface().(time.Time)
|
|
fieldTime := field.Interface().(time.Time)
|
|
|
|
return fieldTime.After(t) || fieldTime.Equal(t)
|
|
}
|
|
}
|
|
|
|
// default reflect.String
|
|
return len(field.String()) >= len(currentField.String())
|
|
}
|
|
|
|
// IsGtField is the validation function for validating if the current field's value is greater than the field specified by the param's value.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsGtField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param)
|
|
if !ok || currentKind != fieldKind {
|
|
return false
|
|
}
|
|
|
|
switch fieldKind {
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
|
|
return field.Int() > currentField.Int()
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
|
|
return field.Uint() > currentField.Uint()
|
|
|
|
case reflect.Float32, reflect.Float64:
|
|
|
|
return field.Float() > currentField.Float()
|
|
|
|
case reflect.Struct:
|
|
|
|
// Not Same underlying type i.e. struct and time
|
|
if fieldType != currentField.Type() {
|
|
return false
|
|
}
|
|
|
|
if fieldType == timeType {
|
|
|
|
t := currentField.Interface().(time.Time)
|
|
fieldTime := field.Interface().(time.Time)
|
|
|
|
return fieldTime.After(t)
|
|
}
|
|
}
|
|
|
|
// default reflect.String
|
|
return len(field.String()) > len(currentField.String())
|
|
}
|
|
|
|
// IsGte is the validation function for validating if the current field's value is greater than or equal to the param's value.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsGte(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
switch fieldKind {
|
|
|
|
case reflect.String:
|
|
p := asInt(param)
|
|
|
|
return int64(utf8.RuneCountInString(field.String())) >= p
|
|
|
|
case reflect.Slice, reflect.Map, reflect.Array:
|
|
p := asInt(param)
|
|
|
|
return int64(field.Len()) >= p
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
p := asInt(param)
|
|
|
|
return field.Int() >= p
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
p := asUint(param)
|
|
|
|
return field.Uint() >= p
|
|
|
|
case reflect.Float32, reflect.Float64:
|
|
p := asFloat(param)
|
|
|
|
return field.Float() >= p
|
|
|
|
case reflect.Struct:
|
|
|
|
if fieldType == timeType || fieldType == timePtrType {
|
|
|
|
now := time.Now().UTC()
|
|
t := field.Interface().(time.Time)
|
|
|
|
return t.After(now) || t.Equal(now)
|
|
}
|
|
}
|
|
|
|
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
|
|
}
|
|
|
|
// IsGt is the validation function for validating if the current field's value is greater than the param's value.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsGt(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
switch fieldKind {
|
|
|
|
case reflect.String:
|
|
p := asInt(param)
|
|
|
|
return int64(utf8.RuneCountInString(field.String())) > p
|
|
|
|
case reflect.Slice, reflect.Map, reflect.Array:
|
|
p := asInt(param)
|
|
|
|
return int64(field.Len()) > p
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
p := asInt(param)
|
|
|
|
return field.Int() > p
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
p := asUint(param)
|
|
|
|
return field.Uint() > p
|
|
|
|
case reflect.Float32, reflect.Float64:
|
|
p := asFloat(param)
|
|
|
|
return field.Float() > p
|
|
case reflect.Struct:
|
|
|
|
if fieldType == timeType || fieldType == timePtrType {
|
|
|
|
return field.Interface().(time.Time).After(time.Now().UTC())
|
|
}
|
|
}
|
|
|
|
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
|
|
}
|
|
|
|
// HasLengthOf is the validation function for validating if the current field's value is equal to the param's value.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func HasLengthOf(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
switch fieldKind {
|
|
|
|
case reflect.String:
|
|
p := asInt(param)
|
|
|
|
return int64(utf8.RuneCountInString(field.String())) == p
|
|
|
|
case reflect.Slice, reflect.Map, reflect.Array:
|
|
p := asInt(param)
|
|
|
|
return int64(field.Len()) == p
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
p := asInt(param)
|
|
|
|
return field.Int() == p
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
p := asUint(param)
|
|
|
|
return field.Uint() == p
|
|
|
|
case reflect.Float32, reflect.Float64:
|
|
p := asFloat(param)
|
|
|
|
return field.Float() == p
|
|
}
|
|
|
|
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
|
|
}
|
|
|
|
// HasMinOf is the validation function for validating if the current field's value is greater than or equal to the param's value.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func HasMinOf(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
return IsGte(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param)
|
|
}
|
|
|
|
// 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.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsLteField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param)
|
|
if !ok || currentKind != fieldKind {
|
|
return false
|
|
}
|
|
|
|
switch fieldKind {
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
|
|
return field.Int() <= currentField.Int()
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
|
|
return field.Uint() <= currentField.Uint()
|
|
|
|
case reflect.Float32, reflect.Float64:
|
|
|
|
return field.Float() <= currentField.Float()
|
|
|
|
case reflect.Struct:
|
|
|
|
// Not Same underlying type i.e. struct and time
|
|
if fieldType != currentField.Type() {
|
|
return false
|
|
}
|
|
|
|
if fieldType == timeType {
|
|
|
|
t := currentField.Interface().(time.Time)
|
|
fieldTime := field.Interface().(time.Time)
|
|
|
|
return fieldTime.Before(t) || fieldTime.Equal(t)
|
|
}
|
|
}
|
|
|
|
// default reflect.String
|
|
return len(field.String()) <= len(currentField.String())
|
|
}
|
|
|
|
// IsLtField is the validation function for validating if the current field's value is less than the field specified by the param's value.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsLtField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param)
|
|
if !ok || currentKind != fieldKind {
|
|
return false
|
|
}
|
|
|
|
switch fieldKind {
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
|
|
return field.Int() < currentField.Int()
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
|
|
return field.Uint() < currentField.Uint()
|
|
|
|
case reflect.Float32, reflect.Float64:
|
|
|
|
return field.Float() < currentField.Float()
|
|
|
|
case reflect.Struct:
|
|
|
|
// Not Same underlying type i.e. struct and time
|
|
if fieldType != currentField.Type() {
|
|
return false
|
|
}
|
|
|
|
if fieldType == timeType {
|
|
|
|
t := currentField.Interface().(time.Time)
|
|
fieldTime := field.Interface().(time.Time)
|
|
|
|
return fieldTime.Before(t)
|
|
}
|
|
}
|
|
|
|
// default reflect.String
|
|
return len(field.String()) < len(currentField.String())
|
|
}
|
|
|
|
// IsLte is the validation function for validating if the current field's value is less than or equal to the param's value.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsLte(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
switch fieldKind {
|
|
|
|
case reflect.String:
|
|
p := asInt(param)
|
|
|
|
return int64(utf8.RuneCountInString(field.String())) <= p
|
|
|
|
case reflect.Slice, reflect.Map, reflect.Array:
|
|
p := asInt(param)
|
|
|
|
return int64(field.Len()) <= p
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
p := asInt(param)
|
|
|
|
return field.Int() <= p
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
p := asUint(param)
|
|
|
|
return field.Uint() <= p
|
|
|
|
case reflect.Float32, reflect.Float64:
|
|
p := asFloat(param)
|
|
|
|
return field.Float() <= p
|
|
|
|
case reflect.Struct:
|
|
|
|
if fieldType == timeType || fieldType == timePtrType {
|
|
|
|
now := time.Now().UTC()
|
|
t := field.Interface().(time.Time)
|
|
|
|
return t.Before(now) || t.Equal(now)
|
|
}
|
|
}
|
|
|
|
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
|
|
}
|
|
|
|
// IsLt is the validation function for validating if the current field's value is less than the param's value.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsLt(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
switch fieldKind {
|
|
|
|
case reflect.String:
|
|
p := asInt(param)
|
|
|
|
return int64(utf8.RuneCountInString(field.String())) < p
|
|
|
|
case reflect.Slice, reflect.Map, reflect.Array:
|
|
p := asInt(param)
|
|
|
|
return int64(field.Len()) < p
|
|
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
p := asInt(param)
|
|
|
|
return field.Int() < p
|
|
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
p := asUint(param)
|
|
|
|
return field.Uint() < p
|
|
|
|
case reflect.Float32, reflect.Float64:
|
|
p := asFloat(param)
|
|
|
|
return field.Float() < p
|
|
|
|
case reflect.Struct:
|
|
|
|
if fieldType == timeType || fieldType == timePtrType {
|
|
|
|
return field.Interface().(time.Time).Before(time.Now().UTC())
|
|
}
|
|
}
|
|
|
|
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
|
|
}
|
|
|
|
// HasMaxOf is the validation function for validating if the current field's value is less than or equal to the param's value.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func HasMaxOf(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
return IsLte(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param)
|
|
}
|
|
|
|
// IsTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsTCP4AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
if !isIP4Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
|
|
return false
|
|
}
|
|
|
|
_, err := net.ResolveTCPAddr("tcp4", field.String())
|
|
return err == nil
|
|
}
|
|
|
|
// IsTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsTCP6AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
if !isIP6Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
|
|
return false
|
|
}
|
|
|
|
_, err := net.ResolveTCPAddr("tcp6", field.String())
|
|
return err == nil
|
|
}
|
|
|
|
// IsTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsTCPAddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
if !isIP4Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) &&
|
|
!isIP6Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
|
|
return false
|
|
}
|
|
|
|
_, err := net.ResolveTCPAddr("tcp", field.String())
|
|
return err == nil
|
|
}
|
|
|
|
// IsUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsUDP4AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
if !isIP4Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
|
|
return false
|
|
}
|
|
|
|
_, err := net.ResolveUDPAddr("udp4", field.String())
|
|
return err == nil
|
|
}
|
|
|
|
// IsUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsUDP6AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
if !isIP6Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
|
|
return false
|
|
}
|
|
|
|
_, err := net.ResolveUDPAddr("udp6", field.String())
|
|
return err == nil
|
|
}
|
|
|
|
// IsUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsUDPAddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
if !isIP4Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) &&
|
|
!isIP6Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
|
|
return false
|
|
}
|
|
|
|
_, err := net.ResolveUDPAddr("udp", field.String())
|
|
return err == nil
|
|
}
|
|
|
|
// IsIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsIP4AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
if !IsIPv4(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
|
|
return false
|
|
}
|
|
|
|
_, err := net.ResolveIPAddr("ip4", field.String())
|
|
return err == nil
|
|
}
|
|
|
|
// IsIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsIP6AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
if !IsIPv6(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
|
|
return false
|
|
}
|
|
|
|
_, err := net.ResolveIPAddr("ip6", field.String())
|
|
return err == nil
|
|
}
|
|
|
|
// IsIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsIPAddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
|
|
if !IsIP(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
|
|
return false
|
|
}
|
|
|
|
_, err := net.ResolveIPAddr("ip", field.String())
|
|
return err == nil
|
|
}
|
|
|
|
// IsUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address.
|
|
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
|
|
func IsUnixAddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
_, err := net.ResolveUnixAddr("unix", field.String())
|
|
return err == nil
|
|
}
|
|
|
|
func isIP4Addr(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
val := field.String()
|
|
|
|
if idx := strings.LastIndex(val, ":"); idx != -1 {
|
|
val = val[0:idx]
|
|
}
|
|
|
|
if !IsIPv4(v, topStruct, currentStructOrField, reflect.ValueOf(val), fieldType, fieldKind, param) {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func isIP6Addr(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
|
|
val := field.String()
|
|
|
|
if idx := strings.LastIndex(val, ":"); idx != -1 {
|
|
if idx != 0 && val[idx-1:idx] == "]" {
|
|
val = val[1 : idx-1]
|
|
}
|
|
}
|
|
|
|
if !IsIPv6(v, topStruct, currentStructOrField, reflect.ValueOf(val), fieldType, fieldKind, param) {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|