diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..aeeee9d --- /dev/null +++ b/Makefile @@ -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 \ No newline at end of file diff --git a/README.md b/README.md index 7bc80b4..6ef0cc6 100644 --- a/README.md +++ b/README.md @@ -66,71 +66,73 @@ Please see http://godoc.org/gopkg.in/go-playground/validator.v9 for detailed usa 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 goos: darwin goarch: amd64 pkg: github.com/go-playground/validator -BenchmarkFieldSuccess-8 20000000 86.4 ns/op 0 B/op 0 allocs/op -BenchmarkFieldSuccessParallel-8 50000000 27.6 ns/op 0 B/op 0 allocs/op -BenchmarkFieldFailure-8 5000000 297 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 -BenchmarkFieldArrayDiveSuccessParallel-8 10000000 225 ns/op 201 B/op 11 allocs/op -BenchmarkFieldArrayDiveFailure-8 2000000 863 ns/op 412 B/op 16 allocs/op -BenchmarkFieldArrayDiveFailureParallel-8 5000000 322 ns/op 413 B/op 16 allocs/op -BenchmarkFieldMapDiveSuccess-8 1000000 1336 ns/op 432 B/op 18 allocs/op -BenchmarkFieldMapDiveSuccessParallel-8 3000000 474 ns/op 432 B/op 18 allocs/op -BenchmarkFieldMapDiveFailure-8 1000000 1103 ns/op 512 B/op 16 allocs/op -BenchmarkFieldMapDiveFailureParallel-8 5000000 412 ns/op 512 B/op 16 allocs/op -BenchmarkFieldMapDiveWithKeysSuccess-8 1000000 1572 ns/op 480 B/op 21 allocs/op -BenchmarkFieldMapDiveWithKeysSuccessParallel-8 3000000 615 ns/op 480 B/op 21 allocs/op -BenchmarkFieldMapDiveWithKeysFailure-8 1000000 1438 ns/op 721 B/op 21 allocs/op -BenchmarkFieldMapDiveWithKeysFailureParallel-8 3000000 543 ns/op 721 B/op 21 allocs/op -BenchmarkFieldCustomTypeSuccess-8 10000000 230 ns/op 32 B/op 2 allocs/op -BenchmarkFieldCustomTypeSuccessParallel-8 20000000 82.5 ns/op 32 B/op 2 allocs/op -BenchmarkFieldCustomTypeFailure-8 5000000 284 ns/op 208 B/op 4 allocs/op -BenchmarkFieldCustomTypeFailureParallel-8 20000000 118 ns/op 208 B/op 4 allocs/op -BenchmarkFieldOrTagSuccess-8 2000000 824 ns/op 16 B/op 1 allocs/op -BenchmarkFieldOrTagSuccessParallel-8 3000000 472 ns/op 16 B/op 1 allocs/op -BenchmarkFieldOrTagFailure-8 3000000 487 ns/op 224 B/op 5 allocs/op -BenchmarkFieldOrTagFailureParallel-8 5000000 405 ns/op 224 B/op 5 allocs/op -BenchmarkStructLevelValidationSuccess-8 10000000 214 ns/op 32 B/op 2 allocs/op -BenchmarkStructLevelValidationSuccessParallel-8 20000000 78.0 ns/op 32 B/op 2 allocs/op -BenchmarkStructLevelValidationFailure-8 3000000 475 ns/op 304 B/op 8 allocs/op -BenchmarkStructLevelValidationFailureParallel-8 10000000 200 ns/op 304 B/op 8 allocs/op -BenchmarkStructSimpleCustomTypeSuccess-8 3000000 403 ns/op 32 B/op 2 allocs/op -BenchmarkStructSimpleCustomTypeSuccessParallel-8 10000000 143 ns/op 32 B/op 2 allocs/op -BenchmarkStructSimpleCustomTypeFailure-8 2000000 655 ns/op 424 B/op 9 allocs/op -BenchmarkStructSimpleCustomTypeFailureParallel-8 5000000 286 ns/op 440 B/op 10 allocs/op -BenchmarkStructFilteredSuccess-8 2000000 598 ns/op 288 B/op 9 allocs/op -BenchmarkStructFilteredSuccessParallel-8 10000000 231 ns/op 288 B/op 9 allocs/op -BenchmarkStructFilteredFailure-8 3000000 455 ns/op 256 B/op 7 allocs/op -BenchmarkStructFilteredFailureParallel-8 10000000 197 ns/op 256 B/op 7 allocs/op -BenchmarkStructPartialSuccess-8 3000000 552 ns/op 256 B/op 6 allocs/op -BenchmarkStructPartialSuccessParallel-8 10000000 206 ns/op 256 B/op 6 allocs/op -BenchmarkStructPartialFailure-8 2000000 750 ns/op 480 B/op 11 allocs/op -BenchmarkStructPartialFailureParallel-8 5000000 317 ns/op 480 B/op 11 allocs/op -BenchmarkStructExceptSuccess-8 2000000 853 ns/op 496 B/op 12 allocs/op -BenchmarkStructExceptSuccessParallel-8 10000000 179 ns/op 240 B/op 5 allocs/op -BenchmarkStructExceptFailure-8 2000000 698 ns/op 464 B/op 10 allocs/op -BenchmarkStructExceptFailureParallel-8 5000000 276 ns/op 464 B/op 10 allocs/op -BenchmarkStructSimpleCrossFieldSuccess-8 3000000 412 ns/op 72 B/op 3 allocs/op -BenchmarkStructSimpleCrossFieldSuccessParallel-8 10000000 148 ns/op 72 B/op 3 allocs/op -BenchmarkStructSimpleCrossFieldFailure-8 2000000 630 ns/op 304 B/op 8 allocs/op -BenchmarkStructSimpleCrossFieldFailureParallel-8 10000000 244 ns/op 304 B/op 8 allocs/op -BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 2000000 610 ns/op 80 B/op 4 allocs/op -BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 10000000 205 ns/op 80 B/op 4 allocs/op -BenchmarkStructSimpleCrossStructCrossFieldFailure-8 2000000 861 ns/op 320 B/op 9 allocs/op -BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 5000000 315 ns/op 320 B/op 9 allocs/op -BenchmarkStructSimpleSuccess-8 5000000 279 ns/op 0 B/op 0 allocs/op -BenchmarkStructSimpleSuccessParallel-8 20000000 86.4 ns/op 0 B/op 0 allocs/op -BenchmarkStructSimpleFailure-8 2000000 636 ns/op 424 B/op 9 allocs/op -BenchmarkStructSimpleFailureParallel-8 10000000 264 ns/op 424 B/op 9 allocs/op -BenchmarkStructComplexSuccess-8 1000000 1539 ns/op 128 B/op 8 allocs/op -BenchmarkStructComplexSuccessParallel-8 3000000 557 ns/op 128 B/op 8 allocs/op -BenchmarkStructComplexFailure-8 300000 4136 ns/op 3041 B/op 53 allocs/op -BenchmarkStructComplexFailureParallel-8 1000000 1855 ns/op 3041 B/op 53 allocs/op +BenchmarkFieldSuccess-8 20000000 83.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 291 ns/op 208 B/op 4 allocs/op +BenchmarkFieldFailureParallel-8 20000000 107 ns/op 208 B/op 4 allocs/op +BenchmarkFieldArrayDiveSuccess-8 2000000 623 ns/op 201 B/op 11 allocs/op +BenchmarkFieldArrayDiveSuccessParallel-8 10000000 237 ns/op 201 B/op 11 allocs/op +BenchmarkFieldArrayDiveFailure-8 2000000 859 ns/op 412 B/op 16 allocs/op +BenchmarkFieldArrayDiveFailureParallel-8 5000000 335 ns/op 413 B/op 16 allocs/op +BenchmarkFieldMapDiveSuccess-8 1000000 1292 ns/op 432 B/op 18 allocs/op +BenchmarkFieldMapDiveSuccessParallel-8 3000000 467 ns/op 432 B/op 18 allocs/op +BenchmarkFieldMapDiveFailure-8 1000000 1082 ns/op 512 B/op 16 allocs/op +BenchmarkFieldMapDiveFailureParallel-8 5000000 425 ns/op 512 B/op 16 allocs/op +BenchmarkFieldMapDiveWithKeysSuccess-8 1000000 1539 ns/op 480 B/op 21 allocs/op +BenchmarkFieldMapDiveWithKeysSuccessParallel-8 3000000 613 ns/op 480 B/op 21 allocs/op +BenchmarkFieldMapDiveWithKeysFailure-8 1000000 1413 ns/op 721 B/op 21 allocs/op +BenchmarkFieldMapDiveWithKeysFailureParallel-8 3000000 575 ns/op 721 B/op 21 allocs/op +BenchmarkFieldCustomTypeSuccess-8 10000000 216 ns/op 32 B/op 2 allocs/op +BenchmarkFieldCustomTypeSuccessParallel-8 20000000 82.2 ns/op 32 B/op 2 allocs/op +BenchmarkFieldCustomTypeFailure-8 5000000 274 ns/op 208 B/op 4 allocs/op +BenchmarkFieldCustomTypeFailureParallel-8 20000000 116 ns/op 208 B/op 4 allocs/op +BenchmarkFieldOrTagSuccess-8 2000000 740 ns/op 16 B/op 1 allocs/op +BenchmarkFieldOrTagSuccessParallel-8 3000000 474 ns/op 16 B/op 1 allocs/op +BenchmarkFieldOrTagFailure-8 3000000 471 ns/op 224 B/op 5 allocs/op +BenchmarkFieldOrTagFailureParallel-8 3000000 414 ns/op 224 B/op 5 allocs/op +BenchmarkStructLevelValidationSuccess-8 10000000 213 ns/op 32 B/op 2 allocs/op +BenchmarkStructLevelValidationSuccessParallel-8 20000000 91.8 ns/op 32 B/op 2 allocs/op +BenchmarkStructLevelValidationFailure-8 3000000 473 ns/op 304 B/op 8 allocs/op +BenchmarkStructLevelValidationFailureParallel-8 10000000 234 ns/op 304 B/op 8 allocs/op +BenchmarkStructSimpleCustomTypeSuccess-8 5000000 385 ns/op 32 B/op 2 allocs/op +BenchmarkStructSimpleCustomTypeSuccessParallel-8 10000000 161 ns/op 32 B/op 2 allocs/op +BenchmarkStructSimpleCustomTypeFailure-8 2000000 640 ns/op 424 B/op 9 allocs/op +BenchmarkStructSimpleCustomTypeFailureParallel-8 5000000 318 ns/op 440 B/op 10 allocs/op +BenchmarkStructFilteredSuccess-8 2000000 597 ns/op 288 B/op 9 allocs/op +BenchmarkStructFilteredSuccessParallel-8 10000000 266 ns/op 288 B/op 9 allocs/op +BenchmarkStructFilteredFailure-8 3000000 454 ns/op 256 B/op 7 allocs/op +BenchmarkStructFilteredFailureParallel-8 10000000 214 ns/op 256 B/op 7 allocs/op +BenchmarkStructPartialSuccess-8 3000000 502 ns/op 256 B/op 6 allocs/op +BenchmarkStructPartialSuccessParallel-8 10000000 225 ns/op 256 B/op 6 allocs/op +BenchmarkStructPartialFailure-8 2000000 702 ns/op 480 B/op 11 allocs/op +BenchmarkStructPartialFailureParallel-8 5000000 329 ns/op 480 B/op 11 allocs/op +BenchmarkStructExceptSuccess-8 2000000 793 ns/op 496 B/op 12 allocs/op +BenchmarkStructExceptSuccessParallel-8 10000000 193 ns/op 240 B/op 5 allocs/op +BenchmarkStructExceptFailure-8 2000000 639 ns/op 464 B/op 10 allocs/op +BenchmarkStructExceptFailureParallel-8 5000000 300 ns/op 464 B/op 10 allocs/op +BenchmarkStructSimpleCrossFieldSuccess-8 3000000 417 ns/op 72 B/op 3 allocs/op +BenchmarkStructSimpleCrossFieldSuccessParallel-8 10000000 163 ns/op 72 B/op 3 allocs/op +BenchmarkStructSimpleCrossFieldFailure-8 2000000 645 ns/op 304 B/op 8 allocs/op +BenchmarkStructSimpleCrossFieldFailureParallel-8 5000000 285 ns/op 304 B/op 8 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 3000000 588 ns/op 80 B/op 4 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 10000000 221 ns/op 80 B/op 4 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldFailure-8 2000000 868 ns/op 320 B/op 9 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 5000000 337 ns/op 320 B/op 9 allocs/op +BenchmarkStructSimpleSuccess-8 5000000 260 ns/op 0 B/op 0 allocs/op +BenchmarkStructSimpleSuccessParallel-8 20000000 90.6 ns/op 0 B/op 0 allocs/op +BenchmarkStructSimpleFailure-8 2000000 619 ns/op 424 B/op 9 allocs/op +BenchmarkStructSimpleFailureParallel-8 5000000 296 ns/op 424 B/op 9 allocs/op +BenchmarkStructComplexSuccess-8 1000000 1454 ns/op 128 B/op 8 allocs/op +BenchmarkStructComplexSuccessParallel-8 3000000 579 ns/op 128 B/op 8 allocs/op +BenchmarkStructComplexFailure-8 300000 4140 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 diff --git a/baked_in.go b/baked_in.go index d3730ca..64b71cb 100644 --- a/baked_in.go +++ b/baked_in.go @@ -440,10 +440,10 @@ func isBitcoinAddress(fl FieldLevel) bool { } h := sha256.New() - h.Write(decode[:21]) + _, _ = h.Write(decode[:21]) d := h.Sum([]byte{}) h = sha256.New() - h.Write(d) + _, _ = h.Write(d) validchecksum := [4]byte{} computedchecksum := [4]byte{} @@ -458,13 +458,13 @@ func isBitcoinAddress(fl FieldLevel) bool { func isBitcoinBech32Address(fl FieldLevel) bool { address := fl.Field().String() - if !btcLowerAddressRegexBech32.MatchString(address) && !btcUpperAddressRegexBech32.MatchString(address){ + if !btcLowerAddressRegexBech32.MatchString(address) && !btcUpperAddressRegexBech32.MatchString(address) { return false } am := len(address) % 8 - if am == 0 || am == 3 || am == 5{ + if am == 0 || am == 3 || am == 5 { return false } @@ -473,15 +473,16 @@ func isBitcoinBech32Address(fl FieldLevel) bool { alphabet := "qpzry9x8gf2tvdw0s3jn54khce6mua7l" 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)) } ver := dp[0] - if ver < 0 || ver > 16{ + if ver < 0 || ver > 16 { return false } @@ -493,16 +494,16 @@ func isBitcoinBech32Address(fl FieldLevel) bool { values := append(hr, dp...) - GEN := []int{ 0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3 } + GEN := []int{0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3} p := 1 for _, v := range values { b := p >> 25 - p = (p & 0x1ffffff) << 5 ^ v + p = (p&0x1ffffff)<<5 ^ v for i := 0; i < 5; i++ { - if (b >> uint(i)) & 1 == 1 { + if (b>>uint(i))&1 == 1 { p ^= GEN[i] } } @@ -515,18 +516,18 @@ func isBitcoinBech32Address(fl FieldLevel) bool { b := uint(0) acc := 0 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 b += 5 - for b >= 8{ + for b >= 8 { b -= 8 sw = append(sw, (acc>>b)&mv) } } - if len(sw) < 2 || len(sw) > 40{ + if len(sw) < 2 || len(sw) > 40 { return false } diff --git a/cache.go b/cache.go index c7fb0fb..a7a4202 100644 --- a/cache.go +++ b/cache.go @@ -223,7 +223,7 @@ func (v *Validate) parseFieldTagsRecursive(tag string, fieldName string, alias s current.typeof = typeKeys 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 diff --git a/doc.go b/doc.go index 602fdc8..6eef72c 100644 --- a/doc.go +++ b/doc.go @@ -168,7 +168,7 @@ StructOnly 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 -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. 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 -This validates that a string value contains a valid IP Adress. +This validates that a string value contains a valid IP Address. Usage: ip 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 @@ -913,7 +913,7 @@ Validator notes: of a regex which conflict with the validation definitions. Although 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 - 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. In place of this new validator functions should be created; a regex can diff --git a/field_level.go b/field_level.go index 6d73192..cbfbc15 100644 --- a/field_level.go +++ b/field_level.go @@ -17,7 +17,7 @@ type FieldLevel interface { Field() reflect.Value // 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 // returns the struct field's name diff --git a/translations.go b/translations.go index 4465abb..4d9d75c 100644 --- a/translations.go +++ b/translations.go @@ -7,5 +7,5 @@ import ut "github.com/go-playground/universal-translator" type TranslationFunc func(ut ut.Translator, fe FieldError) string // 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 diff --git a/translations/en/en.go b/translations/en/en.go index 3ac1c47..f38fa1a 100644 --- a/translations/en/en.go +++ b/translations/en/en.go @@ -429,7 +429,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er case reflect.Struct: 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()) @@ -548,7 +549,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er case reflect.Struct: 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()) @@ -667,7 +669,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er case reflect.Struct: 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()) @@ -786,7 +789,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er case reflect.Struct: 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()) diff --git a/translations/fr/fr.go b/translations/fr/fr.go index 871cf5f..1bf5dae 100644 --- a/translations/fr/fr.go +++ b/translations/fr/fr.go @@ -429,7 +429,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er case reflect.Struct: 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()) @@ -548,7 +549,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er case reflect.Struct: 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()) @@ -667,7 +669,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er case reflect.Struct: 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()) @@ -786,7 +789,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er case reflect.Struct: 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()) diff --git a/translations/pt_BR/pt_BR.go b/translations/pt_BR/pt_BR.go index 13a00bd..dcb223d 100644 --- a/translations/pt_BR/pt_BR.go +++ b/translations/pt_BR/pt_BR.go @@ -429,7 +429,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er case reflect.Struct: 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()) @@ -548,7 +549,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er case reflect.Struct: 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()) @@ -667,7 +669,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er case reflect.Struct: 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()) @@ -786,7 +789,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er case reflect.Struct: 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()) diff --git a/validator.go b/validator.go index 483e0a2..67473f1 100644 --- a/validator.go +++ b/validator.go @@ -213,8 +213,8 @@ func (v *validate) traverseField(ctx context.Context, parent reflect.Value, curr CONTINUE: // 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... - // VarWithField - this allows for validating against each field withing the struct against a specific value - // pretty handly in certain situations + // VarWithField - this allows for validating against each field within the struct against a specific value + // pretty handy in certain situations if len(cf.name) > 0 { ns = append(append(ns, cf.altName...), '.') structNs = append(append(structNs, cf.name...), '.') diff --git a/validator_instance.go b/validator_instance.go index e84b452..a07e4e2 100644 --- a/validator_instance.go +++ b/validator_instance.go @@ -97,7 +97,7 @@ func New() *Validate { for k, val := range bakedInValidators { // 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{ @@ -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 // 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' // // 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 // 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' // // 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 // 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' // // 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 // 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' // // It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise. diff --git a/validator_test.go b/validator_test.go index fd80b8d..ae38537 100644 --- a/validator_test.go +++ b/validator_test.go @@ -1016,7 +1016,7 @@ func TestCrossStructLteFieldValidation(t *testing.T) { NotEqual(t, errs, nil) 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") NotEqual(t, errs, nil) Equal(t, len(errs.(ValidationErrors)), 6) @@ -1113,7 +1113,7 @@ func TestCrossStructLtFieldValidation(t *testing.T) { NotEqual(t, errs, nil) 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") NotEqual(t, errs, nil) AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "ltcsfield") @@ -1221,7 +1221,7 @@ func TestCrossStructGteFieldValidation(t *testing.T) { NotEqual(t, errs, nil) 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") NotEqual(t, errs, nil) AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "gtecsfield") @@ -1317,7 +1317,7 @@ func TestCrossStructGtFieldValidation(t *testing.T) { NotEqual(t, errs, nil) 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") NotEqual(t, errs, nil) AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "gtcsfield") @@ -4432,8 +4432,8 @@ func TestBase64URLValidation(t *testing.T) { if tc.success { Equal(t, err, nil) // make sure encoded value is decoded back to the expected value - d, err := base64.URLEncoding.DecodeString(tc.encoded) - Equal(t, err, nil) + d, innerErr := base64.URLEncoding.DecodeString(tc.encoded) + Equal(t, innerErr, nil) Equal(t, tc.decoded, string(d)) } else { NotEqual(t, err, nil) @@ -6838,8 +6838,8 @@ func TestTranslations(t *testing.T) { }, func(ut ut.Translator, fe FieldError) string { - t, err := ut.T(fe.Tag(), fe.Field()) - if err != nil { + t, transErr := ut.T(fe.Tag(), fe.Field()) + if transErr != nil { fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError)) return fe.(*fieldError).Error() } @@ -7835,7 +7835,7 @@ func TestKeys(t *testing.T) { // 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(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 validate = New()