fix linting and spelling errors

pull/362/head
Dean Karn 7 years ago
parent b297167b88
commit 54da7fa48f
  1. 16
      Makefile
  2. 122
      README.md
  3. 29
      baked_in.go
  4. 2
      cache.go
  5. 38
      doc.go
  6. 2
      field_level.go
  7. 2
      translations.go
  8. 12
      translations/en/en.go
  9. 12
      translations/fr/fr.go
  10. 12
      translations/pt_BR/pt_BR.go
  11. 4
      validator.go
  12. 10
      validator_instance.go
  13. 18
      validator_test.go

@ -0,0 +1,16 @@
GOCMD=go
linters-install:
$(GOCMD) get -u github.com/alecthomas/gometalinter
gometalinter --install
lint: linters-install
gometalinter --vendor --disable-all --enable=vet --enable=vetshadow --enable=golint --enable=maligned --enable=megacheck --enable=ineffassign --enable=misspell --enable=errcheck --enable=goconst ./...
test:
$(GOCMD) test -cover -race ./...
bench:
$(GOCMD) test -bench=. -benchmem ./...
.PHONY: test lint linters-install

@ -66,71 +66,73 @@ Please see http://godoc.org/gopkg.in/go-playground/validator.v9 for detailed usa
Benchmarks Benchmarks
------ ------
###### Run on MacBook Pro (15-inch, 2017) Go version go1.9.4 darwin/amd64 ###### Run on MacBook Pro (15-inch, 2017) go version go1.10.2 darwin/amd64
```go ```go
goos: darwin goos: darwin
goarch: amd64 goarch: amd64
pkg: github.com/go-playground/validator pkg: github.com/go-playground/validator
BenchmarkFieldSuccess-8 20000000 86.4 ns/op 0 B/op 0 allocs/op BenchmarkFieldSuccess-8 20000000 83.6 ns/op 0 B/op 0 allocs/op
BenchmarkFieldSuccessParallel-8 50000000 27.6 ns/op 0 B/op 0 allocs/op BenchmarkFieldSuccessParallel-8 50000000 26.8 ns/op 0 B/op 0 allocs/op
BenchmarkFieldFailure-8 5000000 297 ns/op 208 B/op 4 allocs/op BenchmarkFieldFailure-8 5000000 291 ns/op 208 B/op 4 allocs/op
BenchmarkFieldFailureParallel-8 20000000 107 ns/op 208 B/op 4 allocs/op BenchmarkFieldFailureParallel-8 20000000 107 ns/op 208 B/op 4 allocs/op
BenchmarkFieldArrayDiveSuccess-8 2000000 618 ns/op 201 B/op 11 allocs/op BenchmarkFieldArrayDiveSuccess-8 2000000 623 ns/op 201 B/op 11 allocs/op
BenchmarkFieldArrayDiveSuccessParallel-8 10000000 225 ns/op 201 B/op 11 allocs/op BenchmarkFieldArrayDiveSuccessParallel-8 10000000 237 ns/op 201 B/op 11 allocs/op
BenchmarkFieldArrayDiveFailure-8 2000000 863 ns/op 412 B/op 16 allocs/op BenchmarkFieldArrayDiveFailure-8 2000000 859 ns/op 412 B/op 16 allocs/op
BenchmarkFieldArrayDiveFailureParallel-8 5000000 322 ns/op 413 B/op 16 allocs/op BenchmarkFieldArrayDiveFailureParallel-8 5000000 335 ns/op 413 B/op 16 allocs/op
BenchmarkFieldMapDiveSuccess-8 1000000 1336 ns/op 432 B/op 18 allocs/op BenchmarkFieldMapDiveSuccess-8 1000000 1292 ns/op 432 B/op 18 allocs/op
BenchmarkFieldMapDiveSuccessParallel-8 3000000 474 ns/op 432 B/op 18 allocs/op BenchmarkFieldMapDiveSuccessParallel-8 3000000 467 ns/op 432 B/op 18 allocs/op
BenchmarkFieldMapDiveFailure-8 1000000 1103 ns/op 512 B/op 16 allocs/op BenchmarkFieldMapDiveFailure-8 1000000 1082 ns/op 512 B/op 16 allocs/op
BenchmarkFieldMapDiveFailureParallel-8 5000000 412 ns/op 512 B/op 16 allocs/op BenchmarkFieldMapDiveFailureParallel-8 5000000 425 ns/op 512 B/op 16 allocs/op
BenchmarkFieldMapDiveWithKeysSuccess-8 1000000 1572 ns/op 480 B/op 21 allocs/op BenchmarkFieldMapDiveWithKeysSuccess-8 1000000 1539 ns/op 480 B/op 21 allocs/op
BenchmarkFieldMapDiveWithKeysSuccessParallel-8 3000000 615 ns/op 480 B/op 21 allocs/op BenchmarkFieldMapDiveWithKeysSuccessParallel-8 3000000 613 ns/op 480 B/op 21 allocs/op
BenchmarkFieldMapDiveWithKeysFailure-8 1000000 1438 ns/op 721 B/op 21 allocs/op BenchmarkFieldMapDiveWithKeysFailure-8 1000000 1413 ns/op 721 B/op 21 allocs/op
BenchmarkFieldMapDiveWithKeysFailureParallel-8 3000000 543 ns/op 721 B/op 21 allocs/op BenchmarkFieldMapDiveWithKeysFailureParallel-8 3000000 575 ns/op 721 B/op 21 allocs/op
BenchmarkFieldCustomTypeSuccess-8 10000000 230 ns/op 32 B/op 2 allocs/op BenchmarkFieldCustomTypeSuccess-8 10000000 216 ns/op 32 B/op 2 allocs/op
BenchmarkFieldCustomTypeSuccessParallel-8 20000000 82.5 ns/op 32 B/op 2 allocs/op BenchmarkFieldCustomTypeSuccessParallel-8 20000000 82.2 ns/op 32 B/op 2 allocs/op
BenchmarkFieldCustomTypeFailure-8 5000000 284 ns/op 208 B/op 4 allocs/op BenchmarkFieldCustomTypeFailure-8 5000000 274 ns/op 208 B/op 4 allocs/op
BenchmarkFieldCustomTypeFailureParallel-8 20000000 118 ns/op 208 B/op 4 allocs/op BenchmarkFieldCustomTypeFailureParallel-8 20000000 116 ns/op 208 B/op 4 allocs/op
BenchmarkFieldOrTagSuccess-8 2000000 824 ns/op 16 B/op 1 allocs/op BenchmarkFieldOrTagSuccess-8 2000000 740 ns/op 16 B/op 1 allocs/op
BenchmarkFieldOrTagSuccessParallel-8 3000000 472 ns/op 16 B/op 1 allocs/op BenchmarkFieldOrTagSuccessParallel-8 3000000 474 ns/op 16 B/op 1 allocs/op
BenchmarkFieldOrTagFailure-8 3000000 487 ns/op 224 B/op 5 allocs/op BenchmarkFieldOrTagFailure-8 3000000 471 ns/op 224 B/op 5 allocs/op
BenchmarkFieldOrTagFailureParallel-8 5000000 405 ns/op 224 B/op 5 allocs/op BenchmarkFieldOrTagFailureParallel-8 3000000 414 ns/op 224 B/op 5 allocs/op
BenchmarkStructLevelValidationSuccess-8 10000000 214 ns/op 32 B/op 2 allocs/op BenchmarkStructLevelValidationSuccess-8 10000000 213 ns/op 32 B/op 2 allocs/op
BenchmarkStructLevelValidationSuccessParallel-8 20000000 78.0 ns/op 32 B/op 2 allocs/op BenchmarkStructLevelValidationSuccessParallel-8 20000000 91.8 ns/op 32 B/op 2 allocs/op
BenchmarkStructLevelValidationFailure-8 3000000 475 ns/op 304 B/op 8 allocs/op BenchmarkStructLevelValidationFailure-8 3000000 473 ns/op 304 B/op 8 allocs/op
BenchmarkStructLevelValidationFailureParallel-8 10000000 200 ns/op 304 B/op 8 allocs/op BenchmarkStructLevelValidationFailureParallel-8 10000000 234 ns/op 304 B/op 8 allocs/op
BenchmarkStructSimpleCustomTypeSuccess-8 3000000 403 ns/op 32 B/op 2 allocs/op BenchmarkStructSimpleCustomTypeSuccess-8 5000000 385 ns/op 32 B/op 2 allocs/op
BenchmarkStructSimpleCustomTypeSuccessParallel-8 10000000 143 ns/op 32 B/op 2 allocs/op BenchmarkStructSimpleCustomTypeSuccessParallel-8 10000000 161 ns/op 32 B/op 2 allocs/op
BenchmarkStructSimpleCustomTypeFailure-8 2000000 655 ns/op 424 B/op 9 allocs/op BenchmarkStructSimpleCustomTypeFailure-8 2000000 640 ns/op 424 B/op 9 allocs/op
BenchmarkStructSimpleCustomTypeFailureParallel-8 5000000 286 ns/op 440 B/op 10 allocs/op BenchmarkStructSimpleCustomTypeFailureParallel-8 5000000 318 ns/op 440 B/op 10 allocs/op
BenchmarkStructFilteredSuccess-8 2000000 598 ns/op 288 B/op 9 allocs/op BenchmarkStructFilteredSuccess-8 2000000 597 ns/op 288 B/op 9 allocs/op
BenchmarkStructFilteredSuccessParallel-8 10000000 231 ns/op 288 B/op 9 allocs/op BenchmarkStructFilteredSuccessParallel-8 10000000 266 ns/op 288 B/op 9 allocs/op
BenchmarkStructFilteredFailure-8 3000000 455 ns/op 256 B/op 7 allocs/op BenchmarkStructFilteredFailure-8 3000000 454 ns/op 256 B/op 7 allocs/op
BenchmarkStructFilteredFailureParallel-8 10000000 197 ns/op 256 B/op 7 allocs/op BenchmarkStructFilteredFailureParallel-8 10000000 214 ns/op 256 B/op 7 allocs/op
BenchmarkStructPartialSuccess-8 3000000 552 ns/op 256 B/op 6 allocs/op BenchmarkStructPartialSuccess-8 3000000 502 ns/op 256 B/op 6 allocs/op
BenchmarkStructPartialSuccessParallel-8 10000000 206 ns/op 256 B/op 6 allocs/op BenchmarkStructPartialSuccessParallel-8 10000000 225 ns/op 256 B/op 6 allocs/op
BenchmarkStructPartialFailure-8 2000000 750 ns/op 480 B/op 11 allocs/op BenchmarkStructPartialFailure-8 2000000 702 ns/op 480 B/op 11 allocs/op
BenchmarkStructPartialFailureParallel-8 5000000 317 ns/op 480 B/op 11 allocs/op BenchmarkStructPartialFailureParallel-8 5000000 329 ns/op 480 B/op 11 allocs/op
BenchmarkStructExceptSuccess-8 2000000 853 ns/op 496 B/op 12 allocs/op BenchmarkStructExceptSuccess-8 2000000 793 ns/op 496 B/op 12 allocs/op
BenchmarkStructExceptSuccessParallel-8 10000000 179 ns/op 240 B/op 5 allocs/op BenchmarkStructExceptSuccessParallel-8 10000000 193 ns/op 240 B/op 5 allocs/op
BenchmarkStructExceptFailure-8 2000000 698 ns/op 464 B/op 10 allocs/op BenchmarkStructExceptFailure-8 2000000 639 ns/op 464 B/op 10 allocs/op
BenchmarkStructExceptFailureParallel-8 5000000 276 ns/op 464 B/op 10 allocs/op BenchmarkStructExceptFailureParallel-8 5000000 300 ns/op 464 B/op 10 allocs/op
BenchmarkStructSimpleCrossFieldSuccess-8 3000000 412 ns/op 72 B/op 3 allocs/op BenchmarkStructSimpleCrossFieldSuccess-8 3000000 417 ns/op 72 B/op 3 allocs/op
BenchmarkStructSimpleCrossFieldSuccessParallel-8 10000000 148 ns/op 72 B/op 3 allocs/op BenchmarkStructSimpleCrossFieldSuccessParallel-8 10000000 163 ns/op 72 B/op 3 allocs/op
BenchmarkStructSimpleCrossFieldFailure-8 2000000 630 ns/op 304 B/op 8 allocs/op BenchmarkStructSimpleCrossFieldFailure-8 2000000 645 ns/op 304 B/op 8 allocs/op
BenchmarkStructSimpleCrossFieldFailureParallel-8 10000000 244 ns/op 304 B/op 8 allocs/op BenchmarkStructSimpleCrossFieldFailureParallel-8 5000000 285 ns/op 304 B/op 8 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 2000000 610 ns/op 80 B/op 4 allocs/op BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 3000000 588 ns/op 80 B/op 4 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 10000000 205 ns/op 80 B/op 4 allocs/op BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 10000000 221 ns/op 80 B/op 4 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldFailure-8 2000000 861 ns/op 320 B/op 9 allocs/op BenchmarkStructSimpleCrossStructCrossFieldFailure-8 2000000 868 ns/op 320 B/op 9 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 5000000 315 ns/op 320 B/op 9 allocs/op BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 5000000 337 ns/op 320 B/op 9 allocs/op
BenchmarkStructSimpleSuccess-8 5000000 279 ns/op 0 B/op 0 allocs/op BenchmarkStructSimpleSuccess-8 5000000 260 ns/op 0 B/op 0 allocs/op
BenchmarkStructSimpleSuccessParallel-8 20000000 86.4 ns/op 0 B/op 0 allocs/op BenchmarkStructSimpleSuccessParallel-8 20000000 90.6 ns/op 0 B/op 0 allocs/op
BenchmarkStructSimpleFailure-8 2000000 636 ns/op 424 B/op 9 allocs/op BenchmarkStructSimpleFailure-8 2000000 619 ns/op 424 B/op 9 allocs/op
BenchmarkStructSimpleFailureParallel-8 10000000 264 ns/op 424 B/op 9 allocs/op BenchmarkStructSimpleFailureParallel-8 5000000 296 ns/op 424 B/op 9 allocs/op
BenchmarkStructComplexSuccess-8 1000000 1539 ns/op 128 B/op 8 allocs/op BenchmarkStructComplexSuccess-8 1000000 1454 ns/op 128 B/op 8 allocs/op
BenchmarkStructComplexSuccessParallel-8 3000000 557 ns/op 128 B/op 8 allocs/op BenchmarkStructComplexSuccessParallel-8 3000000 579 ns/op 128 B/op 8 allocs/op
BenchmarkStructComplexFailure-8 300000 4136 ns/op 3041 B/op 53 allocs/op BenchmarkStructComplexFailure-8 300000 4140 ns/op 3041 B/op 53 allocs/op
BenchmarkStructComplexFailureParallel-8 1000000 1855 ns/op 3041 B/op 53 allocs/op BenchmarkStructComplexFailureParallel-8 1000000 2127 ns/op 3041 B/op 53 allocs/op
BenchmarkOneof-8 10000000 140 ns/op 0 B/op 0 allocs/op
BenchmarkOneofParallel-8 20000000 70.1 ns/op 0 B/op 0 allocs/op
``` ```
Complementary Software Complementary Software

