[](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
+
[](https://travis-ci.org/go-playground/validator)
[](https://coveralls.io/github/go-playground/validator?branch=master)
[](https://goreportcard.com/report/github.com/go-playground/validator)
@@ -130,7 +130,7 @@ Baked-in Validations
| contains | Contains |
| containsany | Contains Any |
| containsrune | Contains Rune |
-| endsnotwith | Ends With |
+| endsnotwith | Ends Not With |
| endswith | Ends With |
| excludes | Excludes |
| excludesall | Excludes All |
@@ -153,6 +153,7 @@ Baked-in Validations
| bcp47_language_tag | Language tag (BCP 47) |
| btc_addr | Bitcoin Address |
| btc_addr_bech32 | Bitcoin Bech32 Address (segwit) |
+| credit_card | Credit Card Number |
| datetime | Datetime |
| e164 | e164 formatted phone number |
| email | E-mail String
@@ -189,6 +190,18 @@ Baked-in Validations
| uuid5 | Universally Unique Identifier UUID v5 |
| uuid5_rfc4122 | Universally Unique Identifier UUID v5 RFC4122 |
| uuid_rfc4122 | Universally Unique Identifier UUID RFC4122 |
+| md4 | MD4 hash |
+| md5 | MD5 hash |
+| sha256 | SHA256 hash |
+| sha384 | SHA384 hash |
+| sha512 | SHA512 hash |
+| ripemd128 | RIPEMD-128 hash |
+| ripemd128 | RIPEMD-160 hash |
+| tiger128 | TIGER128 hash |
+| tiger160 | TIGER160 hash |
+| tiger192 | TIGER192 hash |
+| semver | Semantic Versioning 2.0.0 |
+| ulid | Universally Unique Lexicographically Sortable Identifier ULID |
### Comparisons:
| Tag | Description |
@@ -217,6 +230,8 @@ Baked-in Validations
| required_with_all | Required With All |
| required_without | Required Without |
| required_without_all | Required Without All |
+| excluded_if | Excluded If |
+| excluded_unless | Excluded Unless |
| excluded_with | Excluded With |
| excluded_with_all | Excluded With All |
| excluded_without | Excluded Without |
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()
+ if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
+
+ 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
}
-
- if fieldType == timeType {
-
- fieldTime := field.Interface().(time.Time)
- topTime := topField.Interface().(time.Time)
-
- return fieldTime.Before(topTime) || fieldTime.Equal(topTime)
- }
}
// 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()
+ if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
+
+ 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
}
-
- if fieldType == timeType {
-
- fieldTime := field.Interface().(time.Time)
- topTime := topField.Interface().(time.Time)
-
- return fieldTime.Before(topTime)
- }
}
// 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()
+ if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
+
+ 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
}
-
- if fieldType == timeType {
-
- fieldTime := field.Interface().(time.Time)
- topTime := topField.Interface().(time.Time)
-
- return fieldTime.After(topTime) || fieldTime.Equal(topTime)
- }
}
// 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()
+ if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
+
+ 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
}
-
- if fieldType == timeType {
-
- fieldTime := field.Interface().(time.Time)
- topTime := topField.Interface().(time.Time)
-
- return fieldTime.After(topTime)
- }
}
// 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()
+ if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
+
+ 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
}
-
- if fieldType == timeType {
-
- t := field.Interface().(time.Time)
- fieldTime := topField.Interface().(time.Time)
-
- return !fieldTime.Equal(t)
- }
}
// 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()
+ if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
+
+ 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
}
-
- if fieldType == timeType {
-
- t := field.Interface().(time.Time)
- fieldTime := topField.Interface().(time.Time)
-
- return fieldTime.Equal(t)
- }
}
// 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()
+ if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
+
+ 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
}
-
- if fieldType == timeType {
-
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
-
- return fieldTime.After(t) || fieldTime.Equal(t)
- }
}
// 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()
+ if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
+
+ 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
}
-
- if fieldType == timeType {
-
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
-
- return fieldTime.After(t)
- }
}
// 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()
+ if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
+
+ 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
}
-
- if fieldType == timeType {
-
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
-
- return fieldTime.Before(t) || fieldTime.Equal(t)
- }
}
// 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()
+ if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
+
+ 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
}
-
- if fieldType == timeType {
-
- t := currentField.Interface().(time.Time)
- fieldTime := field.Interface().(time.Time)
-
- return fieldTime.Before(t)
- }
}
// 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
+}
diff --git a/vendor/github.com/go-playground/validator/v10/cache.go b/vendor/github.com/go-playground/validator/v10/cache.go
index 0d18d6ec4..7b84c91fe 100644
--- a/vendor/github.com/go-playground/validator/v10/cache.go
+++ b/vendor/github.com/go-playground/validator/v10/cache.go
@@ -114,12 +114,13 @@ func (v *Validate) extractStructCache(current reflect.Value, sName string) *cStr
cs = &cStruct{name: sName, fields: make([]*cField, 0), fn: v.structLevelFuncs[typ]}
numFields := current.NumField()
+ rules := v.rules[typ]
var ctag *cTag
var fld reflect.StructField
var tag string
var customName string
-
+
for i := 0; i < numFields; i++ {
fld = typ.Field(i)
@@ -128,7 +129,11 @@ func (v *Validate) extractStructCache(current reflect.Value, sName string) *cStr
continue
}
- tag = fld.Tag.Get(v.tagName)
+ if rtag, ok := rules[fld.Name]; ok {
+ tag = rtag
+ } else {
+ tag = fld.Tag.Get(v.tagName)
+ }
if tag == skipValidationTag {
continue
diff --git a/vendor/github.com/go-playground/validator/v10/doc.go b/vendor/github.com/go-playground/validator/v10/doc.go
index 8c2584792..7341c67d7 100644
--- a/vendor/github.com/go-playground/validator/v10/doc.go
+++ b/vendor/github.com/go-playground/validator/v10/doc.go
@@ -349,6 +349,40 @@ Example:
// require the field if the Field1 and Field2 is not present:
Usage: required_without_all=Field1 Field2
+Excluded If
+
+The field under validation must not be present or not empty only if all
+the other specified fields are equal to the value following the specified
+field. For strings ensures value is not "". For slices, maps, pointers,
+interfaces, channels and functions ensures the value is not nil.
+
+ Usage: excluded_if
+
+Examples:
+
+ // exclude the field if the Field1 is equal to the parameter given:
+ Usage: excluded_if=Field1 foobar
+
+ // exclude the field if the Field1 and Field2 is equal to the value respectively:
+ Usage: excluded_if=Field1 foo Field2 bar
+
+Excluded Unless
+
+The field under validation must not be present or empty unless all
+the other specified fields are equal to the value following the specified
+field. For strings ensures value is not "". For slices, maps, pointers,
+interfaces, channels and functions ensures the value is not nil.
+
+ Usage: excluded_unless
+
+Examples:
+
+ // exclude the field unless the Field1 is equal to the parameter given:
+ Usage: excluded_unless=Field1 foobar
+
+ // exclude the field unless the Field1 and Field2 is equal to the value respectively:
+ Usage: excluded_unless=Field1 foo Field2 bar
+
Is Default
This validates that the value is the default value and is almost the
@@ -1007,6 +1041,12 @@ This validates that a string value contains a valid version 5 UUID. Uppercase U
Usage: uuid5
+Universally Unique Lexicographically Sortable Identifier ULID
+
+This validates that a string value contains a valid ULID value.
+
+ Usage: ulid
+
ASCII
This validates that a string value contains only ASCII characters.
@@ -1255,6 +1295,13 @@ More information on https://www.iso.org/standard/60390.html
Usage: bic
+RFC 1035 label
+
+This validates that a string value is a valid dns RFC 1035 label, defined in RFC 1035.
+More information on https://datatracker.ietf.org/doc/html/rfc1035
+
+ Usage: dns_rfc1035_label
+
TimeZone
This validates that a string value is a valid time zone based on the time zone database present on the system.
@@ -1263,6 +1310,18 @@ More information on https://golang.org/pkg/time/#LoadLocation
Usage: timezone
+Semantic Version
+
+This validates that a string value is a valid semver version, defined in Semantic Versioning 2.0.0.
+More information on https://semver.org/
+
+ Usage: semver
+
+Credit Card
+
+This validates that a string value contains a valid credit card number using Luhn algoritm.
+
+ Usage: credit_card
Alias Validators and Tags
diff --git a/vendor/github.com/go-playground/validator/v10/regexes.go b/vendor/github.com/go-playground/validator/v10/regexes.go
index df00c4ebc..9c1c63423 100644
--- a/vendor/github.com/go-playground/validator/v10/regexes.go
+++ b/vendor/github.com/go-playground/validator/v10/regexes.go
@@ -10,7 +10,7 @@ const (
numericRegexString = "^[-+]?[0-9]+(?:\\.[0-9]+)?$"
numberRegexString = "^[0-9]+$"
hexadecimalRegexString = "^(0[xX])?[0-9a-fA-F]+$"
- hexColorRegexString = "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$"
+ hexColorRegexString = "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
rgbRegexString = "^rgb\\(\\s*(?:(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])|(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%)\\s*\\)$"
rgbaRegexString = "^rgba\\(\\s*(?:(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])|(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%)\\s*,\\s*(?:(?:0.[1-9]*)|[01])\\s*\\)$"
hslRegexString = "^hsl\\(\\s*(?:0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d|360)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*\\)$"
@@ -29,6 +29,17 @@ const (
uUID4RFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
uUID5RFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-5[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
uUIDRFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
+ uLIDRegexString = "^[A-HJKMNP-TV-Z0-9]{26}$"
+ md4RegexString = "^[0-9a-f]{32}$"
+ md5RegexString = "^[0-9a-f]{32}$"
+ sha256RegexString = "^[0-9a-f]{64}$"
+ sha384RegexString = "^[0-9a-f]{96}$"
+ sha512RegexString = "^[0-9a-f]{128}$"
+ ripemd128RegexString = "^[0-9a-f]{32}$"
+ ripemd160RegexString = "^[0-9a-f]{40}$"
+ tiger128RegexString = "^[0-9a-f]{32}$"
+ tiger160RegexString = "^[0-9a-f]{40}$"
+ tiger192RegexString = "^[0-9a-f]{48}$"
aSCIIRegexString = "^[\x00-\x7F]*$"
printableASCIIRegexString = "^[\x20-\x7E]*$"
multibyteRegexString = "[^\x00-\x7F]"
@@ -36,12 +47,12 @@ const (
latitudeRegexString = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$"
longitudeRegexString = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$"
sSNRegexString = `^[0-9]{3}[ -]?(0[1-9]|[1-9][0-9])[ -]?([1-9][0-9]{3}|[0-9][1-9][0-9]{2}|[0-9]{2}[1-9][0-9]|[0-9]{3}[1-9])$`
- hostnameRegexStringRFC952 = `^[a-zA-Z]([a-zA-Z0-9\-]+[\.]?)*[a-zA-Z0-9]$` // https://tools.ietf.org/html/rfc952
- hostnameRegexStringRFC1123 = `^([a-zA-Z0-9]{1}[a-zA-Z0-9_-]{0,62}){1}(\.[a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62})*?$` // accepts hostname starting with a digit https://tools.ietf.org/html/rfc1123
- fqdnRegexStringRFC1123 = `^([a-zA-Z0-9]{1}[a-zA-Z0-9_-]{0,62})(\.[a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62})*?(\.[a-zA-Z]{1}[a-zA-Z0-9]{0,62})\.?$` // same as hostnameRegexStringRFC1123 but must contain a non numerical TLD (possibly ending with '.')
- btcAddressRegexString = `^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$` // bitcoin address
- btcAddressUpperRegexStringBech32 = `^BC1[02-9AC-HJ-NP-Z]{7,76}$` // bitcoin bech32 address https://en.bitcoin.it/wiki/Bech32
- btcAddressLowerRegexStringBech32 = `^bc1[02-9ac-hj-np-z]{7,76}$` // bitcoin bech32 address https://en.bitcoin.it/wiki/Bech32
+ hostnameRegexStringRFC952 = `^[a-zA-Z]([a-zA-Z0-9\-]+[\.]?)*[a-zA-Z0-9]$` // https://tools.ietf.org/html/rfc952
+ hostnameRegexStringRFC1123 = `^([a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62}){1}(\.[a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62})*?$` // accepts hostname starting with a digit https://tools.ietf.org/html/rfc1123
+ fqdnRegexStringRFC1123 = `^([a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62})(\.[a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62})*?(\.[a-zA-Z]{1}[a-zA-Z0-9]{0,62})\.?$` // same as hostnameRegexStringRFC1123 but must contain a non numerical TLD (possibly ending with '.')
+ btcAddressRegexString = `^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$` // bitcoin address
+ btcAddressUpperRegexStringBech32 = `^BC1[02-9AC-HJ-NP-Z]{7,76}$` // bitcoin bech32 address https://en.bitcoin.it/wiki/Bech32
+ btcAddressLowerRegexStringBech32 = `^bc1[02-9ac-hj-np-z]{7,76}$` // bitcoin bech32 address https://en.bitcoin.it/wiki/Bech32
ethAddressRegexString = `^0x[0-9a-fA-F]{40}$`
ethAddressUpperRegexString = `^0x[0-9A-F]{40}$`
ethAddressLowerRegexString = `^0x[0-9a-f]{40}$`
@@ -51,6 +62,8 @@ const (
jWTRegexString = "^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$"
splitParamsRegexString = `'[^']*'|\S+`
bicRegexString = `^[A-Za-z]{6}[A-Za-z0-9]{2}([A-Za-z0-9]{3})?$`
+ semverRegexString = `^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$` // numbered capture groups https://semver.org/
+ dnsRegexStringRFC1035Label = "^[a-z]([-a-z0-9]*[a-z0-9]){0,62}$"
)
var (
@@ -80,6 +93,17 @@ var (
uUID4RFC4122Regex = regexp.MustCompile(uUID4RFC4122RegexString)
uUID5RFC4122Regex = regexp.MustCompile(uUID5RFC4122RegexString)
uUIDRFC4122Regex = regexp.MustCompile(uUIDRFC4122RegexString)
+ uLIDRegex = regexp.MustCompile(uLIDRegexString)
+ md4Regex = regexp.MustCompile(md4RegexString)
+ md5Regex = regexp.MustCompile(md5RegexString)
+ sha256Regex = regexp.MustCompile(sha256RegexString)
+ sha384Regex = regexp.MustCompile(sha384RegexString)
+ sha512Regex = regexp.MustCompile(sha512RegexString)
+ ripemd128Regex = regexp.MustCompile(ripemd128RegexString)
+ ripemd160Regex = regexp.MustCompile(ripemd160RegexString)
+ tiger128Regex = regexp.MustCompile(tiger128RegexString)
+ tiger160Regex = regexp.MustCompile(tiger160RegexString)
+ tiger192Regex = regexp.MustCompile(tiger192RegexString)
aSCIIRegex = regexp.MustCompile(aSCIIRegexString)
printableASCIIRegex = regexp.MustCompile(printableASCIIRegexString)
multibyteRegex = regexp.MustCompile(multibyteRegexString)
@@ -102,4 +126,6 @@ var (
jWTRegex = regexp.MustCompile(jWTRegexString)
splitParamsRegex = regexp.MustCompile(splitParamsRegexString)
bicRegex = regexp.MustCompile(bicRegexString)
+ semverRegex = regexp.MustCompile(semverRegexString)
+ dnsRegexRFC1035Label = regexp.MustCompile(dnsRegexStringRFC1035Label)
)
diff --git a/vendor/github.com/go-playground/validator/v10/util.go b/vendor/github.com/go-playground/validator/v10/util.go
index 56420f430..36da85514 100644
--- a/vendor/github.com/go-playground/validator/v10/util.go
+++ b/vendor/github.com/go-playground/validator/v10/util.go
@@ -82,7 +82,7 @@ BEGIN:
fld := namespace
var ns string
- if typ != timeType {
+ if !typ.ConvertibleTo(timeType) {
idx := strings.Index(namespace, namespaceSeparator)
diff --git a/vendor/github.com/go-playground/validator/v10/validator.go b/vendor/github.com/go-playground/validator/v10/validator.go
index 2a4fad022..80da095a6 100644
--- a/vendor/github.com/go-playground/validator/v10/validator.go
+++ b/vendor/github.com/go-playground/validator/v10/validator.go
@@ -164,7 +164,7 @@ func (v *validate) traverseField(ctx context.Context, parent reflect.Value, curr
typ = current.Type()
- if typ != timeType {
+ if !typ.ConvertibleTo(timeType) {
if ct != nil {
@@ -355,6 +355,10 @@ OUTER:
v.ct = ct
if ct.fn(ctx, v) {
+ if ct.isBlockEnd {
+ ct = ct.next
+ continue OUTER
+ }
// drain rest of the 'or' values, then continue or leave
for {
@@ -368,6 +372,11 @@ OUTER:
if ct.typeof != typeOr {
continue OUTER
}
+
+ if ct.isBlockEnd {
+ ct = ct.next
+ continue OUTER
+ }
}
}
diff --git a/vendor/github.com/go-playground/validator/v10/validator_instance.go b/vendor/github.com/go-playground/validator/v10/validator_instance.go
index 973964fc2..9493da491 100644
--- a/vendor/github.com/go-playground/validator/v10/validator_instance.go
+++ b/vendor/github.com/go-playground/validator/v10/validator_instance.go
@@ -33,6 +33,8 @@ const (
excludedWithoutTag = "excluded_without"
excludedWithTag = "excluded_with"
excludedWithAllTag = "excluded_with_all"
+ excludedIfTag = "excluded_if"
+ excludedUnlessTag = "excluded_unless"
skipValidationTag = "-"
diveTag = "dive"
keysTag = "keys"
@@ -84,6 +86,7 @@ type Validate struct {
aliases map[string]string
validations map[string]internalValidationFuncWrapper
transTagFunc map[ut.Translator]map[string]TranslationFunc // map[| - | github.com/gorilla | -golang.org/x/net | -
|---|---|---|
| RFC 6455 Features | ||
| Passes Autobahn Test Suite | Yes | No |
| Receive fragmented message | Yes | No, see note 1 |
| Send close message | Yes | No |
| Send pings and receive pongs | Yes | No |
| Get the type of a received data message | Yes | Yes, see note 2 |
| Other Features | ||
| Compression Extensions | Experimental | No |
| Read message using io.Reader | Yes | No, see note 3 |
| Write message using io.WriteCloser | Yes | No, see note 3 |
| Benchmark | go-toml v1 | BurntSushi/toml |
|---|---|---|
| Marshal/HugoFrontMatter-2 | 1.9x | 1.9x |
| Marshal/ReferenceFile/map-2 | 1.7x | 1.8x |
| Marshal/ReferenceFile/struct-2 | 2.2x | 2.5x |
| Unmarshal/HugoFrontMatter-2 | 2.9x | 2.9x |
| Unmarshal/ReferenceFile/map-2 | 2.6x | 2.9x |
| Unmarshal/ReferenceFile/struct-2 | 4.4x | 5.3x |
The table above has the results of the most common use-cases. The table below +contains the results of all benchmarks, including unrealistic ones. It is +provided for completeness.
+ +| Benchmark | go-toml v1 | BurntSushi/toml |
|---|---|---|
| Marshal/SimpleDocument/map-2 | 1.8x | 2.9x |
| Marshal/SimpleDocument/struct-2 | 2.7x | 4.2x |
| Unmarshal/SimpleDocument/map-2 | 4.5x | 3.1x |
| Unmarshal/SimpleDocument/struct-2 | 6.2x | 3.9x |
| UnmarshalDataset/example-2 | 3.1x | 3.5x |
| UnmarshalDataset/code-2 | 2.3x | 3.1x |
| UnmarshalDataset/twitter-2 | 2.5x | 2.6x |
| UnmarshalDataset/citm_catalog-2 | 2.1x | 2.2x |
| UnmarshalDataset/canada-2 | 1.6x | 1.3x |
| UnmarshalDataset/config-2 | 4.3x | 3.2x |
| [Geo mean] | 2.7x | 2.8x |
This table can be generated with ./ci.sh benchmark -a -html.
| Benchmark | go-toml v1 | BurntSushi/toml |
|---|---|---|
| {} | {} | {} |
The table above has the results of the most common use-cases. The table below +contains the results of all benchmarks, including unrealistic ones. It is +provided for completeness.
""") +printtable(below) +print('This table can be generated with ./ci.sh benchmark -a -html.