summaryrefslogtreecommitdiff
path: root/vendor/github.com/go-playground/validator/v10/baked_in.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/go-playground/validator/v10/baked_in.go')
-rw-r--r--vendor/github.com/go-playground/validator/v10/baked_in.go420
1 files changed, 266 insertions, 154 deletions
diff --git a/vendor/github.com/go-playground/validator/v10/baked_in.go b/vendor/github.com/go-playground/validator/v10/baked_in.go
index f5fd2391d..f2f0939cf 100644
--- a/vendor/github.com/go-playground/validator/v10/baked_in.go
+++ b/vendor/github.com/go-playground/validator/v10/baked_in.go
@@ -75,6 +75,8 @@ var (
"required_with_all": requiredWithAll,
"required_without": requiredWithout,
"required_without_all": requiredWithoutAll,
+ "excluded_if": excludedIf,
+ "excluded_unless": excludedUnless,
"excluded_with": excludedWith,
"excluded_with_all": excludedWithAll,
"excluded_without": excludedWithout,
@@ -148,6 +150,17 @@ var (
"uuid3_rfc4122": isUUID3RFC4122,
"uuid4_rfc4122": isUUID4RFC4122,
"uuid5_rfc4122": isUUID5RFC4122,
+ "ulid": isULID,
+ "md4": isMD4,
+ "md5": isMD5,
+ "sha256": isSHA256,
+ "sha384": isSHA384,
+ "sha512": isSHA512,
+ "ripemd128": isRIPEMD128,
+ "ripemd160": isRIPEMD160,
+ "tiger128": isTIGER128,
+ "tiger160": isTIGER160,
+ "tiger192": isTIGER192,
"ascii": isASCII,
"printascii": isPrintableASCII,
"multibyte": hasMultiByteCharacter,
@@ -198,11 +211,16 @@ var (
"postcode_iso3166_alpha2": isPostcodeByIso3166Alpha2,
"postcode_iso3166_alpha2_field": isPostcodeByIso3166Alpha2Field,
"bic": isIsoBicFormat,
+ "semver": isSemverFormat,
+ "dns_rfc1035_label": isDnsRFC1035LabelFormat,
+ "credit_card": isCreditCard,
}
)
-var oneofValsCache = map[string][]string{}
-var oneofValsCacheRWLock = sync.RWMutex{}
+var (
+ oneofValsCache = map[string][]string{}
+ oneofValsCacheRWLock = sync.RWMutex{}
+)
func parseOneOfParam2(s string) []string {
oneofValsCacheRWLock.RLock()
@@ -258,7 +276,6 @@ func isOneOf(fl FieldLevel) bool {
// isUnique is the validation function for validating if each array|slice|map value is unique
func isUnique(fl FieldLevel) bool {
-
field := fl.Field()
param := fl.Param()
v := reflect.ValueOf(struct{}{})
@@ -308,7 +325,6 @@ func isUnique(fl FieldLevel) bool {
// isMAC is the validation function for validating if the field's value is a valid MAC address.
func isMAC(fl FieldLevel) bool {
-
_, err := net.ParseMAC(fl.Field().String())
return err == nil
@@ -316,7 +332,6 @@ func isMAC(fl FieldLevel) bool {
// isCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address.
func isCIDRv4(fl FieldLevel) bool {
-
ip, _, err := net.ParseCIDR(fl.Field().String())
return err == nil && ip.To4() != nil
@@ -324,7 +339,6 @@ func isCIDRv4(fl FieldLevel) bool {
// isCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address.
func isCIDRv6(fl FieldLevel) bool {
-
ip, _, err := net.ParseCIDR(fl.Field().String())
return err == nil && ip.To4() == nil
@@ -332,7 +346,6 @@ func isCIDRv6(fl FieldLevel) bool {
// isCIDR is the validation function for validating if the field's value is a valid v4 or v6 CIDR address.
func isCIDR(fl FieldLevel) bool {
-
_, _, err := net.ParseCIDR(fl.Field().String())
return err == nil
@@ -340,7 +353,6 @@ func isCIDR(fl FieldLevel) bool {
// isIPv4 is the validation function for validating if a value is a valid v4 IP address.
func isIPv4(fl FieldLevel) bool {
-
ip := net.ParseIP(fl.Field().String())
return ip != nil && ip.To4() != nil
@@ -348,7 +360,6 @@ func isIPv4(fl FieldLevel) bool {
// isIPv6 is the validation function for validating if the field's value is a valid v6 IP address.
func isIPv6(fl FieldLevel) bool {
-
ip := net.ParseIP(fl.Field().String())
return ip != nil && ip.To4() == nil
@@ -356,7 +367,6 @@ func isIPv6(fl FieldLevel) bool {
// isIP is the validation function for validating if the field's value is a valid v4 or v6 IP address.
func isIP(fl FieldLevel) bool {
-
ip := net.ParseIP(fl.Field().String())
return ip != nil
@@ -364,7 +374,6 @@ func isIP(fl FieldLevel) bool {
// isSSN is the validation function for validating if the field's value is a valid SSN.
func isSSN(fl FieldLevel) bool {
-
field := fl.Field()
if field.Len() != 11 {
@@ -422,7 +431,6 @@ func isLatitude(fl FieldLevel) bool {
// isDataURI is the validation function for validating if the field's value is a valid data URI.
func isDataURI(fl FieldLevel) bool {
-
uri := strings.SplitN(fl.Field().String(), ",", 2)
if len(uri) != 2 {
@@ -438,7 +446,6 @@ func isDataURI(fl FieldLevel) bool {
// hasMultiByteCharacter is the validation function for validating if the field's value has a multi byte character.
func hasMultiByteCharacter(fl FieldLevel) bool {
-
field := fl.Field()
if field.Len() == 0 {
@@ -498,6 +505,61 @@ func isUUIDRFC4122(fl FieldLevel) bool {
return uUIDRFC4122Regex.MatchString(fl.Field().String())
}
+// isULID is the validation function for validating if the field's value is a valid ULID.
+func isULID(fl FieldLevel) bool {
+ return uLIDRegex.MatchString(fl.Field().String())
+}
+
+// isMD4 is the validation function for validating if the field's value is a valid MD4.
+func isMD4(fl FieldLevel) bool {
+ return md4Regex.MatchString(fl.Field().String())
+}
+
+// isMD5 is the validation function for validating if the field's value is a valid MD5.
+func isMD5(fl FieldLevel) bool {
+ return md5Regex.MatchString(fl.Field().String())
+}
+
+// isSHA256 is the validation function for validating if the field's value is a valid SHA256.
+func isSHA256(fl FieldLevel) bool {
+ return sha256Regex.MatchString(fl.Field().String())
+}
+
+// isSHA384 is the validation function for validating if the field's value is a valid SHA384.
+func isSHA384(fl FieldLevel) bool {
+ return sha384Regex.MatchString(fl.Field().String())
+}
+
+// isSHA512 is the validation function for validating if the field's value is a valid SHA512.
+func isSHA512(fl FieldLevel) bool {
+ return sha512Regex.MatchString(fl.Field().String())
+}
+
+// isRIPEMD128 is the validation function for validating if the field's value is a valid PIPEMD128.
+func isRIPEMD128(fl FieldLevel) bool {
+ return ripemd128Regex.MatchString(fl.Field().String())
+}
+
+// isRIPEMD160 is the validation function for validating if the field's value is a valid PIPEMD160.
+func isRIPEMD160(fl FieldLevel) bool {
+ return ripemd160Regex.MatchString(fl.Field().String())
+}
+
+// isTIGER128 is the validation function for validating if the field's value is a valid TIGER128.
+func isTIGER128(fl FieldLevel) bool {
+ return tiger128Regex.MatchString(fl.Field().String())
+}
+
+// isTIGER160 is the validation function for validating if the field's value is a valid TIGER160.
+func isTIGER160(fl FieldLevel) bool {
+ return tiger160Regex.MatchString(fl.Field().String())
+}
+
+// isTIGER192 is the validation function for validating if the field's value is a valid isTIGER192.
+func isTIGER192(fl FieldLevel) bool {
+ return tiger192Regex.MatchString(fl.Field().String())
+}
+
// isISBN is the validation function for validating if the field's value is a valid v10 or v13 ISBN.
func isISBN(fl FieldLevel) bool {
return isISBN10(fl) || isISBN13(fl)
@@ -505,7 +567,6 @@ func isISBN(fl FieldLevel) bool {
// isISBN13 is the validation function for validating if the field's value is a valid v13 ISBN.
func isISBN13(fl FieldLevel) bool {
-
s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 4), " ", "", 4)
if !iSBN13Regex.MatchString(s) {
@@ -526,7 +587,6 @@ func isISBN13(fl FieldLevel) bool {
// isISBN10 is the validation function for validating if the field's value is a valid v10 ISBN.
func isISBN10(fl FieldLevel) bool {
-
s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 3), " ", "", 3)
if !iSBN10Regex.MatchString(s) {
@@ -714,7 +774,6 @@ func excludes(fl FieldLevel) bool {
// containsRune is the validation function for validating that the field's value contains the rune specified within the param.
func containsRune(fl FieldLevel) bool {
-
r, _ := utf8.DecodeRuneInString(fl.Param())
return strings.ContainsRune(fl.Field().String(), r)
@@ -777,7 +836,6 @@ func fieldExcludes(fl FieldLevel) bool {
// 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.
func isNeField(fl FieldLevel) bool {
-
field := fl.Field()
kind := field.Kind()
@@ -808,12 +866,7 @@ func isNeField(fl FieldLevel) bool {
fieldType := field.Type()
- // Not Same underlying type i.e. struct and time
- if fieldType != currentField.Type() {
- return true
- }
-
- if fieldType == timeType {
+ if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
t := currentField.Interface().(time.Time)
fieldTime := field.Interface().(time.Time)
@@ -821,6 +874,10 @@ func isNeField(fl FieldLevel) bool {
return !fieldTime.Equal(t)
}
+ // Not Same underlying type i.e. struct and time
+ if fieldType != currentField.Type() {
+ return true
+ }
}
// default reflect.String:
@@ -834,7 +891,6 @@ func isNe(fl FieldLevel) bool {
// 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.
func isLteCrossStructField(fl FieldLevel) bool {
-
field := fl.Field()
kind := field.Kind()
@@ -861,18 +917,18 @@ func isLteCrossStructField(fl FieldLevel) bool {
fieldType := field.Type()
- // Not Same underlying type i.e. struct and time
- if fieldType != topField.Type() {
- return false
- }
-
- if fieldType == timeType {
+ if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
- fieldTime := field.Interface().(time.Time)
- topTime := topField.Interface().(time.Time)
+ fieldTime := field.Convert(timeType).Interface().(time.Time)
+ topTime := topField.Convert(timeType).Interface().(time.Time)
return fieldTime.Before(topTime) || fieldTime.Equal(topTime)
}
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != topField.Type() {
+ return false
+ }
}
// default reflect.String:
@@ -882,7 +938,6 @@ func isLteCrossStructField(fl FieldLevel) bool {
// 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(fl FieldLevel) bool {
-
field := fl.Field()
kind := field.Kind()
@@ -909,18 +964,18 @@ func isLtCrossStructField(fl FieldLevel) bool {
fieldType := field.Type()
- // Not Same underlying type i.e. struct and time
- if fieldType != topField.Type() {
- return false
- }
-
- if fieldType == timeType {
+ if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
- fieldTime := field.Interface().(time.Time)
- topTime := topField.Interface().(time.Time)
+ fieldTime := field.Convert(timeType).Interface().(time.Time)
+ topTime := topField.Convert(timeType).Interface().(time.Time)
return fieldTime.Before(topTime)
}
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != topField.Type() {
+ return false
+ }
}
// default reflect.String:
@@ -929,7 +984,6 @@ func isLtCrossStructField(fl FieldLevel) bool {
// 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.
func isGteCrossStructField(fl FieldLevel) bool {
-
field := fl.Field()
kind := field.Kind()
@@ -956,18 +1010,18 @@ func isGteCrossStructField(fl FieldLevel) bool {
fieldType := field.Type()
- // Not Same underlying type i.e. struct and time
- if fieldType != topField.Type() {
- return false
- }
-
- if fieldType == timeType {
+ if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
- fieldTime := field.Interface().(time.Time)
- topTime := topField.Interface().(time.Time)
+ fieldTime := field.Convert(timeType).Interface().(time.Time)
+ topTime := topField.Convert(timeType).Interface().(time.Time)
return fieldTime.After(topTime) || fieldTime.Equal(topTime)
}
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != topField.Type() {
+ return false
+ }
}
// default reflect.String:
@@ -976,7 +1030,6 @@ func isGteCrossStructField(fl FieldLevel) bool {
// 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.
func isGtCrossStructField(fl FieldLevel) bool {
-
field := fl.Field()
kind := field.Kind()
@@ -1003,18 +1056,18 @@ func isGtCrossStructField(fl FieldLevel) bool {
fieldType := field.Type()
- // Not Same underlying type i.e. struct and time
- if fieldType != topField.Type() {
- return false
- }
-
- if fieldType == timeType {
+ if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
- fieldTime := field.Interface().(time.Time)
- topTime := topField.Interface().(time.Time)
+ fieldTime := field.Convert(timeType).Interface().(time.Time)
+ topTime := topField.Convert(timeType).Interface().(time.Time)
return fieldTime.After(topTime)
}
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != topField.Type() {
+ return false
+ }
}
// default reflect.String:
@@ -1023,7 +1076,6 @@ func isGtCrossStructField(fl FieldLevel) bool {
// 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.
func isNeCrossStructField(fl FieldLevel) bool {
-
field := fl.Field()
kind := field.Kind()
@@ -1053,18 +1105,18 @@ func isNeCrossStructField(fl FieldLevel) bool {
fieldType := field.Type()
- // Not Same underlying type i.e. struct and time
- if fieldType != topField.Type() {
- return true
- }
-
- if fieldType == timeType {
+ if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
- t := field.Interface().(time.Time)
- fieldTime := topField.Interface().(time.Time)
+ t := field.Convert(timeType).Interface().(time.Time)
+ fieldTime := topField.Convert(timeType).Interface().(time.Time)
return !fieldTime.Equal(t)
}
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != topField.Type() {
+ return true
+ }
}
// default reflect.String:
@@ -1073,7 +1125,6 @@ func isNeCrossStructField(fl FieldLevel) bool {
// 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.
func isEqCrossStructField(fl FieldLevel) bool {
-
field := fl.Field()
kind := field.Kind()
@@ -1103,18 +1154,18 @@ func isEqCrossStructField(fl FieldLevel) bool {
fieldType := field.Type()
- // Not Same underlying type i.e. struct and time
- if fieldType != topField.Type() {
- return false
- }
+ if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
- if fieldType == timeType {
-
- t := field.Interface().(time.Time)
- fieldTime := topField.Interface().(time.Time)
+ t := field.Convert(timeType).Interface().(time.Time)
+ fieldTime := topField.Convert(timeType).Interface().(time.Time)
return fieldTime.Equal(t)
}
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != topField.Type() {
+ return false
+ }
}
// default reflect.String:
@@ -1123,7 +1174,6 @@ func isEqCrossStructField(fl FieldLevel) bool {
// isEqField is the validation function for validating if the current field's value is equal to the field specified by the param's value.
func isEqField(fl FieldLevel) bool {
-
field := fl.Field()
kind := field.Kind()
@@ -1153,19 +1203,18 @@ func isEqField(fl FieldLevel) bool {
fieldType := field.Type()
- // Not Same underlying type i.e. struct and time
- if fieldType != currentField.Type() {
- return false
- }
+ if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
- if fieldType == timeType {
-
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
+ t := currentField.Convert(timeType).Interface().(time.Time)
+ fieldTime := field.Convert(timeType).Interface().(time.Time)
return fieldTime.Equal(t)
}
+ // Not Same underlying type i.e. struct and time
+ if fieldType != currentField.Type() {
+ return false
+ }
}
// default reflect.String:
@@ -1174,7 +1223,6 @@ func isEqField(fl FieldLevel) bool {
// isEq is the validation function for validating if the current field's value is equal to the param's value.
func isEq(fl FieldLevel) bool {
-
field := fl.Field()
param := fl.Param()
@@ -1226,7 +1274,7 @@ func isPostcodeByIso3166Alpha2(fl FieldLevel) bool {
return reg.MatchString(field.String())
}
-// isPostcodeByIso3166Alpha2 validates by field which represents for a value of country code in iso 3166 alpha 2
+// isPostcodeByIso3166Alpha2Field validates by field which represents for a value of country code in iso 3166 alpha 2
// example: `postcode_iso3166_alpha2_field=CountryCode`
func isPostcodeByIso3166Alpha2Field(fl FieldLevel) bool {
field := fl.Field()
@@ -1265,11 +1313,9 @@ func isBase64URL(fl FieldLevel) bool {
// isURI is the validation function for validating if the current field's value is a valid URI.
func isURI(fl FieldLevel) bool {
-
field := fl.Field()
switch field.Kind() {
-
case reflect.String:
s := field.String()
@@ -1294,11 +1340,9 @@ func isURI(fl FieldLevel) bool {
// isURL is the validation function for validating if the current field's value is a valid URL.
func isURL(fl FieldLevel) bool {
-
field := fl.Field()
switch field.Kind() {
-
case reflect.String:
var i int
@@ -1331,7 +1375,6 @@ func isUrnRFC2141(fl FieldLevel) bool {
field := fl.Field()
switch field.Kind() {
-
case reflect.String:
str := field.String()
@@ -1534,6 +1577,22 @@ func requiredIf(fl FieldLevel) bool {
return hasValue(fl)
}
+// excludedIf is the validation function
+// The field under validation must not be present or is empty only if all the other specified fields are equal to the value following with the specified field.
+func excludedIf(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ if len(params)%2 != 0 {
+ panic(fmt.Sprintf("Bad param number for excluded_if %s", fl.FieldName()))
+ }
+
+ for i := 0; i < len(params); i += 2 {
+ if !requireCheckFieldValue(fl, params[i], params[i+1], false) {
+ return false
+ }
+ }
+ return true
+}
+
// requiredUnless is the validation function
// The field under validation must be present and not empty only unless all the other specified fields are equal to the value following with the specified field.
func requiredUnless(fl FieldLevel) bool {
@@ -1550,6 +1609,21 @@ func requiredUnless(fl FieldLevel) bool {
return hasValue(fl)
}
+// excludedUnless is the validation function
+// The field under validation must not be present or is empty unless all the other specified fields are equal to the value following with the specified field.
+func excludedUnless(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ if len(params)%2 != 0 {
+ panic(fmt.Sprintf("Bad param number for excluded_unless %s", fl.FieldName()))
+ }
+ for i := 0; i < len(params); i += 2 {
+ if !requireCheckFieldValue(fl, params[i], params[i+1], false) {
+ return true
+ }
+ }
+ return !hasValue(fl)
+}
+
// excludedWith is the validation function
// The field under validation must not be present or is empty if any of the other specified fields are present.
func excludedWith(fl FieldLevel) bool {
@@ -1642,7 +1716,6 @@ func requiredWithoutAll(fl FieldLevel) bool {
// 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.
func isGteField(fl FieldLevel) bool {
-
field := fl.Field()
kind := field.Kind()
@@ -1669,18 +1742,18 @@ func isGteField(fl FieldLevel) bool {
fieldType := field.Type()
- // Not Same underlying type i.e. struct and time
- if fieldType != currentField.Type() {
- return false
- }
-
- if fieldType == timeType {
+ if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
+ t := currentField.Convert(timeType).Interface().(time.Time)
+ fieldTime := field.Convert(timeType).Interface().(time.Time)
return fieldTime.After(t) || fieldTime.Equal(t)
}
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != currentField.Type() {
+ return false
+ }
}
// default reflect.String
@@ -1689,7 +1762,6 @@ func isGteField(fl FieldLevel) bool {
// isGtField is the validation function for validating if the current field's value is greater than the field specified by the param's value.
func isGtField(fl FieldLevel) bool {
-
field := fl.Field()
kind := field.Kind()
@@ -1716,18 +1788,18 @@ func isGtField(fl FieldLevel) bool {
fieldType := field.Type()
- // Not Same underlying type i.e. struct and time
- if fieldType != currentField.Type() {
- return false
- }
-
- if fieldType == timeType {
+ if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
+ t := currentField.Convert(timeType).Interface().(time.Time)
+ fieldTime := field.Convert(timeType).Interface().(time.Time)
return fieldTime.After(t)
}
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != currentField.Type() {
+ return false
+ }
}
// default reflect.String
@@ -1736,7 +1808,6 @@ func isGtField(fl FieldLevel) bool {
// isGte is the validation function for validating if the current field's value is greater than or equal to the param's value.
func isGte(fl FieldLevel) bool {
-
field := fl.Field()
param := fl.Param()
@@ -1769,10 +1840,10 @@ func isGte(fl FieldLevel) bool {
case reflect.Struct:
- if field.Type() == timeType {
+ if field.Type().ConvertibleTo(timeType) {
now := time.Now().UTC()
- t := field.Interface().(time.Time)
+ t := field.Convert(timeType).Interface().(time.Time)
return t.After(now) || t.Equal(now)
}
@@ -1783,7 +1854,6 @@ func isGte(fl FieldLevel) bool {
// isGt is the validation function for validating if the current field's value is greater than the param's value.
func isGt(fl FieldLevel) bool {
-
field := fl.Field()
param := fl.Param()
@@ -1815,9 +1885,9 @@ func isGt(fl FieldLevel) bool {
return field.Float() > p
case reflect.Struct:
- if field.Type() == timeType {
+ if field.Type().ConvertibleTo(timeType) {
- return field.Interface().(time.Time).After(time.Now().UTC())
+ return field.Convert(timeType).Interface().(time.Time).After(time.Now().UTC())
}
}
@@ -1826,7 +1896,6 @@ func isGt(fl FieldLevel) bool {
// hasLengthOf is the validation function for validating if the current field's value is equal to the param's value.
func hasLengthOf(fl FieldLevel) bool {
-
field := fl.Field()
param := fl.Param()
@@ -1868,7 +1937,6 @@ func hasMinOf(fl FieldLevel) bool {
// 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.
func isLteField(fl FieldLevel) bool {
-
field := fl.Field()
kind := field.Kind()
@@ -1895,18 +1963,18 @@ func isLteField(fl FieldLevel) bool {
fieldType := field.Type()
- // Not Same underlying type i.e. struct and time
- if fieldType != currentField.Type() {
- return false
- }
+ if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
- if fieldType == timeType {
-
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
+ t := currentField.Convert(timeType).Interface().(time.Time)
+ fieldTime := field.Convert(timeType).Interface().(time.Time)
return fieldTime.Before(t) || fieldTime.Equal(t)
}
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != currentField.Type() {
+ return false
+ }
}
// default reflect.String
@@ -1915,7 +1983,6 @@ func isLteField(fl FieldLevel) bool {
// isLtField is the validation function for validating if the current field's value is less than the field specified by the param's value.
func isLtField(fl FieldLevel) bool {
-
field := fl.Field()
kind := field.Kind()
@@ -1942,18 +2009,18 @@ func isLtField(fl FieldLevel) bool {
fieldType := field.Type()
- // Not Same underlying type i.e. struct and time
- if fieldType != currentField.Type() {
- return false
- }
-
- if fieldType == timeType {
+ if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
+ t := currentField.Convert(timeType).Interface().(time.Time)
+ fieldTime := field.Convert(timeType).Interface().(time.Time)
return fieldTime.Before(t)
}
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != currentField.Type() {
+ return false
+ }
}
// default reflect.String
@@ -1962,7 +2029,6 @@ func isLtField(fl FieldLevel) bool {
// isLte is the validation function for validating if the current field's value is less than or equal to the param's value.
func isLte(fl FieldLevel) bool {
-
field := fl.Field()
param := fl.Param()
@@ -1995,10 +2061,10 @@ func isLte(fl FieldLevel) bool {
case reflect.Struct:
- if field.Type() == timeType {
+ if field.Type().ConvertibleTo(timeType) {
now := time.Now().UTC()
- t := field.Interface().(time.Time)
+ t := field.Convert(timeType).Interface().(time.Time)
return t.Before(now) || t.Equal(now)
}
@@ -2009,7 +2075,6 @@ func isLte(fl FieldLevel) bool {
// isLt is the validation function for validating if the current field's value is less than the param's value.
func isLt(fl FieldLevel) bool {
-
field := fl.Field()
param := fl.Param()
@@ -2042,9 +2107,9 @@ func isLt(fl FieldLevel) bool {
case reflect.Struct:
- if field.Type() == timeType {
+ if field.Type().ConvertibleTo(timeType) {
- return field.Interface().(time.Time).Before(time.Now().UTC())
+ return field.Convert(timeType).Interface().(time.Time).Before(time.Now().UTC())
}
}
@@ -2058,7 +2123,6 @@ func hasMaxOf(fl FieldLevel) bool {
// isTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address.
func isTCP4AddrResolvable(fl FieldLevel) bool {
-
if !isIP4Addr(fl) {
return false
}
@@ -2069,7 +2133,6 @@ func isTCP4AddrResolvable(fl FieldLevel) bool {
// isTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address.
func isTCP6AddrResolvable(fl FieldLevel) bool {
-
if !isIP6Addr(fl) {
return false
}
@@ -2081,7 +2144,6 @@ func isTCP6AddrResolvable(fl FieldLevel) bool {
// isTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address.
func isTCPAddrResolvable(fl FieldLevel) bool {
-
if !isIP4Addr(fl) && !isIP6Addr(fl) {
return false
}
@@ -2093,7 +2155,6 @@ func isTCPAddrResolvable(fl FieldLevel) bool {
// isUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address.
func isUDP4AddrResolvable(fl FieldLevel) bool {
-
if !isIP4Addr(fl) {
return false
}
@@ -2105,7 +2166,6 @@ func isUDP4AddrResolvable(fl FieldLevel) bool {
// isUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address.
func isUDP6AddrResolvable(fl FieldLevel) bool {
-
if !isIP6Addr(fl) {
return false
}
@@ -2117,7 +2177,6 @@ func isUDP6AddrResolvable(fl FieldLevel) bool {
// isUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address.
func isUDPAddrResolvable(fl FieldLevel) bool {
-
if !isIP4Addr(fl) && !isIP6Addr(fl) {
return false
}
@@ -2129,7 +2188,6 @@ func isUDPAddrResolvable(fl FieldLevel) bool {
// isIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address.
func isIP4AddrResolvable(fl FieldLevel) bool {
-
if !isIPv4(fl) {
return false
}
@@ -2141,7 +2199,6 @@ func isIP4AddrResolvable(fl FieldLevel) bool {
// isIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address.
func isIP6AddrResolvable(fl FieldLevel) bool {
-
if !isIPv6(fl) {
return false
}
@@ -2153,7 +2210,6 @@ func isIP6AddrResolvable(fl FieldLevel) bool {
// isIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address.
func isIPAddrResolvable(fl FieldLevel) bool {
-
if !isIP(fl) {
return false
}
@@ -2165,14 +2221,12 @@ func isIPAddrResolvable(fl FieldLevel) bool {
// isUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address.
func isUnixAddrResolvable(fl FieldLevel) bool {
-
_, err := net.ResolveUnixAddr("unix", fl.Field().String())
return err == nil
}
func isIP4Addr(fl FieldLevel) bool {
-
val := fl.Field().String()
if idx := strings.LastIndex(val, ":"); idx != -1 {
@@ -2185,7 +2239,6 @@ func isIP4Addr(fl FieldLevel) bool {
}
func isIP6Addr(fl FieldLevel) bool {
-
val := fl.Field().String()
if idx := strings.LastIndex(val, ":"); idx != -1 {
@@ -2351,6 +2404,12 @@ func isIso3166AlphaNumeric(fl FieldLevel) bool {
var code int
switch field.Kind() {
+ case reflect.String:
+ i, err := strconv.Atoi(field.String())
+ if err != nil {
+ return false
+ }
+ code = i % 1000
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
code = int(field.Int() % 1000)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
@@ -2407,3 +2466,56 @@ func isIsoBicFormat(fl FieldLevel) bool {
return bicRegex.MatchString(bicString)
}
+
+// isSemverFormat is the validation function for validating if the current field's value is a valid semver version, defined in Semantic Versioning 2.0.0
+func isSemverFormat(fl FieldLevel) bool {
+ semverString := fl.Field().String()
+
+ return semverRegex.MatchString(semverString)
+}
+
+// isDnsRFC1035LabelFormat is the validation function
+// for validating if the current field's value is
+// a valid dns RFC 1035 label, defined in RFC 1035.
+func isDnsRFC1035LabelFormat(fl FieldLevel) bool {
+ val := fl.Field().String()
+ return dnsRegexRFC1035Label.MatchString(val)
+}
+
+// isCreditCard is the validation function for validating if the current field's value is a valid credit card number
+func isCreditCard(fl FieldLevel) bool {
+ val := fl.Field().String()
+ var creditCard bytes.Buffer
+ segments := strings.Split(val, " ")
+ for _, segment := range segments {
+ if len(segment) < 3 {
+ return false
+ }
+ creditCard.WriteString(segment)
+ }
+
+ ccDigits := strings.Split(creditCard.String(), "")
+ size := len(ccDigits)
+ if size < 12 || size > 19 {
+ return false
+ }
+
+ sum := 0
+ for i, digit := range ccDigits {
+ value, err := strconv.Atoi(digit)
+ if err != nil {
+ return false
+ }
+ if size%2 == 0 && i%2 == 0 || size%2 == 1 && i%2 == 1 {
+ v := value * 2
+ if v >= 10 {
+ sum += 1 + (v % 10)
+ } else {
+ sum += v
+ }
+ } else {
+ sum += value
+ }
+ }
+ return (sum % 10) == 0
+}