@ -440,10 +440,10 @@ func isBitcoinAddress(fl FieldLevel) bool {
} }
h := sha256.New() h := sha256.New()
h.Write(decode[:21]) _, _ = h.Write(decode[:21])
d := h.Sum([]byte{}) d := h.Sum([]byte{})
h = sha256.New() h = sha256.New()
h.Write(d) _, _ = h.Write(d)
validchecksum := [4]byte{} validchecksum := [4]byte{}
computedchecksum := [4]byte{} computedchecksum := [4]byte{}
@ -458,13 +458,13 @@ func isBitcoinAddress(fl FieldLevel) bool {
func isBitcoinBech32Address(fl FieldLevel) bool { func isBitcoinBech32Address(fl FieldLevel) bool {
address := fl.Field().String() address := fl.Field().String()
if !btcLowerAddressRegexBech32.MatchString(address) && !btcUpperAddressRegexBech32.MatchString(address){ if !btcLowerAddressRegexBech32.MatchString(address) && !btcUpperAddressRegexBech32.MatchString(address) {
return false return false
} }
am := len(address) % 8 am := len(address) % 8
if am == 0 || am == 3 || am == 5{ if am == 0 || am == 3 || am == 5 {
return false return false
} }
@ -473,15 +473,16 @@ func isBitcoinBech32Address(fl FieldLevel) bool {
alphabet := "qpzry9x8gf2tvdw0s3jn54khce6mua7l" alphabet := "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
hr := []int{3, 3, 0, 2, 3} // the human readable part will always be bc hr := []int{3, 3, 0, 2, 3} // the human readable part will always be bc
dp := []int{} addr := address[3:]
dp := make([]int, 0, len(addr))
for _, c := range []rune(address[3:]) { for _, c := range addr {
dp = append(dp, strings.IndexRune(alphabet, c)) dp = append(dp, strings.IndexRune(alphabet, c))
} }
ver := dp[0] ver := dp[0]
if ver < 0 || ver > 16{ if ver < 0 || ver > 16 {
return false return false
} }
@ -493,16 +494,16 @@ func isBitcoinBech32Address(fl FieldLevel) bool {
values := append(hr, dp...) values := append(hr, dp...)
GEN := []int{ 0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3 } GEN := []int{0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3}
p := 1 p := 1
for _, v := range values { for _, v := range values {
b := p >> 25 b := p >> 25
p = (p & 0x1ffffff) << 5 ^ v p = (p&0x1ffffff)<<5 ^ v
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
if (b >> uint(i)) & 1 == 1 { if (b>>uint(i))&1 == 1 {
p ^= GEN[i] p ^= GEN[i]
} }
} }
@ -515,18 +516,18 @@ func isBitcoinBech32Address(fl FieldLevel) bool {
b := uint(0) b := uint(0)
acc := 0 acc := 0
mv := (1 << 5) - 1 mv := (1 << 5) - 1
sw := []int{} var sw []int
for _, v := range dp[1:len(dp) - 6]{ for _, v := range dp[1 : len(dp)-6] {
acc = (acc << 5) | v acc = (acc << 5) | v
b += 5 b += 5
for b >= 8{ for b >= 8 {
b -= 8 b -= 8
sw = append(sw, (acc>>b)&mv) sw = append(sw, (acc>>b)&mv)
} }
} }
if len(sw) < 2 || len(sw) > 40{ if len(sw) < 2 || len(sw) > 40 {
return false return false
} }

@ -223,7 +223,7 @@ func (v *Validate) parseFieldTagsRecursive(tag string, fieldName string, alias s
current.typeof = typeKeys current.typeof = typeKeys
if i == 0 || prevTag != typeDive { if i == 0 || prevTag != typeDive {
panic(fmt.Sprintf("'%s' tag must be immediately preceeded by the '%s' tag", keysTag, diveTag)) panic(fmt.Sprintf("'%s' tag must be immediately preceded by the '%s' tag", keysTag, diveTag))
} }
current.typeof = typeKeys current.typeof = typeKeys

@ -168,7 +168,7 @@ StructOnly
When a field that is a nested struct is encountered, and contains this flag When a field that is a nested struct is encountered, and contains this flag
any validation on the nested struct will be run, but none of the nested any validation on the nested struct will be run, but none of the nested
struct fields will be validated. This is usefull if inside of you program struct fields will be validated. This is useful if inside of you program
you know the struct will be valid, but need to verify it has been assigned. you know the struct will be valid, but need to verify it has been assigned.
NOTE: only "required" and "omitempty" can be used on a struct itself. NOTE: only "required" and "omitempty" can be used on a struct itself.
@ -772,103 +772,103 @@ This validates that a string value contains a valid U.S. Social Security Number.
Internet Protocol Address IP Internet Protocol Address IP
This validates that a string value contains a valid IP Adress. This validates that a string value contains a valid IP Address.
Usage: ip Usage: ip
Internet Protocol Address IPv4 Internet Protocol Address IPv4
This validates that a string value contains a valid v4 IP Adress. This validates that a string value contains a valid v4 IP Address.
Usage: ipv4 Usage: ipv4
Internet Protocol Address IPv6 Internet Protocol Address IPv6
This validates that a string value contains a valid v6 IP Adress. This validates that a string value contains a valid v6 IP Address.
Usage: ipv6 Usage: ipv6
Classless Inter-Domain Routing CIDR Classless Inter-Domain Routing CIDR
This validates that a string value contains a valid CIDR Adress. This validates that a string value contains a valid CIDR Address.
Usage: cidr Usage: cidr
Classless Inter-Domain Routing CIDRv4 Classless Inter-Domain Routing CIDRv4
This validates that a string value contains a valid v4 CIDR Adress. This validates that a string value contains a valid v4 CIDR Address.
Usage: cidrv4 Usage: cidrv4
Classless Inter-Domain Routing CIDRv6 Classless Inter-Domain Routing CIDRv6
This validates that a string value contains a valid v6 CIDR Adress. This validates that a string value contains a valid v6 CIDR Address.
Usage: cidrv6 Usage: cidrv6
Transmission Control Protocol Address TCP Transmission Control Protocol Address TCP
This validates that a string value contains a valid resolvable TCP Adress. This validates that a string value contains a valid resolvable TCP Address.
Usage: tcp_addr Usage: tcp_addr
Transmission Control Protocol Address TCPv4 Transmission Control Protocol Address TCPv4
This validates that a string value contains a valid resolvable v4 TCP Adress. This validates that a string value contains a valid resolvable v4 TCP Address.
Usage: tcp4_addr Usage: tcp4_addr
Transmission Control Protocol Address TCPv6 Transmission Control Protocol Address TCPv6
This validates that a string value contains a valid resolvable v6 TCP Adress. This validates that a string value contains a valid resolvable v6 TCP Address.
Usage: tcp6_addr Usage: tcp6_addr
User Datagram Protocol Address UDP User Datagram Protocol Address UDP
This validates that a string value contains a valid resolvable UDP Adress. This validates that a string value contains a valid resolvable UDP Address.
Usage: udp_addr Usage: udp_addr
User Datagram Protocol Address UDPv4 User Datagram Protocol Address UDPv4
This validates that a string value contains a valid resolvable v4 UDP Adress. This validates that a string value contains a valid resolvable v4 UDP Address.
Usage: udp4_addr Usage: udp4_addr
User Datagram Protocol Address UDPv6 User Datagram Protocol Address UDPv6
This validates that a string value contains a valid resolvable v6 UDP Adress. This validates that a string value contains a valid resolvable v6 UDP Address.
Usage: udp6_addr Usage: udp6_addr
Internet Protocol Address IP Internet Protocol Address IP
This validates that a string value contains a valid resolvable IP Adress. This validates that a string value contains a valid resolvable IP Address.
Usage: ip_addr Usage: ip_addr
Internet Protocol Address IPv4 Internet Protocol Address IPv4
This validates that a string value contains a valid resolvable v4 IP Adress. This validates that a string value contains a valid resolvable v4 IP Address.
Usage: ip4_addr Usage: ip4_addr
Internet Protocol Address IPv6 Internet Protocol Address IPv6
This validates that a string value contains a valid resolvable v6 IP Adress. This validates that a string value contains a valid resolvable v6 IP Address.
Usage: ip6_addr Usage: ip6_addr
Unix domain socket end point Address Unix domain socket end point Address
This validates that a string value contains a valid Unix Adress. This validates that a string value contains a valid Unix Address.
Usage: unix_addr Usage: unix_addr
Media Access Control Address MAC Media Access Control Address MAC
This validates that a string value contains a valid MAC Adress. This validates that a string value contains a valid MAC Address.
Usage: mac Usage: mac
@ -913,7 +913,7 @@ Validator notes:
of a regex which conflict with the validation definitions. Although of a regex which conflict with the validation definitions. Although
workarounds can be made, they take away from using pure regex's. workarounds can be made, they take away from using pure regex's.
Furthermore it's quick and dirty but the regex's become harder to Furthermore it's quick and dirty but the regex's become harder to
maintain and are not reusable, so it's as much a programming philosiphy maintain and are not reusable, so it's as much a programming philosophy
as anything. as anything.
In place of this new validator functions should be created; a regex can In place of this new validator functions should be created; a regex can

@ -17,7 +17,7 @@ type FieldLevel interface {
Field() reflect.Value Field() reflect.Value
// returns the field's name with the tag // returns the field's name with the tag
// name takeing precedence over the fields actual name. // name taking precedence over the fields actual name.
FieldName() string FieldName() string
// returns the struct field's name // returns the struct field's name

@ -7,5 +7,5 @@ import ut "github.com/go-playground/universal-translator"
type TranslationFunc func(ut ut.Translator, fe FieldError) string type TranslationFunc func(ut ut.Translator, fe FieldError) string
// RegisterTranslationsFunc allows for registering of translations // RegisterTranslationsFunc allows for registering of translations
// for a 'ut.Translator' for use withing the 'TranslationFunc' // for a 'ut.Translator' for use within the 'TranslationFunc'
type RegisterTranslationsFunc func(ut ut.Translator) error type RegisterTranslationsFunc func(ut ut.Translator) error

@ -429,7 +429,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
case reflect.Struct: case reflect.Struct:
if fe.Type() != reflect.TypeOf(time.Time{}) { if fe.Type() != reflect.TypeOf(time.Time{}) {
err = fmt.Errorf("tag '%s' cannot be used on a struct type.", fe.Tag()) err = fmt.Errorf("tag '%s' cannot be used on a struct type", fe.Tag())
goto END
} }
t, err = ut.T("lt-datetime", fe.Field()) t, err = ut.T("lt-datetime", fe.Field())
@ -548,7 +549,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
case reflect.Struct: case reflect.Struct:
if fe.Type() != reflect.TypeOf(time.Time{}) { if fe.Type() != reflect.TypeOf(time.Time{}) {
err = fmt.Errorf("tag '%s' cannot be used on a struct type.", fe.Tag()) err = fmt.Errorf("tag '%s' cannot be used on a struct type", fe.Tag())
goto END
} }
t, err = ut.T("lte-datetime", fe.Field()) t, err = ut.T("lte-datetime", fe.Field())
@ -667,7 +669,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
case reflect.Struct: case reflect.Struct:
if fe.Type() != reflect.TypeOf(time.Time{}) { if fe.Type() != reflect.TypeOf(time.Time{}) {
err = fmt.Errorf("tag '%s' cannot be used on a struct type.", fe.Tag()) err = fmt.Errorf("tag '%s' cannot be used on a struct type", fe.Tag())
goto END
} }
t, err = ut.T("gt-datetime", fe.Field()) t, err = ut.T("gt-datetime", fe.Field())
@ -786,7 +789,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
case reflect.Struct: case reflect.Struct:
if fe.Type() != reflect.TypeOf(time.Time{}) { if fe.Type() != reflect.TypeOf(time.Time{}) {
err = fmt.Errorf("tag '%s' cannot be used on a struct type.", fe.Tag()) err = fmt.Errorf("tag '%s' cannot be used on a struct type", fe.Tag())
goto END
} }
t, err = ut.T("gte-datetime", fe.Field()) t, err = ut.T("gte-datetime", fe.Field())

@ -429,7 +429,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
case reflect.Struct: case reflect.Struct:
if fe.Type() != reflect.TypeOf(time.Time{}) { if fe.Type() != reflect.TypeOf(time.Time{}) {
err = fmt.Errorf("tag '%s' cannot be used on a struct type.", fe.Tag()) err = fmt.Errorf("tag '%s' cannot be used on a struct type", fe.Tag())
goto END
} }
t, err = ut.T("lt-datetime", fe.Field()) t, err = ut.T("lt-datetime", fe.Field())
@ -548,7 +549,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
case reflect.Struct: case reflect.Struct:
if fe.Type() != reflect.TypeOf(time.Time{}) { if fe.Type() != reflect.TypeOf(time.Time{}) {
err = fmt.Errorf("tag '%s' cannot be used on a struct type.", fe.Tag()) err = fmt.Errorf("tag '%s' cannot be used on a struct type", fe.Tag())
goto END
} }
t, err = ut.T("lte-datetime", fe.Field()) t, err = ut.T("lte-datetime", fe.Field())
@ -667,7 +669,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
case reflect.Struct: case reflect.Struct:
if fe.Type() != reflect.TypeOf(time.Time{}) { if fe.Type() != reflect.TypeOf(time.Time{}) {
err = fmt.Errorf("tag '%s' cannot be used on a struct type.", fe.Tag()) err = fmt.Errorf("tag '%s' cannot be used on a struct type", fe.Tag())
goto END
} }
t, err = ut.T("gt-datetime", fe.Field()) t, err = ut.T("gt-datetime", fe.Field())
@ -786,7 +789,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
case reflect.Struct: case reflect.Struct:
if fe.Type() != reflect.TypeOf(time.Time{}) { if fe.Type() != reflect.TypeOf(time.Time{}) {
err = fmt.Errorf("tag '%s' cannot be used on a struct type.", fe.Tag()) err = fmt.Errorf("tag '%s' cannot be used on a struct type", fe.Tag())
goto END
} }
t, err = ut.T("gte-datetime", fe.Field()) t, err = ut.T("gte-datetime", fe.Field())

@ -429,7 +429,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
case reflect.Struct: case reflect.Struct:
if fe.Type() != reflect.TypeOf(time.Time{}) { if fe.Type() != reflect.TypeOf(time.Time{}) {
err = fmt.Errorf("a tag '%s' não pode ser usada em uma struct type.", fe.Tag()) err = fmt.Errorf("a tag '%s' não pode ser usada em uma struct type", fe.Tag())
goto END
} }
t, err = ut.T("lt-datetime", fe.Field()) t, err = ut.T("lt-datetime", fe.Field())
@ -548,7 +549,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
case reflect.Struct: case reflect.Struct:
if fe.Type() != reflect.TypeOf(time.Time{}) { if fe.Type() != reflect.TypeOf(time.Time{}) {
err = fmt.Errorf("a tag '%s' não pode ser usado em uma struct type.", fe.Tag()) err = fmt.Errorf("a tag '%s' não pode ser usado em uma struct type", fe.Tag())
goto END
} }
t, err = ut.T("lte-datetime", fe.Field()) t, err = ut.T("lte-datetime", fe.Field())
@ -667,7 +669,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
case reflect.Struct: case reflect.Struct:
if fe.Type() != reflect.TypeOf(time.Time{}) { if fe.Type() != reflect.TypeOf(time.Time{}) {
err = fmt.Errorf("a tag '%s' não pode ser usado em uma struct type.", fe.Tag()) err = fmt.Errorf("a tag '%s' não pode ser usado em uma struct type", fe.Tag())
goto END
} }
t, err = ut.T("gt-datetime", fe.Field()) t, err = ut.T("gt-datetime", fe.Field())
@ -786,7 +789,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
case reflect.Struct: case reflect.Struct:
if fe.Type() != reflect.TypeOf(time.Time{}) { if fe.Type() != reflect.TypeOf(time.Time{}) {
err = fmt.Errorf("a tag '%s' não pode ser usado em uma struct type.", fe.Tag()) err = fmt.Errorf("a tag '%s' não pode ser usado em uma struct type", fe.Tag())
goto END
} }
t, err = ut.T("gte-datetime", fe.Field()) t, err = ut.T("gte-datetime", fe.Field())

@ -213,8 +213,8 @@ func (v *validate) traverseField(ctx context.Context, parent reflect.Value, curr
CONTINUE: CONTINUE:
// if len == 0 then validating using 'Var' or 'VarWithValue' // if len == 0 then validating using 'Var' or 'VarWithValue'
// Var - doesn't make much sense to do it that way, should call 'Struct', but no harm... // Var - doesn't make much sense to do it that way, should call 'Struct', but no harm...
// VarWithField - this allows for validating against each field withing the struct against a specific value // VarWithField - this allows for validating against each field within the struct against a specific value
// pretty handly in certain situations // pretty handy in certain situations
if len(cf.name) > 0 { if len(cf.name) > 0 {
ns = append(append(ns, cf.altName...), '.') ns = append(append(ns, cf.altName...), '.')
structNs = append(append(structNs, cf.name...), '.') structNs = append(append(structNs, cf.name...), '.')

@ -97,7 +97,7 @@ func New() *Validate {
for k, val := range bakedInValidators { for k, val := range bakedInValidators {
// no need to error check here, baked in will always be valid // no need to error check here, baked in will always be valid
v.registerValidation(k, wrapFunc(val), true) _ = v.registerValidation(k, wrapFunc(val), true)
} }
v.pool = &sync.Pool{ v.pool = &sync.Pool{
@ -489,7 +489,7 @@ func (v *Validate) StructExceptCtx(ctx context.Context, s interface{}, fields ..
// //
// WARNING: a struct can be passed for validation eg. time.Time is a struct or // WARNING: a struct can be passed for validation eg. time.Time is a struct or
// if you have a custom type and have registered a custom type handler, so must // if you have a custom type and have registered a custom type handler, so must
// allow it; however unforseen validations will occur if trying to validate a // allow it; however unforeseen validations will occur if trying to validate a
// struct that is meant to be passed to 'validate.Struct' // struct that is meant to be passed to 'validate.Struct'
// //
// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise. // It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
@ -507,7 +507,7 @@ func (v *Validate) Var(field interface{}, tag string) error {
// //
// WARNING: a struct can be passed for validation eg. time.Time is a struct or // WARNING: a struct can be passed for validation eg. time.Time is a struct or
// if you have a custom type and have registered a custom type handler, so must // if you have a custom type and have registered a custom type handler, so must
// allow it; however unforseen validations will occur if trying to validate a // allow it; however unforeseen validations will occur if trying to validate a
// struct that is meant to be passed to 'validate.Struct' // struct that is meant to be passed to 'validate.Struct'
// //
// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise. // It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
@ -541,7 +541,7 @@ func (v *Validate) VarCtx(ctx context.Context, field interface{}, tag string) (e
// //
// WARNING: a struct can be passed for validation eg. time.Time is a struct or // WARNING: a struct can be passed for validation eg. time.Time is a struct or
// if you have a custom type and have registered a custom type handler, so must // if you have a custom type and have registered a custom type handler, so must
// allow it; however unforseen validations will occur if trying to validate a // allow it; however unforeseen validations will occur if trying to validate a
// struct that is meant to be passed to 'validate.Struct' // struct that is meant to be passed to 'validate.Struct'
// //
// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise. // It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
@ -560,7 +560,7 @@ func (v *Validate) VarWithValue(field interface{}, other interface{}, tag string
// //
// WARNING: a struct can be passed for validation eg. time.Time is a struct or // WARNING: a struct can be passed for validation eg. time.Time is a struct or
// if you have a custom type and have registered a custom type handler, so must // if you have a custom type and have registered a custom type handler, so must
// allow it; however unforseen validations will occur if trying to validate a // allow it; however unforeseen validations will occur if trying to validate a
// struct that is meant to be passed to 'validate.Struct' // struct that is meant to be passed to 'validate.Struct'
// //
// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise. // It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.

@ -1016,7 +1016,7 @@ func TestCrossStructLteFieldValidation(t *testing.T) {
NotEqual(t, errs, nil) NotEqual(t, errs, nil)
AssertError(t, errs, "", "", "", "", "ltecsfield") AssertError(t, errs, "", "", "", "", "ltecsfield")
// this test is for the WARNING about unforseen validation issues. // this test is for the WARNING about unforeseen validation issues.
errs = validate.VarWithValue(test, now, "ltecsfield") errs = validate.VarWithValue(test, now, "ltecsfield")
NotEqual(t, errs, nil) NotEqual(t, errs, nil)
Equal(t, len(errs.(ValidationErrors)), 6) Equal(t, len(errs.(ValidationErrors)), 6)
@ -1113,7 +1113,7 @@ func TestCrossStructLtFieldValidation(t *testing.T) {
NotEqual(t, errs, nil) NotEqual(t, errs, nil)
AssertError(t, errs, "", "", "", "", "ltcsfield") AssertError(t, errs, "", "", "", "", "ltcsfield")
// this test is for the WARNING about unforseen validation issues. // this test is for the WARNING about unforeseen validation issues.
errs = validate.VarWithValue(test, now, "ltcsfield") errs = validate.VarWithValue(test, now, "ltcsfield")
NotEqual(t, errs, nil) NotEqual(t, errs, nil)
AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "ltcsfield") AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "ltcsfield")
@ -1221,7 +1221,7 @@ func TestCrossStructGteFieldValidation(t *testing.T) {
NotEqual(t, errs, nil) NotEqual(t, errs, nil)
AssertError(t, errs, "", "", "", "", "gtecsfield") AssertError(t, errs, "", "", "", "", "gtecsfield")
// this test is for the WARNING about unforseen validation issues. // this test is for the WARNING about unforeseen validation issues.
errs = validate.VarWithValue(test, now, "gtecsfield") errs = validate.VarWithValue(test, now, "gtecsfield")
NotEqual(t, errs, nil) NotEqual(t, errs, nil)
AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "gtecsfield") AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "gtecsfield")
@ -1317,7 +1317,7 @@ func TestCrossStructGtFieldValidation(t *testing.T) {
NotEqual(t, errs, nil) NotEqual(t, errs, nil)
AssertError(t, errs, "", "", "", "", "gtcsfield") AssertError(t, errs, "", "", "", "", "gtcsfield")
// this test is for the WARNING about unforseen validation issues. // this test is for the WARNING about unforeseen validation issues.
errs = validate.VarWithValue(test, now, "gtcsfield") errs = validate.VarWithValue(test, now, "gtcsfield")
NotEqual(t, errs, nil) NotEqual(t, errs, nil)
AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "gtcsfield") AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "gtcsfield")
@ -4432,8 +4432,8 @@ func TestBase64URLValidation(t *testing.T) {
if tc.success { if tc.success {
Equal(t, err, nil) Equal(t, err, nil)
// make sure encoded value is decoded back to the expected value // make sure encoded value is decoded back to the expected value
d, err := base64.URLEncoding.DecodeString(tc.encoded) d, innerErr := base64.URLEncoding.DecodeString(tc.encoded)
Equal(t, err, nil) Equal(t, innerErr, nil)
Equal(t, tc.decoded, string(d)) Equal(t, tc.decoded, string(d))
} else { } else {
NotEqual(t, err, nil) NotEqual(t, err, nil)
@ -6838,8 +6838,8 @@ func TestTranslations(t *testing.T) {
}, func(ut ut.Translator, fe FieldError) string { }, func(ut ut.Translator, fe FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field()) t, transErr := ut.T(fe.Tag(), fe.Field())
if err != nil { if transErr != nil {
fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError)) fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError))
return fe.(*fieldError).Error() return fe.(*fieldError).Error()
} }
@ -7835,7 +7835,7 @@ func TestKeys(t *testing.T) {
// test bad tag definitions // test bad tag definitions
PanicMatches(t, func() { validate.Var(map[string]string{"key": "val"}, "endkeys,dive,eq=val") }, "'endkeys' tag encountered without a corresponding 'keys' tag") PanicMatches(t, func() { validate.Var(map[string]string{"key": "val"}, "endkeys,dive,eq=val") }, "'endkeys' tag encountered without a corresponding 'keys' tag")
PanicMatches(t, func() { validate.Var(1, "keys,eq=1,endkeys") }, "'keys' tag must be immediately preceeded by the 'dive' tag") PanicMatches(t, func() { validate.Var(1, "keys,eq=1,endkeys") }, "'keys' tag must be immediately preceded by the 'dive' tag")
// test custom tag name // test custom tag name
validate = New() validate = New()

Loading…
Cancel
Save