Compare commits

..

4 Commits

Author SHA1 Message Date
Dean Karn 96d7f70a71 fix indentation 4 years ago
Dean Karn 793791d72b fix yaml 4 years ago
Dean Karn ce708b121e move linting to separate job 4 years ago
Dean Karn e3a9ac5b17 restore cache on all but ubuntu and latest go 4 years ago
  1. 1
      .github/CODEOWNERS
  2. 3
      .github/ISSUE_TEMPLATE.md
  3. 2
      .github/PULL_REQUEST_TEMPLATE.md
  4. 19
      .github/workflows/workflow.yml
  5. 1
      .gitignore
  6. 16
      MAINTAINERS.md
  7. 4
      Makefile
  8. 83
      README.md
  9. 87
      _examples/map-validation/main.go
  10. 80
      _examples/struct-level/main.go
  11. 92
      _examples/struct-map-rules-validation/main.go
  12. 1262
      baked_in.go
  13. 7
      cache.go
  14. 976
      country_codes.go
  15. 79
      currency_codes.go
  16. 449
      doc.go
  17. 27
      errors.go
  18. 23
      field_level.go
  19. 15
      go.mod
  20. 49
      go.sum
  21. 2
      non-standard/validators/notblank.go
  22. 4
      non-standard/validators/notblank_test.go
  23. 173
      postcode_regexes.go
  24. 58
      regexes.go
  25. 12
      struct_level.go
  26. 1389
      translations/ar/ar.go
  27. 695
      translations/ar/ar_test.go
  28. 119
      translations/en/en.go
  29. 48
      translations/en/en_test.go
  30. 10
      translations/es/es.go
  31. 8
      translations/es/es_test.go
  32. 1384
      translations/fa/fa.go
  33. 690
      translations/fa/fa_test.go
  34. 5
      translations/fr/fr.go
  35. 13
      translations/fr/fr_test.go
  36. 5
      translations/id/id.go
  37. 7
      translations/id/id_test.go
  38. 1261
      translations/it/it.go
  39. 725
      translations/it/it_test.go
  40. 129
      translations/ja/ja.go
  41. 302
      translations/ja/ja_test.go
  42. 1399
      translations/lv/lv.go
  43. 709
      translations/lv/lv_test.go
  44. 5
      translations/nl/nl.go
  45. 7
      translations/nl/nl_test.go
  46. 5
      translations/pt/pt.go
  47. 5
      translations/pt/pt_test.go
  48. 17
      translations/pt_BR/pt_BR.go
  49. 25
      translations/pt_BR/pt_BR_test.go
  50. 118
      translations/ru/ru.go
  51. 379
      translations/ru/ru_test.go
  52. 5
      translations/tr/tr.go
  53. 7
      translations/tr/tr_test.go
  54. 1384
      translations/vi/vi.go
  55. 690
      translations/vi/vi_test.go
  56. 90
      translations/zh/zh.go
  57. 257
      translations/zh/zh_test.go
  58. 5
      translations/zh_tw/zh_tw.go
  59. 5
      translations/zh_tw/zh_tw_test.go
  60. 2
      util.go
  61. 18
      validator.go
  62. 113
      validator_instance.go
  63. 7329
      validator_test.go

@ -1 +0,0 @@
* @go-playground/validator-maintainers

@ -1,6 +1,3 @@
- [ ] I have looked at the documentation [here](https://pkg.go.dev/github.com/go-playground/validator/v10#section-documentation) first?
- [ ] I have looked at the examples provided that may showcase my question [here](/_examples)?
### Package version eg. v9, v10: ### Package version eg. v9, v10:

@ -4,4 +4,4 @@
**Make sure that you've checked the boxes below before you submit PR:** **Make sure that you've checked the boxes below before you submit PR:**
- [ ] Tests exist or have been written that cover this particular change. - [ ] Tests exist or have been written that cover this particular change.
@go-playground/validator-maintainers @go-playground/admins

@ -8,20 +8,20 @@ jobs:
test: test:
strategy: strategy:
matrix: matrix:
go-version: [1.19.x] go-version: [1.14.x, 1.15.x]
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- name: Install Go - name: Install Go
uses: actions/setup-go@v3 uses: actions/setup-go@v2
with: with:
go-version: ${{ matrix.go-version }} go-version: ${{ matrix.go-version }}
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v2
- name: Restore Cache - name: Restore Cache
uses: actions/cache@v3 uses: actions/cache@v2
with: with:
path: ~/go/pkg/mod path: ~/go/pkg/mod
key: ${{ runner.os }}-v1-go-${{ hashFiles('**/go.sum') }} key: ${{ runner.os }}-v1-go-${{ hashFiles('**/go.sum') }}
@ -32,7 +32,7 @@ jobs:
run: go test -race -covermode=atomic -coverprofile="profile.cov" ./... run: go test -race -covermode=atomic -coverprofile="profile.cov" ./...
- name: Send Coverage - name: Send Coverage
if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.19.x' if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.15.x'
uses: shogo82148/actions-goveralls@v1 uses: shogo82148/actions-goveralls@v1
with: with:
path-to-profile: profile.cov path-to-profile: profile.cov
@ -41,11 +41,8 @@ jobs:
name: lint name: lint
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/setup-go@v3 - uses: actions/checkout@v2
with:
go-version: 1.19.x
- uses: actions/checkout@v3
- name: golangci-lint - name: golangci-lint
uses: golangci/golangci-lint-action@v3 uses: golangci/golangci-lint-action@v2
with: with:
version: v1.50.1 version: v1.31

1
.gitignore vendored

@ -28,4 +28,3 @@ _testmain.go
*.txt *.txt
cover.html cover.html
README.html README.html
.idea

@ -1,16 +0,0 @@
## Maintainers Guide
### Semantic Versioning
Semantic versioning as defined [here](https://semver.org) must be strictly adhered to.
### External Dependencies
Any new external dependencies MUST:
- Have a compatible LICENSE present.
- Be actively maintained.
- Be approved by @go-playground/admins
### PR Merge Requirements
- Up-to-date branch.
- Passing tests and linting.
- CODEOWNERS approval.
- Tests that cover both the Happy and Unhappy paths.

@ -3,11 +3,11 @@ GOCMD=GO111MODULE=on go
linters-install: linters-install:
@golangci-lint --version >/dev/null 2>&1 || { \ @golangci-lint --version >/dev/null 2>&1 || { \
echo "installing linting tools..."; \ echo "installing linting tools..."; \
curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v1.41.1; \ curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v1.21.0; \
} }
lint: linters-install lint: linters-install
golangci-lint run $(PWD)/bin/golangci-lint run
test: test:
$(GOCMD) test -cover -race ./... $(GOCMD) test -cover -race ./...

@ -1,7 +1,7 @@
Package validator Package validator
================= ================
<img align="right" src="https://raw.githubusercontent.com/go-playground/validator/v10/logo.png">[![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) <img align="right" src="https://raw.githubusercontent.com/go-playground/validator/v9/logo.png">[![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
![Project status](https://img.shields.io/badge/version-10.12.0-green.svg) ![Project status](https://img.shields.io/badge/version-10.4.1-green.svg)
[![Build Status](https://travis-ci.org/go-playground/validator.svg?branch=master)](https://travis-ci.org/go-playground/validator) [![Build Status](https://travis-ci.org/go-playground/validator.svg?branch=master)](https://travis-ci.org/go-playground/validator)
[![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=master&service=github)](https://coveralls.io/github/go-playground/validator?branch=master) [![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=master&service=github)](https://coveralls.io/github/go-playground/validator?branch=master)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator) [![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator)
@ -43,7 +43,7 @@ They return type error to avoid the issue discussed in the following, where err
* http://stackoverflow.com/a/29138676/3158232 * http://stackoverflow.com/a/29138676/3158232
* https://github.com/go-playground/validator/issues/134 * https://github.com/go-playground/validator/issues/134
Validator returns only InvalidValidationError for bad validation input, nil or ValidationErrors as type error; so, in your code all you need to do is check if the error returned is not nil, and if it's not check if error is InvalidValidationError ( if necessary, most of the time it isn't ) type cast it to type ValidationErrors like so: Validator only InvalidValidationError for bad validation input, nil or ValidationErrors as type error; so, in your code all you need to do is check if the error returned is not nil, and if it's not check if error is InvalidValidationError ( if necessary, most of the time it isn't ) type cast it to type ValidationErrors like so:
```go ```go
err := validate.Struct(mystruct) err := validate.Struct(mystruct)
@ -53,7 +53,7 @@ validationErrors := err.(validator.ValidationErrors)
Usage and documentation Usage and documentation
------ ------
Please see https://pkg.go.dev/github.com/go-playground/validator/v10 for detailed usage docs. Please see https://godoc.org/github.com/go-playground/validator for detailed usage docs.
##### Examples: ##### Examples:
@ -73,8 +73,8 @@ Baked-in Validations
| - | - | | - | - |
| eqcsfield | Field Equals Another Field (relative)| | eqcsfield | Field Equals Another Field (relative)|
| eqfield | Field Equals Another Field | | eqfield | Field Equals Another Field |
| fieldcontains | Check the indicated characters are present in the Field | | fieldcontains | NOT DOCUMENTED IN doc.go |
| fieldexcludes | Check the indicated characters are not present in the field | | fieldexcludes | NOT DOCUMENTED IN doc.go |
| gtcsfield | Field Greater Than Another Relative Field | | gtcsfield | Field Greater Than Another Relative Field |
| gtecsfield | Field Greater Than or Equal To Another Relative Field | | gtecsfield | Field Greater Than or Equal To Another Relative Field |
| gtefield | Field Greater Than or Equal To Another Field | | gtefield | Field Greater Than or Equal To Another Field |
@ -100,7 +100,7 @@ Baked-in Validations
| hostname_rfc1123 | Hostname RFC 1123 | | hostname_rfc1123 | Hostname RFC 1123 |
| ip | Internet Protocol Address IP | | ip | Internet Protocol Address IP |
| ip4_addr | Internet Protocol Address IPv4 | | ip4_addr | Internet Protocol Address IPv4 |
| ip6_addr | Internet Protocol Address IPv6 | | ip6_addr |Internet Protocol Address IPv6 |
| ip_addr | Internet Protocol Address IP | | ip_addr | Internet Protocol Address IP |
| ipv4 | Internet Protocol Address IPv4 | | ipv4 | Internet Protocol Address IPv4 |
| ipv6 | Internet Protocol Address IPv6 | | ipv6 | Internet Protocol Address IPv6 |
@ -114,7 +114,6 @@ Baked-in Validations
| unix_addr | Unix domain socket end point Address | | unix_addr | Unix domain socket end point Address |
| uri | URI String | | uri | URI String |
| url | URL String | | url | URL String |
| http_url | HTTP URL String |
| url_encoded | URL Encoded | | url_encoded | URL Encoded |
| urn_rfc2141 | Urn RFC 2141 String | | urn_rfc2141 | Urn RFC 2141 String |
@ -127,21 +126,15 @@ Baked-in Validations
| alphanumunicode | Alphanumeric Unicode | | alphanumunicode | Alphanumeric Unicode |
| alphaunicode | Alpha Unicode | | alphaunicode | Alpha Unicode |
| ascii | ASCII | | ascii | ASCII |
| boolean | Boolean |
| contains | Contains | | contains | Contains |
| containsany | Contains Any | | containsany | Contains Any |
| containsrune | Contains Rune | | containsrune | Contains Rune |
| endsnotwith | Ends Not With |
| endswith | Ends With | | endswith | Ends With |
| excludes | Excludes |
| excludesall | Excludes All |
| excludesrune | Excludes Rune |
| lowercase | Lowercase | | lowercase | Lowercase |
| multibyte | Multi-Byte Characters | | multibyte | Multi-Byte Characters |
| number | Number | | number | NOT DOCUMENTED IN doc.go |
| numeric | Numeric | | numeric | Numeric |
| printascii | Printable ASCII | | printascii | Printable ASCII |
| startsnotwith | Starts Not With |
| startswith | Starts With | | startswith | Starts With |
| uppercase | Uppercase | | uppercase | Uppercase |
@ -150,14 +143,8 @@ Baked-in Validations
| - | - | | - | - |
| base64 | Base64 String | | base64 | Base64 String |
| base64url | Base64URL String | | base64url | Base64URL String |
| base64rawurl | Base64RawURL String |
| bic | Business Identifier Code (ISO 9362) |
| bcp47_language_tag | Language tag (BCP 47) |
| btc_addr | Bitcoin Address | | btc_addr | Bitcoin Address |
| btc_addr_bech32 | Bitcoin Bech32 Address (segwit) | | btc_addr_bech32 | Bitcoin Bech32 Address (segwit) |
| credit_card | Credit Card Number |
| mongodb | MongoDB ObjectID |
| cron | Cron |
| datetime | Datetime | | datetime | Datetime |
| e164 | e164 formatted phone number | | e164 | e164 formatted phone number |
| email | E-mail String | email | E-mail String
@ -171,22 +158,12 @@ Baked-in Validations
| isbn | International Standard Book Number | | isbn | International Standard Book Number |
| isbn10 | International Standard Book Number 10 | | isbn10 | International Standard Book Number 10 |
| isbn13 | International Standard Book Number 13 | | isbn13 | International Standard Book Number 13 |
| iso3166_1_alpha2 | Two-letter country code (ISO 3166-1 alpha-2) |
| iso3166_1_alpha3 | Three-letter country code (ISO 3166-1 alpha-3) |
| iso3166_1_alpha_numeric | Numeric country code (ISO 3166-1 numeric) |
| iso3166_2 | Country subdivision code (ISO 3166-2) |
| iso4217 | Currency code (ISO 4217) |
| json | JSON | | json | JSON |
| jwt | JSON Web Token (JWT) |
| latitude | Latitude | | latitude | Latitude |
| longitude | Longitude | | longitude | Longitude |
| luhn_checksum | Luhn Algorithm Checksum (for strings and (u)int) |
| postcode_iso3166_alpha2 | Postcode |
| postcode_iso3166_alpha2_field | Postcode |
| rgb | RGB String | | rgb | RGB String |
| rgba | RGBA String | | rgba | RGBA String |
| ssn | Social Security Number SSN | | ssn | Social Security Number SSN |
| timezone | Timezone |
| uuid | Universally Unique Identifier UUID | | uuid | Universally Unique Identifier UUID |
| uuid3 | Universally Unique Identifier UUID v3 | | uuid3 | Universally Unique Identifier UUID v3 |
| uuid3_rfc4122 | Universally Unique Identifier UUID v3 RFC4122 | | uuid3_rfc4122 | Universally Unique Identifier UUID v3 RFC4122 |
@ -195,39 +172,26 @@ Baked-in Validations
| uuid5 | Universally Unique Identifier UUID v5 | | uuid5 | Universally Unique Identifier UUID v5 |
| uuid5_rfc4122 | Universally Unique Identifier UUID v5 RFC4122 | | uuid5_rfc4122 | Universally Unique Identifier UUID v5 RFC4122 |
| uuid_rfc4122 | Universally Unique Identifier UUID 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 |
| cve | Common Vulnerabilities and Exposures Identifier (CVE id) |
### Comparisons: ### Comparisons:
| Tag | Description | | Tag | Description |
| - | - | | - | - |
| eq | Equals | | eq | Equals |
| eq_ignore_case | Equals ignoring case |
| gt | Greater than| | gt | Greater than|
| gte | Greater than or equal | | gte |Greater than or equal |
| lt | Less Than | | lt | Less Than |
| lte | Less Than or Equal | | lte | Less Than or Equal |
| ne | Not Equal | | ne | Not Equal |
| ne_ignore_case | Not Equal ignoring case |
### Other: ### Other:
| Tag | Description | | Tag | Description |
| - | - | | - | - |
| dir | Existing Directory | | dir | Directory |
| dirpath | Directory Path | | endswith | Ends With |
| file | Existing File | | excludes | Excludes |
| filepath | File Path | | excludesall | Excludes All |
| excludesrune | Excludes Rune |
| file | File path |
| isdefault | Is Default | | isdefault | Is Default |
| len | Length | | len | Length |
| max | Maximum | | max | Maximum |
@ -240,20 +204,12 @@ Baked-in Validations
| required_with_all | Required With All | | required_with_all | Required With All |
| required_without | Required Without | | required_without | Required Without |
| required_without_all | Required Without All | | required_without_all | Required Without All |
| excluded_if | Excluded If |
| excluded_unless | Excluded Unless |
| excluded_with | Excluded With | | excluded_with | Excluded With |
| excluded_with_all | Excluded With All | | excluded_with_all | Excluded With All |
| excluded_without | Excluded Without | | excluded_without | Excluded Without |
| excluded_without_all | Excluded Without All | | excluded_without_all | Excluded Without All |
| unique | Unique | | unique | Unique |
#### Aliases:
| Tag | Description |
| - | - |
| iscolor | hexcolor\|rgb\|rgba\|hsl\|hsla |
| country_code | iso3166_1_alpha2\|iso3166_1_alpha3\|iso3166_1_alpha_numeric |
Benchmarks Benchmarks
------ ------
###### Run on MacBook Pro (15-inch, 2017) go version go1.10.2 darwin/amd64 ###### Run on MacBook Pro (15-inch, 2017) go version go1.10.2 darwin/amd64
@ -339,10 +295,5 @@ How to Contribute
Make a pull request... Make a pull request...
License License
------- ------
Distributed under MIT License, please see license file within the code for more details. Distributed under MIT License, please see license file within the code for more details.
Maintainers
-----------
This project has grown large enough that more than one person is required to properly support the community.
If you are interested in becoming a maintainer please reach out to me https://github.com/deankarn

@ -1,87 +0,0 @@
package main
import (
"fmt"
"github.com/go-playground/validator/v10"
)
var validate *validator.Validate
func main() {
validate = validator.New()
validateMap()
validateNestedMap()
}
func validateMap() {
user := map[string]interface{}{"name": "Arshiya Kiani", "email": "zytel3301@gmail.com"}
// Every rule will be applied to the item of the data that the offset of rule is pointing to.
// So if you have a field "email": "omitempty,required,email", the validator will apply these
// rules to offset of email in user data
rules := map[string]interface{}{"name": "required,min=8,max=32", "email": "omitempty,required,email"}
// ValidateMap will return map[string]error.
// The offset of every item in errs is the name of invalid field and the value
// is the message of error. If there was no error, ValidateMap method will
// return an EMPTY map of errors, not nil. If you want to check that
// if there was an error or not, you must check the length of the return value
errs := validate.ValidateMap(user, rules)
if len(errs) > 0 {
fmt.Println(errs)
// The user is invalid
}
// The user is valid
}
func validateNestedMap() {
data := map[string]interface{}{
"name": "Arshiya Kiani",
"email": "zytel3301@gmail.com",
"details": map[string]interface{}{
"family_members": map[string]interface{}{
"father_name": "Micheal",
"mother_name": "Hannah",
},
"salary": "1000",
"phones": []map[string]interface{}{
{
"number": "11-111-1111",
"remark": "home",
},
{
"number": "22-222-2222",
"remark": "work",
},
},
},
}
// Rules must be set as the structure as the data itself. If you want to dive into the
// map, just declare its rules as a map
rules := map[string]interface{}{
"name": "min=4,max=32",
"email": "required,email",
"details": map[string]interface{}{
"family_members": map[string]interface{}{
"father_name": "required,min=4,max=32",
"mother_name": "required,min=4,max=32",
},
"salary": "number",
"phones": map[string]interface{}{
"number": "required,min=4,max=32",
"remark": "required,min=1,max=32",
},
},
}
if len(validate.ValidateMap(data, rules)) == 0 {
// Data is valid
}
// Data is invalid
}

@ -1,7 +1,6 @@
package main package main
import ( import (
"encoding/json"
"fmt" "fmt"
"reflect" "reflect"
"strings" "strings"
@ -9,36 +8,6 @@ import (
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
) )
type validationError struct {
Namespace string `json:"namespace"` // can differ when a custom TagNameFunc is registered or
Field string `json:"field"` // by passing alt name to ReportError like below
StructNamespace string `json:"structNamespace"`
StructField string `json:"structField"`
Tag string `json:"tag"`
ActualTag string `json:"actualTag"`
Kind string `json:"kind"`
Type string `json:"type"`
Value string `json:"value"`
Param string `json:"param"`
Message string `json:"message"`
}
type Gender uint
const (
Male Gender = iota + 1
Female
Intersex
)
func (gender Gender) String() string {
terms := []string{"Male", "Female", "Intersex"}
if gender < Male || gender > Intersex {
return "unknown"
}
return terms[gender]
}
// User contains user information // User contains user information
type User struct { type User struct {
FirstName string `json:"fname"` FirstName string `json:"fname"`
@ -47,7 +16,6 @@ type User struct {
Email string `json:"e-mail" validate:"required,email"` Email string `json:"e-mail" validate:"required,email"`
FavouriteColor string `validate:"hexcolor|rgb|rgba"` FavouriteColor string `validate:"hexcolor|rgb|rgba"`
Addresses []*Address `validate:"required,dive,required"` // a person can have a home and cottage... Addresses []*Address `validate:"required,dive,required"` // a person can have a home and cottage...
Gender Gender `json:"gender" validate:"required,gender_custom_validation"`
} }
// Address houses a users address information // Address houses a users address information
@ -76,20 +44,9 @@ func main() {
// register validation for 'User' // register validation for 'User'
// NOTE: only have to register a non-pointer type for 'User', validator // NOTE: only have to register a non-pointer type for 'User', validator
// internally dereferences during it's type checks. // interanlly dereferences during it's type checks.
validate.RegisterStructValidation(UserStructLevelValidation, User{}) validate.RegisterStructValidation(UserStructLevelValidation, User{})
// register a custom validation for user genre on a line
// validates that an enum is within the interval
err := validate.RegisterValidation("gender_custom_validation", func(fl validator.FieldLevel) bool {
value := fl.Field().Interface().(Gender)
return value.String() != "unknown"
})
if err != nil {
fmt.Println(err)
return
}
// build 'User' info, normally posted data etc... // build 'User' info, normally posted data etc...
address := &Address{ address := &Address{
Street: "Eavesdown Docks", Street: "Eavesdown Docks",
@ -108,7 +65,7 @@ func main() {
} }
// returns InvalidValidationError for bad validation input, nil or ValidationErrors ( []FieldError ) // returns InvalidValidationError for bad validation input, nil or ValidationErrors ( []FieldError )
err = validate.Struct(user) err := validate.Struct(user)
if err != nil { if err != nil {
// this check is only needed when your code could produce // this check is only needed when your code could produce
@ -120,27 +77,18 @@ func main() {
} }
for _, err := range err.(validator.ValidationErrors) { for _, err := range err.(validator.ValidationErrors) {
e := validationError{
Namespace: err.Namespace(), fmt.Println(err.Namespace()) // can differ when a custom TagNameFunc is registered or
Field: err.Field(), fmt.Println(err.Field()) // by passing alt name to ReportError like below
StructNamespace: err.StructNamespace(), fmt.Println(err.StructNamespace())
StructField: err.StructField(), fmt.Println(err.StructField())
Tag: err.Tag(), fmt.Println(err.Tag())
ActualTag: err.ActualTag(), fmt.Println(err.ActualTag())
Kind: fmt.Sprintf("%v", err.Kind()), fmt.Println(err.Kind())
Type: fmt.Sprintf("%v", err.Type()), fmt.Println(err.Type())
Value: fmt.Sprintf("%v", err.Value()), fmt.Println(err.Value())
Param: err.Param(), fmt.Println(err.Param())
Message: err.Error(), fmt.Println()
}
indent, err := json.MarshalIndent(e, "", " ")
if err != nil {
fmt.Println(err)
panic(err)
}
fmt.Println(string(indent))
} }
// from here you can create your own error messages in whatever language you wish // from here you can create your own error messages in whatever language you wish

@ -1,92 +0,0 @@
package main
import (
"fmt"
"github.com/go-playground/validator/v10"
)
type Data struct {
Name string
Email string
Details *Details
}
type Details struct {
FamilyMembers *FamilyMembers
Salary string
}
type FamilyMembers struct {
FatherName string
MotherName string
}
type Data2 struct {
Name string
Age uint32
}
var validate = validator.New()
func main() {
validateStruct()
// output
// Key: 'Data2.Name' Error:Field validation for 'Name' failed on the 'min' tag
// Key: 'Data2.Age' Error:Field validation for 'Age' failed on the 'max' tag
validateStructNested()
// output
// Key: 'Data.Name' Error:Field validation for 'Name' failed on the 'max' tag
// Key: 'Data.Details.FamilyMembers' Error:Field validation for 'FamilyMembers' failed on the 'required' tag
}
func validateStruct() {
data := Data2{
Name: "leo",
Age: 1000,
}
rules := map[string]string{
"Name": "min=4,max=6",
"Age": "min=4,max=6",
}
validate.RegisterStructValidationMapRules(rules, Data2{})
err := validate.Struct(data)
fmt.Println(err)
fmt.Println()
}
func validateStructNested() {
data := Data{
Name: "11sdfddd111",
Email: "zytel3301@mail.com",
Details: &Details{
Salary: "1000",
},
}
rules1 := map[string]string{
"Name": "min=4,max=6",
"Email": "required,email",
"Details": "required",
}
rules2 := map[string]string{
"Salary": "number",
"FamilyMembers": "required",
}
rules3 := map[string]string{
"FatherName": "required,min=4,max=32",
"MotherName": "required,min=4,max=32",
}
validate.RegisterStructValidationMapRules(rules1, Data{})
validate.RegisterStructValidationMapRules(rules2, Details{})
validate.RegisterStructValidationMapRules(rules3, FamilyMembers{})
err := validate.Struct(data)
fmt.Println(err)
}

File diff suppressed because it is too large Load Diff

@ -114,7 +114,6 @@ func (v *Validate) extractStructCache(current reflect.Value, sName string) *cStr
cs = &cStruct{name: sName, fields: make([]*cField, 0), fn: v.structLevelFuncs[typ]} cs = &cStruct{name: sName, fields: make([]*cField, 0), fn: v.structLevelFuncs[typ]}
numFields := current.NumField() numFields := current.NumField()
rules := v.rules[typ]
var ctag *cTag var ctag *cTag
var fld reflect.StructField var fld reflect.StructField
@ -129,11 +128,7 @@ func (v *Validate) extractStructCache(current reflect.Value, sName string) *cStr
continue continue
} }
if rtag, ok := rules[fld.Name]; ok { tag = fld.Tag.Get(v.tagName)
tag = rtag
} else {
tag = fld.Tag.Get(v.tagName)
}
if tag == skipValidationTag { if tag == skipValidationTag {
continue continue

@ -51,7 +51,7 @@ var iso3166_1_alpha2 = map[string]bool{
"TV": true, "UG": true, "UA": true, "AE": true, "GB": true, "TV": true, "UG": true, "UA": true, "AE": true, "GB": true,
"US": true, "UM": true, "UY": true, "UZ": true, "VU": true, "US": true, "UM": true, "UY": true, "UZ": true, "VU": true,
"VE": true, "VN": true, "VG": true, "VI": true, "WF": true, "VE": true, "VN": true, "VG": true, "VI": true, "WF": true,
"EH": true, "YE": true, "ZM": true, "ZW": true, "XK": true, "EH": true, "YE": true, "ZM": true, "ZW": true,
} }
var iso3166_1_alpha3 = map[string]bool{ var iso3166_1_alpha3 = map[string]bool{
@ -105,7 +105,7 @@ var iso3166_1_alpha3 = map[string]bool{
"UGA": true, "UKR": true, "ARE": true, "GBR": true, "UMI": true, "UGA": true, "UKR": true, "ARE": true, "GBR": true, "UMI": true,
"USA": true, "URY": true, "UZB": true, "VUT": true, "VEN": true, "USA": true, "URY": true, "UZB": true, "VUT": true, "VEN": true,
"VNM": true, "VGB": true, "VIR": true, "WLF": true, "ESH": true, "VNM": true, "VGB": true, "VIR": true, "WLF": true, "ESH": true,
"YEM": true, "ZMB": true, "ZWE": true, "ALA": true, "UNK": true, "YEM": true, "ZMB": true, "ZWE": true, "ALA": true,
} }
var iso3166_1_alpha_numeric = map[int]bool{ var iso3166_1_alpha_numeric = map[int]bool{
// see: https://www.iso.org/iso-3166-country-codes.html // see: https://www.iso.org/iso-3166-country-codes.html
@ -158,975 +158,5 @@ var iso3166_1_alpha_numeric = map[int]bool{
800: true, 804: true, 784: true, 826: true, 581: true, 800: true, 804: true, 784: true, 826: true, 581: true,
840: true, 858: true, 860: true, 548: true, 862: true, 840: true, 858: true, 860: true, 548: true, 862: true,
704: true, 92: true, 850: true, 876: true, 732: true, 704: true, 92: true, 850: true, 876: true, 732: true,
887: true, 894: true, 716: true, 248: true, 153:true, 887: true, 894: true, 716: true, 248: true,
}
var iso3166_2 = map[string]bool{
"AD-02" : true, "AD-03" : true, "AD-04" : true, "AD-05" : true, "AD-06" : true,
"AD-07" : true, "AD-08" : true, "AE-AJ" : true, "AE-AZ" : true, "AE-DU" : true,
"AE-FU" : true, "AE-RK" : true, "AE-SH" : true, "AE-UQ" : true, "AF-BAL" : true,
"AF-BAM" : true, "AF-BDG" : true, "AF-BDS" : true, "AF-BGL" : true, "AF-DAY" : true,
"AF-FRA" : true, "AF-FYB" : true, "AF-GHA" : true, "AF-GHO" : true, "AF-HEL" : true,
"AF-HER" : true, "AF-JOW" : true, "AF-KAB" : true, "AF-KAN" : true, "AF-KAP" : true,
"AF-KDZ" : true, "AF-KHO" : true, "AF-KNR" : true, "AF-LAG" : true, "AF-LOG" : true,
"AF-NAN" : true, "AF-NIM" : true, "AF-NUR" : true, "AF-PAN" : true, "AF-PAR" : true,
"AF-PIA" : true, "AF-PKA" : true, "AF-SAM" : true, "AF-SAR" : true, "AF-TAK" : true,
"AF-URU" : true, "AF-WAR" : true, "AF-ZAB" : true, "AG-03" : true, "AG-04" : true,
"AG-05" : true, "AG-06" : true, "AG-07" : true, "AG-08" : true, "AG-10" : true,
"AG-11" : true, "AL-01" : true, "AL-02" : true, "AL-03" : true, "AL-04" : true,
"AL-05" : true, "AL-06" : true, "AL-07" : true, "AL-08" : true, "AL-09" : true,
"AL-10" : true, "AL-11" : true, "AL-12" : true, "AL-BR" : true, "AL-BU" : true,
"AL-DI" : true, "AL-DL" : true, "AL-DR" : true, "AL-DV" : true, "AL-EL" : true,
"AL-ER" : true, "AL-FR" : true, "AL-GJ" : true, "AL-GR" : true, "AL-HA" : true,
"AL-KA" : true, "AL-KB" : true, "AL-KC" : true, "AL-KO" : true, "AL-KR" : true,
"AL-KU" : true, "AL-LB" : true, "AL-LE" : true, "AL-LU" : true, "AL-MK" : true,
"AL-MM" : true, "AL-MR" : true, "AL-MT" : true, "AL-PG" : true, "AL-PQ" : true,
"AL-PR" : true, "AL-PU" : true, "AL-SH" : true, "AL-SK" : true, "AL-SR" : true,
"AL-TE" : true, "AL-TP" : true, "AL-TR" : true, "AL-VL" : true, "AM-AG" : true,
"AM-AR" : true, "AM-AV" : true, "AM-ER" : true, "AM-GR" : true, "AM-KT" : true,
"AM-LO" : true, "AM-SH" : true, "AM-SU" : true, "AM-TV" : true, "AM-VD" : true,
"AO-BGO" : true, "AO-BGU" : true, "AO-BIE" : true, "AO-CAB" : true, "AO-CCU" : true,
"AO-CNN" : true, "AO-CNO" : true, "AO-CUS" : true, "AO-HUA" : true, "AO-HUI" : true,
"AO-LNO" : true, "AO-LSU" : true, "AO-LUA" : true, "AO-MAL" : true, "AO-MOX" : true,
"AO-NAM" : true, "AO-UIG" : true, "AO-ZAI" : true, "AR-A" : true, "AR-B" : true,
"AR-C" : true, "AR-D" : true, "AR-E" : true, "AR-G" : true, "AR-H" : true,
"AR-J" : true, "AR-K" : true, "AR-L" : true, "AR-M" : true, "AR-N" : true,
"AR-P" : true, "AR-Q" : true, "AR-R" : true, "AR-S" : true, "AR-T" : true,
"AR-U" : true, "AR-V" : true, "AR-W" : true, "AR-X" : true, "AR-Y" : true,
"AR-Z" : true, "AT-1" : true, "AT-2" : true, "AT-3" : true, "AT-4" : true,
"AT-5" : true, "AT-6" : true, "AT-7" : true, "AT-8" : true, "AT-9" : true,
"AU-ACT" : true, "AU-NSW" : true, "AU-NT" : true, "AU-QLD" : true, "AU-SA" : true,
"AU-TAS" : true, "AU-VIC" : true, "AU-WA" : true, "AZ-ABS" : true, "AZ-AGA" : true,
"AZ-AGC" : true, "AZ-AGM" : true, "AZ-AGS" : true, "AZ-AGU" : true, "AZ-AST" : true,
"AZ-BA" : true, "AZ-BAB" : true, "AZ-BAL" : true, "AZ-BAR" : true, "AZ-BEY" : true,
"AZ-BIL" : true, "AZ-CAB" : true, "AZ-CAL" : true, "AZ-CUL" : true, "AZ-DAS" : true,
"AZ-FUZ" : true, "AZ-GA" : true, "AZ-GAD" : true, "AZ-GOR" : true, "AZ-GOY" : true,
"AZ-GYG" : true, "AZ-HAC" : true, "AZ-IMI" : true, "AZ-ISM" : true, "AZ-KAL" : true,
"AZ-KAN" : true, "AZ-KUR" : true, "AZ-LA" : true, "AZ-LAC" : true, "AZ-LAN" : true,
"AZ-LER" : true, "AZ-MAS" : true, "AZ-MI" : true, "AZ-NA" : true, "AZ-NEF" : true,
"AZ-NV" : true, "AZ-NX" : true, "AZ-OGU" : true, "AZ-ORD" : true, "AZ-QAB" : true,
"AZ-QAX" : true, "AZ-QAZ" : true, "AZ-QBA" : true, "AZ-QBI" : true, "AZ-QOB" : true,
"AZ-QUS" : true, "AZ-SA" : true, "AZ-SAB" : true, "AZ-SAD" : true, "AZ-SAH" : true,
"AZ-SAK" : true, "AZ-SAL" : true, "AZ-SAR" : true, "AZ-SAT" : true, "AZ-SBN" : true,
"AZ-SIY" : true, "AZ-SKR" : true, "AZ-SM" : true, "AZ-SMI" : true, "AZ-SMX" : true,
"AZ-SR" : true, "AZ-SUS" : true, "AZ-TAR" : true, "AZ-TOV" : true, "AZ-UCA" : true,
"AZ-XA" : true, "AZ-XAC" : true, "AZ-XCI" : true, "AZ-XIZ" : true, "AZ-XVD" : true,
"AZ-YAR" : true, "AZ-YE" : true, "AZ-YEV" : true, "AZ-ZAN" : true, "AZ-ZAQ" : true,
"AZ-ZAR" : true, "BA-01" : true, "BA-02" : true, "BA-03" : true, "BA-04" : true,
"BA-05" : true, "BA-06" : true, "BA-07" : true, "BA-08" : true, "BA-09" : true,
"BA-10" : true, "BA-BIH" : true, "BA-BRC" : true, "BA-SRP" : true, "BB-01" : true,
"BB-02" : true, "BB-03" : true, "BB-04" : true, "BB-05" : true, "BB-06" : true,
"BB-07" : true, "BB-08" : true, "BB-09" : true, "BB-10" : true, "BB-11" : true,
"BD-01" : true, "BD-02" : true, "BD-03" : true, "BD-04" : true, "BD-05" : true,
"BD-06" : true, "BD-07" : true, "BD-08" : true, "BD-09" : true, "BD-10" : true,
"BD-11" : true, "BD-12" : true, "BD-13" : true, "BD-14" : true, "BD-15" : true,
"BD-16" : true, "BD-17" : true, "BD-18" : true, "BD-19" : true, "BD-20" : true,
"BD-21" : true, "BD-22" : true, "BD-23" : true, "BD-24" : true, "BD-25" : true,
"BD-26" : true, "BD-27" : true, "BD-28" : true, "BD-29" : true, "BD-30" : true,
"BD-31" : true, "BD-32" : true, "BD-33" : true, "BD-34" : true, "BD-35" : true,
"BD-36" : true, "BD-37" : true, "BD-38" : true, "BD-39" : true, "BD-40" : true,
"BD-41" : true, "BD-42" : true, "BD-43" : true, "BD-44" : true, "BD-45" : true,
"BD-46" : true, "BD-47" : true, "BD-48" : true, "BD-49" : true, "BD-50" : true,
"BD-51" : true, "BD-52" : true, "BD-53" : true, "BD-54" : true, "BD-55" : true,
"BD-56" : true, "BD-57" : true, "BD-58" : true, "BD-59" : true, "BD-60" : true,
"BD-61" : true, "BD-62" : true, "BD-63" : true, "BD-64" : true, "BD-A" : true,
"BD-B" : true, "BD-C" : true, "BD-D" : true, "BD-E" : true, "BD-F" : true,
"BD-G" : true, "BE-BRU" : true, "BE-VAN" : true, "BE-VBR" : true, "BE-VLG" : true,
"BE-VLI" : true, "BE-VOV" : true, "BE-VWV" : true, "BE-WAL" : true, "BE-WBR" : true,
"BE-WHT" : true, "BE-WLG" : true, "BE-WLX" : true, "BE-WNA" : true, "BF-01" : true,
"BF-02" : true, "BF-03" : true, "BF-04" : true, "BF-05" : true, "BF-06" : true,
"BF-07" : true, "BF-08" : true, "BF-09" : true, "BF-10" : true, "BF-11" : true,
"BF-12" : true, "BF-13" : true, "BF-BAL" : true, "BF-BAM" : true, "BF-BAN" : true,
"BF-BAZ" : true, "BF-BGR" : true, "BF-BLG" : true, "BF-BLK" : true, "BF-COM" : true,
"BF-GAN" : true, "BF-GNA" : true, "BF-GOU" : true, "BF-HOU" : true, "BF-IOB" : true,
"BF-KAD" : true, "BF-KEN" : true, "BF-KMD" : true, "BF-KMP" : true, "BF-KOP" : true,
"BF-KOS" : true, "BF-KOT" : true, "BF-KOW" : true, "BF-LER" : true, "BF-LOR" : true,
"BF-MOU" : true, "BF-NAM" : true, "BF-NAO" : true, "BF-NAY" : true, "BF-NOU" : true,
"BF-OUB" : true, "BF-OUD" : true, "BF-PAS" : true, "BF-PON" : true, "BF-SEN" : true,
"BF-SIS" : true, "BF-SMT" : true, "BF-SNG" : true, "BF-SOM" : true, "BF-SOR" : true,
"BF-TAP" : true, "BF-TUI" : true, "BF-YAG" : true, "BF-YAT" : true, "BF-ZIR" : true,
"BF-ZON" : true, "BF-ZOU" : true, "BG-01" : true, "BG-02" : true, "BG-03" : true,
"BG-04" : true, "BG-05" : true, "BG-06" : true, "BG-07" : true, "BG-08" : true,
"BG-09" : true, "BG-10" : true, "BG-11" : true, "BG-12" : true, "BG-13" : true,
"BG-14" : true, "BG-15" : true, "BG-16" : true, "BG-17" : true, "BG-18" : true,
"BG-19" : true, "BG-20" : true, "BG-21" : true, "BG-22" : true, "BG-23" : true,
"BG-24" : true, "BG-25" : true, "BG-26" : true, "BG-27" : true, "BG-28" : true,
"BH-13" : true, "BH-14" : true, "BH-15" : true, "BH-16" : true, "BH-17" : true,
"BI-BB" : true, "BI-BL" : true, "BI-BM" : true, "BI-BR" : true, "BI-CA" : true,
"BI-CI" : true, "BI-GI" : true, "BI-KI" : true, "BI-KR" : true, "BI-KY" : true,
"BI-MA" : true, "BI-MU" : true, "BI-MW" : true, "BI-NG" : true, "BI-RT" : true,
"BI-RY" : true, "BJ-AK" : true, "BJ-AL" : true, "BJ-AQ" : true, "BJ-BO" : true,
"BJ-CO" : true, "BJ-DO" : true, "BJ-KO" : true, "BJ-LI" : true, "BJ-MO" : true,
"BJ-OU" : true, "BJ-PL" : true, "BJ-ZO" : true, "BN-BE" : true, "BN-BM" : true,
"BN-TE" : true, "BN-TU" : true, "BO-B" : true, "BO-C" : true, "BO-H" : true,
"BO-L" : true, "BO-N" : true, "BO-O" : true, "BO-P" : true, "BO-S" : true,
"BO-T" : true, "BQ-BO" : true, "BQ-SA" : true, "BQ-SE" : true, "BR-AC" : true,
"BR-AL" : true, "BR-AM" : true, "BR-AP" : true, "BR-BA" : true, "BR-CE" : true,
"BR-DF" : true, "BR-ES" : true, "BR-FN" : true, "BR-GO" : true, "BR-MA" : true,
"BR-MG" : true, "BR-MS" : true, "BR-MT" : true, "BR-PA" : true, "BR-PB" : true,
"BR-PE" : true, "BR-PI" : true, "BR-PR" : true, "BR-RJ" : true, "BR-RN" : true,
"BR-RO" : true, "BR-RR" : true, "BR-RS" : true, "BR-SC" : true, "BR-SE" : true,
"BR-SP" : true, "BR-TO" : true, "BS-AK" : true, "BS-BI" : true, "BS-BP" : true,
"BS-BY" : true, "BS-CE" : true, "BS-CI" : true, "BS-CK" : true, "BS-CO" : true,
"BS-CS" : true, "BS-EG" : true, "BS-EX" : true, "BS-FP" : true, "BS-GC" : true,
"BS-HI" : true, "BS-HT" : true, "BS-IN" : true, "BS-LI" : true, "BS-MC" : true,
"BS-MG" : true, "BS-MI" : true, "BS-NE" : true, "BS-NO" : true, "BS-NS" : true,
"BS-RC" : true, "BS-RI" : true, "BS-SA" : true, "BS-SE" : true, "BS-SO" : true,
"BS-SS" : true, "BS-SW" : true, "BS-WG" : true, "BT-11" : true, "BT-12" : true,
"BT-13" : true, "BT-14" : true, "BT-15" : true, "BT-21" : true, "BT-22" : true,
"BT-23" : true, "BT-24" : true, "BT-31" : true, "BT-32" : true, "BT-33" : true,
"BT-34" : true, "BT-41" : true, "BT-42" : true, "BT-43" : true, "BT-44" : true,
"BT-45" : true, "BT-GA" : true, "BT-TY" : true, "BW-CE" : true, "BW-GH" : true,
"BW-KG" : true, "BW-KL" : true, "BW-KW" : true, "BW-NE" : true, "BW-NW" : true,
"BW-SE" : true, "BW-SO" : true, "BY-BR" : true, "BY-HM" : true, "BY-HO" : true,
"BY-HR" : true, "BY-MA" : true, "BY-MI" : true, "BY-VI" : true, "BZ-BZ" : true,
"BZ-CY" : true, "BZ-CZL" : true, "BZ-OW" : true, "BZ-SC" : true, "BZ-TOL" : true,
"CA-AB" : true, "CA-BC" : true, "CA-MB" : true, "CA-NB" : true, "CA-NL" : true,
"CA-NS" : true, "CA-NT" : true, "CA-NU" : true, "CA-ON" : true, "CA-PE" : true,
"CA-QC" : true, "CA-SK" : true, "CA-YT" : true, "CD-BC" : true, "CD-BN" : true,
"CD-EQ" : true, "CD-KA" : true, "CD-KE" : true, "CD-KN" : true, "CD-KW" : true,
"CD-MA" : true, "CD-NK" : true, "CD-OR" : true, "CD-SK" : true, "CF-AC" : true,
"CF-BB" : true, "CF-BGF" : true, "CF-BK" : true, "CF-HK" : true, "CF-HM" : true,
"CF-HS" : true, "CF-KB" : true, "CF-KG" : true, "CF-LB" : true, "CF-MB" : true,
"CF-MP" : true, "CF-NM" : true, "CF-OP" : true, "CF-SE" : true, "CF-UK" : true,
"CF-VK" : true, "CG-11" : true, "CG-12" : true, "CG-13" : true, "CG-14" : true,
"CG-15" : true, "CG-2" : true, "CG-5" : true, "CG-7" : true, "CG-8" : true,
"CG-9" : true, "CG-BZV" : true, "CH-AG" : true, "CH-AI" : true, "CH-AR" : true,
"CH-BE" : true, "CH-BL" : true, "CH-BS" : true, "CH-FR" : true, "CH-GE" : true,
"CH-GL" : true, "CH-GR" : true, "CH-JU" : true, "CH-LU" : true, "CH-NE" : true,
"CH-NW" : true, "CH-OW" : true, "CH-SG" : true, "CH-SH" : true, "CH-SO" : true,
"CH-SZ" : true, "CH-TG" : true, "CH-TI" : true, "CH-UR" : true, "CH-VD" : true,
"CH-VS" : true, "CH-ZG" : true, "CH-ZH" : true, "CI-01" : true, "CI-02" : true,
"CI-03" : true, "CI-04" : true, "CI-05" : true, "CI-06" : true, "CI-07" : true,
"CI-08" : true, "CI-09" : true, "CI-10" : true, "CI-11" : true, "CI-12" : true,
"CI-13" : true, "CI-14" : true, "CI-15" : true, "CI-16" : true, "CI-17" : true,
"CI-18" : true, "CI-19" : true, "CL-AI" : true, "CL-AN" : true, "CL-AP" : true,
"CL-AR" : true, "CL-AT" : true, "CL-BI" : true, "CL-CO" : true, "CL-LI" : true,
"CL-LL" : true, "CL-LR" : true, "CL-MA" : true, "CL-ML" : true, "CL-RM" : true,
"CL-TA" : true, "CL-VS" : true, "CM-AD" : true, "CM-CE" : true, "CM-EN" : true,
"CM-ES" : true, "CM-LT" : true, "CM-NO" : true, "CM-NW" : true, "CM-OU" : true,
"CM-SU" : true, "CM-SW" : true, "CN-11" : true, "CN-12" : true, "CN-13" : true,
"CN-14" : true, "CN-15" : true, "CN-21" : true, "CN-22" : true, "CN-23" : true,
"CN-31" : true, "CN-32" : true, "CN-33" : true, "CN-34" : true, "CN-35" : true,
"CN-36" : true, "CN-37" : true, "CN-41" : true, "CN-42" : true, "CN-43" : true,
"CN-44" : true, "CN-45" : true, "CN-46" : true, "CN-50" : true, "CN-51" : true,
"CN-52" : true, "CN-53" : true, "CN-54" : true, "CN-61" : true, "CN-62" : true,
"CN-63" : true, "CN-64" : true, "CN-65" : true, "CN-71" : true, "CN-91" : true,
"CN-92" : true, "CO-AMA" : true, "CO-ANT" : true, "CO-ARA" : true, "CO-ATL" : true,
"CO-BOL" : true, "CO-BOY" : true, "CO-CAL" : true, "CO-CAQ" : true, "CO-CAS" : true,
"CO-CAU" : true, "CO-CES" : true, "CO-CHO" : true, "CO-COR" : true, "CO-CUN" : true,
"CO-DC" : true, "CO-GUA" : true, "CO-GUV" : true, "CO-HUI" : true, "CO-LAG" : true,
"CO-MAG" : true, "CO-MET" : true, "CO-NAR" : true, "CO-NSA" : true, "CO-PUT" : true,
"CO-QUI" : true, "CO-RIS" : true, "CO-SAN" : true, "CO-SAP" : true, "CO-SUC" : true,
"CO-TOL" : true, "CO-VAC" : true, "CO-VAU" : true, "CO-VID" : true, "CR-A" : true,
"CR-C" : true, "CR-G" : true, "CR-H" : true, "CR-L" : true, "CR-P" : true,
"CR-SJ" : true, "CU-01" : true, "CU-02" : true, "CU-03" : true, "CU-04" : true,
"CU-05" : true, "CU-06" : true, "CU-07" : true, "CU-08" : true, "CU-09" : true,
"CU-10" : true, "CU-11" : true, "CU-12" : true, "CU-13" : true, "CU-14" : true,
"CU-99" : true, "CV-B" : true, "CV-BR" : true, "CV-BV" : true, "CV-CA" : true,
"CV-CF" : true, "CV-CR" : true, "CV-MA" : true, "CV-MO" : true, "CV-PA" : true,
"CV-PN" : true, "CV-PR" : true, "CV-RB" : true, "CV-RG" : true, "CV-RS" : true,
"CV-S" : true, "CV-SD" : true, "CV-SF" : true, "CV-SL" : true, "CV-SM" : true,
"CV-SO" : true, "CV-SS" : true, "CV-SV" : true, "CV-TA" : true, "CV-TS" : true,
"CY-01" : true, "CY-02" : true, "CY-03" : true, "CY-04" : true, "CY-05" : true,
"CY-06" : true, "CZ-10" : true, "CZ-101" : true, "CZ-102" : true, "CZ-103" : true,
"CZ-104" : true, "CZ-105" : true, "CZ-106" : true, "CZ-107" : true, "CZ-108" : true,
"CZ-109" : true, "CZ-110" : true, "CZ-111" : true, "CZ-112" : true, "CZ-113" : true,
"CZ-114" : true, "CZ-115" : true, "CZ-116" : true, "CZ-117" : true, "CZ-118" : true,
"CZ-119" : true, "CZ-120" : true, "CZ-121" : true, "CZ-122" : true, "CZ-20" : true,
"CZ-201" : true, "CZ-202" : true, "CZ-203" : true, "CZ-204" : true, "CZ-205" : true,
"CZ-206" : true, "CZ-207" : true, "CZ-208" : true, "CZ-209" : true, "CZ-20A" : true,
"CZ-20B" : true, "CZ-20C" : true, "CZ-31" : true, "CZ-311" : true, "CZ-312" : true,
"CZ-313" : true, "CZ-314" : true, "CZ-315" : true, "CZ-316" : true, "CZ-317" : true,
"CZ-32" : true, "CZ-321" : true, "CZ-322" : true, "CZ-323" : true, "CZ-324" : true,
"CZ-325" : true, "CZ-326" : true, "CZ-327" : true, "CZ-41" : true, "CZ-411" : true,
"CZ-412" : true, "CZ-413" : true, "CZ-42" : true, "CZ-421" : true, "CZ-422" : true,
"CZ-423" : true, "CZ-424" : true, "CZ-425" : true, "CZ-426" : true, "CZ-427" : true,
"CZ-51" : true, "CZ-511" : true, "CZ-512" : true, "CZ-513" : true, "CZ-514" : true,
"CZ-52" : true, "CZ-521" : true, "CZ-522" : true, "CZ-523" : true, "CZ-524" : true,
"CZ-525" : true, "CZ-53" : true, "CZ-531" : true, "CZ-532" : true, "CZ-533" : true,
"CZ-534" : true, "CZ-63" : true, "CZ-631" : true, "CZ-632" : true, "CZ-633" : true,
"CZ-634" : true, "CZ-635" : true, "CZ-64" : true, "CZ-641" : true, "CZ-642" : true,
"CZ-643" : true, "CZ-644" : true, "CZ-645" : true, "CZ-646" : true, "CZ-647" : true,
"CZ-71" : true, "CZ-711" : true, "CZ-712" : true, "CZ-713" : true, "CZ-714" : true,
"CZ-715" : true, "CZ-72" : true, "CZ-721" : true, "CZ-722" : true, "CZ-723" : true,
"CZ-724" : true, "CZ-80" : true, "CZ-801" : true, "CZ-802" : true, "CZ-803" : true,
"CZ-804" : true, "CZ-805" : true, "CZ-806" : true, "DE-BB" : true, "DE-BE" : true,
"DE-BW" : true, "DE-BY" : true, "DE-HB" : true, "DE-HE" : true, "DE-HH" : true,
"DE-MV" : true, "DE-NI" : true, "DE-NW" : true, "DE-RP" : true, "DE-SH" : true,
"DE-SL" : true, "DE-SN" : true, "DE-ST" : true, "DE-TH" : true, "DJ-AR" : true,
"DJ-AS" : true, "DJ-DI" : true, "DJ-DJ" : true, "DJ-OB" : true, "DJ-TA" : true,
"DK-81" : true, "DK-82" : true, "DK-83" : true, "DK-84" : true, "DK-85" : true,
"DM-01" : true, "DM-02" : true, "DM-03" : true, "DM-04" : true, "DM-05" : true,
"DM-06" : true, "DM-07" : true, "DM-08" : true, "DM-09" : true, "DM-10" : true,
"DO-01" : true, "DO-02" : true, "DO-03" : true, "DO-04" : true, "DO-05" : true,
"DO-06" : true, "DO-07" : true, "DO-08" : true, "DO-09" : true, "DO-10" : true,
"DO-11" : true, "DO-12" : true, "DO-13" : true, "DO-14" : true, "DO-15" : true,
"DO-16" : true, "DO-17" : true, "DO-18" : true, "DO-19" : true, "DO-20" : true,
"DO-21" : true, "DO-22" : true, "DO-23" : true, "DO-24" : true, "DO-25" : true,
"DO-26" : true, "DO-27" : true, "DO-28" : true, "DO-29" : true, "DO-30" : true,
"DZ-01" : true, "DZ-02" : true, "DZ-03" : true, "DZ-04" : true, "DZ-05" : true,
"DZ-06" : true, "DZ-07" : true, "DZ-08" : true, "DZ-09" : true, "DZ-10" : true,
"DZ-11" : true, "DZ-12" : true, "DZ-13" : true, "DZ-14" : true, "DZ-15" : true,
"DZ-16" : true, "DZ-17" : true, "DZ-18" : true, "DZ-19" : true, "DZ-20" : true,
"DZ-21" : true, "DZ-22" : true, "DZ-23" : true, "DZ-24" : true, "DZ-25" : true,
"DZ-26" : true, "DZ-27" : true, "DZ-28" : true, "DZ-29" : true, "DZ-30" : true,
"DZ-31" : true, "DZ-32" : true, "DZ-33" : true, "DZ-34" : true, "DZ-35" : true,
"DZ-36" : true, "DZ-37" : true, "DZ-38" : true, "DZ-39" : true, "DZ-40" : true,
"DZ-41" : true, "DZ-42" : true, "DZ-43" : true, "DZ-44" : true, "DZ-45" : true,
"DZ-46" : true, "DZ-47" : true, "DZ-48" : true, "EC-A" : true, "EC-B" : true,
"EC-C" : true, "EC-D" : true, "EC-E" : true, "EC-F" : true, "EC-G" : true,
"EC-H" : true, "EC-I" : true, "EC-L" : true, "EC-M" : true, "EC-N" : true,
"EC-O" : true, "EC-P" : true, "EC-R" : true, "EC-S" : true, "EC-SD" : true,
"EC-SE" : true, "EC-T" : true, "EC-U" : true, "EC-W" : true, "EC-X" : true,
"EC-Y" : true, "EC-Z" : true, "EE-37" : true, "EE-39" : true, "EE-44" : true,
"EE-49" : true, "EE-51" : true, "EE-57" : true, "EE-59" : true, "EE-65" : true,
"EE-67" : true, "EE-70" : true, "EE-74" : true, "EE-78" : true, "EE-82" : true,
"EE-84" : true, "EE-86" : true, "EG-ALX" : true, "EG-ASN" : true, "EG-AST" : true,
"EG-BA" : true, "EG-BH" : true, "EG-BNS" : true, "EG-C" : true, "EG-DK" : true,
"EG-DT" : true, "EG-FYM" : true, "EG-GH" : true, "EG-GZ" : true, "EG-HU" : true,
"EG-IS" : true, "EG-JS" : true, "EG-KB" : true, "EG-KFS" : true, "EG-KN" : true,
"EG-MN" : true, "EG-MNF" : true, "EG-MT" : true, "EG-PTS" : true, "EG-SHG" : true,
"EG-SHR" : true, "EG-SIN" : true, "EG-SU" : true, "EG-SUZ" : true, "EG-WAD" : true,
"ER-AN" : true, "ER-DK" : true, "ER-DU" : true, "ER-GB" : true, "ER-MA" : true,
"ER-SK" : true, "ES-A" : true, "ES-AB" : true, "ES-AL" : true, "ES-AN" : true,
"ES-AR" : true, "ES-AS" : true, "ES-AV" : true, "ES-B" : true, "ES-BA" : true,
"ES-BI" : true, "ES-BU" : true, "ES-C" : true, "ES-CA" : true, "ES-CB" : true,
"ES-CC" : true, "ES-CE" : true, "ES-CL" : true, "ES-CM" : true, "ES-CN" : true,
"ES-CO" : true, "ES-CR" : true, "ES-CS" : true, "ES-CT" : true, "ES-CU" : true,
"ES-EX" : true, "ES-GA" : true, "ES-GC" : true, "ES-GI" : true, "ES-GR" : true,
"ES-GU" : true, "ES-H" : true, "ES-HU" : true, "ES-IB" : true, "ES-J" : true,
"ES-L" : true, "ES-LE" : true, "ES-LO" : true, "ES-LU" : true, "ES-M" : true,
"ES-MA" : true, "ES-MC" : true, "ES-MD" : true, "ES-ML" : true, "ES-MU" : true,
"ES-NA" : true, "ES-NC" : true, "ES-O" : true, "ES-OR" : true, "ES-P" : true,
"ES-PM" : true, "ES-PO" : true, "ES-PV" : true, "ES-RI" : true, "ES-S" : true,
"ES-SA" : true, "ES-SE" : true, "ES-SG" : true, "ES-SO" : true, "ES-SS" : true,
"ES-T" : true, "ES-TE" : true, "ES-TF" : true, "ES-TO" : true, "ES-V" : true,
"ES-VA" : true, "ES-VC" : true, "ES-VI" : true, "ES-Z" : true, "ES-ZA" : true,
"ET-AA" : true, "ET-AF" : true, "ET-AM" : true, "ET-BE" : true, "ET-DD" : true,
"ET-GA" : true, "ET-HA" : true, "ET-OR" : true, "ET-SN" : true, "ET-SO" : true,
"ET-TI" : true, "FI-01" : true, "FI-02" : true, "FI-03" : true, "FI-04" : true,
"FI-05" : true, "FI-06" : true, "FI-07" : true, "FI-08" : true, "FI-09" : true,
"FI-10" : true, "FI-11" : true, "FI-12" : true, "FI-13" : true, "FI-14" : true,
"FI-15" : true, "FI-16" : true, "FI-17" : true, "FI-18" : true, "FI-19" : true,
"FJ-C" : true, "FJ-E" : true, "FJ-N" : true, "FJ-R" : true, "FJ-W" : true,
"FM-KSA" : true, "FM-PNI" : true, "FM-TRK" : true, "FM-YAP" : true, "FR-01" : true,
"FR-02" : true, "FR-03" : true, "FR-04" : true, "FR-05" : true, "FR-06" : true,
"FR-07" : true, "FR-08" : true, "FR-09" : true, "FR-10" : true, "FR-11" : true,
"FR-12" : true, "FR-13" : true, "FR-14" : true, "FR-15" : true, "FR-16" : true,
"FR-17" : true, "FR-18" : true, "FR-19" : true, "FR-21" : true, "FR-22" : true,
"FR-23" : true, "FR-24" : true, "FR-25" : true, "FR-26" : true, "FR-27" : true,
"FR-28" : true, "FR-29" : true, "FR-2A" : true, "FR-2B" : true, "FR-30" : true,
"FR-31" : true, "FR-32" : true, "FR-33" : true, "FR-34" : true, "FR-35" : true,
"FR-36" : true, "FR-37" : true, "FR-38" : true, "FR-39" : true, "FR-40" : true,
"FR-41" : true, "FR-42" : true, "FR-43" : true, "FR-44" : true, "FR-45" : true,
"FR-46" : true, "FR-47" : true, "FR-48" : true, "FR-49" : true, "FR-50" : true,
"FR-51" : true, "FR-52" : true, "FR-53" : true, "FR-54" : true, "FR-55" : true,
"FR-56" : true, "FR-57" : true, "FR-58" : true, "FR-59" : true, "FR-60" : true,
"FR-61" : true, "FR-62" : true, "FR-63" : true, "FR-64" : true, "FR-65" : true,
"FR-66" : true, "FR-67" : true, "FR-68" : true, "FR-69" : true, "FR-70" : true,
"FR-71" : true, "FR-72" : true, "FR-73" : true, "FR-74" : true, "FR-75" : true,
"FR-76" : true, "FR-77" : true, "FR-78" : true, "FR-79" : true, "FR-80" : true,
"FR-81" : true, "FR-82" : true, "FR-83" : true, "FR-84" : true, "FR-85" : true,
"FR-86" : true, "FR-87" : true, "FR-88" : true, "FR-89" : true, "FR-90" : true,
"FR-91" : true, "FR-92" : true, "FR-93" : true, "FR-94" : true, "FR-95" : true,
"FR-ARA" : true, "FR-BFC" : true, "FR-BL" : true, "FR-BRE" : true, "FR-COR" : true,
"FR-CP" : true, "FR-CVL" : true, "FR-GES" : true, "FR-GF" : true, "FR-GP" : true,
"FR-GUA" : true, "FR-HDF" : true, "FR-IDF" : true, "FR-LRE" : true, "FR-MAY" : true,
"FR-MF" : true, "FR-MQ" : true, "FR-NAQ" : true, "FR-NC" : true, "FR-NOR" : true,
"FR-OCC" : true, "FR-PAC" : true, "FR-PDL" : true, "FR-PF" : true, "FR-PM" : true,
"FR-RE" : true, "FR-TF" : true, "FR-WF" : true, "FR-YT" : true, "GA-1" : true,
"GA-2" : true, "GA-3" : true, "GA-4" : true, "GA-5" : true, "GA-6" : true,
"GA-7" : true, "GA-8" : true, "GA-9" : true, "GB-ABC" : true, "GB-ABD" : true,
"GB-ABE" : true, "GB-AGB" : true, "GB-AGY" : true, "GB-AND" : true, "GB-ANN" : true,
"GB-ANS" : true, "GB-BAS" : true, "GB-BBD" : true, "GB-BDF" : true, "GB-BDG" : true,
"GB-BEN" : true, "GB-BEX" : true, "GB-BFS" : true, "GB-BGE" : true, "GB-BGW" : true,
"GB-BIR" : true, "GB-BKM" : true, "GB-BMH" : true, "GB-BNE" : true, "GB-BNH" : true,
"GB-BNS" : true, "GB-BOL" : true, "GB-BPL" : true, "GB-BRC" : true, "GB-BRD" : true,
"GB-BRY" : true, "GB-BST" : true, "GB-BUR" : true, "GB-CAM" : true, "GB-CAY" : true,
"GB-CBF" : true, "GB-CCG" : true, "GB-CGN" : true, "GB-CHE" : true, "GB-CHW" : true,
"GB-CLD" : true, "GB-CLK" : true, "GB-CMA" : true, "GB-CMD" : true, "GB-CMN" : true,
"GB-CON" : true, "GB-COV" : true, "GB-CRF" : true, "GB-CRY" : true, "GB-CWY" : true,
"GB-DAL" : true, "GB-DBY" : true, "GB-DEN" : true, "GB-DER" : true, "GB-DEV" : true,
"GB-DGY" : true, "GB-DNC" : true, "GB-DND" : true, "GB-DOR" : true, "GB-DRS" : true,
"GB-DUD" : true, "GB-DUR" : true, "GB-EAL" : true, "GB-EAW" : true, "GB-EAY" : true,
"GB-EDH" : true, "GB-EDU" : true, "GB-ELN" : true, "GB-ELS" : true, "GB-ENF" : true,
"GB-ENG" : true, "GB-ERW" : true, "GB-ERY" : true, "GB-ESS" : true, "GB-ESX" : true,
"GB-FAL" : true, "GB-FIF" : true, "GB-FLN" : true, "GB-FMO" : true, "GB-GAT" : true,
"GB-GBN" : true, "GB-GLG" : true, "GB-GLS" : true, "GB-GRE" : true, "GB-GWN" : true,
"GB-HAL" : true, "GB-HAM" : true, "GB-HAV" : true, "GB-HCK" : true, "GB-HEF" : true,
"GB-HIL" : true, "GB-HLD" : true, "GB-HMF" : true, "GB-HNS" : true, "GB-HPL" : true,
"GB-HRT" : true, "GB-HRW" : true, "GB-HRY" : true, "GB-IOS" : true, "GB-IOW" : true,
"GB-ISL" : true, "GB-IVC" : true, "GB-KEC" : true, "GB-KEN" : true, "GB-KHL" : true,
"GB-KIR" : true, "GB-KTT" : true, "GB-KWL" : true, "GB-LAN" : true, "GB-LBC" : true,
"GB-LBH" : true, "GB-LCE" : true, "GB-LDS" : true, "GB-LEC" : true, "GB-LEW" : true,
"GB-LIN" : true, "GB-LIV" : true, "GB-LND" : true, "GB-LUT" : true, "GB-MAN" : true,
"GB-MDB" : true, "GB-MDW" : true, "GB-MEA" : true, "GB-MIK" : true, "GD-01" : true,
"GB-MLN" : true, "GB-MON" : true, "GB-MRT" : true, "GB-MRY" : true, "GB-MTY" : true,
"GB-MUL" : true, "GB-NAY" : true, "GB-NBL" : true, "GB-NEL" : true, "GB-NET" : true,
"GB-NFK" : true, "GB-NGM" : true, "GB-NIR" : true, "GB-NLK" : true, "GB-NLN" : true,
"GB-NMD" : true, "GB-NSM" : true, "GB-NTH" : true, "GB-NTL" : true, "GB-NTT" : true,
"GB-NTY" : true, "GB-NWM" : true, "GB-NWP" : true, "GB-NYK" : true, "GB-OLD" : true,
"GB-ORK" : true, "GB-OXF" : true, "GB-PEM" : true, "GB-PKN" : true, "GB-PLY" : true,
"GB-POL" : true, "GB-POR" : true, "GB-POW" : true, "GB-PTE" : true, "GB-RCC" : true,
"GB-RCH" : true, "GB-RCT" : true, "GB-RDB" : true, "GB-RDG" : true, "GB-RFW" : true,
"GB-RIC" : true, "GB-ROT" : true, "GB-RUT" : true, "GB-SAW" : true, "GB-SAY" : true,
"GB-SCB" : true, "GB-SCT" : true, "GB-SFK" : true, "GB-SFT" : true, "GB-SGC" : true,
"GB-SHF" : true, "GB-SHN" : true, "GB-SHR" : true, "GB-SKP" : true, "GB-SLF" : true,
"GB-SLG" : true, "GB-SLK" : true, "GB-SND" : true, "GB-SOL" : true, "GB-SOM" : true,
"GB-SOS" : true, "GB-SRY" : true, "GB-STE" : true, "GB-STG" : true, "GB-STH" : true,
"GB-STN" : true, "GB-STS" : true, "GB-STT" : true, "GB-STY" : true, "GB-SWA" : true,
"GB-SWD" : true, "GB-SWK" : true, "GB-TAM" : true, "GB-TFW" : true, "GB-THR" : true,
"GB-TOB" : true, "GB-TOF" : true, "GB-TRF" : true, "GB-TWH" : true, "GB-UKM" : true,
"GB-VGL" : true, "GB-WAR" : true, "GB-WBK" : true, "GB-WDU" : true, "GB-WFT" : true,
"GB-WGN" : true, "GB-WIL" : true, "GB-WKF" : true, "GB-WLL" : true, "GB-WLN" : true,
"GB-WLS" : true, "GB-WLV" : true, "GB-WND" : true, "GB-WNM" : true, "GB-WOK" : true,
"GB-WOR" : true, "GB-WRL" : true, "GB-WRT" : true, "GB-WRX" : true, "GB-WSM" : true,
"GB-WSX" : true, "GB-YOR" : true, "GB-ZET" : true, "GD-02" : true, "GD-03" : true,
"GD-04" : true, "GD-05" : true, "GD-06" : true, "GD-10" : true, "GE-AB" : true,
"GE-AJ" : true, "GE-GU" : true, "GE-IM" : true, "GE-KA" : true, "GE-KK" : true,
"GE-MM" : true, "GE-RL" : true, "GE-SJ" : true, "GE-SK" : true, "GE-SZ" : true,
"GE-TB" : true, "GH-AA" : true, "GH-AH" : true, "GH-BA" : true, "GH-CP" : true,
"GH-EP" : true, "GH-NP" : true, "GH-TV" : true, "GH-UE" : true, "GH-UW" : true,
"GH-WP" : true, "GL-KU" : true, "GL-QA" : true, "GL-QE" : true, "GL-SM" : true,
"GM-B" : true, "GM-L" : true, "GM-M" : true, "GM-N" : true, "GM-U" : true,
"GM-W" : true, "GN-B" : true, "GN-BE" : true, "GN-BF" : true, "GN-BK" : true,
"GN-C" : true, "GN-CO" : true, "GN-D" : true, "GN-DB" : true, "GN-DI" : true,
"GN-DL" : true, "GN-DU" : true, "GN-F" : true, "GN-FA" : true, "GN-FO" : true,
"GN-FR" : true, "GN-GA" : true, "GN-GU" : true, "GN-K" : true, "GN-KA" : true,
"GN-KB" : true, "GN-KD" : true, "GN-KE" : true, "GN-KN" : true, "GN-KO" : true,
"GN-KS" : true, "GN-L" : true, "GN-LA" : true, "GN-LE" : true, "GN-LO" : true,
"GN-M" : true, "GN-MC" : true, "GN-MD" : true, "GN-ML" : true, "GN-MM" : true,
"GN-N" : true, "GN-NZ" : true, "GN-PI" : true, "GN-SI" : true, "GN-TE" : true,
"GN-TO" : true, "GN-YO" : true, "GQ-AN" : true, "GQ-BN" : true, "GQ-BS" : true,
"GQ-C" : true, "GQ-CS" : true, "GQ-I" : true, "GQ-KN" : true, "GQ-LI" : true,
"GQ-WN" : true, "GR-01" : true, "GR-03" : true, "GR-04" : true, "GR-05" : true,
"GR-06" : true, "GR-07" : true, "GR-11" : true, "GR-12" : true, "GR-13" : true,
"GR-14" : true, "GR-15" : true, "GR-16" : true, "GR-17" : true, "GR-21" : true,
"GR-22" : true, "GR-23" : true, "GR-24" : true, "GR-31" : true, "GR-32" : true,
"GR-33" : true, "GR-34" : true, "GR-41" : true, "GR-42" : true, "GR-43" : true,
"GR-44" : true, "GR-51" : true, "GR-52" : true, "GR-53" : true, "GR-54" : true,
"GR-55" : true, "GR-56" : true, "GR-57" : true, "GR-58" : true, "GR-59" : true,
"GR-61" : true, "GR-62" : true, "GR-63" : true, "GR-64" : true, "GR-69" : true,
"GR-71" : true, "GR-72" : true, "GR-73" : true, "GR-81" : true, "GR-82" : true,
"GR-83" : true, "GR-84" : true, "GR-85" : true, "GR-91" : true, "GR-92" : true,
"GR-93" : true, "GR-94" : true, "GR-A" : true, "GR-A1" : true, "GR-B" : true,
"GR-C" : true, "GR-D" : true, "GR-E" : true, "GR-F" : true, "GR-G" : true,
"GR-H" : true, "GR-I" : true, "GR-J" : true, "GR-K" : true, "GR-L" : true,
"GR-M" : true, "GT-AV" : true, "GT-BV" : true, "GT-CM" : true, "GT-CQ" : true,
"GT-ES" : true, "GT-GU" : true, "GT-HU" : true, "GT-IZ" : true, "GT-JA" : true,
"GT-JU" : true, "GT-PE" : true, "GT-PR" : true, "GT-QC" : true, "GT-QZ" : true,
"GT-RE" : true, "GT-SA" : true, "GT-SM" : true, "GT-SO" : true, "GT-SR" : true,
"GT-SU" : true, "GT-TO" : true, "GT-ZA" : true, "GW-BA" : true, "GW-BL" : true,
"GW-BM" : true, "GW-BS" : true, "GW-CA" : true, "GW-GA" : true, "GW-L" : true,
"GW-N" : true, "GW-OI" : true, "GW-QU" : true, "GW-S" : true, "GW-TO" : true,
"GY-BA" : true, "GY-CU" : true, "GY-DE" : true, "GY-EB" : true, "GY-ES" : true,
"GY-MA" : true, "GY-PM" : true, "GY-PT" : true, "GY-UD" : true, "GY-UT" : true,
"HN-AT" : true, "HN-CH" : true, "HN-CL" : true, "HN-CM" : true, "HN-CP" : true,
"HN-CR" : true, "HN-EP" : true, "HN-FM" : true, "HN-GD" : true, "HN-IB" : true,
"HN-IN" : true, "HN-LE" : true, "HN-LP" : true, "HN-OC" : true, "HN-OL" : true,
"HN-SB" : true, "HN-VA" : true, "HN-YO" : true, "HR-01" : true, "HR-02" : true,
"HR-03" : true, "HR-04" : true, "HR-05" : true, "HR-06" : true, "HR-07" : true,
"HR-08" : true, "HR-09" : true, "HR-10" : true, "HR-11" : true, "HR-12" : true,
"HR-13" : true, "HR-14" : true, "HR-15" : true, "HR-16" : true, "HR-17" : true,
"HR-18" : true, "HR-19" : true, "HR-20" : true, "HR-21" : true, "HT-AR" : true,
"HT-CE" : true, "HT-GA" : true, "HT-ND" : true, "HT-NE" : true, "HT-NO" : true,
"HT-OU" : true, "HT-SD" : true, "HT-SE" : true, "HU-BA" : true, "HU-BC" : true,
"HU-BE" : true, "HU-BK" : true, "HU-BU" : true, "HU-BZ" : true, "HU-CS" : true,
"HU-DE" : true, "HU-DU" : true, "HU-EG" : true, "HU-ER" : true, "HU-FE" : true,
"HU-GS" : true, "HU-GY" : true, "HU-HB" : true, "HU-HE" : true, "HU-HV" : true,
"HU-JN" : true, "HU-KE" : true, "HU-KM" : true, "HU-KV" : true, "HU-MI" : true,
"HU-NK" : true, "HU-NO" : true, "HU-NY" : true, "HU-PE" : true, "HU-PS" : true,
"HU-SD" : true, "HU-SF" : true, "HU-SH" : true, "HU-SK" : true, "HU-SN" : true,
"HU-SO" : true, "HU-SS" : true, "HU-ST" : true, "HU-SZ" : true, "HU-TB" : true,
"HU-TO" : true, "HU-VA" : true, "HU-VE" : true, "HU-VM" : true, "HU-ZA" : true,
"HU-ZE" : true, "ID-AC" : true, "ID-BA" : true, "ID-BB" : true, "ID-BE" : true,
"ID-BT" : true, "ID-GO" : true, "ID-IJ" : true, "ID-JA" : true, "ID-JB" : true,
"ID-JI" : true, "ID-JK" : true, "ID-JT" : true, "ID-JW" : true, "ID-KA" : true,
"ID-KB" : true, "ID-KI" : true, "ID-KR" : true, "ID-KS" : true, "ID-KT" : true,
"ID-LA" : true, "ID-MA" : true, "ID-ML" : true, "ID-MU" : true, "ID-NB" : true,
"ID-NT" : true, "ID-NU" : true, "ID-PA" : true, "ID-PB" : true, "ID-RI" : true,
"ID-SA" : true, "ID-SB" : true, "ID-SG" : true, "ID-SL" : true, "ID-SM" : true,
"ID-SN" : true, "ID-SR" : true, "ID-SS" : true, "ID-ST" : true, "ID-SU" : true,
"ID-YO" : true, "IE-C" : true, "IE-CE" : true, "IE-CN" : true, "IE-CO" : true,
"IE-CW" : true, "IE-D" : true, "IE-DL" : true, "IE-G" : true, "IE-KE" : true,
"IE-KK" : true, "IE-KY" : true, "IE-L" : true, "IE-LD" : true, "IE-LH" : true,
"IE-LK" : true, "IE-LM" : true, "IE-LS" : true, "IE-M" : true, "IE-MH" : true,
"IE-MN" : true, "IE-MO" : true, "IE-OY" : true, "IE-RN" : true, "IE-SO" : true,
"IE-TA" : true, "IE-U" : true, "IE-WD" : true, "IE-WH" : true, "IE-WW" : true,
"IE-WX" : true, "IL-D" : true, "IL-HA" : true, "IL-JM" : true, "IL-M" : true,
"IL-TA" : true, "IL-Z" : true, "IN-AN" : true, "IN-AP" : true, "IN-AR" : true,
"IN-AS" : true, "IN-BR" : true, "IN-CH" : true, "IN-CT" : true, "IN-DD" : true,
"IN-DL" : true, "IN-DN" : true, "IN-GA" : true, "IN-GJ" : true, "IN-HP" : true,
"IN-HR" : true, "IN-JH" : true, "IN-JK" : true, "IN-KA" : true, "IN-KL" : true,
"IN-LD" : true, "IN-MH" : true, "IN-ML" : true, "IN-MN" : true, "IN-MP" : true,
"IN-MZ" : true, "IN-NL" : true, "IN-OR" : true, "IN-PB" : true, "IN-PY" : true,
"IN-RJ" : true, "IN-SK" : true, "IN-TN" : true, "IN-TR" : true, "IN-UP" : true,
"IN-UT" : true, "IN-WB" : true, "IQ-AN" : true, "IQ-AR" : true, "IQ-BA" : true,
"IQ-BB" : true, "IQ-BG" : true, "IQ-DA" : true, "IQ-DI" : true, "IQ-DQ" : true,
"IQ-KA" : true, "IQ-MA" : true, "IQ-MU" : true, "IQ-NA" : true, "IQ-NI" : true,
"IQ-QA" : true, "IQ-SD" : true, "IQ-SW" : true, "IQ-TS" : true, "IQ-WA" : true,
"IR-01" : true, "IR-02" : true, "IR-03" : true, "IR-04" : true, "IR-05" : true,
"IR-06" : true, "IR-07" : true, "IR-08" : true, "IR-10" : true, "IR-11" : true,
"IR-12" : true, "IR-13" : true, "IR-14" : true, "IR-15" : true, "IR-16" : true,
"IR-17" : true, "IR-18" : true, "IR-19" : true, "IR-20" : true, "IR-21" : true,
"IR-22" : true, "IR-23" : true, "IR-24" : true, "IR-25" : true, "IR-26" : true,
"IR-27" : true, "IR-28" : true, "IR-29" : true, "IR-30" : true, "IR-31" : true,
"IS-0" : true, "IS-1" : true, "IS-2" : true, "IS-3" : true, "IS-4" : true,
"IS-5" : true, "IS-6" : true, "IS-7" : true, "IS-8" : true, "IT-21" : true,
"IT-23" : true, "IT-25" : true, "IT-32" : true, "IT-34" : true, "IT-36" : true,
"IT-42" : true, "IT-45" : true, "IT-52" : true, "IT-55" : true, "IT-57" : true,
"IT-62" : true, "IT-65" : true, "IT-67" : true, "IT-72" : true, "IT-75" : true,
"IT-77" : true, "IT-78" : true, "IT-82" : true, "IT-88" : true, "IT-AG" : true,
"IT-AL" : true, "IT-AN" : true, "IT-AO" : true, "IT-AP" : true, "IT-AQ" : true,
"IT-AR" : true, "IT-AT" : true, "IT-AV" : true, "IT-BA" : true, "IT-BG" : true,
"IT-BI" : true, "IT-BL" : true, "IT-BN" : true, "IT-BO" : true, "IT-BR" : true,
"IT-BS" : true, "IT-BT" : true, "IT-BZ" : true, "IT-CA" : true, "IT-CB" : true,
"IT-CE" : true, "IT-CH" : true, "IT-CI" : true, "IT-CL" : true, "IT-CN" : true,
"IT-CO" : true, "IT-CR" : true, "IT-CS" : true, "IT-CT" : true, "IT-CZ" : true,
"IT-EN" : true, "IT-FC" : true, "IT-FE" : true, "IT-FG" : true, "IT-FI" : true,
"IT-FM" : true, "IT-FR" : true, "IT-GE" : true, "IT-GO" : true, "IT-GR" : true,
"IT-IM" : true, "IT-IS" : true, "IT-KR" : true, "IT-LC" : true, "IT-LE" : true,
"IT-LI" : true, "IT-LO" : true, "IT-LT" : true, "IT-LU" : true, "IT-MB" : true,
"IT-MC" : true, "IT-ME" : true, "IT-MI" : true, "IT-MN" : true, "IT-MO" : true,
"IT-MS" : true, "IT-MT" : true, "IT-NA" : true, "IT-NO" : true, "IT-NU" : true,
"IT-OG" : true, "IT-OR" : true, "IT-OT" : true, "IT-PA" : true, "IT-PC" : true,
"IT-PD" : true, "IT-PE" : true, "IT-PG" : true, "IT-PI" : true, "IT-PN" : true,
"IT-PO" : true, "IT-PR" : true, "IT-PT" : true, "IT-PU" : true, "IT-PV" : true,
"IT-PZ" : true, "IT-RA" : true, "IT-RC" : true, "IT-RE" : true, "IT-RG" : true,
"IT-RI" : true, "IT-RM" : true, "IT-RN" : true, "IT-RO" : true, "IT-SA" : true,
"IT-SI" : true, "IT-SO" : true, "IT-SP" : true, "IT-SR" : true, "IT-SS" : true,
"IT-SV" : true, "IT-TA" : true, "IT-TE" : true, "IT-TN" : true, "IT-TO" : true,
"IT-TP" : true, "IT-TR" : true, "IT-TS" : true, "IT-TV" : true, "IT-UD" : true,
"IT-VA" : true, "IT-VB" : true, "IT-VC" : true, "IT-VE" : true, "IT-VI" : true,
"IT-VR" : true, "IT-VS" : true, "IT-VT" : true, "IT-VV" : true, "JM-01" : true,
"JM-02" : true, "JM-03" : true, "JM-04" : true, "JM-05" : true, "JM-06" : true,
"JM-07" : true, "JM-08" : true, "JM-09" : true, "JM-10" : true, "JM-11" : true,
"JM-12" : true, "JM-13" : true, "JM-14" : true, "JO-AJ" : true, "JO-AM" : true,
"JO-AQ" : true, "JO-AT" : true, "JO-AZ" : true, "JO-BA" : true, "JO-IR" : true,
"JO-JA" : true, "JO-KA" : true, "JO-MA" : true, "JO-MD" : true, "JO-MN" : true,
"JP-01" : true, "JP-02" : true, "JP-03" : true, "JP-04" : true, "JP-05" : true,
"JP-06" : true, "JP-07" : true, "JP-08" : true, "JP-09" : true, "JP-10" : true,
"JP-11" : true, "JP-12" : true, "JP-13" : true, "JP-14" : true, "JP-15" : true,
"JP-16" : true, "JP-17" : true, "JP-18" : true, "JP-19" : true, "JP-20" : true,
"JP-21" : true, "JP-22" : true, "JP-23" : true, "JP-24" : true, "JP-25" : true,
"JP-26" : true, "JP-27" : true, "JP-28" : true, "JP-29" : true, "JP-30" : true,
"JP-31" : true, "JP-32" : true, "JP-33" : true, "JP-34" : true, "JP-35" : true,
"JP-36" : true, "JP-37" : true, "JP-38" : true, "JP-39" : true, "JP-40" : true,
"JP-41" : true, "JP-42" : true, "JP-43" : true, "JP-44" : true, "JP-45" : true,
"JP-46" : true, "JP-47" : true, "KE-110" : true, "KE-200" : true, "KE-300" : true,
"KE-400" : true, "KE-500" : true, "KE-700" : true, "KE-800" : true, "KG-B" : true,
"KG-C" : true, "KG-GB" : true, "KG-J" : true, "KG-N" : true, "KG-O" : true,
"KG-T" : true, "KG-Y" : true, "KH-1" : true, "KH-10" : true, "KH-11" : true,
"KH-12" : true, "KH-13" : true, "KH-14" : true, "KH-15" : true, "KH-16" : true,
"KH-17" : true, "KH-18" : true, "KH-19" : true, "KH-2" : true, "KH-20" : true,
"KH-21" : true, "KH-22" : true, "KH-23" : true, "KH-24" : true, "KH-3" : true,
"KH-4" : true, "KH-5" : true, "KH-6" : true, "KH-7" : true, "KH-8" : true,
"KH-9" : true, "KI-G" : true, "KI-L" : true, "KI-P" : true, "KM-A" : true,
"KM-G" : true, "KM-M" : true, "KN-01" : true, "KN-02" : true, "KN-03" : true,
"KN-04" : true, "KN-05" : true, "KN-06" : true, "KN-07" : true, "KN-08" : true,
"KN-09" : true, "KN-10" : true, "KN-11" : true, "KN-12" : true, "KN-13" : true,
"KN-15" : true, "KN-K" : true, "KN-N" : true, "KP-01" : true, "KP-02" : true,
"KP-03" : true, "KP-04" : true, "KP-05" : true, "KP-06" : true, "KP-07" : true,
"KP-08" : true, "KP-09" : true, "KP-10" : true, "KP-13" : true, "KR-11" : true,
"KR-26" : true, "KR-27" : true, "KR-28" : true, "KR-29" : true, "KR-30" : true,
"KR-31" : true, "KR-41" : true, "KR-42" : true, "KR-43" : true, "KR-44" : true,
"KR-45" : true, "KR-46" : true, "KR-47" : true, "KR-48" : true, "KR-49" : true,
"KW-AH" : true, "KW-FA" : true, "KW-HA" : true, "KW-JA" : true, "KW-KU" : true,
"KW-MU" : true, "KZ-AKM" : true, "KZ-AKT" : true, "KZ-ALA" : true, "KZ-ALM" : true,
"KZ-AST" : true, "KZ-ATY" : true, "KZ-KAR" : true, "KZ-KUS" : true, "KZ-KZY" : true,
"KZ-MAN" : true, "KZ-PAV" : true, "KZ-SEV" : true, "KZ-VOS" : true, "KZ-YUZ" : true,
"KZ-ZAP" : true, "KZ-ZHA" : true, "LA-AT" : true, "LA-BK" : true, "LA-BL" : true,
"LA-CH" : true, "LA-HO" : true, "LA-KH" : true, "LA-LM" : true, "LA-LP" : true,
"LA-OU" : true, "LA-PH" : true, "LA-SL" : true, "LA-SV" : true, "LA-VI" : true,
"LA-VT" : true, "LA-XA" : true, "LA-XE" : true, "LA-XI" : true, "LA-XS" : true,
"LB-AK" : true, "LB-AS" : true, "LB-BA" : true, "LB-BH" : true, "LB-BI" : true,
"LB-JA" : true, "LB-JL" : true, "LB-NA" : true, "LI-01" : true, "LI-02" : true,
"LI-03" : true, "LI-04" : true, "LI-05" : true, "LI-06" : true, "LI-07" : true,
"LI-08" : true, "LI-09" : true, "LI-10" : true, "LI-11" : true, "LK-1" : true,
"LK-11" : true, "LK-12" : true, "LK-13" : true, "LK-2" : true, "LK-21" : true,
"LK-22" : true, "LK-23" : true, "LK-3" : true, "LK-31" : true, "LK-32" : true,
"LK-33" : true, "LK-4" : true, "LK-41" : true, "LK-42" : true, "LK-43" : true,
"LK-44" : true, "LK-45" : true, "LK-5" : true, "LK-51" : true, "LK-52" : true,
"LK-53" : true, "LK-6" : true, "LK-61" : true, "LK-62" : true, "LK-7" : true,
"LK-71" : true, "LK-72" : true, "LK-8" : true, "LK-81" : true, "LK-82" : true,
"LK-9" : true, "LK-91" : true, "LK-92" : true, "LR-BG" : true, "LR-BM" : true,
"LR-CM" : true, "LR-GB" : true, "LR-GG" : true, "LR-GK" : true, "LR-LO" : true,
"LR-MG" : true, "LR-MO" : true, "LR-MY" : true, "LR-NI" : true, "LR-RI" : true,
"LR-SI" : true, "LS-A" : true, "LS-B" : true, "LS-C" : true, "LS-D" : true,
"LS-E" : true, "LS-F" : true, "LS-G" : true, "LS-H" : true, "LS-J" : true,
"LS-K" : true, "LT-AL" : true, "LT-KL" : true, "LT-KU" : true, "LT-MR" : true,
"LT-PN" : true, "LT-SA" : true, "LT-TA" : true, "LT-TE" : true, "LT-UT" : true,
"LT-VL" : true, "LU-D" : true, "LU-G" : true, "LU-L" : true, "LV-001" : true,
"LV-002" : true, "LV-003" : true, "LV-004" : true, "LV-005" : true, "LV-006" : true,
"LV-007" : true, "LV-008" : true, "LV-009" : true, "LV-010" : true, "LV-011" : true,
"LV-012" : true, "LV-013" : true, "LV-014" : true, "LV-015" : true, "LV-016" : true,
"LV-017" : true, "LV-018" : true, "LV-019" : true, "LV-020" : true, "LV-021" : true,
"LV-022" : true, "LV-023" : true, "LV-024" : true, "LV-025" : true, "LV-026" : true,
"LV-027" : true, "LV-028" : true, "LV-029" : true, "LV-030" : true, "LV-031" : true,
"LV-032" : true, "LV-033" : true, "LV-034" : true, "LV-035" : true, "LV-036" : true,
"LV-037" : true, "LV-038" : true, "LV-039" : true, "LV-040" : true, "LV-041" : true,
"LV-042" : true, "LV-043" : true, "LV-044" : true, "LV-045" : true, "LV-046" : true,
"LV-047" : true, "LV-048" : true, "LV-049" : true, "LV-050" : true, "LV-051" : true,
"LV-052" : true, "LV-053" : true, "LV-054" : true, "LV-055" : true, "LV-056" : true,
"LV-057" : true, "LV-058" : true, "LV-059" : true, "LV-060" : true, "LV-061" : true,
"LV-062" : true, "LV-063" : true, "LV-064" : true, "LV-065" : true, "LV-066" : true,
"LV-067" : true, "LV-068" : true, "LV-069" : true, "LV-070" : true, "LV-071" : true,
"LV-072" : true, "LV-073" : true, "LV-074" : true, "LV-075" : true, "LV-076" : true,
"LV-077" : true, "LV-078" : true, "LV-079" : true, "LV-080" : true, "LV-081" : true,
"LV-082" : true, "LV-083" : true, "LV-084" : true, "LV-085" : true, "LV-086" : true,
"LV-087" : true, "LV-088" : true, "LV-089" : true, "LV-090" : true, "LV-091" : true,
"LV-092" : true, "LV-093" : true, "LV-094" : true, "LV-095" : true, "LV-096" : true,
"LV-097" : true, "LV-098" : true, "LV-099" : true, "LV-100" : true, "LV-101" : true,
"LV-102" : true, "LV-103" : true, "LV-104" : true, "LV-105" : true, "LV-106" : true,
"LV-107" : true, "LV-108" : true, "LV-109" : true, "LV-110" : true, "LV-DGV" : true,
"LV-JEL" : true, "LV-JKB" : true, "LV-JUR" : true, "LV-LPX" : true, "LV-REZ" : true,
"LV-RIX" : true, "LV-VEN" : true, "LV-VMR" : true, "LY-BA" : true, "LY-BU" : true,
"LY-DR" : true, "LY-GT" : true, "LY-JA" : true, "LY-JB" : true, "LY-JG" : true,
"LY-JI" : true, "LY-JU" : true, "LY-KF" : true, "LY-MB" : true, "LY-MI" : true,
"LY-MJ" : true, "LY-MQ" : true, "LY-NL" : true, "LY-NQ" : true, "LY-SB" : true,
"LY-SR" : true, "LY-TB" : true, "LY-WA" : true, "LY-WD" : true, "LY-WS" : true,
"LY-ZA" : true, "MA-01" : true, "MA-02" : true, "MA-03" : true, "MA-04" : true,
"MA-05" : true, "MA-06" : true, "MA-07" : true, "MA-08" : true, "MA-09" : true,
"MA-10" : true, "MA-11" : true, "MA-12" : true, "MA-13" : true, "MA-14" : true,
"MA-15" : true, "MA-16" : true, "MA-AGD" : true, "MA-AOU" : true, "MA-ASZ" : true,
"MA-AZI" : true, "MA-BEM" : true, "MA-BER" : true, "MA-BES" : true, "MA-BOD" : true,
"MA-BOM" : true, "MA-CAS" : true, "MA-CHE" : true, "MA-CHI" : true, "MA-CHT" : true,
"MA-ERR" : true, "MA-ESI" : true, "MA-ESM" : true, "MA-FAH" : true, "MA-FES" : true,
"MA-FIG" : true, "MA-GUE" : true, "MA-HAJ" : true, "MA-HAO" : true, "MA-HOC" : true,
"MA-IFR" : true, "MA-INE" : true, "MA-JDI" : true, "MA-JRA" : true, "MA-KEN" : true,
"MA-KES" : true, "MA-KHE" : true, "MA-KHN" : true, "MA-KHO" : true, "MA-LAA" : true,
"MA-LAR" : true, "MA-MED" : true, "MA-MEK" : true, "MA-MMD" : true, "MA-MMN" : true,
"MA-MOH" : true, "MA-MOU" : true, "MA-NAD" : true, "MA-NOU" : true, "MA-OUA" : true,
"MA-OUD" : true, "MA-OUJ" : true, "MA-RAB" : true, "MA-SAF" : true, "MA-SAL" : true,
"MA-SEF" : true, "MA-SET" : true, "MA-SIK" : true, "MA-SKH" : true, "MA-SYB" : true,
"MA-TAI" : true, "MA-TAO" : true, "MA-TAR" : true, "MA-TAT" : true, "MA-TAZ" : true,
"MA-TET" : true, "MA-TIZ" : true, "MA-TNG" : true, "MA-TNT" : true, "MA-ZAG" : true,
"MC-CL" : true, "MC-CO" : true, "MC-FO" : true, "MC-GA" : true, "MC-JE" : true,
"MC-LA" : true, "MC-MA" : true, "MC-MC" : true, "MC-MG" : true, "MC-MO" : true,
"MC-MU" : true, "MC-PH" : true, "MC-SD" : true, "MC-SO" : true, "MC-SP" : true,
"MC-SR" : true, "MC-VR" : true, "MD-AN" : true, "MD-BA" : true, "MD-BD" : true,
"MD-BR" : true, "MD-BS" : true, "MD-CA" : true, "MD-CL" : true, "MD-CM" : true,
"MD-CR" : true, "MD-CS" : true, "MD-CT" : true, "MD-CU" : true, "MD-DO" : true,
"MD-DR" : true, "MD-DU" : true, "MD-ED" : true, "MD-FA" : true, "MD-FL" : true,
"MD-GA" : true, "MD-GL" : true, "MD-HI" : true, "MD-IA" : true, "MD-LE" : true,
"MD-NI" : true, "MD-OC" : true, "MD-OR" : true, "MD-RE" : true, "MD-RI" : true,
"MD-SD" : true, "MD-SI" : true, "MD-SN" : true, "MD-SO" : true, "MD-ST" : true,
"MD-SV" : true, "MD-TA" : true, "MD-TE" : true, "MD-UN" : true, "ME-01" : true,
"ME-02" : true, "ME-03" : true, "ME-04" : true, "ME-05" : true, "ME-06" : true,
"ME-07" : true, "ME-08" : true, "ME-09" : true, "ME-10" : true, "ME-11" : true,
"ME-12" : true, "ME-13" : true, "ME-14" : true, "ME-15" : true, "ME-16" : true,
"ME-17" : true, "ME-18" : true, "ME-19" : true, "ME-20" : true, "ME-21" : true,
"MG-A" : true, "MG-D" : true, "MG-F" : true, "MG-M" : true, "MG-T" : true,
"MG-U" : true, "MH-ALK" : true, "MH-ALL" : true, "MH-ARN" : true, "MH-AUR" : true,
"MH-EBO" : true, "MH-ENI" : true, "MH-JAB" : true, "MH-JAL" : true, "MH-KIL" : true,
"MH-KWA" : true, "MH-L" : true, "MH-LAE" : true, "MH-LIB" : true, "MH-LIK" : true,
"MH-MAJ" : true, "MH-MAL" : true, "MH-MEJ" : true, "MH-MIL" : true, "MH-NMK" : true,
"MH-NMU" : true, "MH-RON" : true, "MH-T" : true, "MH-UJA" : true, "MH-UTI" : true,
"MH-WTJ" : true, "MH-WTN" : true, "MK-01" : true, "MK-02" : true, "MK-03" : true,
"MK-04" : true, "MK-05" : true, "MK-06" : true, "MK-07" : true, "MK-08" : true,
"MK-09" : true, "MK-10" : true, "MK-11" : true, "MK-12" : true, "MK-13" : true,
"MK-14" : true, "MK-15" : true, "MK-16" : true, "MK-17" : true, "MK-18" : true,
"MK-19" : true, "MK-20" : true, "MK-21" : true, "MK-22" : true, "MK-23" : true,
"MK-24" : true, "MK-25" : true, "MK-26" : true, "MK-27" : true, "MK-28" : true,
"MK-29" : true, "MK-30" : true, "MK-31" : true, "MK-32" : true, "MK-33" : true,
"MK-34" : true, "MK-35" : true, "MK-36" : true, "MK-37" : true, "MK-38" : true,
"MK-39" : true, "MK-40" : true, "MK-41" : true, "MK-42" : true, "MK-43" : true,
"MK-44" : true, "MK-45" : true, "MK-46" : true, "MK-47" : true, "MK-48" : true,
"MK-49" : true, "MK-50" : true, "MK-51" : true, "MK-52" : true, "MK-53" : true,
"MK-54" : true, "MK-55" : true, "MK-56" : true, "MK-57" : true, "MK-58" : true,
"MK-59" : true, "MK-60" : true, "MK-61" : true, "MK-62" : true, "MK-63" : true,
"MK-64" : true, "MK-65" : true, "MK-66" : true, "MK-67" : true, "MK-68" : true,
"MK-69" : true, "MK-70" : true, "MK-71" : true, "MK-72" : true, "MK-73" : true,
"MK-74" : true, "MK-75" : true, "MK-76" : true, "MK-77" : true, "MK-78" : true,
"MK-79" : true, "MK-80" : true, "MK-81" : true, "MK-82" : true, "MK-83" : true,
"MK-84" : true, "ML-1" : true, "ML-2" : true, "ML-3" : true, "ML-4" : true,
"ML-5" : true, "ML-6" : true, "ML-7" : true, "ML-8" : true, "ML-BK0" : true,
"MM-01" : true, "MM-02" : true, "MM-03" : true, "MM-04" : true, "MM-05" : true,
"MM-06" : true, "MM-07" : true, "MM-11" : true, "MM-12" : true, "MM-13" : true,
"MM-14" : true, "MM-15" : true, "MM-16" : true, "MM-17" : true, "MN-035" : true,
"MN-037" : true, "MN-039" : true, "MN-041" : true, "MN-043" : true, "MN-046" : true,
"MN-047" : true, "MN-049" : true, "MN-051" : true, "MN-053" : true, "MN-055" : true,
"MN-057" : true, "MN-059" : true, "MN-061" : true, "MN-063" : true, "MN-064" : true,
"MN-065" : true, "MN-067" : true, "MN-069" : true, "MN-071" : true, "MN-073" : true,
"MN-1" : true, "MR-01" : true, "MR-02" : true, "MR-03" : true, "MR-04" : true,
"MR-05" : true, "MR-06" : true, "MR-07" : true, "MR-08" : true, "MR-09" : true,
"MR-10" : true, "MR-11" : true, "MR-12" : true, "MR-NKC" : true, "MT-01" : true,
"MT-02" : true, "MT-03" : true, "MT-04" : true, "MT-05" : true, "MT-06" : true,
"MT-07" : true, "MT-08" : true, "MT-09" : true, "MT-10" : true, "MT-11" : true,
"MT-12" : true, "MT-13" : true, "MT-14" : true, "MT-15" : true, "MT-16" : true,
"MT-17" : true, "MT-18" : true, "MT-19" : true, "MT-20" : true, "MT-21" : true,
"MT-22" : true, "MT-23" : true, "MT-24" : true, "MT-25" : true, "MT-26" : true,
"MT-27" : true, "MT-28" : true, "MT-29" : true, "MT-30" : true, "MT-31" : true,
"MT-32" : true, "MT-33" : true, "MT-34" : true, "MT-35" : true, "MT-36" : true,
"MT-37" : true, "MT-38" : true, "MT-39" : true, "MT-40" : true, "MT-41" : true,
"MT-42" : true, "MT-43" : true, "MT-44" : true, "MT-45" : true, "MT-46" : true,
"MT-47" : true, "MT-48" : true, "MT-49" : true, "MT-50" : true, "MT-51" : true,
"MT-52" : true, "MT-53" : true, "MT-54" : true, "MT-55" : true, "MT-56" : true,
"MT-57" : true, "MT-58" : true, "MT-59" : true, "MT-60" : true, "MT-61" : true,
"MT-62" : true, "MT-63" : true, "MT-64" : true, "MT-65" : true, "MT-66" : true,
"MT-67" : true, "MT-68" : true, "MU-AG" : true, "MU-BL" : true, "MU-BR" : true,
"MU-CC" : true, "MU-CU" : true, "MU-FL" : true, "MU-GP" : true, "MU-MO" : true,
"MU-PA" : true, "MU-PL" : true, "MU-PU" : true, "MU-PW" : true, "MU-QB" : true,
"MU-RO" : true, "MU-RP" : true, "MU-SA" : true, "MU-VP" : true, "MV-00" : true,
"MV-01" : true, "MV-02" : true, "MV-03" : true, "MV-04" : true, "MV-05" : true,
"MV-07" : true, "MV-08" : true, "MV-12" : true, "MV-13" : true, "MV-14" : true,
"MV-17" : true, "MV-20" : true, "MV-23" : true, "MV-24" : true, "MV-25" : true,
"MV-26" : true, "MV-27" : true, "MV-28" : true, "MV-29" : true, "MV-CE" : true,
"MV-MLE" : true, "MV-NC" : true, "MV-NO" : true, "MV-SC" : true, "MV-SU" : true,
"MV-UN" : true, "MV-US" : true, "MW-BA" : true, "MW-BL" : true, "MW-C" : true,
"MW-CK" : true, "MW-CR" : true, "MW-CT" : true, "MW-DE" : true, "MW-DO" : true,
"MW-KR" : true, "MW-KS" : true, "MW-LI" : true, "MW-LK" : true, "MW-MC" : true,
"MW-MG" : true, "MW-MH" : true, "MW-MU" : true, "MW-MW" : true, "MW-MZ" : true,
"MW-N" : true, "MW-NB" : true, "MW-NE" : true, "MW-NI" : true, "MW-NK" : true,
"MW-NS" : true, "MW-NU" : true, "MW-PH" : true, "MW-RU" : true, "MW-S" : true,
"MW-SA" : true, "MW-TH" : true, "MW-ZO" : true, "MX-AGU" : true, "MX-BCN" : true,
"MX-BCS" : true, "MX-CAM" : true, "MX-CHH" : true, "MX-CHP" : true, "MX-COA" : true,
"MX-COL" : true, "MX-DIF" : true, "MX-DUR" : true, "MX-GRO" : true, "MX-GUA" : true,
"MX-HID" : true, "MX-JAL" : true, "MX-MEX" : true, "MX-MIC" : true, "MX-MOR" : true,
"MX-NAY" : true, "MX-NLE" : true, "MX-OAX" : true, "MX-PUE" : true, "MX-QUE" : true,
"MX-ROO" : true, "MX-SIN" : true, "MX-SLP" : true, "MX-SON" : true, "MX-TAB" : true,
"MX-TAM" : true, "MX-TLA" : true, "MX-VER" : true, "MX-YUC" : true, "MX-ZAC" : true,
"MY-01" : true, "MY-02" : true, "MY-03" : true, "MY-04" : true, "MY-05" : true,
"MY-06" : true, "MY-07" : true, "MY-08" : true, "MY-09" : true, "MY-10" : true,
"MY-11" : true, "MY-12" : true, "MY-13" : true, "MY-14" : true, "MY-15" : true,
"MY-16" : true, "MZ-A" : true, "MZ-B" : true, "MZ-G" : true, "MZ-I" : true,
"MZ-L" : true, "MZ-MPM" : true, "MZ-N" : true, "MZ-P" : true, "MZ-Q" : true,
"MZ-S" : true, "MZ-T" : true, "NA-CA" : true, "NA-ER" : true, "NA-HA" : true,
"NA-KA" : true, "NA-KH" : true, "NA-KU" : true, "NA-OD" : true, "NA-OH" : true,
"NA-OK" : true, "NA-ON" : true, "NA-OS" : true, "NA-OT" : true, "NA-OW" : true,
"NE-1" : true, "NE-2" : true, "NE-3" : true, "NE-4" : true, "NE-5" : true,
"NE-6" : true, "NE-7" : true, "NE-8" : true, "NG-AB" : true, "NG-AD" : true,
"NG-AK" : true, "NG-AN" : true, "NG-BA" : true, "NG-BE" : true, "NG-BO" : true,
"NG-BY" : true, "NG-CR" : true, "NG-DE" : true, "NG-EB" : true, "NG-ED" : true,
"NG-EK" : true, "NG-EN" : true, "NG-FC" : true, "NG-GO" : true, "NG-IM" : true,
"NG-JI" : true, "NG-KD" : true, "NG-KE" : true, "NG-KN" : true, "NG-KO" : true,
"NG-KT" : true, "NG-KW" : true, "NG-LA" : true, "NG-NA" : true, "NG-NI" : true,
"NG-OG" : true, "NG-ON" : true, "NG-OS" : true, "NG-OY" : true, "NG-PL" : true,
"NG-RI" : true, "NG-SO" : true, "NG-TA" : true, "NG-YO" : true, "NG-ZA" : true,
"NI-AN" : true, "NI-AS" : true, "NI-BO" : true, "NI-CA" : true, "NI-CI" : true,
"NI-CO" : true, "NI-ES" : true, "NI-GR" : true, "NI-JI" : true, "NI-LE" : true,
"NI-MD" : true, "NI-MN" : true, "NI-MS" : true, "NI-MT" : true, "NI-NS" : true,
"NI-RI" : true, "NI-SJ" : true, "NL-AW" : true, "NL-BQ1" : true, "NL-BQ2" : true,
"NL-BQ3" : true, "NL-CW" : true, "NL-DR" : true, "NL-FL" : true, "NL-FR" : true,
"NL-GE" : true, "NL-GR" : true, "NL-LI" : true, "NL-NB" : true, "NL-NH" : true,
"NL-OV" : true, "NL-SX" : true, "NL-UT" : true, "NL-ZE" : true, "NL-ZH" : true,
"NO-01" : true, "NO-02" : true, "NO-03" : true, "NO-04" : true, "NO-05" : true,
"NO-06" : true, "NO-07" : true, "NO-08" : true, "NO-09" : true, "NO-10" : true,
"NO-11" : true, "NO-12" : true, "NO-14" : true, "NO-15" : true, "NO-16" : true,
"NO-17" : true, "NO-18" : true, "NO-19" : true, "NO-20" : true, "NO-21" : true,
"NO-22" : true, "NP-1" : true, "NP-2" : true, "NP-3" : true, "NP-4" : true,
"NP-5" : true, "NP-BA" : true, "NP-BH" : true, "NP-DH" : true, "NP-GA" : true,
"NP-JA" : true, "NP-KA" : true, "NP-KO" : true, "NP-LU" : true, "NP-MA" : true,
"NP-ME" : true, "NP-NA" : true, "NP-RA" : true, "NP-SA" : true, "NP-SE" : true,
"NR-01" : true, "NR-02" : true, "NR-03" : true, "NR-04" : true, "NR-05" : true,
"NR-06" : true, "NR-07" : true, "NR-08" : true, "NR-09" : true, "NR-10" : true,
"NR-11" : true, "NR-12" : true, "NR-13" : true, "NR-14" : true, "NZ-AUK" : true,
"NZ-BOP" : true, "NZ-CAN" : true, "NZ-CIT" : true, "NZ-GIS" : true, "NZ-HKB" : true,
"NZ-MBH" : true, "NZ-MWT" : true, "NZ-N" : true, "NZ-NSN" : true, "NZ-NTL" : true,
"NZ-OTA" : true, "NZ-S" : true, "NZ-STL" : true, "NZ-TAS" : true, "NZ-TKI" : true,
"NZ-WGN" : true, "NZ-WKO" : true, "NZ-WTC" : true, "OM-BA" : true, "OM-BU" : true,
"OM-DA" : true, "OM-MA" : true, "OM-MU" : true, "OM-SH" : true, "OM-WU" : true,
"OM-ZA" : true, "OM-ZU" : true, "PA-1" : true, "PA-2" : true, "PA-3" : true,
"PA-4" : true, "PA-5" : true, "PA-6" : true, "PA-7" : true, "PA-8" : true,
"PA-9" : true, "PA-EM" : true, "PA-KY" : true, "PA-NB" : true, "PE-AMA" : true,
"PE-ANC" : true, "PE-APU" : true, "PE-ARE" : true, "PE-AYA" : true, "PE-CAJ" : true,
"PE-CAL" : true, "PE-CUS" : true, "PE-HUC" : true, "PE-HUV" : true, "PE-ICA" : true,
"PE-JUN" : true, "PE-LAL" : true, "PE-LAM" : true, "PE-LIM" : true, "PE-LMA" : true,
"PE-LOR" : true, "PE-MDD" : true, "PE-MOQ" : true, "PE-PAS" : true, "PE-PIU" : true,
"PE-PUN" : true, "PE-SAM" : true, "PE-TAC" : true, "PE-TUM" : true, "PE-UCA" : true,
"PG-CPK" : true, "PG-CPM" : true, "PG-EBR" : true, "PG-EHG" : true, "PG-EPW" : true,
"PG-ESW" : true, "PG-GPK" : true, "PG-MBA" : true, "PG-MPL" : true, "PG-MPM" : true,
"PG-MRL" : true, "PG-NCD" : true, "PG-NIK" : true, "PG-NPP" : true, "PG-NSB" : true,
"PG-SAN" : true, "PG-SHM" : true, "PG-WBK" : true, "PG-WHM" : true, "PG-WPD" : true,
"PH-00" : true, "PH-01" : true, "PH-02" : true, "PH-03" : true, "PH-05" : true,
"PH-06" : true, "PH-07" : true, "PH-08" : true, "PH-09" : true, "PH-10" : true,
"PH-11" : true, "PH-12" : true, "PH-13" : true, "PH-14" : true, "PH-15" : true,
"PH-40" : true, "PH-41" : true, "PH-ABR" : true, "PH-AGN" : true, "PH-AGS" : true,
"PH-AKL" : true, "PH-ALB" : true, "PH-ANT" : true, "PH-APA" : true, "PH-AUR" : true,
"PH-BAN" : true, "PH-BAS" : true, "PH-BEN" : true, "PH-BIL" : true, "PH-BOH" : true,
"PH-BTG" : true, "PH-BTN" : true, "PH-BUK" : true, "PH-BUL" : true, "PH-CAG" : true,
"PH-CAM" : true, "PH-CAN" : true, "PH-CAP" : true, "PH-CAS" : true, "PH-CAT" : true,
"PH-CAV" : true, "PH-CEB" : true, "PH-COM" : true, "PH-DAO" : true, "PH-DAS" : true,
"PH-DAV" : true, "PH-DIN" : true, "PH-EAS" : true, "PH-GUI" : true, "PH-IFU" : true,
"PH-ILI" : true, "PH-ILN" : true, "PH-ILS" : true, "PH-ISA" : true, "PH-KAL" : true,
"PH-LAG" : true, "PH-LAN" : true, "PH-LAS" : true, "PH-LEY" : true, "PH-LUN" : true,
"PH-MAD" : true, "PH-MAG" : true, "PH-MAS" : true, "PH-MDC" : true, "PH-MDR" : true,
"PH-MOU" : true, "PH-MSC" : true, "PH-MSR" : true, "PH-NCO" : true, "PH-NEC" : true,
"PH-NER" : true, "PH-NSA" : true, "PH-NUE" : true, "PH-NUV" : true, "PH-PAM" : true,
"PH-PAN" : true, "PH-PLW" : true, "PH-QUE" : true, "PH-QUI" : true, "PH-RIZ" : true,
"PH-ROM" : true, "PH-SAR" : true, "PH-SCO" : true, "PH-SIG" : true, "PH-SLE" : true,
"PH-SLU" : true, "PH-SOR" : true, "PH-SUK" : true, "PH-SUN" : true, "PH-SUR" : true,
"PH-TAR" : true, "PH-TAW" : true, "PH-WSA" : true, "PH-ZAN" : true, "PH-ZAS" : true,
"PH-ZMB" : true, "PH-ZSI" : true, "PK-BA" : true, "PK-GB" : true, "PK-IS" : true,
"PK-JK" : true, "PK-KP" : true, "PK-PB" : true, "PK-SD" : true, "PK-TA" : true,
"PL-DS" : true, "PL-KP" : true, "PL-LB" : true, "PL-LD" : true, "PL-LU" : true,
"PL-MA" : true, "PL-MZ" : true, "PL-OP" : true, "PL-PD" : true, "PL-PK" : true,
"PL-PM" : true, "PL-SK" : true, "PL-SL" : true, "PL-WN" : true, "PL-WP" : true,
"PL-ZP" : true, "PS-BTH" : true, "PS-DEB" : true, "PS-GZA" : true, "PS-HBN" : true,
"PS-JEM" : true, "PS-JEN" : true, "PS-JRH" : true, "PS-KYS" : true, "PS-NBS" : true,
"PS-NGZ" : true, "PS-QQA" : true, "PS-RBH" : true, "PS-RFH" : true, "PS-SLT" : true,
"PS-TBS" : true, "PS-TKM" : true, "PT-01" : true, "PT-02" : true, "PT-03" : true,
"PT-04" : true, "PT-05" : true, "PT-06" : true, "PT-07" : true, "PT-08" : true,
"PT-09" : true, "PT-10" : true, "PT-11" : true, "PT-12" : true, "PT-13" : true,
"PT-14" : true, "PT-15" : true, "PT-16" : true, "PT-17" : true, "PT-18" : true,
"PT-20" : true, "PT-30" : true, "PW-002" : true, "PW-004" : true, "PW-010" : true,
"PW-050" : true, "PW-100" : true, "PW-150" : true, "PW-212" : true, "PW-214" : true,
"PW-218" : true, "PW-222" : true, "PW-224" : true, "PW-226" : true, "PW-227" : true,
"PW-228" : true, "PW-350" : true, "PW-370" : true, "PY-1" : true, "PY-10" : true,
"PY-11" : true, "PY-12" : true, "PY-13" : true, "PY-14" : true, "PY-15" : true,
"PY-16" : true, "PY-19" : true, "PY-2" : true, "PY-3" : true, "PY-4" : true,
"PY-5" : true, "PY-6" : true, "PY-7" : true, "PY-8" : true, "PY-9" : true,
"PY-ASU" : true, "QA-DA" : true, "QA-KH" : true, "QA-MS" : true, "QA-RA" : true,
"QA-US" : true, "QA-WA" : true, "QA-ZA" : true, "RO-AB" : true, "RO-AG" : true,
"RO-AR" : true, "RO-B" : true, "RO-BC" : true, "RO-BH" : true, "RO-BN" : true,
"RO-BR" : true, "RO-BT" : true, "RO-BV" : true, "RO-BZ" : true, "RO-CJ" : true,
"RO-CL" : true, "RO-CS" : true, "RO-CT" : true, "RO-CV" : true, "RO-DB" : true,
"RO-DJ" : true, "RO-GJ" : true, "RO-GL" : true, "RO-GR" : true, "RO-HD" : true,
"RO-HR" : true, "RO-IF" : true, "RO-IL" : true, "RO-IS" : true, "RO-MH" : true,
"RO-MM" : true, "RO-MS" : true, "RO-NT" : true, "RO-OT" : true, "RO-PH" : true,
"RO-SB" : true, "RO-SJ" : true, "RO-SM" : true, "RO-SV" : true, "RO-TL" : true,
"RO-TM" : true, "RO-TR" : true, "RO-VL" : true, "RO-VN" : true, "RO-VS" : true,
"RS-00" : true, "RS-01" : true, "RS-02" : true, "RS-03" : true, "RS-04" : true,
"RS-05" : true, "RS-06" : true, "RS-07" : true, "RS-08" : true, "RS-09" : true,
"RS-10" : true, "RS-11" : true, "RS-12" : true, "RS-13" : true, "RS-14" : true,
"RS-15" : true, "RS-16" : true, "RS-17" : true, "RS-18" : true, "RS-19" : true,
"RS-20" : true, "RS-21" : true, "RS-22" : true, "RS-23" : true, "RS-24" : true,
"RS-25" : true, "RS-26" : true, "RS-27" : true, "RS-28" : true, "RS-29" : true,
"RS-KM" : true, "RS-VO" : true, "RU-AD" : true, "RU-AL" : true, "RU-ALT" : true,
"RU-AMU" : true, "RU-ARK" : true, "RU-AST" : true, "RU-BA" : true, "RU-BEL" : true,
"RU-BRY" : true, "RU-BU" : true, "RU-CE" : true, "RU-CHE" : true, "RU-CHU" : true,
"RU-CU" : true, "RU-DA" : true, "RU-IN" : true, "RU-IRK" : true, "RU-IVA" : true,
"RU-KAM" : true, "RU-KB" : true, "RU-KC" : true, "RU-KDA" : true, "RU-KEM" : true,
"RU-KGD" : true, "RU-KGN" : true, "RU-KHA" : true, "RU-KHM" : true, "RU-KIR" : true,
"RU-KK" : true, "RU-KL" : true, "RU-KLU" : true, "RU-KO" : true, "RU-KOS" : true,
"RU-KR" : true, "RU-KRS" : true, "RU-KYA" : true, "RU-LEN" : true, "RU-LIP" : true,
"RU-MAG" : true, "RU-ME" : true, "RU-MO" : true, "RU-MOS" : true, "RU-MOW" : true,
"RU-MUR" : true, "RU-NEN" : true, "RU-NGR" : true, "RU-NIZ" : true, "RU-NVS" : true,
"RU-OMS" : true, "RU-ORE" : true, "RU-ORL" : true, "RU-PER" : true, "RU-PNZ" : true,
"RU-PRI" : true, "RU-PSK" : true, "RU-ROS" : true, "RU-RYA" : true, "RU-SA" : true,
"RU-SAK" : true, "RU-SAM" : true, "RU-SAR" : true, "RU-SE" : true, "RU-SMO" : true,
"RU-SPE" : true, "RU-STA" : true, "RU-SVE" : true, "RU-TA" : true, "RU-TAM" : true,
"RU-TOM" : true, "RU-TUL" : true, "RU-TVE" : true, "RU-TY" : true, "RU-TYU" : true,
"RU-UD" : true, "RU-ULY" : true, "RU-VGG" : true, "RU-VLA" : true, "RU-VLG" : true,
"RU-VOR" : true, "RU-YAN" : true, "RU-YAR" : true, "RU-YEV" : true, "RU-ZAB" : true,
"RW-01" : true, "RW-02" : true, "RW-03" : true, "RW-04" : true, "RW-05" : true,
"SA-01" : true, "SA-02" : true, "SA-03" : true, "SA-04" : true, "SA-05" : true,
"SA-06" : true, "SA-07" : true, "SA-08" : true, "SA-09" : true, "SA-10" : true,
"SA-11" : true, "SA-12" : true, "SA-14" : true, "SB-CE" : true, "SB-CH" : true,
"SB-CT" : true, "SB-GU" : true, "SB-IS" : true, "SB-MK" : true, "SB-ML" : true,
"SB-RB" : true, "SB-TE" : true, "SB-WE" : true, "SC-01" : true, "SC-02" : true,
"SC-03" : true, "SC-04" : true, "SC-05" : true, "SC-06" : true, "SC-07" : true,
"SC-08" : true, "SC-09" : true, "SC-10" : true, "SC-11" : true, "SC-12" : true,
"SC-13" : true, "SC-14" : true, "SC-15" : true, "SC-16" : true, "SC-17" : true,
"SC-18" : true, "SC-19" : true, "SC-20" : true, "SC-21" : true, "SC-22" : true,
"SC-23" : true, "SC-24" : true, "SC-25" : true, "SD-DC" : true, "SD-DE" : true,
"SD-DN" : true, "SD-DS" : true, "SD-DW" : true, "SD-GD" : true, "SD-GZ" : true,
"SD-KA" : true, "SD-KH" : true, "SD-KN" : true, "SD-KS" : true, "SD-NB" : true,
"SD-NO" : true, "SD-NR" : true, "SD-NW" : true, "SD-RS" : true, "SD-SI" : true,
"SE-AB" : true, "SE-AC" : true, "SE-BD" : true, "SE-C" : true, "SE-D" : true,
"SE-E" : true, "SE-F" : true, "SE-G" : true, "SE-H" : true, "SE-I" : true,
"SE-K" : true, "SE-M" : true, "SE-N" : true, "SE-O" : true, "SE-S" : true,
"SE-T" : true, "SE-U" : true, "SE-W" : true, "SE-X" : true, "SE-Y" : true,
"SE-Z" : true, "SG-01" : true, "SG-02" : true, "SG-03" : true, "SG-04" : true,
"SG-05" : true, "SH-AC" : true, "SH-HL" : true, "SH-TA" : true, "SI-001" : true,
"SI-002" : true, "SI-003" : true, "SI-004" : true, "SI-005" : true, "SI-006" : true,
"SI-007" : true, "SI-008" : true, "SI-009" : true, "SI-010" : true, "SI-011" : true,
"SI-012" : true, "SI-013" : true, "SI-014" : true, "SI-015" : true, "SI-016" : true,
"SI-017" : true, "SI-018" : true, "SI-019" : true, "SI-020" : true, "SI-021" : true,
"SI-022" : true, "SI-023" : true, "SI-024" : true, "SI-025" : true, "SI-026" : true,
"SI-027" : true, "SI-028" : true, "SI-029" : true, "SI-030" : true, "SI-031" : true,
"SI-032" : true, "SI-033" : true, "SI-034" : true, "SI-035" : true, "SI-036" : true,
"SI-037" : true, "SI-038" : true, "SI-039" : true, "SI-040" : true, "SI-041" : true,
"SI-042" : true, "SI-043" : true, "SI-044" : true, "SI-045" : true, "SI-046" : true,
"SI-047" : true, "SI-048" : true, "SI-049" : true, "SI-050" : true, "SI-051" : true,
"SI-052" : true, "SI-053" : true, "SI-054" : true, "SI-055" : true, "SI-056" : true,
"SI-057" : true, "SI-058" : true, "SI-059" : true, "SI-060" : true, "SI-061" : true,
"SI-062" : true, "SI-063" : true, "SI-064" : true, "SI-065" : true, "SI-066" : true,
"SI-067" : true, "SI-068" : true, "SI-069" : true, "SI-070" : true, "SI-071" : true,
"SI-072" : true, "SI-073" : true, "SI-074" : true, "SI-075" : true, "SI-076" : true,
"SI-077" : true, "SI-078" : true, "SI-079" : true, "SI-080" : true, "SI-081" : true,
"SI-082" : true, "SI-083" : true, "SI-084" : true, "SI-085" : true, "SI-086" : true,
"SI-087" : true, "SI-088" : true, "SI-089" : true, "SI-090" : true, "SI-091" : true,
"SI-092" : true, "SI-093" : true, "SI-094" : true, "SI-095" : true, "SI-096" : true,
"SI-097" : true, "SI-098" : true, "SI-099" : true, "SI-100" : true, "SI-101" : true,
"SI-102" : true, "SI-103" : true, "SI-104" : true, "SI-105" : true, "SI-106" : true,
"SI-107" : true, "SI-108" : true, "SI-109" : true, "SI-110" : true, "SI-111" : true,
"SI-112" : true, "SI-113" : true, "SI-114" : true, "SI-115" : true, "SI-116" : true,
"SI-117" : true, "SI-118" : true, "SI-119" : true, "SI-120" : true, "SI-121" : true,
"SI-122" : true, "SI-123" : true, "SI-124" : true, "SI-125" : true, "SI-126" : true,
"SI-127" : true, "SI-128" : true, "SI-129" : true, "SI-130" : true, "SI-131" : true,
"SI-132" : true, "SI-133" : true, "SI-134" : true, "SI-135" : true, "SI-136" : true,
"SI-137" : true, "SI-138" : true, "SI-139" : true, "SI-140" : true, "SI-141" : true,
"SI-142" : true, "SI-143" : true, "SI-144" : true, "SI-146" : true, "SI-147" : true,
"SI-148" : true, "SI-149" : true, "SI-150" : true, "SI-151" : true, "SI-152" : true,
"SI-153" : true, "SI-154" : true, "SI-155" : true, "SI-156" : true, "SI-157" : true,
"SI-158" : true, "SI-159" : true, "SI-160" : true, "SI-161" : true, "SI-162" : true,
"SI-163" : true, "SI-164" : true, "SI-165" : true, "SI-166" : true, "SI-167" : true,
"SI-168" : true, "SI-169" : true, "SI-170" : true, "SI-171" : true, "SI-172" : true,
"SI-173" : true, "SI-174" : true, "SI-175" : true, "SI-176" : true, "SI-177" : true,
"SI-178" : true, "SI-179" : true, "SI-180" : true, "SI-181" : true, "SI-182" : true,
"SI-183" : true, "SI-184" : true, "SI-185" : true, "SI-186" : true, "SI-187" : true,
"SI-188" : true, "SI-189" : true, "SI-190" : true, "SI-191" : true, "SI-192" : true,
"SI-193" : true, "SI-194" : true, "SI-195" : true, "SI-196" : true, "SI-197" : true,
"SI-198" : true, "SI-199" : true, "SI-200" : true, "SI-201" : true, "SI-202" : true,
"SI-203" : true, "SI-204" : true, "SI-205" : true, "SI-206" : true, "SI-207" : true,
"SI-208" : true, "SI-209" : true, "SI-210" : true, "SI-211" : true, "SK-BC" : true,
"SK-BL" : true, "SK-KI" : true, "SK-NI" : true, "SK-PV" : true, "SK-TA" : true,
"SK-TC" : true, "SK-ZI" : true, "SL-E" : true, "SL-N" : true, "SL-S" : true,
"SL-W" : true, "SM-01" : true, "SM-02" : true, "SM-03" : true, "SM-04" : true,
"SM-05" : true, "SM-06" : true, "SM-07" : true, "SM-08" : true, "SM-09" : true,
"SN-DB" : true, "SN-DK" : true, "SN-FK" : true, "SN-KA" : true, "SN-KD" : true,
"SN-KE" : true, "SN-KL" : true, "SN-LG" : true, "SN-MT" : true, "SN-SE" : true,
"SN-SL" : true, "SN-TC" : true, "SN-TH" : true, "SN-ZG" : true, "SO-AW" : true,
"SO-BK" : true, "SO-BN" : true, "SO-BR" : true, "SO-BY" : true, "SO-GA" : true,
"SO-GE" : true, "SO-HI" : true, "SO-JD" : true, "SO-JH" : true, "SO-MU" : true,
"SO-NU" : true, "SO-SA" : true, "SO-SD" : true, "SO-SH" : true, "SO-SO" : true,
"SO-TO" : true, "SO-WO" : true, "SR-BR" : true, "SR-CM" : true, "SR-CR" : true,
"SR-MA" : true, "SR-NI" : true, "SR-PM" : true, "SR-PR" : true, "SR-SA" : true,
"SR-SI" : true, "SR-WA" : true, "SS-BN" : true, "SS-BW" : true, "SS-EC" : true,
"SS-EE8" : true, "SS-EW" : true, "SS-JG" : true, "SS-LK" : true, "SS-NU" : true,
"SS-UY" : true, "SS-WR" : true, "ST-P" : true, "ST-S" : true, "SV-AH" : true,
"SV-CA" : true, "SV-CH" : true, "SV-CU" : true, "SV-LI" : true, "SV-MO" : true,
"SV-PA" : true, "SV-SA" : true, "SV-SM" : true, "SV-SO" : true, "SV-SS" : true,
"SV-SV" : true, "SV-UN" : true, "SV-US" : true, "SY-DI" : true, "SY-DR" : true,
"SY-DY" : true, "SY-HA" : true, "SY-HI" : true, "SY-HL" : true, "SY-HM" : true,
"SY-ID" : true, "SY-LA" : true, "SY-QU" : true, "SY-RA" : true, "SY-RD" : true,
"SY-SU" : true, "SY-TA" : true, "SZ-HH" : true, "SZ-LU" : true, "SZ-MA" : true,
"SZ-SH" : true, "TD-BA" : true, "TD-BG" : true, "TD-BO" : true, "TD-CB" : true,
"TD-EN" : true, "TD-GR" : true, "TD-HL" : true, "TD-KA" : true, "TD-LC" : true,
"TD-LO" : true, "TD-LR" : true, "TD-MA" : true, "TD-MC" : true, "TD-ME" : true,
"TD-MO" : true, "TD-ND" : true, "TD-OD" : true, "TD-SA" : true, "TD-SI" : true,
"TD-TA" : true, "TD-TI" : true, "TD-WF" : true, "TG-C" : true, "TG-K" : true,
"TG-M" : true, "TG-P" : true, "TG-S" : true, "TH-10" : true, "TH-11" : true,
"TH-12" : true, "TH-13" : true, "TH-14" : true, "TH-15" : true, "TH-16" : true,
"TH-17" : true, "TH-18" : true, "TH-19" : true, "TH-20" : true, "TH-21" : true,
"TH-22" : true, "TH-23" : true, "TH-24" : true, "TH-25" : true, "TH-26" : true,
"TH-27" : true, "TH-30" : true, "TH-31" : true, "TH-32" : true, "TH-33" : true,
"TH-34" : true, "TH-35" : true, "TH-36" : true, "TH-37" : true, "TH-39" : true,
"TH-40" : true, "TH-41" : true, "TH-42" : true, "TH-43" : true, "TH-44" : true,
"TH-45" : true, "TH-46" : true, "TH-47" : true, "TH-48" : true, "TH-49" : true,
"TH-50" : true, "TH-51" : true, "TH-52" : true, "TH-53" : true, "TH-54" : true,
"TH-55" : true, "TH-56" : true, "TH-57" : true, "TH-58" : true, "TH-60" : true,
"TH-61" : true, "TH-62" : true, "TH-63" : true, "TH-64" : true, "TH-65" : true,
"TH-66" : true, "TH-67" : true, "TH-70" : true, "TH-71" : true, "TH-72" : true,
"TH-73" : true, "TH-74" : true, "TH-75" : true, "TH-76" : true, "TH-77" : true,
"TH-80" : true, "TH-81" : true, "TH-82" : true, "TH-83" : true, "TH-84" : true,
"TH-85" : true, "TH-86" : true, "TH-90" : true, "TH-91" : true, "TH-92" : true,
"TH-93" : true, "TH-94" : true, "TH-95" : true, "TH-96" : true, "TH-S" : true,
"TJ-GB" : true, "TJ-KT" : true, "TJ-SU" : true, "TL-AL" : true, "TL-AN" : true,
"TL-BA" : true, "TL-BO" : true, "TL-CO" : true, "TL-DI" : true, "TL-ER" : true,
"TL-LA" : true, "TL-LI" : true, "TL-MF" : true, "TL-MT" : true, "TL-OE" : true,
"TL-VI" : true, "TM-A" : true, "TM-B" : true, "TM-D" : true, "TM-L" : true,
"TM-M" : true, "TM-S" : true, "TN-11" : true, "TN-12" : true, "TN-13" : true,
"TN-14" : true, "TN-21" : true, "TN-22" : true, "TN-23" : true, "TN-31" : true,
"TN-32" : true, "TN-33" : true, "TN-34" : true, "TN-41" : true, "TN-42" : true,
"TN-43" : true, "TN-51" : true, "TN-52" : true, "TN-53" : true, "TN-61" : true,
"TN-71" : true, "TN-72" : true, "TN-73" : true, "TN-81" : true, "TN-82" : true,
"TN-83" : true, "TO-01" : true, "TO-02" : true, "TO-03" : true, "TO-04" : true,
"TO-05" : true, "TR-01" : true, "TR-02" : true, "TR-03" : true, "TR-04" : true,
"TR-05" : true, "TR-06" : true, "TR-07" : true, "TR-08" : true, "TR-09" : true,
"TR-10" : true, "TR-11" : true, "TR-12" : true, "TR-13" : true, "TR-14" : true,
"TR-15" : true, "TR-16" : true, "TR-17" : true, "TR-18" : true, "TR-19" : true,
"TR-20" : true, "TR-21" : true, "TR-22" : true, "TR-23" : true, "TR-24" : true,
"TR-25" : true, "TR-26" : true, "TR-27" : true, "TR-28" : true, "TR-29" : true,
"TR-30" : true, "TR-31" : true, "TR-32" : true, "TR-33" : true, "TR-34" : true,
"TR-35" : true, "TR-36" : true, "TR-37" : true, "TR-38" : true, "TR-39" : true,
"TR-40" : true, "TR-41" : true, "TR-42" : true, "TR-43" : true, "TR-44" : true,
"TR-45" : true, "TR-46" : true, "TR-47" : true, "TR-48" : true, "TR-49" : true,
"TR-50" : true, "TR-51" : true, "TR-52" : true, "TR-53" : true, "TR-54" : true,
"TR-55" : true, "TR-56" : true, "TR-57" : true, "TR-58" : true, "TR-59" : true,
"TR-60" : true, "TR-61" : true, "TR-62" : true, "TR-63" : true, "TR-64" : true,
"TR-65" : true, "TR-66" : true, "TR-67" : true, "TR-68" : true, "TR-69" : true,
"TR-70" : true, "TR-71" : true, "TR-72" : true, "TR-73" : true, "TR-74" : true,
"TR-75" : true, "TR-76" : true, "TR-77" : true, "TR-78" : true, "TR-79" : true,
"TR-80" : true, "TR-81" : true, "TT-ARI" : true, "TT-CHA" : true, "TT-CTT" : true,
"TT-DMN" : true, "TT-ETO" : true, "TT-PED" : true, "TT-POS" : true, "TT-PRT" : true,
"TT-PTF" : true, "TT-RCM" : true, "TT-SFO" : true, "TT-SGE" : true, "TT-SIP" : true,
"TT-SJL" : true, "TT-TUP" : true, "TT-WTO" : true, "TV-FUN" : true, "TV-NIT" : true,
"TV-NKF" : true, "TV-NKL" : true, "TV-NMA" : true, "TV-NMG" : true, "TV-NUI" : true,
"TV-VAI" : true, "TW-CHA" : true, "TW-CYI" : true, "TW-CYQ" : true, "TW-HSQ" : true,
"TW-HSZ" : true, "TW-HUA" : true, "TW-ILA" : true, "TW-KEE" : true, "TW-KHH" : true,
"TW-KHQ" : true, "TW-MIA" : true, "TW-NAN" : true, "TW-PEN" : true, "TW-PIF" : true,
"TW-TAO" : true, "TW-TNN" : true, "TW-TNQ" : true, "TW-TPE" : true, "TW-TPQ" : true,
"TW-TTT" : true, "TW-TXG" : true, "TW-TXQ" : true, "TW-YUN" : true, "TZ-01" : true,
"TZ-02" : true, "TZ-03" : true, "TZ-04" : true, "TZ-05" : true, "TZ-06" : true,
"TZ-07" : true, "TZ-08" : true, "TZ-09" : true, "TZ-10" : true, "TZ-11" : true,
"TZ-12" : true, "TZ-13" : true, "TZ-14" : true, "TZ-15" : true, "TZ-16" : true,
"TZ-17" : true, "TZ-18" : true, "TZ-19" : true, "TZ-20" : true, "TZ-21" : true,
"TZ-22" : true, "TZ-23" : true, "TZ-24" : true, "TZ-25" : true, "TZ-26" : true,
"UA-05" : true, "UA-07" : true, "UA-09" : true, "UA-12" : true, "UA-14" : true,
"UA-18" : true, "UA-21" : true, "UA-23" : true, "UA-26" : true, "UA-30" : true,
"UA-32" : true, "UA-35" : true, "UA-40" : true, "UA-43" : true, "UA-46" : true,
"UA-48" : true, "UA-51" : true, "UA-53" : true, "UA-56" : true, "UA-59" : true,
"UA-61" : true, "UA-63" : true, "UA-65" : true, "UA-68" : true, "UA-71" : true,
"UA-74" : true, "UA-77" : true, "UG-101" : true, "UG-102" : true, "UG-103" : true,
"UG-104" : true, "UG-105" : true, "UG-106" : true, "UG-107" : true, "UG-108" : true,
"UG-109" : true, "UG-110" : true, "UG-111" : true, "UG-112" : true, "UG-113" : true,
"UG-114" : true, "UG-115" : true, "UG-116" : true, "UG-201" : true, "UG-202" : true,
"UG-203" : true, "UG-204" : true, "UG-205" : true, "UG-206" : true, "UG-207" : true,
"UG-208" : true, "UG-209" : true, "UG-210" : true, "UG-211" : true, "UG-212" : true,
"UG-213" : true, "UG-214" : true, "UG-215" : true, "UG-216" : true, "UG-217" : true,
"UG-218" : true, "UG-219" : true, "UG-220" : true, "UG-221" : true, "UG-222" : true,
"UG-223" : true, "UG-224" : true, "UG-301" : true, "UG-302" : true, "UG-303" : true,
"UG-304" : true, "UG-305" : true, "UG-306" : true, "UG-307" : true, "UG-308" : true,
"UG-309" : true, "UG-310" : true, "UG-311" : true, "UG-312" : true, "UG-313" : true,
"UG-314" : true, "UG-315" : true, "UG-316" : true, "UG-317" : true, "UG-318" : true,
"UG-319" : true, "UG-320" : true, "UG-321" : true, "UG-401" : true, "UG-402" : true,
"UG-403" : true, "UG-404" : true, "UG-405" : true, "UG-406" : true, "UG-407" : true,
"UG-408" : true, "UG-409" : true, "UG-410" : true, "UG-411" : true, "UG-412" : true,
"UG-413" : true, "UG-414" : true, "UG-415" : true, "UG-416" : true, "UG-417" : true,
"UG-418" : true, "UG-419" : true, "UG-C" : true, "UG-E" : true, "UG-N" : true,
"UG-W" : true, "UM-67" : true, "UM-71" : true, "UM-76" : true, "UM-79" : true,
"UM-81" : true, "UM-84" : true, "UM-86" : true, "UM-89" : true, "UM-95" : true,
"US-AK" : true, "US-AL" : true, "US-AR" : true, "US-AS" : true, "US-AZ" : true,
"US-CA" : true, "US-CO" : true, "US-CT" : true, "US-DC" : true, "US-DE" : true,
"US-FL" : true, "US-GA" : true, "US-GU" : true, "US-HI" : true, "US-IA" : true,
"US-ID" : true, "US-IL" : true, "US-IN" : true, "US-KS" : true, "US-KY" : true,
"US-LA" : true, "US-MA" : true, "US-MD" : true, "US-ME" : true, "US-MI" : true,
"US-MN" : true, "US-MO" : true, "US-MP" : true, "US-MS" : true, "US-MT" : true,
"US-NC" : true, "US-ND" : true, "US-NE" : true, "US-NH" : true, "US-NJ" : true,
"US-NM" : true, "US-NV" : true, "US-NY" : true, "US-OH" : true, "US-OK" : true,
"US-OR" : true, "US-PA" : true, "US-PR" : true, "US-RI" : true, "US-SC" : true,
"US-SD" : true, "US-TN" : true, "US-TX" : true, "US-UM" : true, "US-UT" : true,
"US-VA" : true, "US-VI" : true, "US-VT" : true, "US-WA" : true, "US-WI" : true,
"US-WV" : true, "US-WY" : true, "UY-AR" : true, "UY-CA" : true, "UY-CL" : true,
"UY-CO" : true, "UY-DU" : true, "UY-FD" : true, "UY-FS" : true, "UY-LA" : true,
"UY-MA" : true, "UY-MO" : true, "UY-PA" : true, "UY-RN" : true, "UY-RO" : true,
"UY-RV" : true, "UY-SA" : true, "UY-SJ" : true, "UY-SO" : true, "UY-TA" : true,
"UY-TT" : true, "UZ-AN" : true, "UZ-BU" : true, "UZ-FA" : true, "UZ-JI" : true,
"UZ-NG" : true, "UZ-NW" : true, "UZ-QA" : true, "UZ-QR" : true, "UZ-SA" : true,
"UZ-SI" : true, "UZ-SU" : true, "UZ-TK" : true, "UZ-TO" : true, "UZ-XO" : true,
"VC-01" : true, "VC-02" : true, "VC-03" : true, "VC-04" : true, "VC-05" : true,
"VC-06" : true, "VE-A" : true, "VE-B" : true, "VE-C" : true, "VE-D" : true,
"VE-E" : true, "VE-F" : true, "VE-G" : true, "VE-H" : true, "VE-I" : true,
"VE-J" : true, "VE-K" : true, "VE-L" : true, "VE-M" : true, "VE-N" : true,
"VE-O" : true, "VE-P" : true, "VE-R" : true, "VE-S" : true, "VE-T" : true,
"VE-U" : true, "VE-V" : true, "VE-W" : true, "VE-X" : true, "VE-Y" : true,
"VE-Z" : true, "VN-01" : true, "VN-02" : true, "VN-03" : true, "VN-04" : true,
"VN-05" : true, "VN-06" : true, "VN-07" : true, "VN-09" : true, "VN-13" : true,
"VN-14" : true, "VN-15" : true, "VN-18" : true, "VN-20" : true, "VN-21" : true,
"VN-22" : true, "VN-23" : true, "VN-24" : true, "VN-25" : true, "VN-26" : true,
"VN-27" : true, "VN-28" : true, "VN-29" : true, "VN-30" : true, "VN-31" : true,
"VN-32" : true, "VN-33" : true, "VN-34" : true, "VN-35" : true, "VN-36" : true,
"VN-37" : true, "VN-39" : true, "VN-40" : true, "VN-41" : true, "VN-43" : true,
"VN-44" : true, "VN-45" : true, "VN-46" : true, "VN-47" : true, "VN-49" : true,
"VN-50" : true, "VN-51" : true, "VN-52" : true, "VN-53" : true, "VN-54" : true,
"VN-55" : true, "VN-56" : true, "VN-57" : true, "VN-58" : true, "VN-59" : true,
"VN-61" : true, "VN-63" : true, "VN-66" : true, "VN-67" : true, "VN-68" : true,
"VN-69" : true, "VN-70" : true, "VN-71" : true, "VN-72" : true, "VN-73" : true,
"VN-CT" : true, "VN-DN" : true, "VN-HN" : true, "VN-HP" : true, "VN-SG" : true,
"VU-MAP" : true, "VU-PAM" : true, "VU-SAM" : true, "VU-SEE" : true, "VU-TAE" : true,
"VU-TOB" : true, "WS-AA" : true, "WS-AL" : true, "WS-AT" : true, "WS-FA" : true,
"WS-GE" : true, "WS-GI" : true, "WS-PA" : true, "WS-SA" : true, "WS-TU" : true,
"WS-VF" : true, "WS-VS" : true, "YE-AB" : true, "YE-AD" : true, "YE-AM" : true,
"YE-BA" : true, "YE-DA" : true, "YE-DH" : true, "YE-HD" : true, "YE-HJ" : true,
"YE-IB" : true, "YE-JA" : true, "YE-LA" : true, "YE-MA" : true, "YE-MR" : true,
"YE-MU" : true, "YE-MW" : true, "YE-RA" : true, "YE-SD" : true, "YE-SH" : true,
"YE-SN" : true, "YE-TA" : true, "ZA-EC" : true, "ZA-FS" : true, "ZA-GP" : true,
"ZA-LP" : true, "ZA-MP" : true, "ZA-NC" : true, "ZA-NW" : true, "ZA-WC" : true,
"ZA-ZN" : true, "ZM-01" : true, "ZM-02" : true, "ZM-03" : true, "ZM-04" : true,
"ZM-05" : true, "ZM-06" : true, "ZM-07" : true, "ZM-08" : true, "ZM-09" : true,
"ZW-BU" : true, "ZW-HA" : true, "ZW-MA" : true, "ZW-MC" : true, "ZW-ME" : true,
"ZW-MI" : true, "ZW-MN" : true, "ZW-MS" : true, "ZW-MV" : true, "ZW-MW" : true,
} }

@ -1,79 +0,0 @@
package validator
var iso4217 = map[string]bool{
"AFN": true, "EUR": true, "ALL": true, "DZD": true, "USD": true,
"AOA": true, "XCD": true, "ARS": true, "AMD": true, "AWG": true,
"AUD": true, "AZN": true, "BSD": true, "BHD": true, "BDT": true,
"BBD": true, "BYN": true, "BZD": true, "XOF": true, "BMD": true,
"INR": true, "BTN": true, "BOB": true, "BOV": true, "BAM": true,
"BWP": true, "NOK": true, "BRL": true, "BND": true, "BGN": true,
"BIF": true, "CVE": true, "KHR": true, "XAF": true, "CAD": true,
"KYD": true, "CLP": true, "CLF": true, "CNY": true, "COP": true,
"COU": true, "KMF": true, "CDF": true, "NZD": true, "CRC": true,
"HRK": true, "CUP": true, "CUC": true, "ANG": true, "CZK": true,
"DKK": true, "DJF": true, "DOP": true, "EGP": true, "SVC": true,
"ERN": true, "SZL": true, "ETB": true, "FKP": true, "FJD": true,
"XPF": true, "GMD": true, "GEL": true, "GHS": true, "GIP": true,
"GTQ": true, "GBP": true, "GNF": true, "GYD": true, "HTG": true,
"HNL": true, "HKD": true, "HUF": true, "ISK": true, "IDR": true,
"XDR": true, "IRR": true, "IQD": true, "ILS": true, "JMD": true,
"JPY": true, "JOD": true, "KZT": true, "KES": true, "KPW": true,
"KRW": true, "KWD": true, "KGS": true, "LAK": true, "LBP": true,
"LSL": true, "ZAR": true, "LRD": true, "LYD": true, "CHF": true,
"MOP": true, "MKD": true, "MGA": true, "MWK": true, "MYR": true,
"MVR": true, "MRU": true, "MUR": true, "XUA": true, "MXN": true,
"MXV": true, "MDL": true, "MNT": true, "MAD": true, "MZN": true,
"MMK": true, "NAD": true, "NPR": true, "NIO": true, "NGN": true,
"OMR": true, "PKR": true, "PAB": true, "PGK": true, "PYG": true,
"PEN": true, "PHP": true, "PLN": true, "QAR": true, "RON": true,
"RUB": true, "RWF": true, "SHP": true, "WST": true, "STN": true,
"SAR": true, "RSD": true, "SCR": true, "SLL": true, "SGD": true,
"XSU": true, "SBD": true, "SOS": true, "SSP": true, "LKR": true,
"SDG": true, "SRD": true, "SEK": true, "CHE": true, "CHW": true,
"SYP": true, "TWD": true, "TJS": true, "TZS": true, "THB": true,
"TOP": true, "TTD": true, "TND": true, "TRY": true, "TMT": true,
"UGX": true, "UAH": true, "AED": true, "USN": true, "UYU": true,
"UYI": true, "UYW": true, "UZS": true, "VUV": true, "VES": true,
"VND": true, "YER": true, "ZMW": true, "ZWL": true, "XBA": true,
"XBB": true, "XBC": true, "XBD": true, "XTS": true, "XXX": true,
"XAU": true, "XPD": true, "XPT": true, "XAG": true,
}
var iso4217_numeric = map[int]bool{
8: true, 12: true, 32: true, 36: true, 44: true,
48: true, 50: true, 51: true, 52: true, 60: true,
64: true, 68: true, 72: true, 84: true, 90: true,
96: true, 104: true, 108: true, 116: true, 124: true,
132: true, 136: true, 144: true, 152: true, 156: true,
170: true, 174: true, 188: true, 191: true, 192: true,
203: true, 208: true, 214: true, 222: true, 230: true,
232: true, 238: true, 242: true, 262: true, 270: true,
292: true, 320: true, 324: true, 328: true, 332: true,
340: true, 344: true, 348: true, 352: true, 356: true,
360: true, 364: true, 368: true, 376: true, 388: true,
392: true, 398: true, 400: true, 404: true, 408: true,
410: true, 414: true, 417: true, 418: true, 422: true,
426: true, 430: true, 434: true, 446: true, 454: true,
458: true, 462: true, 480: true, 484: true, 496: true,
498: true, 504: true, 512: true, 516: true, 524: true,
532: true, 533: true, 548: true, 554: true, 558: true,
566: true, 578: true, 586: true, 590: true, 598: true,
600: true, 604: true, 608: true, 634: true, 643: true,
646: true, 654: true, 682: true, 690: true, 694: true,
702: true, 704: true, 706: true, 710: true, 728: true,
748: true, 752: true, 756: true, 760: true, 764: true,
776: true, 780: true, 784: true, 788: true, 800: true,
807: true, 818: true, 826: true, 834: true, 840: true,
858: true, 860: true, 882: true, 886: true, 901: true,
927: true, 928: true, 929: true, 930: true, 931: true,
932: true, 933: true, 934: true, 936: true, 938: true,
940: true, 941: true, 943: true, 944: true, 946: true,
947: true, 948: true, 949: true, 950: true, 951: true,
952: true, 953: true, 955: true, 956: true, 957: true,
958: true, 959: true, 960: true, 961: true, 962: true,
963: true, 964: true, 965: true, 967: true, 968: true,
969: true, 970: true, 971: true, 972: true, 973: true,
975: true, 976: true, 977: true, 978: true, 979: true,
980: true, 981: true, 984: true, 985: true, 986: true,
990: true, 994: true, 997: true, 999: true,
}

449
doc.go

File diff suppressed because it is too large Load Diff

@ -44,9 +44,12 @@ func (ve ValidationErrors) Error() string {
buff := bytes.NewBufferString("") buff := bytes.NewBufferString("")
var fe *fieldError
for i := 0; i < len(ve); i++ { for i := 0; i < len(ve); i++ {
buff.WriteString(ve[i].Error()) fe = ve[i].(*fieldError)
buff.WriteString(fe.Error())
buff.WriteString("\n") buff.WriteString("\n")
} }
@ -79,7 +82,7 @@ func (ve ValidationErrors) Translate(ut ut.Translator) ValidationErrorsTranslati
// FieldError contains all functions to get error details // FieldError contains all functions to get error details
type FieldError interface { type FieldError interface {
// Tag returns the validation tag that failed. if the // returns the validation tag that failed. if the
// validation was an alias, this will return the // validation was an alias, this will return the
// alias name and not the underlying tag that failed. // alias name and not the underlying tag that failed.
// //
@ -87,7 +90,7 @@ type FieldError interface {
// will return "iscolor" // will return "iscolor"
Tag() string Tag() string
// ActualTag returns the validation tag that failed, even if an // returns the validation tag that failed, even if an
// alias the actual tag within the alias will be returned. // alias the actual tag within the alias will be returned.
// If an 'or' validation fails the entire or will be returned. // If an 'or' validation fails the entire or will be returned.
// //
@ -95,7 +98,7 @@ type FieldError interface {
// will return "hexcolor|rgb|rgba|hsl|hsla" // will return "hexcolor|rgb|rgba|hsl|hsla"
ActualTag() string ActualTag() string
// Namespace returns the namespace for the field error, with the tag // returns the namespace for the field error, with the tag
// name taking precedence over the field's actual name. // name taking precedence over the field's actual name.
// //
// eg. JSON name "User.fname" // eg. JSON name "User.fname"
@ -106,7 +109,7 @@ type FieldError interface {
// using validate.Field(...) as there is no way to extract it's name // using validate.Field(...) as there is no way to extract it's name
Namespace() string Namespace() string
// StructNamespace returns the namespace for the field error, with the field's // returns the namespace for the field error, with the field's
// actual name. // actual name.
// //
// eq. "User.FirstName" see Namespace for comparison // eq. "User.FirstName" see Namespace for comparison
@ -115,24 +118,24 @@ type FieldError interface {
// using validate.Field(...) as there is no way to extract its name // using validate.Field(...) as there is no way to extract its name
StructNamespace() string StructNamespace() string
// Field returns the fields name with the tag name taking precedence over the // returns the fields name with the tag name taking precedence over the
// field's actual name. // field's actual name.
// //
// eq. JSON name "fname" // eq. JSON name "fname"
// see StructField for comparison // see StructField for comparison
Field() string Field() string
// StructField returns the field's actual name from the struct, when able to determine. // returns the field's actual name from the struct, when able to determine.
// //
// eq. "FirstName" // eq. "FirstName"
// see Field for comparison // see Field for comparison
StructField() string StructField() string
// Value returns the actual field's value in case needed for creating the error // returns the actual field's value in case needed for creating the error
// message // message
Value() interface{} Value() interface{}
// Param returns the param value, in string form for comparison; this will also // returns the param value, in string form for comparison; this will also
// help with generating an error message // help with generating an error message
Param() string Param() string
@ -143,10 +146,10 @@ type FieldError interface {
// Type returns the Field's reflect Type // Type returns the Field's reflect Type
// //
// eg. time.Time's type is time.Time // // eg. time.Time's type is time.Time
Type() reflect.Type Type() reflect.Type
// Translate returns the FieldError's translated error // returns the FieldError's translated error
// from the provided 'ut.Translator' and registered 'TranslationFunc' // from the provided 'ut.Translator' and registered 'TranslationFunc'
// //
// NOTE: if no registered translator can be found it returns the same as // NOTE: if no registered translator can be found it returns the same as
@ -218,7 +221,7 @@ func (fe *fieldError) Field() string {
// return fld // return fld
} }
// StructField returns the field's actual name from the struct, when able to determine. // returns the field's actual name from the struct, when able to determine.
func (fe *fieldError) StructField() string { func (fe *fieldError) StructField() string {
// return fe.structField // return fe.structField
return fe.structNs[len(fe.structNs)-int(fe.structfieldLen):] return fe.structNs[len(fe.structNs)-int(fe.structfieldLen):]

@ -5,25 +5,24 @@ import "reflect"
// FieldLevel contains all the information and helper functions // FieldLevel contains all the information and helper functions
// to validate a field // to validate a field
type FieldLevel interface { type FieldLevel interface {
// returns the top level struct, if any
// Top returns the top level struct, if any
Top() reflect.Value Top() reflect.Value
// Parent returns the current fields parent struct, if any or // returns the current fields parent struct, if any or
// the comparison value if called 'VarWithValue' // the comparison value if called 'VarWithValue'
Parent() reflect.Value Parent() reflect.Value
// Field returns current field for validation // returns current field for validation
Field() reflect.Value Field() reflect.Value
// FieldName returns the field's name with the tag // returns the field's name with the tag
// name taking precedence over the fields actual name. // name taking precedence over the fields actual name.
FieldName() string FieldName() string
// StructFieldName returns the struct field's name // returns the struct field's name
StructFieldName() string StructFieldName() string
// Param returns param for validation against current field // returns param for validation against current field
Param() string Param() string
// GetTag returns the current validations tag name // GetTag returns the current validations tag name
@ -34,7 +33,7 @@ type FieldLevel interface {
// underlying value and it's kind. // underlying value and it's kind.
ExtractType(field reflect.Value) (value reflect.Value, kind reflect.Kind, nullable bool) ExtractType(field reflect.Value) (value reflect.Value, kind reflect.Kind, nullable bool)
// GetStructFieldOK traverses the parent struct to retrieve a specific field denoted by the provided namespace // traverses the parent struct to retrieve a specific field denoted by the provided namespace
// in the param and returns the field, field kind and whether is was successful in retrieving // in the param and returns the field, field kind and whether is was successful in retrieving
// the field at all. // the field at all.
// //
@ -50,7 +49,7 @@ type FieldLevel interface {
// Deprecated: Use GetStructFieldOKAdvanced2() instead which also return if the value is nullable. // Deprecated: Use GetStructFieldOKAdvanced2() instead which also return if the value is nullable.
GetStructFieldOKAdvanced(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool) GetStructFieldOKAdvanced(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool)
// GetStructFieldOK2 traverses the parent struct to retrieve a specific field denoted by the provided namespace // traverses the parent struct to retrieve a specific field denoted by the provided namespace
// in the param and returns the field, field kind, if it's a nullable type and whether is was successful in retrieving // in the param and returns the field, field kind, if it's a nullable type and whether is was successful in retrieving
// the field at all. // the field at all.
// //
@ -58,7 +57,7 @@ type FieldLevel interface {
// could not be retrieved because it didn't exist. // could not be retrieved because it didn't exist.
GetStructFieldOK2() (reflect.Value, reflect.Kind, bool, bool) GetStructFieldOK2() (reflect.Value, reflect.Kind, bool, bool)
// GetStructFieldOKAdvanced2 is the same as GetStructFieldOK except that it accepts the parent struct to start looking for // GetStructFieldOKAdvanced is the same as GetStructFieldOK except that it accepts the parent struct to start looking for
// the field and namespace allowing more extensibility for validators. // the field and namespace allowing more extensibility for validators.
GetStructFieldOKAdvanced2(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool, bool) GetStructFieldOKAdvanced2(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool, bool)
} }
@ -108,12 +107,12 @@ func (v *validate) GetStructFieldOKAdvanced(val reflect.Value, namespace string)
return current, kind, found return current, kind, found
} }
// GetStructFieldOK2 returns Param returns param for validation against current field // GetStructFieldOK returns Param returns param for validation against current field
func (v *validate) GetStructFieldOK2() (reflect.Value, reflect.Kind, bool, bool) { func (v *validate) GetStructFieldOK2() (reflect.Value, reflect.Kind, bool, bool) {
return v.getStructFieldOKInternal(v.slflParent, v.ct.param) return v.getStructFieldOKInternal(v.slflParent, v.ct.param)
} }
// GetStructFieldOKAdvanced2 is the same as GetStructFieldOK except that it accepts the parent struct to start looking for // GetStructFieldOKAdvanced is the same as GetStructFieldOK except that it accepts the parent struct to start looking for
// the field and namespace allowing more extensibility for validators. // the field and namespace allowing more extensibility for validators.
func (v *validate) GetStructFieldOKAdvanced2(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool, bool) { func (v *validate) GetStructFieldOKAdvanced2(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool, bool) {
return v.getStructFieldOKInternal(val, namespace) return v.getStructFieldOKInternal(val, namespace)

@ -1,14 +1,11 @@
module github.com/go-playground/validator/v10 module github.com/go-playground/validator/v10
go 1.18 go 1.13
require ( require (
github.com/go-playground/assert/v2 v2.2.0 github.com/go-playground/assert/v2 v2.0.1
github.com/go-playground/locales v0.14.1 github.com/go-playground/locales v0.13.0
github.com/go-playground/universal-translator v0.18.1 github.com/go-playground/universal-translator v0.17.0
github.com/leodido/go-urn v1.2.2 github.com/leodido/go-urn v1.2.0
golang.org/x/crypto v0.7.0 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
golang.org/x/text v0.8.0
) )
require golang.org/x/sys v0.6.0 // indirect

@ -1,31 +1,28 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/leodido/go-urn v1.2.2 h1:7z68G0FCGvDk646jz1AelTYNYWrTNm0bEcFAo147wt4=
github.com/leodido/go-urn v1.2.2/go.mod h1:kUaIbLZWttglzwNuG0pgsh5vuV6u2YcGBYz1hIPjtOQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rwtodd/Go.Sed v0.0.0-20210816025313-55464686f9ef/go.mod h1:8AEUvGVi2uQ5b24BIhcr0GCcpd/RNAFWaN2CJFrWIIQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

@ -14,7 +14,7 @@ func NotBlank(fl validator.FieldLevel) bool {
switch field.Kind() { switch field.Kind() {
case reflect.String: case reflect.String:
return len(strings.Trim(strings.TrimSpace(field.String()), "\x1c\x1d\x1e\x1f")) > 0 return len(strings.TrimSpace(field.String())) > 0
case reflect.Chan, reflect.Map, reflect.Slice, reflect.Array: case reflect.Chan, reflect.Map, reflect.Slice, reflect.Array:
return field.Len() > 0 return field.Len() > 0
case reflect.Ptr, reflect.Interface, reflect.Func: case reflect.Ptr, reflect.Interface, reflect.Func:

@ -3,8 +3,8 @@ package validators
import ( import (
"testing" "testing"
"github.com/go-playground/assert/v2"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
"github.com/go-playground/assert/v2"
) )
type test struct { type test struct {
@ -24,7 +24,7 @@ func TestNotBlank(t *testing.T) {
// Errors // Errors
var x *int var x *int
invalid := test{ invalid := test{
String: " \x1c\x1d\x1e\x1f\r\n", String: " ",
Array: []int{}, Array: []int{},
Pointer: x, Pointer: x,
Number: 0, Number: 0,

@ -1,173 +0,0 @@
package validator
import "regexp"
var postCodePatternDict = map[string]string{
"GB": `^GIR[ ]?0AA|((AB|AL|B|BA|BB|BD|BH|BL|BN|BR|BS|BT|CA|CB|CF|CH|CM|CO|CR|CT|CV|CW|DA|DD|DE|DG|DH|DL|DN|DT|DY|E|EC|EH|EN|EX|FK|FY|G|GL|GY|GU|HA|HD|HG|HP|HR|HS|HU|HX|IG|IM|IP|IV|JE|KA|KT|KW|KY|L|LA|LD|LE|LL|LN|LS|LU|M|ME|MK|ML|N|NE|NG|NN|NP|NR|NW|OL|OX|PA|PE|PH|PL|PO|PR|RG|RH|RM|S|SA|SE|SG|SK|SL|SM|SN|SO|SP|SR|SS|ST|SW|SY|TA|TD|TF|TN|TQ|TR|TS|TW|UB|W|WA|WC|WD|WF|WN|WR|WS|WV|YO|ZE)(\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}))|BFPO[ ]?\d{1,4}$`,
"JE": `^JE\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}$`,
"GG": `^GY\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}$`,
"IM": `^IM\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}$`,
"US": `^\d{5}([ \-]\d{4})?$`,
"CA": `^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ ]?\d[ABCEGHJ-NPRSTV-Z]\d$`,
"DE": `^\d{5}$`,
"JP": `^\d{3}-\d{4}$`,
"FR": `^\d{2}[ ]?\d{3}$`,
"AU": `^\d{4}$`,
"IT": `^\d{5}$`,
"CH": `^\d{4}$`,
"AT": `^\d{4}$`,
"ES": `^\d{5}$`,
"NL": `^\d{4}[ ]?[A-Z]{2}$`,
"BE": `^\d{4}$`,
"DK": `^\d{4}$`,
"SE": `^\d{3}[ ]?\d{2}$`,
"NO": `^\d{4}$`,
"BR": `^\d{5}[\-]?\d{3}$`,
"PT": `^\d{4}([\-]\d{3})?$`,
"FI": `^\d{5}$`,
"AX": `^22\d{3}$`,
"KR": `^\d{3}[\-]\d{3}$`,
"CN": `^\d{6}$`,
"TW": `^\d{3}(\d{2})?$`,
"SG": `^\d{6}$`,
"DZ": `^\d{5}$`,
"AD": `^AD\d{3}$`,
"AR": `^([A-HJ-NP-Z])?\d{4}([A-Z]{3})?$`,
"AM": `^(37)?\d{4}$`,
"AZ": `^\d{4}$`,
"BH": `^((1[0-2]|[2-9])\d{2})?$`,
"BD": `^\d{4}$`,
"BB": `^(BB\d{5})?$`,
"BY": `^\d{6}$`,
"BM": `^[A-Z]{2}[ ]?[A-Z0-9]{2}$`,
"BA": `^\d{5}$`,
"IO": `^BBND 1ZZ$`,
"BN": `^[A-Z]{2}[ ]?\d{4}$`,
"BG": `^\d{4}$`,
"KH": `^\d{5}$`,
"CV": `^\d{4}$`,
"CL": `^\d{7}$`,
"CR": `^\d{4,5}|\d{3}-\d{4}$`,
"HR": `^\d{5}$`,
"CY": `^\d{4}$`,
"CZ": `^\d{3}[ ]?\d{2}$`,
"DO": `^\d{5}$`,
"EC": `^([A-Z]\d{4}[A-Z]|(?:[A-Z]{2})?\d{6})?$`,
"EG": `^\d{5}$`,
"EE": `^\d{5}$`,
"FO": `^\d{3}$`,
"GE": `^\d{4}$`,
"GR": `^\d{3}[ ]?\d{2}$`,
"GL": `^39\d{2}$`,
"GT": `^\d{5}$`,
"HT": `^\d{4}$`,
"HN": `^(?:\d{5})?$`,
"HU": `^\d{4}$`,
"IS": `^\d{3}$`,
"IN": `^\d{6}$`,
"ID": `^\d{5}$`,
"IL": `^\d{5}$`,
"JO": `^\d{5}$`,
"KZ": `^\d{6}$`,
"KE": `^\d{5}$`,
"KW": `^\d{5}$`,
"LA": `^\d{5}$`,
"LV": `^\d{4}$`,
"LB": `^(\d{4}([ ]?\d{4})?)?$`,
"LI": `^(948[5-9])|(949[0-7])$`,
"LT": `^\d{5}$`,
"LU": `^\d{4}$`,
"MK": `^\d{4}$`,
"MY": `^\d{5}$`,
"MV": `^\d{5}$`,
"MT": `^[A-Z]{3}[ ]?\d{2,4}$`,
"MU": `^(\d{3}[A-Z]{2}\d{3})?$`,
"MX": `^\d{5}$`,
"MD": `^\d{4}$`,
"MC": `^980\d{2}$`,
"MA": `^\d{5}$`,
"NP": `^\d{5}$`,
"NZ": `^\d{4}$`,
"NI": `^((\d{4}-)?\d{3}-\d{3}(-\d{1})?)?$`,
"NG": `^(\d{6})?$`,
"OM": `^(PC )?\d{3}$`,
"PK": `^\d{5}$`,
"PY": `^\d{4}$`,
"PH": `^\d{4}$`,
"PL": `^\d{2}-\d{3}$`,
"PR": `^00[679]\d{2}([ \-]\d{4})?$`,
"RO": `^\d{6}$`,
"RU": `^\d{6}$`,
"SM": `^4789\d$`,
"SA": `^\d{5}$`,
"SN": `^\d{5}$`,
"SK": `^\d{3}[ ]?\d{2}$`,
"SI": `^\d{4}$`,
"ZA": `^\d{4}$`,
"LK": `^\d{5}$`,
"TJ": `^\d{6}$`,
"TH": `^\d{5}$`,
"TN": `^\d{4}$`,
"TR": `^\d{5}$`,
"TM": `^\d{6}$`,
"UA": `^\d{5}$`,
"UY": `^\d{5}$`,
"UZ": `^\d{6}$`,
"VA": `^00120$`,
"VE": `^\d{4}$`,
"ZM": `^\d{5}$`,
"AS": `^96799$`,
"CC": `^6799$`,
"CK": `^\d{4}$`,
"RS": `^\d{6}$`,
"ME": `^8\d{4}$`,
"CS": `^\d{5}$`,
"YU": `^\d{5}$`,
"CX": `^6798$`,
"ET": `^\d{4}$`,
"FK": `^FIQQ 1ZZ$`,
"NF": `^2899$`,
"FM": `^(9694[1-4])([ \-]\d{4})?$`,
"GF": `^9[78]3\d{2}$`,
"GN": `^\d{3}$`,
"GP": `^9[78][01]\d{2}$`,
"GS": `^SIQQ 1ZZ$`,
"GU": `^969[123]\d([ \-]\d{4})?$`,
"GW": `^\d{4}$`,
"HM": `^\d{4}$`,
"IQ": `^\d{5}$`,
"KG": `^\d{6}$`,
"LR": `^\d{4}$`,
"LS": `^\d{3}$`,
"MG": `^\d{3}$`,
"MH": `^969[67]\d([ \-]\d{4})?$`,
"MN": `^\d{6}$`,
"MP": `^9695[012]([ \-]\d{4})?$`,
"MQ": `^9[78]2\d{2}$`,
"NC": `^988\d{2}$`,
"NE": `^\d{4}$`,
"VI": `^008(([0-4]\d)|(5[01]))([ \-]\d{4})?$`,
"VN": `^[0-9]{1,6}$`,
"PF": `^987\d{2}$`,
"PG": `^\d{3}$`,
"PM": `^9[78]5\d{2}$`,
"PN": `^PCRN 1ZZ$`,
"PW": `^96940$`,
"RE": `^9[78]4\d{2}$`,
"SH": `^(ASCN|STHL) 1ZZ$`,
"SJ": `^\d{4}$`,
"SO": `^\d{5}$`,
"SZ": `^[HLMS]\d{3}$`,
"TC": `^TKCA 1ZZ$`,
"WF": `^986\d{2}$`,
"XK": `^\d{5}$`,
"YT": `^976\d{2}$`,
}
var postCodeRegexDict = map[string]*regexp.Regexp{}
func init() {
for countryCode, pattern := range postCodePatternDict {
postCodeRegexDict[countryCode] = regexp.MustCompile(pattern)
}
}

@ -10,7 +10,7 @@ const (
numericRegexString = "^[-+]?[0-9]+(?:\\.[0-9]+)?$" numericRegexString = "^[-+]?[0-9]+(?:\\.[0-9]+)?$"
numberRegexString = "^[0-9]+$" numberRegexString = "^[0-9]+$"
hexadecimalRegexString = "^(0[xX])?[0-9a-fA-F]+$" hexadecimalRegexString = "^(0[xX])?[0-9a-fA-F]+$"
hexColorRegexString = "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$" hexcolorRegexString = "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$"
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*\\)$" 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*\\)$" 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*\\)$" 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*\\)$"
@ -19,7 +19,6 @@ const (
e164RegexString = "^\\+[1-9]?[0-9]{7,14}$" e164RegexString = "^\\+[1-9]?[0-9]{7,14}$"
base64RegexString = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$" base64RegexString = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$"
base64URLRegexString = "^(?:[A-Za-z0-9-_]{4})*(?:[A-Za-z0-9-_]{2}==|[A-Za-z0-9-_]{3}=|[A-Za-z0-9-_]{4})$" base64URLRegexString = "^(?:[A-Za-z0-9-_]{4})*(?:[A-Za-z0-9-_]{2}==|[A-Za-z0-9-_]{3}=|[A-Za-z0-9-_]{4})$"
base64RawURLRegexString = "^(?:[A-Za-z0-9-_]{4})*(?:[A-Za-z0-9-_]{2,4})$"
iSBN10RegexString = "^(?:[0-9]{9}X|[0-9]{10})$" iSBN10RegexString = "^(?:[0-9]{9}X|[0-9]{10})$"
iSBN13RegexString = "^(?:(?:97(?:8|9))[0-9]{10})$" iSBN13RegexString = "^(?:(?:97(?:8|9))[0-9]{10})$"
uUID3RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$" uUID3RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$"
@ -30,17 +29,6 @@ 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}$" 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}$" 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}$" 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]*$" aSCIIRegexString = "^[\x00-\x7F]*$"
printableASCIIRegexString = "^[\x20-\x7E]*$" printableASCIIRegexString = "^[\x20-\x7E]*$"
multibyteRegexString = "[^\x00-\x7F]" multibyteRegexString = "[^\x00-\x7F]"
@ -48,26 +36,19 @@ const (
latitudeRegexString = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$" latitudeRegexString = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$"
longitudeRegexString = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$" 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])$` 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 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 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 '.') 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 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 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 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}$` ethAddressRegexString = `^0x[0-9a-fA-F]{40}$`
ethAddressUpperRegexString = `^0x[0-9A-F]{40}$` ethAddressUpperRegexString = `^0x[0-9A-F]{40}$`
ethAddressLowerRegexString = `^0x[0-9a-f]{40}$` ethAddressLowerRegexString = `^0x[0-9a-f]{40}$`
uRLEncodedRegexString = `^(?:[^%]|%[0-9A-Fa-f]{2})*$` uRLEncodedRegexString = `(%[A-Fa-f0-9]{2})`
hTMLEncodedRegexString = `&#[x]?([0-9a-fA-F]{2})|(&gt)|(&lt)|(&quot)|(&amp)+[;]?` hTMLEncodedRegexString = `&#[x]?([0-9a-fA-F]{2})|(&gt)|(&lt)|(&quot)|(&amp)+[;]?`
hTMLRegexString = `<[/]?([a-zA-Z]+).*?>` hTMLRegexString = `<[/]?([a-zA-Z]+).*?>`
jWTRegexString = "^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$"
splitParamsRegexString = `'[^']*'|\S+` 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}$"
cveRegexString = `^CVE-(1999|2\d{3})-(0[^0]\d{2}|0\d[^0]\d{1}|0\d{2}[^0]|[1-9]{1}\d{3,})$` // CVE Format Id https://cve.mitre.org/cve/identifiers/syntaxchange.html
mongodbRegexString = "^[a-f\\d]{24}$"
cronRegexString = `(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|µs|ms|s|m|h))+)|((((\d+,)+\d+|(\d+(\/|-)\d+)|\d+|\*) ?){5,7})`
) )
var ( var (
@ -78,7 +59,7 @@ var (
numericRegex = regexp.MustCompile(numericRegexString) numericRegex = regexp.MustCompile(numericRegexString)
numberRegex = regexp.MustCompile(numberRegexString) numberRegex = regexp.MustCompile(numberRegexString)
hexadecimalRegex = regexp.MustCompile(hexadecimalRegexString) hexadecimalRegex = regexp.MustCompile(hexadecimalRegexString)
hexColorRegex = regexp.MustCompile(hexColorRegexString) hexcolorRegex = regexp.MustCompile(hexcolorRegexString)
rgbRegex = regexp.MustCompile(rgbRegexString) rgbRegex = regexp.MustCompile(rgbRegexString)
rgbaRegex = regexp.MustCompile(rgbaRegexString) rgbaRegex = regexp.MustCompile(rgbaRegexString)
hslRegex = regexp.MustCompile(hslRegexString) hslRegex = regexp.MustCompile(hslRegexString)
@ -87,7 +68,6 @@ var (
emailRegex = regexp.MustCompile(emailRegexString) emailRegex = regexp.MustCompile(emailRegexString)
base64Regex = regexp.MustCompile(base64RegexString) base64Regex = regexp.MustCompile(base64RegexString)
base64URLRegex = regexp.MustCompile(base64URLRegexString) base64URLRegex = regexp.MustCompile(base64URLRegexString)
base64RawURLRegex = regexp.MustCompile(base64RawURLRegexString)
iSBN10Regex = regexp.MustCompile(iSBN10RegexString) iSBN10Regex = regexp.MustCompile(iSBN10RegexString)
iSBN13Regex = regexp.MustCompile(iSBN13RegexString) iSBN13Regex = regexp.MustCompile(iSBN13RegexString)
uUID3Regex = regexp.MustCompile(uUID3RegexString) uUID3Regex = regexp.MustCompile(uUID3RegexString)
@ -98,17 +78,6 @@ var (
uUID4RFC4122Regex = regexp.MustCompile(uUID4RFC4122RegexString) uUID4RFC4122Regex = regexp.MustCompile(uUID4RFC4122RegexString)
uUID5RFC4122Regex = regexp.MustCompile(uUID5RFC4122RegexString) uUID5RFC4122Regex = regexp.MustCompile(uUID5RFC4122RegexString)
uUIDRFC4122Regex = regexp.MustCompile(uUIDRFC4122RegexString) 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) aSCIIRegex = regexp.MustCompile(aSCIIRegexString)
printableASCIIRegex = regexp.MustCompile(printableASCIIRegexString) printableASCIIRegex = regexp.MustCompile(printableASCIIRegexString)
multibyteRegex = regexp.MustCompile(multibyteRegexString) multibyteRegex = regexp.MustCompile(multibyteRegexString)
@ -123,15 +92,10 @@ var (
btcUpperAddressRegexBech32 = regexp.MustCompile(btcAddressUpperRegexStringBech32) btcUpperAddressRegexBech32 = regexp.MustCompile(btcAddressUpperRegexStringBech32)
btcLowerAddressRegexBech32 = regexp.MustCompile(btcAddressLowerRegexStringBech32) btcLowerAddressRegexBech32 = regexp.MustCompile(btcAddressLowerRegexStringBech32)
ethAddressRegex = regexp.MustCompile(ethAddressRegexString) ethAddressRegex = regexp.MustCompile(ethAddressRegexString)
ethaddressRegexUpper = regexp.MustCompile(ethAddressUpperRegexString)
ethAddressRegexLower = regexp.MustCompile(ethAddressLowerRegexString)
uRLEncodedRegex = regexp.MustCompile(uRLEncodedRegexString) uRLEncodedRegex = regexp.MustCompile(uRLEncodedRegexString)
hTMLEncodedRegex = regexp.MustCompile(hTMLEncodedRegexString) hTMLEncodedRegex = regexp.MustCompile(hTMLEncodedRegexString)
hTMLRegex = regexp.MustCompile(hTMLRegexString) hTMLRegex = regexp.MustCompile(hTMLRegexString)
jWTRegex = regexp.MustCompile(jWTRegexString)
splitParamsRegex = regexp.MustCompile(splitParamsRegexString) splitParamsRegex = regexp.MustCompile(splitParamsRegexString)
bicRegex = regexp.MustCompile(bicRegexString)
semverRegex = regexp.MustCompile(semverRegexString)
dnsRegexRFC1035Label = regexp.MustCompile(dnsRegexStringRFC1035Label)
cveRegex = regexp.MustCompile(cveRegexString)
mongodbRegex = regexp.MustCompile(mongodbRegexString)
cronRegex = regexp.MustCompile(cronRegexString)
) )

@ -23,18 +23,18 @@ func wrapStructLevelFunc(fn StructLevelFunc) StructLevelFuncCtx {
// to validate a struct // to validate a struct
type StructLevel interface { type StructLevel interface {
// Validator returns the main validation object, in case one wants to call validations internally. // returns the main validation object, in case one wants to call validations internally.
// this is so you don't have to use anonymous functions to get access to the validate // this is so you don't have to use anonymous functions to get access to the validate
// instance. // instance.
Validator() *Validate Validator() *Validate
// Top returns the top level struct, if any // returns the top level struct, if any
Top() reflect.Value Top() reflect.Value
// Parent returns the current fields parent struct, if any // returns the current fields parent struct, if any
Parent() reflect.Value Parent() reflect.Value
// Current returns the current struct. // returns the current struct.
Current() reflect.Value Current() reflect.Value
// ExtractType gets the actual underlying type of field value. // ExtractType gets the actual underlying type of field value.
@ -42,7 +42,7 @@ type StructLevel interface {
// underlying value and its kind. // underlying value and its kind.
ExtractType(field reflect.Value) (value reflect.Value, kind reflect.Kind, nullable bool) ExtractType(field reflect.Value) (value reflect.Value, kind reflect.Kind, nullable bool)
// ReportError reports an error just by passing the field and tag information // reports an error just by passing the field and tag information
// //
// NOTES: // NOTES:
// //
@ -54,7 +54,7 @@ type StructLevel interface {
// and process on the flip side it's up to you. // and process on the flip side it's up to you.
ReportError(field interface{}, fieldName, structFieldName string, tag, param string) ReportError(field interface{}, fieldName, structFieldName string, tag, param string)
// ReportValidationErrors reports an error just by passing ValidationErrors // reports an error just by passing ValidationErrors
// //
// NOTES: // NOTES:
// //

File diff suppressed because it is too large Load Diff

@ -1,695 +0,0 @@
package ar
import (
"testing"
"time"
. "github.com/go-playground/assert/v2"
english "github.com/go-playground/locales/en"
ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
)
func TestTranslations(t *testing.T) {
eng := english.New()
uni := ut.New(eng, eng)
trans, _ := uni.GetTranslator("en")
validate := validator.New()
err := RegisterDefaultTranslations(validate, trans)
Equal(t, err, nil)
type Inner struct {
EqCSFieldString string
NeCSFieldString string
GtCSFieldString string
GteCSFieldString string
LtCSFieldString string
LteCSFieldString string
}
type Test struct {
Inner Inner
RequiredString string `validate:"required"`
RequiredNumber int `validate:"required"`
RequiredMultiple []string `validate:"required"`
LenString string `validate:"len=1"`
LenNumber float64 `validate:"len=1113.00"`
LenMultiple []string `validate:"len=7"`
MinString string `validate:"min=1"`
MinNumber float64 `validate:"min=1113.00"`
MinMultiple []string `validate:"min=7"`
MaxString string `validate:"max=3"`
MaxNumber float64 `validate:"max=1113.00"`
MaxMultiple []string `validate:"max=7"`
EqString string `validate:"eq=3"`
EqNumber float64 `validate:"eq=2.33"`
EqMultiple []string `validate:"eq=7"`
NeString string `validate:"ne="`
NeNumber float64 `validate:"ne=0.00"`
NeMultiple []string `validate:"ne=0"`
LtString string `validate:"lt=3"`
LtNumber float64 `validate:"lt=5.56"`
LtMultiple []string `validate:"lt=2"`
LtTime time.Time `validate:"lt"`
LteString string `validate:"lte=3"`
LteNumber float64 `validate:"lte=5.56"`
LteMultiple []string `validate:"lte=2"`
LteTime time.Time `validate:"lte"`
GtString string `validate:"gt=3"`
GtNumber float64 `validate:"gt=5.56"`
GtMultiple []string `validate:"gt=2"`
GtTime time.Time `validate:"gt"`
GteString string `validate:"gte=3"`
GteNumber float64 `validate:"gte=5.56"`
GteMultiple []string `validate:"gte=2"`
GteTime time.Time `validate:"gte"`
EqFieldString string `validate:"eqfield=MaxString"`
EqCSFieldString string `validate:"eqcsfield=Inner.EqCSFieldString"`
NeCSFieldString string `validate:"necsfield=Inner.NeCSFieldString"`
GtCSFieldString string `validate:"gtcsfield=Inner.GtCSFieldString"`
GteCSFieldString string `validate:"gtecsfield=Inner.GteCSFieldString"`
LtCSFieldString string `validate:"ltcsfield=Inner.LtCSFieldString"`
LteCSFieldString string `validate:"ltecsfield=Inner.LteCSFieldString"`
NeFieldString string `validate:"nefield=EqFieldString"`
GtFieldString string `validate:"gtfield=MaxString"`
GteFieldString string `validate:"gtefield=MaxString"`
LtFieldString string `validate:"ltfield=MaxString"`
LteFieldString string `validate:"ltefield=MaxString"`
AlphaString string `validate:"alpha"`
AlphanumString string `validate:"alphanum"`
NumericString string `validate:"numeric"`
NumberString string `validate:"number"`
HexadecimalString string `validate:"hexadecimal"`
HexColorString string `validate:"hexcolor"`
RGBColorString string `validate:"rgb"`
RGBAColorString string `validate:"rgba"`
HSLColorString string `validate:"hsl"`
HSLAColorString string `validate:"hsla"`
Email string `validate:"email"`
URL string `validate:"url"`
URI string `validate:"uri"`
Base64 string `validate:"base64"`
Contains string `validate:"contains=purpose"`
ContainsAny string `validate:"containsany=!@#$"`
Excludes string `validate:"excludes=text"`
ExcludesAll string `validate:"excludesall=!@#$"`
ExcludesRune string `validate:"excludesrune=☻"`
ISBN string `validate:"isbn"`
ISBN10 string `validate:"isbn10"`
ISBN13 string `validate:"isbn13"`
UUID string `validate:"uuid"`
UUID3 string `validate:"uuid3"`
UUID4 string `validate:"uuid4"`
UUID5 string `validate:"uuid5"`
ULID string `validate:"ulid"`
ASCII string `validate:"ascii"`
PrintableASCII string `validate:"printascii"`
MultiByte string `validate:"multibyte"`
DataURI string `validate:"datauri"`
Latitude string `validate:"latitude"`
Longitude string `validate:"longitude"`
SSN string `validate:"ssn"`
IP string `validate:"ip"`
IPv4 string `validate:"ipv4"`
IPv6 string `validate:"ipv6"`
CIDR string `validate:"cidr"`
CIDRv4 string `validate:"cidrv4"`
CIDRv6 string `validate:"cidrv6"`
TCPAddr string `validate:"tcp_addr"`
TCPAddrv4 string `validate:"tcp4_addr"`
TCPAddrv6 string `validate:"tcp6_addr"`
UDPAddr string `validate:"udp_addr"`
UDPAddrv4 string `validate:"udp4_addr"`
UDPAddrv6 string `validate:"udp6_addr"`
IPAddr string `validate:"ip_addr"`
IPAddrv4 string `validate:"ip4_addr"`
IPAddrv6 string `validate:"ip6_addr"`
UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future
MAC string `validate:"mac"`
IsColor string `validate:"iscolor"`
StrPtrMinLen *string `validate:"min=10"`
StrPtrMaxLen *string `validate:"max=1"`
StrPtrLen *string `validate:"len=2"`
StrPtrLt *string `validate:"lt=1"`
StrPtrLte *string `validate:"lte=1"`
StrPtrGt *string `validate:"gt=10"`
StrPtrGte *string `validate:"gte=10"`
OneOfString string `validate:"oneof=red green"`
OneOfInt int `validate:"oneof=5 63"`
UniqueSlice []string `validate:"unique"`
UniqueArray [3]string `validate:"unique"`
UniqueMap map[string]string `validate:"unique"`
JSONString string `validate:"json"`
JWTString string `validate:"jwt"`
LowercaseString string `validate:"lowercase"`
UppercaseString string `validate:"uppercase"`
Datetime string `validate:"datetime=2006-01-02"`
PostCode string `validate:"postcode_iso3166_alpha2=SG"`
PostCodeCountry string
PostCodeByField string `validate:"postcode_iso3166_alpha2_field=PostCodeCountry"`
}
var test Test
test.Inner.EqCSFieldString = "1234"
test.Inner.GtCSFieldString = "1234"
test.Inner.GteCSFieldString = "1234"
test.MaxString = "1234"
test.MaxNumber = 2000
test.MaxMultiple = make([]string, 9)
test.LtString = "1234"
test.LtNumber = 6
test.LtMultiple = make([]string, 3)
test.LtTime = time.Now().Add(time.Hour * 24)
test.LteString = "1234"
test.LteNumber = 6
test.LteMultiple = make([]string, 3)
test.LteTime = time.Now().Add(time.Hour * 24)
test.LtFieldString = "12345"
test.LteFieldString = "12345"
test.LtCSFieldString = "1234"
test.LteCSFieldString = "1234"
test.AlphaString = "abc3"
test.AlphanumString = "abc3!"
test.NumericString = "12E.00"
test.NumberString = "12E"
test.Excludes = "this is some test text"
test.ExcludesAll = "This is Great!"
test.ExcludesRune = "Love it ☻"
test.ASCII = "カタカナ"
test.PrintableASCII = "カタカナ"
test.MultiByte = "1234feerf"
test.LowercaseString = "ABCDEFG"
test.UppercaseString = "abcdefg"
s := "toolong"
test.StrPtrMaxLen = &s
test.StrPtrLen = &s
test.UniqueSlice = []string{"1234", "1234"}
test.UniqueMap = map[string]string{"key1": "1234", "key2": "1234"}
test.Datetime = "2008-Feb-01"
err = validate.Struct(test)
NotEqual(t, err, nil)
errs, ok := err.(validator.ValidationErrors)
Equal(t, ok, true)
tests := []struct {
ns string
expected string
}{
{
ns: "Test.IsColor",
expected: "يجب أن يكون IsColor لون صالح",
},
{
ns: "Test.MAC",
expected: "يجب أن يحتوي MAC على عنوان MAC صالح",
},
{
ns: "Test.IPAddr",
expected: "يجب أن يكون IPAddr عنوان IP قابل للحل",
},
{
ns: "Test.IPAddrv4",
expected: "يجب أن يكون IPAddrv4 عنوان IP قابل للحل",
},
{
ns: "Test.IPAddrv6",
expected: "يجب أن يكون IPAddrv6 عنوان IPv6 قابل للحل",
},
{
ns: "Test.UDPAddr",
expected: "يجب أن يكون UDPAddr عنوان UDP صالح",
},
{
ns: "Test.UDPAddrv4",
expected: "يجب أن يكون UDPAddrv4 عنوان IPv4 UDP صالح",
},
{
ns: "Test.UDPAddrv6",
expected: "يجب أن يكون UDPAddrv6 عنوان IPv6 UDP صالح",
},
{
ns: "Test.TCPAddr",
expected: "يجب أن يكون TCPAddr عنوان TCP صالح",
},
{
ns: "Test.TCPAddrv4",
expected: "يجب أن يكون TCPAddrv4 عنوان IPv4 TCP صالح",
},
{
ns: "Test.TCPAddrv6",
expected: "يجب أن يكون TCPAddrv6 عنوان IPv6 TCP صالح",
},
{
ns: "Test.CIDR",
expected: "يجب أن يحتوي CIDR على علامة CIDR صالحة",
},
{
ns: "Test.CIDRv4",
expected: "يجب أن يحتوي CIDRv4 على علامة CIDR صالحة لعنوان IPv4",
},
{
ns: "Test.CIDRv6",
expected: "يجب أن يحتوي CIDRv6 على علامة CIDR صالحة لعنوان IPv6",
},
{
ns: "Test.SSN",
expected: "يجب أن يكون SSN رقم SSN صالح",
},
{
ns: "Test.IP",
expected: "يجب أن يكون IP عنوان IP صالح",
},
{
ns: "Test.IPv4",
expected: "يجب أن يكون IPv4 عنوان IPv4 صالح",
},
{
ns: "Test.IPv6",
expected: "يجب أن يكون IPv6 عنوان IPv6 صالح",
},
{
ns: "Test.DataURI",
expected: "يجب أن يحتوي DataURI على URI صالح للبيانات",
},
{
ns: "Test.Latitude",
expected: "يجب أن يحتوي Latitude على إحداثيات خط عرض صالحة",
},
{
ns: "Test.Longitude",
expected: "يجب أن يحتوي Longitude على إحداثيات خط طول صالحة",
},
{
ns: "Test.MultiByte",
expected: "يجب أن يحتوي MultiByte على أحرف متعددة البايت",
},
{
ns: "Test.ASCII",
expected: "يجب أن يحتوي ASCII على أحرف ascii فقط",
},
{
ns: "Test.PrintableASCII",
expected: "يجب أن يحتوي PrintableASCII على أحرف ascii قابلة للطباعة فقط",
},
{
ns: "Test.UUID",
expected: "يجب أن يكون UUID UUID صالح",
},
{
ns: "Test.UUID3",
expected: "يجب أن يكون UUID3 UUID صالح من النسخة 3",
},
{
ns: "Test.UUID4",
expected: "يجب أن يكون UUID4 UUID صالح من النسخة 4",
},
{
ns: "Test.UUID5",
expected: "يجب أن يكون UUID5 UUID صالح من النسخة 5",
},
{
ns: "Test.ULID",
expected: "يجب أن يكون ULID ULID صالح من نسخة",
},
{
ns: "Test.ISBN",
expected: "يجب أن يكون ISBN رقم ISBN صالح",
},
{
ns: "Test.ISBN10",
expected: "يجب أن يكون ISBN10 رقم ISBN-10 صالح",
},
{
ns: "Test.ISBN13",
expected: "يجب أن يكون ISBN13 رقم ISBN-13 صالح",
},
{
ns: "Test.Excludes",
expected: "لا يمكن أن يحتوي Excludes على النص 'text'",
},
{
ns: "Test.ExcludesAll",
expected: "لا يمكن أن يحتوي ExcludesAll على أي من الأحرف التالية '!@#$'",
},
{
ns: "Test.ExcludesRune",
expected: "لا يمكن أن يحتوي ExcludesRune على التالي '☻'",
},
{
ns: "Test.ContainsAny",
expected: "يجب أن يحتوي ContainsAny على حرف واحد على الأقل من الأحرف التالية '!@#$'",
},
{
ns: "Test.Contains",
expected: "يجب أن يحتوي Contains على النص 'purpose'",
},
{
ns: "Test.Base64",
expected: "يجب أن يكون Base64 سلسلة Base64 صالحة",
},
{
ns: "Test.Email",
expected: "يجب أن يكون Email عنوان بريد إلكتروني صالح",
},
{
ns: "Test.URL",
expected: "يجب أن يكون URL رابط إنترنت صالح",
},
{
ns: "Test.URI",
expected: "يجب أن يكون URI URI صالح",
},
{
ns: "Test.RGBColorString",
expected: "يجب أن يكون RGBColorString لون RGB صالح",
},
{
ns: "Test.RGBAColorString",
expected: "يجب أن يكون RGBAColorString لون RGBA صالح",
},
{
ns: "Test.HSLColorString",
expected: "يجب أن يكون HSLColorString لون HSL صالح",
},
{
ns: "Test.HSLAColorString",
expected: "يجب أن يكون HSLAColorString لون HSLA صالح",
},
{
ns: "Test.HexadecimalString",
expected: "يجب أن يكون HexadecimalString عددًا سداسيًا عشريًا صالحاً",
},
{
ns: "Test.HexColorString",
expected: "يجب أن يكون HexColorString لون HEX صالح",
},
{
ns: "Test.NumberString",
expected: "يجب أن يكون NumberString رقم صالح",
},
{
ns: "Test.NumericString",
expected: "يجب أن يكون NumericString قيمة رقمية صالحة",
},
{
ns: "Test.AlphanumString",
expected: "يمكن أن يحتوي AlphanumString على أحرف أبجدية رقمية فقط",
},
{
ns: "Test.AlphaString",
expected: "يمكن أن يحتوي AlphaString على أحرف أبجدية فقط",
},
{
ns: "Test.LtFieldString",
expected: "يجب أن يكون LtFieldString أصغر من MaxString",
},
{
ns: "Test.LteFieldString",
expected: "يجب أن يكون LteFieldString أصغر من أو يساوي MaxString",
},
{
ns: "Test.GtFieldString",
expected: "يجب أن يكون GtFieldString أكبر من MaxString",
},
{
ns: "Test.GteFieldString",
expected: "يجب أن يكون GteFieldString أكبر من أو يساوي MaxString",
},
{
ns: "Test.NeFieldString",
expected: "NeFieldString لا يمكن أن يساوي EqFieldString",
},
{
ns: "Test.LtCSFieldString",
expected: "يجب أن يكون LtCSFieldString أصغر من Inner.LtCSFieldString",
},
{
ns: "Test.LteCSFieldString",
expected: "يجب أن يكون LteCSFieldString أصغر من أو يساوي Inner.LteCSFieldString",
},
{
ns: "Test.GtCSFieldString",
expected: "يجب أن يكون GtCSFieldString أكبر من Inner.GtCSFieldString",
},
{
ns: "Test.GteCSFieldString",
expected: "يجب أن يكون GteCSFieldString أكبر من أو يساوي Inner.GteCSFieldString",
},
{
ns: "Test.NeCSFieldString",
expected: "NeCSFieldString لا يمكن أن يساوي Inner.NeCSFieldString",
},
{
ns: "Test.EqCSFieldString",
expected: "يجب أن يكون EqCSFieldString مساويا ل Inner.EqCSFieldString",
},
{
ns: "Test.EqFieldString",
expected: "يجب أن يكون EqFieldString مساويا ل MaxString",
},
{
ns: "Test.GteString",
expected: "يجب أن يكون طول GteString على الأقل 3 أحرف",
},
{
ns: "Test.GteNumber",
expected: "GteNumber يجب أن يكون 5.56 أو أكبر",
},
{
ns: "Test.GteMultiple",
expected: "يجب أن يحتوي GteMultiple على 2 عناصر على الأقل",
},
{
ns: "Test.GteTime",
expected: "يجب أن يكون GteTime أكبر من أو يساوي التاريخ والوقت الحاليين",
},
{
ns: "Test.GtString",
expected: "يجب أن يكون طول GtString أكبر من 3 أحرف",
},
{
ns: "Test.GtNumber",
expected: "يجب أن يكون GtNumber أكبر من 5.56",
},
{
ns: "Test.GtMultiple",
expected: "يجب أن يحتوي GtMultiple على أكثر من 2 عناصر",
},
{
ns: "Test.GtTime",
expected: "يجب أن يكون GtTime أكبر من التاريخ والوقت الحاليين",
},
{
ns: "Test.LteString",
expected: "يجب أن يكون طول LteString كحد أقصى 3 أحرف",
},
{
ns: "Test.LteNumber",
expected: "LteNumber يجب أن يكون 5.56 أو اقل",
},
{
ns: "Test.LteMultiple",
expected: "يجب أن يحتوي LteMultiple على 2 عناصر كحد أقصى",
},
{
ns: "Test.LteTime",
expected: "يجب أن يكون LteTime أقل من أو يساوي التاريخ والوقت الحاليين",
},
{
ns: "Test.LtString",
expected: "يجب أن يكون طول LtString أقل من 3 أحرف",
},
{
ns: "Test.LtNumber",
expected: "يجب أن يكون LtNumber أقل من 5.56",
},
{
ns: "Test.LtMultiple",
expected: "يجب أن يحتوي LtMultiple على أقل من 2 عناصر",
},
{
ns: "Test.LtTime",
expected: "يجب أن يكون LtTime أقل من التاريخ والوقت الحاليين",
},
{
ns: "Test.NeString",
expected: "NeString يجب ألا يساوي ",
},
{
ns: "Test.NeNumber",
expected: "NeNumber يجب ألا يساوي 0.00",
},
{
ns: "Test.NeMultiple",
expected: "NeMultiple يجب ألا يساوي 0",
},
{
ns: "Test.EqString",
expected: "EqString لا يساوي 3",
},
{
ns: "Test.EqNumber",
expected: "EqNumber لا يساوي 2.33",
},
{
ns: "Test.EqMultiple",
expected: "EqMultiple لا يساوي 7",
},
{
ns: "Test.MaxString",
expected: "يجب أن يكون طول MaxString بحد أقصى 3 أحرف",
},
{
ns: "Test.MaxNumber",
expected: "MaxNumber يجب أن يكون 1,113.00 أو اقل",
},
{
ns: "Test.MaxMultiple",
expected: "يجب أن يحتوي MaxMultiple على 7 عناصر كحد أقصى",
},
{
ns: "Test.MinString",
expected: "MinString يجب أن يكون 1 حرف أو اقل",
},
{
ns: "Test.MinNumber",
expected: "MinNumber يجب أن يكون 1,113.00 أو اقل",
},
{
ns: "Test.MinMultiple",
expected: "يجب أن يحتوي MinMultiple على 7 عناصر على الأقل",
},
{
ns: "Test.LenString",
expected: "يجب أن يكون طول LenString مساويا ل 1 حرف",
},
{
ns: "Test.LenNumber",
expected: "يجب أن يكون LenNumber مساويا ل 1,113.00",
},
{
ns: "Test.LenMultiple",
expected: "يجب أن يحتوي LenMultiple على 7 عناصر",
},
{
ns: "Test.RequiredString",
expected: "حقل RequiredString مطلوب",
},
{
ns: "Test.RequiredNumber",
expected: "حقل RequiredNumber مطلوب",
},
{
ns: "Test.RequiredMultiple",
expected: "حقل RequiredMultiple مطلوب",
},
{
ns: "Test.StrPtrMinLen",
expected: "StrPtrMinLen يجب أن يكون 10 أحرف أو اقل",
},
{
ns: "Test.StrPtrMaxLen",
expected: "يجب أن يكون طول StrPtrMaxLen بحد أقصى 1 حرف",
},
{
ns: "Test.StrPtrLen",
expected: "يجب أن يكون طول StrPtrLen مساويا ل 2 أحرف",
},
{
ns: "Test.StrPtrLt",
expected: "يجب أن يكون طول StrPtrLt أقل من 1 حرف",
},
{
ns: "Test.StrPtrLte",
expected: "يجب أن يكون طول StrPtrLte كحد أقصى 1 حرف",
},
{
ns: "Test.StrPtrGt",
expected: "يجب أن يكون طول StrPtrGt أكبر من 10 أحرف",
},
{
ns: "Test.StrPtrGte",
expected: "يجب أن يكون طول StrPtrGte على الأقل 10 أحرف",
},
{
ns: "Test.OneOfString",
expected: "يجب أن يكون OneOfString واحدا من [red green]",
},
{
ns: "Test.OneOfInt",
expected: "يجب أن يكون OneOfInt واحدا من [5 63]",
},
{
ns: "Test.UniqueSlice",
expected: "يجب أن يحتوي UniqueSlice على قيم فريدة",
},
{
ns: "Test.UniqueArray",
expected: "يجب أن يحتوي UniqueArray على قيم فريدة",
},
{
ns: "Test.UniqueMap",
expected: "يجب أن يحتوي UniqueMap على قيم فريدة",
},
{
ns: "Test.JSONString",
expected: "يجب أن يكون JSONString نص json صالح",
},
{
ns: "Test.JWTString",
expected: "يجب أن يكون JWTString نص jwt صالح",
},
{
ns: "Test.LowercaseString",
expected: "يجب أن يكون LowercaseString نص حروف صغيرة",
},
{
ns: "Test.UppercaseString",
expected: "يجب أن يكون UppercaseString نص حروف كبيرة",
},
{
ns: "Test.Datetime",
expected: "لا يتطابق Datetime مع تنسيق 2006-01-02",
},
{
ns: "Test.PostCode",
expected: "لا يتطابق PostCode مع تنسيق الرمز البريدي للبلد SG",
},
{
ns: "Test.PostCodeByField",
expected: "لا يتطابق PostCodeByField مع تنسيق الرمز البريدي للبلد في حقل PostCodeCountry",
},
}
for _, tt := range tests {
var fe validator.FieldError
for _, e := range errs {
if tt.ns == e.Namespace() {
fe = e
break
}
}
NotEqual(t, fe, nil)
Equal(t, tt.expected, fe.Translate(trans))
}
}

@ -16,6 +16,7 @@ import (
// RegisterDefaultTranslations registers a set of default translations // RegisterDefaultTranslations registers a set of default translations
// for all built in tag's in validator; you may add your own as desired. // for all built in tag's in validator; you may add your own as desired.
func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (err error) { func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (err error) {
translations := []struct { translations := []struct {
tag string tag string
translation string translation string
@ -28,14 +29,10 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} is a required field", translation: "{0} is a required field",
override: false, override: false,
}, },
{
tag: "required_if",
translation: "{0} is a required field",
override: false,
},
{ {
tag: "len", tag: "len",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("len-string", "{0} must be {1} in length", false); err != nil { if err = ut.Add("len-string", "{0} must be {1} in length", false); err != nil {
return return
} }
@ -64,8 +61,10 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
} }
return return
}, },
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
var err error var err error
var t string var t string
@ -124,6 +123,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{ {
tag: "min", tag: "min",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("min-string", "{0} must be at least {1} in length", false); err != nil { if err = ut.Add("min-string", "{0} must be at least {1} in length", false); err != nil {
return return
} }
@ -152,8 +152,10 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
} }
return return
}, },
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
var err error var err error
var t string var t string
@ -212,6 +214,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{ {
tag: "max", tag: "max",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("max-string", "{0} must be a maximum of {1} in length", false); err != nil { if err = ut.Add("max-string", "{0} must be a maximum of {1} in length", false); err != nil {
return return
} }
@ -240,8 +243,10 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
} }
return return
}, },
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
var err error var err error
var t string var t string
@ -302,6 +307,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} is not equal to {1}", translation: "{0} is not equal to {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
fmt.Printf("warning: error translating FieldError: %#v", fe) fmt.Printf("warning: error translating FieldError: %#v", fe)
@ -316,6 +322,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} should not be equal to {1}", translation: "{0} should not be equal to {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
fmt.Printf("warning: error translating FieldError: %#v", fe) fmt.Printf("warning: error translating FieldError: %#v", fe)
@ -328,6 +335,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{ {
tag: "lt", tag: "lt",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("lt-string", "{0} must be less than {1} in length", false); err != nil { if err = ut.Add("lt-string", "{0} must be less than {1} in length", false); err != nil {
return return
} }
@ -361,8 +369,10 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
} }
return return
}, },
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
var err error var err error
var t string var t string
var f64 float64 var f64 float64
@ -370,6 +380,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var kind reflect.Kind var kind reflect.Kind
fn := func() (err error) { fn := func() (err error) {
if idx := strings.Index(fe.Param(), "."); idx != -1 { if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:])) digits = uint64(len(fe.Param()[idx+1:]))
} }
@ -445,6 +456,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{ {
tag: "lte", tag: "lte",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("lte-string", "{0} must be at maximum {1} in length", false); err != nil { if err = ut.Add("lte-string", "{0} must be at maximum {1} in length", false); err != nil {
return return
} }
@ -480,6 +492,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
}, },
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
var err error var err error
var t string var t string
var f64 float64 var f64 float64
@ -487,6 +500,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var kind reflect.Kind var kind reflect.Kind
fn := func() (err error) { fn := func() (err error) {
if idx := strings.Index(fe.Param(), "."); idx != -1 { if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:])) digits = uint64(len(fe.Param()[idx+1:]))
} }
@ -562,6 +576,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{ {
tag: "gt", tag: "gt",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("gt-string", "{0} must be greater than {1} in length", false); err != nil { if err = ut.Add("gt-string", "{0} must be greater than {1} in length", false); err != nil {
return return
} }
@ -597,6 +612,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
}, },
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
var err error var err error
var t string var t string
var f64 float64 var f64 float64
@ -604,6 +620,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var kind reflect.Kind var kind reflect.Kind
fn := func() (err error) { fn := func() (err error) {
if idx := strings.Index(fe.Param(), "."); idx != -1 { if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:])) digits = uint64(len(fe.Param()[idx+1:]))
} }
@ -679,6 +696,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{ {
tag: "gte", tag: "gte",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("gte-string", "{0} must be at least {1} in length", false); err != nil { if err = ut.Add("gte-string", "{0} must be at least {1} in length", false); err != nil {
return return
} }
@ -714,6 +732,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
}, },
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
var err error var err error
var t string var t string
var f64 float64 var f64 float64
@ -721,6 +740,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var kind reflect.Kind var kind reflect.Kind
fn := func() (err error) { fn := func() (err error) {
if idx := strings.Index(fe.Param(), "."); idx != -1 { if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:])) digits = uint64(len(fe.Param()[idx+1:]))
} }
@ -798,6 +818,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be equal to {1}", translation: "{0} must be equal to {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -812,6 +833,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be equal to {1}", translation: "{0} must be equal to {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -826,6 +848,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} cannot be equal to {1}", translation: "{0} cannot be equal to {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -840,6 +863,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be greater than {1}", translation: "{0} must be greater than {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -854,6 +878,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be greater than or equal to {1}", translation: "{0} must be greater than or equal to {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -868,6 +893,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be less than {1}", translation: "{0} must be less than {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -882,6 +908,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be less than or equal to {1}", translation: "{0} must be less than or equal to {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -896,6 +923,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} cannot be equal to {1}", translation: "{0} cannot be equal to {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -910,6 +938,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be greater than {1}", translation: "{0} must be greater than {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -924,6 +953,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be greater than or equal to {1}", translation: "{0} must be greater than or equal to {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -938,6 +968,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be less than {1}", translation: "{0} must be less than {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -952,6 +983,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be less than or equal to {1}", translation: "{0} must be less than or equal to {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1041,6 +1073,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must contain the text '{1}'", translation: "{0} must contain the text '{1}'",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1055,6 +1088,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must contain at least one of the following characters '{1}'", translation: "{0} must contain at least one of the following characters '{1}'",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1069,6 +1103,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} cannot contain the text '{1}'", translation: "{0} cannot contain the text '{1}'",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1083,6 +1118,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} cannot contain any of the following characters '{1}'", translation: "{0} cannot contain any of the following characters '{1}'",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1097,6 +1133,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} cannot contain the following '{1}'", translation: "{0} cannot contain the following '{1}'",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1141,11 +1178,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be a valid version 5 UUID", translation: "{0} must be a valid version 5 UUID",
override: false, override: false,
}, },
{
tag: "ulid",
translation: "{0} must be a valid ULID",
override: false,
},
{ {
tag: "ascii", tag: "ascii",
translation: "{0} must contain only ascii characters", translation: "{0} must contain only ascii characters",
@ -1266,11 +1298,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must contain a valid MAC address", translation: "{0} must contain a valid MAC address",
override: false, override: false,
}, },
{
tag: "fqdn",
translation: "{0} must be a valid FQDN",
override: false,
},
{ {
tag: "unique", tag: "unique",
translation: "{0} must contain unique values", translation: "{0} must contain unique values",
@ -1281,11 +1308,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be a valid color", translation: "{0} must be a valid color",
override: false, override: false,
}, },
{
tag: "cron",
translation: "{0} must be a valid cron expression",
override: false,
},
{ {
tag: "oneof", tag: "oneof",
translation: "{0} must be one of [{1}]", translation: "{0} must be one of [{1}]",
@ -1303,13 +1325,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
tag: "json", tag: "json",
translation: "{0} must be a valid json string", translation: "{0} must be a valid json string",
override: false, override: false,
}, },
{ {
tag: "jwt",
translation: "{0} must be a valid jwt string",
override: false,
},
{
tag: "lowercase", tag: "lowercase",
translation: "{0} must be a lowercase string", translation: "{0} must be a lowercase string",
override: false, override: false,
@ -1324,34 +1341,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} does not match the {1} format", translation: "{0} does not match the {1} format",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
return fe.(error).Error()
}
return t
},
},
{
tag: "postcode_iso3166_alpha2",
translation: "{0} does not match postcode format of {1} country",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
return fe.(error).Error()
}
return t
},
},
{
tag: "postcode_iso3166_alpha2_field",
translation: "{0} does not match postcode format of country in {1} field",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1361,26 +1351,22 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return t return t
}, },
}, },
{
tag: "boolean",
translation: "{0} must be a valid boolean value",
override: false,
},
{
tag: "cve",
translation: "{0} must be a valid cve identifier",
override: false,
},
} }
for _, t := range translations { for _, t := range translations {
if t.customTransFunc != nil && t.customRegisFunc != nil { if t.customTransFunc != nil && t.customRegisFunc != nil {
err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, t.customTransFunc) err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, t.customTransFunc)
} else if t.customTransFunc != nil && t.customRegisFunc == nil { } else if t.customTransFunc != nil && t.customRegisFunc == nil {
err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), t.customTransFunc) err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), t.customTransFunc)
} else if t.customTransFunc == nil && t.customRegisFunc != nil { } else if t.customTransFunc == nil && t.customRegisFunc != nil {
err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, translateFunc) err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, translateFunc)
} else { } else {
err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), translateFunc) err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), translateFunc)
} }
@ -1394,16 +1380,21 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
} }
func registrationFunc(tag string, translation string, override bool) validator.RegisterTranslationsFunc { func registrationFunc(tag string, translation string, override bool) validator.RegisterTranslationsFunc {
return func(ut ut.Translator) (err error) { return func(ut ut.Translator) (err error) {
if err = ut.Add(tag, translation, override); err != nil { if err = ut.Add(tag, translation, override); err != nil {
return return
} }
return return
} }
} }
func translateFunc(ut ut.Translator, fe validator.FieldError) string { func translateFunc(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field()) t, err := ut.T(fe.Tag(), fe.Field())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)

@ -11,6 +11,7 @@ import (
) )
func TestTranslations(t *testing.T) { func TestTranslations(t *testing.T) {
eng := english.New() eng := english.New()
uni := ut.New(eng, eng) uni := ut.New(eng, eng)
trans, _ := uni.GetTranslator("en") trans, _ := uni.GetTranslator("en")
@ -27,7 +28,6 @@ func TestTranslations(t *testing.T) {
GteCSFieldString string GteCSFieldString string
LtCSFieldString string LtCSFieldString string
LteCSFieldString string LteCSFieldString string
RequiredIf string
} }
type Test struct { type Test struct {
@ -35,7 +35,6 @@ func TestTranslations(t *testing.T) {
RequiredString string `validate:"required"` RequiredString string `validate:"required"`
RequiredNumber int `validate:"required"` RequiredNumber int `validate:"required"`
RequiredMultiple []string `validate:"required"` RequiredMultiple []string `validate:"required"`
RequiredIf string `validate:"required_if=Inner.RequiredIf abcd"`
LenString string `validate:"len=1"` LenString string `validate:"len=1"`
LenNumber float64 `validate:"len=1113.00"` LenNumber float64 `validate:"len=1113.00"`
LenMultiple []string `validate:"len=7"` LenMultiple []string `validate:"len=7"`
@ -105,7 +104,6 @@ func TestTranslations(t *testing.T) {
UUID3 string `validate:"uuid3"` UUID3 string `validate:"uuid3"`
UUID4 string `validate:"uuid4"` UUID4 string `validate:"uuid4"`
UUID5 string `validate:"uuid5"` UUID5 string `validate:"uuid5"`
ULID string `validate:"ulid"`
ASCII string `validate:"ascii"` ASCII string `validate:"ascii"`
PrintableASCII string `validate:"printascii"` PrintableASCII string `validate:"printascii"`
MultiByte string `validate:"multibyte"` MultiByte string `validate:"multibyte"`
@ -130,7 +128,6 @@ func TestTranslations(t *testing.T) {
IPAddrv6 string `validate:"ip6_addr"` IPAddrv6 string `validate:"ip6_addr"`
UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future
MAC string `validate:"mac"` MAC string `validate:"mac"`
FQDN string `validate:"fqdn"`
IsColor string `validate:"iscolor"` IsColor string `validate:"iscolor"`
StrPtrMinLen *string `validate:"min=10"` StrPtrMinLen *string `validate:"min=10"`
StrPtrMaxLen *string `validate:"max=1"` StrPtrMaxLen *string `validate:"max=1"`
@ -145,15 +142,9 @@ func TestTranslations(t *testing.T) {
UniqueArray [3]string `validate:"unique"` UniqueArray [3]string `validate:"unique"`
UniqueMap map[string]string `validate:"unique"` UniqueMap map[string]string `validate:"unique"`
JSONString string `validate:"json"` JSONString string `validate:"json"`
JWTString string `validate:"jwt"`
LowercaseString string `validate:"lowercase"` LowercaseString string `validate:"lowercase"`
UppercaseString string `validate:"uppercase"` UppercaseString string `validate:"uppercase"`
Datetime string `validate:"datetime=2006-01-02"` Datetime string `validate:"datetime=2006-01-02"`
PostCode string `validate:"postcode_iso3166_alpha2=SG"`
PostCodeCountry string
PostCodeByField string `validate:"postcode_iso3166_alpha2_field=PostCodeCountry"`
BooleanString string `validate:"boolean"`
CveString string `validate:"cve"`
} }
var test Test var test Test
@ -206,10 +197,6 @@ func TestTranslations(t *testing.T) {
test.UniqueSlice = []string{"1234", "1234"} test.UniqueSlice = []string{"1234", "1234"}
test.UniqueMap = map[string]string{"key1": "1234", "key2": "1234"} test.UniqueMap = map[string]string{"key1": "1234", "key2": "1234"}
test.Datetime = "2008-Feb-01" test.Datetime = "2008-Feb-01"
test.BooleanString = "A"
test.CveString = "A"
test.Inner.RequiredIf = "abcd"
err = validate.Struct(test) err = validate.Struct(test)
NotEqual(t, err, nil) NotEqual(t, err, nil)
@ -229,10 +216,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.MAC", ns: "Test.MAC",
expected: "MAC must contain a valid MAC address", expected: "MAC must contain a valid MAC address",
}, },
{
ns: "Test.FQDN",
expected: "FQDN must be a valid FQDN",
},
{ {
ns: "Test.IPAddr", ns: "Test.IPAddr",
expected: "IPAddr must be a resolvable IP address", expected: "IPAddr must be a resolvable IP address",
@ -337,10 +320,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.UUID5", ns: "Test.UUID5",
expected: "UUID5 must be a valid version 5 UUID", expected: "UUID5 must be a valid version 5 UUID",
}, },
{
ns: "Test.ULID",
expected: "ULID must be a valid ULID",
},
{ {
ns: "Test.ISBN", ns: "Test.ISBN",
expected: "ISBN must be a valid ISBN number", expected: "ISBN must be a valid ISBN number",
@ -605,10 +584,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.RequiredString", ns: "Test.RequiredString",
expected: "RequiredString is a required field", expected: "RequiredString is a required field",
}, },
{
ns: "Test.RequiredIf",
expected: "RequiredIf is a required field",
},
{ {
ns: "Test.RequiredNumber", ns: "Test.RequiredNumber",
expected: "RequiredNumber is a required field", expected: "RequiredNumber is a required field",
@ -669,10 +644,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.JSONString", ns: "Test.JSONString",
expected: "JSONString must be a valid json string", expected: "JSONString must be a valid json string",
}, },
{
ns: "Test.JWTString",
expected: "JWTString must be a valid jwt string",
},
{ {
ns: "Test.LowercaseString", ns: "Test.LowercaseString",
expected: "LowercaseString must be a lowercase string", expected: "LowercaseString must be a lowercase string",
@ -685,22 +656,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.Datetime", ns: "Test.Datetime",
expected: "Datetime does not match the 2006-01-02 format", expected: "Datetime does not match the 2006-01-02 format",
}, },
{
ns: "Test.PostCode",
expected: "PostCode does not match postcode format of SG country",
},
{
ns: "Test.PostCodeByField",
expected: "PostCodeByField does not match postcode format of country in PostCodeCountry field",
},
{
ns: "Test.BooleanString",
expected: "BooleanString must be a valid boolean value",
},
{
ns: "Test.CveString",
expected: "CveString must be a valid cve identifier",
},
} }
for _, tt := range tests { for _, tt := range tests {
@ -717,4 +672,5 @@ func TestTranslations(t *testing.T) {
NotEqual(t, fe, nil) NotEqual(t, fe, nil)
Equal(t, tt.expected, fe.Translate(trans)) Equal(t, tt.expected, fe.Translate(trans))
} }
} }

@ -29,11 +29,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} es un campo requerido", translation: "{0} es un campo requerido",
override: false, override: false,
}, },
{
tag: "required_if",
translation: "{0} es un campo requerido",
override: false,
},
{ {
tag: "len", tag: "len",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
@ -1183,11 +1178,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} debe ser una versión válida 5 UUID", translation: "{0} debe ser una versión válida 5 UUID",
override: false, override: false,
}, },
{
tag: "ulid",
translation: "{0} debe ser un ULID válido",
override: false,
},
{ {
tag: "ascii", tag: "ascii",
translation: "{0} debe contener sólo caracteres ascii", translation: "{0} debe contener sólo caracteres ascii",

@ -4,9 +4,9 @@ import (
"testing" "testing"
"time" "time"
. "github.com/go-playground/assert/v2"
spanish "github.com/go-playground/locales/es" spanish "github.com/go-playground/locales/es"
ut "github.com/go-playground/universal-translator" ut "github.com/go-playground/universal-translator"
. "github.com/go-playground/assert/v2"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
) )
@ -35,7 +35,6 @@ func TestTranslations(t *testing.T) {
RequiredString string `validate:"required"` RequiredString string `validate:"required"`
RequiredNumber int `validate:"required"` RequiredNumber int `validate:"required"`
RequiredMultiple []string `validate:"required"` RequiredMultiple []string `validate:"required"`
RequiredIf string `validate:"required_if=Inner.RequiredIf abcd"`
LenString string `validate:"len=1"` LenString string `validate:"len=1"`
LenNumber float64 `validate:"len=1113.00"` LenNumber float64 `validate:"len=1113.00"`
LenMultiple []string `validate:"len=7"` LenMultiple []string `validate:"len=7"`
@ -105,7 +104,6 @@ func TestTranslations(t *testing.T) {
UUID3 string `validate:"uuid3"` UUID3 string `validate:"uuid3"`
UUID4 string `validate:"uuid4"` UUID4 string `validate:"uuid4"`
UUID5 string `validate:"uuid5"` UUID5 string `validate:"uuid5"`
ULID string `validate:"ulid"`
ASCII string `validate:"ascii"` ASCII string `validate:"ascii"`
PrintableASCII string `validate:"printascii"` PrintableASCII string `validate:"printascii"`
MultiByte string `validate:"multibyte"` MultiByte string `validate:"multibyte"`
@ -314,10 +312,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.UUID5", ns: "Test.UUID5",
expected: "UUID5 debe ser una versión válida 5 UUID", expected: "UUID5 debe ser una versión válida 5 UUID",
}, },
{
ns: "Test.ULID",
expected: "ULID debe ser un ULID válido",
},
{ {
ns: "Test.ISBN", ns: "Test.ISBN",
expected: "ISBN debe ser un número ISBN válido", expected: "ISBN debe ser un número ISBN válido",

File diff suppressed because it is too large Load Diff

@ -1,690 +0,0 @@
package fa
import (
"testing"
"time"
. "github.com/go-playground/assert/v2"
english "github.com/go-playground/locales/en"
ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
)
func TestTranslations(t *testing.T) {
eng := english.New()
uni := ut.New(eng, eng)
trans, _ := uni.GetTranslator("en")
validate := validator.New()
err := RegisterDefaultTranslations(validate, trans)
Equal(t, err, nil)
type Inner struct {
EqCSFieldString string
NeCSFieldString string
GtCSFieldString string
GteCSFieldString string
LtCSFieldString string
LteCSFieldString string
}
type Test struct {
Inner Inner
RequiredString string `validate:"required"`
RequiredNumber int `validate:"required"`
RequiredMultiple []string `validate:"required"`
LenString string `validate:"len=1"`
LenNumber float64 `validate:"len=1113.00"`
LenMultiple []string `validate:"len=7"`
MinString string `validate:"min=1"`
MinNumber float64 `validate:"min=1113.00"`
MinMultiple []string `validate:"min=7"`
MaxString string `validate:"max=3"`
MaxNumber float64 `validate:"max=1113.00"`
MaxMultiple []string `validate:"max=7"`
EqString string `validate:"eq=3"`
EqNumber float64 `validate:"eq=2.33"`
EqMultiple []string `validate:"eq=7"`
NeString string `validate:"ne="`
NeNumber float64 `validate:"ne=0.00"`
NeMultiple []string `validate:"ne=0"`
LtString string `validate:"lt=3"`
LtNumber float64 `validate:"lt=5.56"`
LtMultiple []string `validate:"lt=2"`
LtTime time.Time `validate:"lt"`
LteString string `validate:"lte=3"`
LteNumber float64 `validate:"lte=5.56"`
LteMultiple []string `validate:"lte=2"`
LteTime time.Time `validate:"lte"`
GtString string `validate:"gt=3"`
GtNumber float64 `validate:"gt=5.56"`
GtMultiple []string `validate:"gt=2"`
GtTime time.Time `validate:"gt"`
GteString string `validate:"gte=3"`
GteNumber float64 `validate:"gte=5.56"`
GteMultiple []string `validate:"gte=2"`
GteTime time.Time `validate:"gte"`
EqFieldString string `validate:"eqfield=MaxString"`
EqCSFieldString string `validate:"eqcsfield=Inner.EqCSFieldString"`
NeCSFieldString string `validate:"necsfield=Inner.NeCSFieldString"`
GtCSFieldString string `validate:"gtcsfield=Inner.GtCSFieldString"`
GteCSFieldString string `validate:"gtecsfield=Inner.GteCSFieldString"`
LtCSFieldString string `validate:"ltcsfield=Inner.LtCSFieldString"`
LteCSFieldString string `validate:"ltecsfield=Inner.LteCSFieldString"`
NeFieldString string `validate:"nefield=EqFieldString"`
GtFieldString string `validate:"gtfield=MaxString"`
GteFieldString string `validate:"gtefield=MaxString"`
LtFieldString string `validate:"ltfield=MaxString"`
LteFieldString string `validate:"ltefield=MaxString"`
AlphaString string `validate:"alpha"`
AlphanumString string `validate:"alphanum"`
NumericString string `validate:"numeric"`
NumberString string `validate:"number"`
HexadecimalString string `validate:"hexadecimal"`
HexColorString string `validate:"hexcolor"`
RGBColorString string `validate:"rgb"`
RGBAColorString string `validate:"rgba"`
HSLColorString string `validate:"hsl"`
HSLAColorString string `validate:"hsla"`
Email string `validate:"email"`
URL string `validate:"url"`
URI string `validate:"uri"`
Base64 string `validate:"base64"`
Contains string `validate:"contains=purpose"`
ContainsAny string `validate:"containsany=!@#$"`
Excludes string `validate:"excludes=text"`
ExcludesAll string `validate:"excludesall=!@#$"`
ExcludesRune string `validate:"excludesrune=☻"`
ISBN string `validate:"isbn"`
ISBN10 string `validate:"isbn10"`
ISBN13 string `validate:"isbn13"`
UUID string `validate:"uuid"`
UUID3 string `validate:"uuid3"`
UUID4 string `validate:"uuid4"`
UUID5 string `validate:"uuid5"`
ULID string `validate:"ulid"`
ASCII string `validate:"ascii"`
PrintableASCII string `validate:"printascii"`
MultiByte string `validate:"multibyte"`
DataURI string `validate:"datauri"`
Latitude string `validate:"latitude"`
Longitude string `validate:"longitude"`
SSN string `validate:"ssn"`
IP string `validate:"ip"`
IPv4 string `validate:"ipv4"`
IPv6 string `validate:"ipv6"`
CIDR string `validate:"cidr"`
CIDRv4 string `validate:"cidrv4"`
CIDRv6 string `validate:"cidrv6"`
TCPAddr string `validate:"tcp_addr"`
TCPAddrv4 string `validate:"tcp4_addr"`
TCPAddrv6 string `validate:"tcp6_addr"`
UDPAddr string `validate:"udp_addr"`
UDPAddrv4 string `validate:"udp4_addr"`
UDPAddrv6 string `validate:"udp6_addr"`
IPAddr string `validate:"ip_addr"`
IPAddrv4 string `validate:"ip4_addr"`
IPAddrv6 string `validate:"ip6_addr"`
UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future
MAC string `validate:"mac"`
IsColor string `validate:"iscolor"`
StrPtrMinLen *string `validate:"min=10"`
StrPtrMaxLen *string `validate:"max=1"`
StrPtrLen *string `validate:"len=2"`
StrPtrLt *string `validate:"lt=1"`
StrPtrLte *string `validate:"lte=1"`
StrPtrGt *string `validate:"gt=10"`
StrPtrGte *string `validate:"gte=10"`
OneOfString string `validate:"oneof=red green"`
OneOfInt int `validate:"oneof=5 63"`
UniqueSlice []string `validate:"unique"`
UniqueArray [3]string `validate:"unique"`
UniqueMap map[string]string `validate:"unique"`
JSONString string `validate:"json"`
LowercaseString string `validate:"lowercase"`
UppercaseString string `validate:"uppercase"`
Datetime string `validate:"datetime=2006-01-02"`
PostCode string `validate:"postcode_iso3166_alpha2=SG"`
PostCodeCountry string
PostCodeByField string `validate:"postcode_iso3166_alpha2_field=PostCodeCountry"`
}
var test Test
test.Inner.EqCSFieldString = "1234"
test.Inner.GtCSFieldString = "1234"
test.Inner.GteCSFieldString = "1234"
test.MaxString = "1234"
test.MaxNumber = 2000
test.MaxMultiple = make([]string, 9)
test.LtString = "1234"
test.LtNumber = 6
test.LtMultiple = make([]string, 3)
test.LtTime = time.Now().Add(time.Hour * 24)
test.LteString = "1234"
test.LteNumber = 6
test.LteMultiple = make([]string, 3)
test.LteTime = time.Now().Add(time.Hour * 24)
test.LtFieldString = "12345"
test.LteFieldString = "12345"
test.LtCSFieldString = "1234"
test.LteCSFieldString = "1234"
test.AlphaString = "abc3"
test.AlphanumString = "abc3!"
test.NumericString = "12E.00"
test.NumberString = "12E"
test.Excludes = "this is some test text"
test.ExcludesAll = "This is Great!"
test.ExcludesRune = "Love it ☻"
test.ASCII = "カタカナ"
test.PrintableASCII = "カタカナ"
test.MultiByte = "1234feerf"
test.LowercaseString = "ABCDEFG"
test.UppercaseString = "abcdefg"
s := "toolong"
test.StrPtrMaxLen = &s
test.StrPtrLen = &s
test.UniqueSlice = []string{"1234", "1234"}
test.UniqueMap = map[string]string{"key1": "1234", "key2": "1234"}
test.Datetime = "2008-Feb-01"
err = validate.Struct(test)
NotEqual(t, err, nil)
errs, ok := err.(validator.ValidationErrors)
Equal(t, ok, true)
tests := []struct {
ns string
expected string
}{
{
ns: "Test.IsColor",
expected: "IsColor باید یک رنگ معتبر باشد",
},
{
ns: "Test.MAC",
expected: "MAC باید یک مکآدرس معتبر باشد",
},
{
ns: "Test.IPAddr",
expected: "IPAddr باید یک آدرس آیپی قابل دسترس باشد",
},
{
ns: "Test.IPAddrv4",
expected: "IPAddrv4 باید یک آدرس آیپی IPv4 قابل دسترس باشد",
},
{
ns: "Test.IPAddrv6",
expected: "IPAddrv6 باید یک آدرس آیپی IPv6 قابل دسترس باشد",
},
{
ns: "Test.UDPAddr",
expected: "UDPAddr باید یک آدرس UDP معتبر باشد",
},
{
ns: "Test.UDPAddrv4",
expected: "UDPAddrv4 باید یک آدرس UDP IPv4 معتبر باشد",
},
{
ns: "Test.UDPAddrv6",
expected: "UDPAddrv6 باید یک آدرس UDP IPv6 معتبر باشد",
},
{
ns: "Test.TCPAddr",
expected: "TCPAddr باید یک آدرس TCP معتبر باشد",
},
{
ns: "Test.TCPAddrv4",
expected: "TCPAddrv4 باید یک آدرس TCP IPv4 معتبر باشد",
},
{
ns: "Test.TCPAddrv6",
expected: "TCPAddrv6 باید یک آدرس TCP IPv6 معتبر باشد",
},
{
ns: "Test.CIDR",
expected: "CIDR باید یک نشانهگذاری CIDR معتبر باشد",
},
{
ns: "Test.CIDRv4",
expected: "CIDRv4 باید یک نشانهگذاری CIDR معتبر برای آدرس آیپی IPv4 باشد",
},
{
ns: "Test.CIDRv6",
expected: "CIDRv6 باید یک نشانهگذاری CIDR معتبر برای آدرس آیپی IPv6 باشد",
},
{
ns: "Test.SSN",
expected: "SSN باید یک شماره SSN معتبر باشد",
},
{
ns: "Test.IP",
expected: "IP باید یک آدرس آیپی معتبر باشد",
},
{
ns: "Test.IPv4",
expected: "IPv4 باید یک آدرس آیپی IPv4 معتبر باشد",
},
{
ns: "Test.IPv6",
expected: "IPv6 باید یک آدرس آیپی IPv6 معتبر باشد",
},
{
ns: "Test.DataURI",
expected: "DataURI باید یک Data URI معتبر باشد",
},
{
ns: "Test.Latitude",
expected: "Latitude باید یک عرض جغرافیایی معتبر باشد",
},
{
ns: "Test.Longitude",
expected: "Longitude باید یک طول جغرافیایی معتبر باشد",
},
{
ns: "Test.MultiByte",
expected: "MultiByte باید شامل کاراکترهای چندبایته باشد",
},
{
ns: "Test.ASCII",
expected: "ASCII باید فقط شامل کاراکترهای اسکی باشد",
},
{
ns: "Test.PrintableASCII",
expected: "PrintableASCII باید فقط شامل کاراکترهای اسکی قابل چاپ باشد",
},
{
ns: "Test.UUID",
expected: "UUID باید یک UUID معتبر باشد",
},
{
ns: "Test.UUID3",
expected: "UUID3 باید یک UUID نسخه 3 معتبر باشد",
},
{
ns: "Test.UUID4",
expected: "UUID4 باید یک UUID نسخه 4 معتبر باشد",
},
{
ns: "Test.UUID5",
expected: "UUID5 باید یک UUID نسخه 5 معتبر باشد",
},
{
ns: "Test.ULID",
expected: "ULID باید یک ULID معتبر باشد",
},
{
ns: "Test.ISBN",
expected: "ISBN باید یک شابک معتبر باشد",
},
{
ns: "Test.ISBN10",
expected: "ISBN10 باید یک شابک(ISBN-10) معتبر باشد",
},
{
ns: "Test.ISBN13",
expected: "ISBN13 باید یک شابک(ISBN-13) معتبر باشد",
},
{
ns: "Test.Excludes",
expected: "Excludes نمیتواند شامل 'text' باشد",
},
{
ns: "Test.ExcludesAll",
expected: "ExcludesAll نمیتواند شامل کاراکترهای '!@#$' باشد",
},
{
ns: "Test.ExcludesRune",
expected: "ExcludesRune نمیتواند شامل '☻' باشد",
},
{
ns: "Test.ContainsAny",
expected: "ContainsAny باید شامل کاراکترهای '!@#$' باشد",
},
{
ns: "Test.Contains",
expected: "Contains باید شامل 'purpose' باشد",
},
{
ns: "Test.Base64",
expected: "Base64 باید یک متن درمبنای64 معتبر باشد",
},
{
ns: "Test.Email",
expected: "Email باید یک ایمیل معتبر باشد",
},
{
ns: "Test.URL",
expected: "URL باید یک آدرس اینترنتی معتبر باشد",
},
{
ns: "Test.URI",
expected: "URI باید یک URI معتبر باشد",
},
{
ns: "Test.RGBColorString",
expected: "RGBColorString باید یک کد رنگ RGB باشد",
},
{
ns: "Test.RGBAColorString",
expected: "RGBAColorString باید یک کد رنگ RGBA باشد",
},
{
ns: "Test.HSLColorString",
expected: "HSLColorString باید یک کد رنگ HSL باشد",
},
{
ns: "Test.HSLAColorString",
expected: "HSLAColorString باید یک کد رنگ HSLA باشد",
},
{
ns: "Test.HexadecimalString",
expected: "HexadecimalString باید یک عدد درمبنای16 باشد",
},
{
ns: "Test.HexColorString",
expected: "HexColorString باید یک کد رنگ HEX باشد",
},
{
ns: "Test.NumberString",
expected: "NumberString باید یک عدد معتبر باشد",
},
{
ns: "Test.NumericString",
expected: "NumericString باید یک عدد معتبر باشد",
},
{
ns: "Test.AlphanumString",
expected: "AlphanumString میتواند فقط شامل حروف و اعداد باشد",
},
{
ns: "Test.AlphaString",
expected: "AlphaString میتواند فقط شامل حروف باشد",
},
{
ns: "Test.LtFieldString",
expected: "طول LtFieldString باید کمتر از MaxString باشد",
},
{
ns: "Test.LteFieldString",
expected: "طول LteFieldString باید کمتر یا برابر MaxString باشد",
},
{
ns: "Test.GtFieldString",
expected: "طول GtFieldString باید بیشتر از MaxString باشد",
},
{
ns: "Test.GteFieldString",
expected: "طول GteFieldString باید بیشتر یا برابر MaxString باشد",
},
{
ns: "Test.NeFieldString",
expected: "NeFieldString نمیتواند برابر EqFieldString باشد",
},
{
ns: "Test.LtCSFieldString",
expected: "طول LtCSFieldString باید کمتر از Inner.LtCSFieldString باشد",
},
{
ns: "Test.LteCSFieldString",
expected: "طول LteCSFieldString باید کمتر یا برابر Inner.LteCSFieldString باشد",
},
{
ns: "Test.GtCSFieldString",
expected: "طول GtCSFieldString باید بیشتر از Inner.GtCSFieldString باشد",
},
{
ns: "Test.GteCSFieldString",
expected: "طول GteCSFieldString باید بیشتر یا برابر Inner.GteCSFieldString باشد",
},
{
ns: "Test.NeCSFieldString",
expected: "NeCSFieldString نمیتواند برابر Inner.NeCSFieldString باشد",
},
{
ns: "Test.EqCSFieldString",
expected: "EqCSFieldString باید برابر Inner.EqCSFieldString باشد",
},
{
ns: "Test.EqFieldString",
expected: "EqFieldString باید برابر MaxString باشد",
},
{
ns: "Test.GteString",
expected: "طول GteString باید حداقل 3 کاراکتر باشد",
},
{
ns: "Test.GteNumber",
expected: "GteNumber باید بیشتر یا برابر 5.56 باشد",
},
{
ns: "Test.GteMultiple",
expected: "GteMultiple باید شامل حداقل 2 آیتم باشد",
},
{
ns: "Test.GteTime",
expected: "GteTime باید بعد یا برابر تاریخ و زمان کنونی باشد",
},
{
ns: "Test.GtString",
expected: "طول GtString باید بیشتر از 3 کاراکتر باشد",
},
{
ns: "Test.GtNumber",
expected: "GtNumber باید بیشتر از 5.56 باشد",
},
{
ns: "Test.GtMultiple",
expected: "GtMultiple باید دارای بیشتر از 2 آیتم باشد",
},
{
ns: "Test.GtTime",
expected: "GtTime باید بعد از تاریخ و زمان کنونی باشد",
},
{
ns: "Test.LteString",
expected: "طول LteString باید حداکثر 3 کاراکتر باشد",
},
{
ns: "Test.LteNumber",
expected: "LteNumber باید کمتر یا برابر 5.56 باشد",
},
{
ns: "Test.LteMultiple",
expected: "LteMultiple باید حداکثر شامل 2 آیتم باشد",
},
{
ns: "Test.LteTime",
expected: "LteTime باید قبل یا برابر تاریخ و زمان کنونی باشد",
},
{
ns: "Test.LtString",
expected: "طول LtString باید کمتر از 3 کاراکتر باشد",
},
{
ns: "Test.LtNumber",
expected: "LtNumber باید کمتر از 5.56 باشد",
},
{
ns: "Test.LtMultiple",
expected: "LtMultiple باید دارای کمتر از 2 آیتم باشد",
},
{
ns: "Test.LtTime",
expected: "LtTime باید قبل از تاریخ و زمان کنونی باشد",
},
{
ns: "Test.NeString",
expected: "NeString نباید برابر باشد",
},
{
ns: "Test.NeNumber",
expected: "NeNumber نباید برابر 0.00 باشد",
},
{
ns: "Test.NeMultiple",
expected: "NeMultiple نباید برابر 0 باشد",
},
{
ns: "Test.EqString",
expected: "EqString برابر 3 نمیباشد",
},
{
ns: "Test.EqNumber",
expected: "EqNumber برابر 2.33 نمیباشد",
},
{
ns: "Test.EqMultiple",
expected: "EqMultiple برابر 7 نمیباشد",
},
{
ns: "Test.MaxString",
expected: "طول MaxString باید حداکثر 3 کاراکتر باشد",
},
{
ns: "Test.MaxNumber",
expected: "MaxNumber باید کمتر یا برابر 1,113.00 باشد",
},
{
ns: "Test.MaxMultiple",
expected: "MaxMultiple باید شامل حداکثر 7 آیتم باشد",
},
{
ns: "Test.MinString",
expected: "طول MinString باید حداقل 1 کاراکتر باشد",
},
{
ns: "Test.MinNumber",
expected: "MinNumber باید بزرگتر یا برابر 1,113.00 باشد",
},
{
ns: "Test.MinMultiple",
expected: "MinMultiple باید شامل حداقل 7 آیتم باشد",
},
{
ns: "Test.LenString",
expected: "طول LenString باید 1 کاراکتر باشد",
},
{
ns: "Test.LenNumber",
expected: "طول LenNumber باید برابر 1,113.00 باشد",
},
{
ns: "Test.LenMultiple",
expected: "تعداد LenMultiple باید برابر 7 آیتم باشد",
},
{
ns: "Test.RequiredString",
expected: "فیلد RequiredString اجباری میباشد",
},
{
ns: "Test.RequiredNumber",
expected: "فیلد RequiredNumber اجباری میباشد",
},
{
ns: "Test.RequiredMultiple",
expected: "فیلد RequiredMultiple اجباری میباشد",
},
{
ns: "Test.StrPtrMinLen",
expected: "طول StrPtrMinLen باید حداقل 10 کاراکتر باشد",
},
{
ns: "Test.StrPtrMaxLen",
expected: "طول StrPtrMaxLen باید حداکثر 1 کاراکتر باشد",
},
{
ns: "Test.StrPtrLen",
expected: "طول StrPtrLen باید 2 کاراکتر باشد",
},
{
ns: "Test.StrPtrLt",
expected: "طول StrPtrLt باید کمتر از 1 کاراکتر باشد",
},
{
ns: "Test.StrPtrLte",
expected: "طول StrPtrLte باید حداکثر 1 کاراکتر باشد",
},
{
ns: "Test.StrPtrGt",
expected: "طول StrPtrGt باید بیشتر از 10 کاراکتر باشد",
},
{
ns: "Test.StrPtrGte",
expected: "طول StrPtrGte باید حداقل 10 کاراکتر باشد",
},
{
ns: "Test.OneOfString",
expected: "OneOfString باید یکی از مقادیر [red green] باشد",
},
{
ns: "Test.OneOfInt",
expected: "OneOfInt باید یکی از مقادیر [5 63] باشد",
},
{
ns: "Test.UniqueSlice",
expected: "UniqueSlice باید شامل مقادیر منحصربفرد باشد",
},
{
ns: "Test.UniqueArray",
expected: "UniqueArray باید شامل مقادیر منحصربفرد باشد",
},
{
ns: "Test.UniqueMap",
expected: "UniqueMap باید شامل مقادیر منحصربفرد باشد",
},
{
ns: "Test.JSONString",
expected: "JSONString باید یک json معتبر باشد",
},
{
ns: "Test.LowercaseString",
expected: "LowercaseString باید یک متن با حروف کوچک باشد",
},
{
ns: "Test.UppercaseString",
expected: "UppercaseString باید یک متن با حروف بزرگ باشد",
},
{
ns: "Test.Datetime",
expected: "فرمت Datetime با 2006-01-02 سازگار نیست",
},
{
ns: "Test.PostCode",
expected: "PostCode یک کدپستی معتبر کشور SG نیست",
},
{
ns: "Test.PostCodeByField",
expected: "PostCodeByField یک کدپستی معتبر کشور فیلد PostCodeCountry نیست",
},
}
for _, tt := range tests {
var fe validator.FieldError
for _, e := range errs {
if tt.ns == e.Namespace() {
fe = e
break
}
}
NotEqual(t, fe, nil)
Equal(t, tt.expected, fe.Translate(trans))
}
}

@ -1173,11 +1173,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} doit être un UUID version 5 valid", translation: "{0} doit être un UUID version 5 valid",
override: false, override: false,
}, },
{
tag: "ulid",
translation: "{0} doit être une ULID valide",
override: false,
},
{ {
tag: "ascii", tag: "ascii",
translation: "{0} ne doit contenir que des caractères ascii", translation: "{0} ne doit contenir que des caractères ascii",

@ -4,9 +4,9 @@ import (
"testing" "testing"
"time" "time"
. "github.com/go-playground/assert/v2"
french "github.com/go-playground/locales/fr" french "github.com/go-playground/locales/fr"
ut "github.com/go-playground/universal-translator" ut "github.com/go-playground/universal-translator"
. "github.com/go-playground/assert/v2"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
) )
@ -104,7 +104,6 @@ func TestTranslations(t *testing.T) {
UUID3 string `validate:"uuid3"` UUID3 string `validate:"uuid3"`
UUID4 string `validate:"uuid4"` UUID4 string `validate:"uuid4"`
UUID5 string `validate:"uuid5"` UUID5 string `validate:"uuid5"`
ULID string `validate:"ulid"`
ASCII string `validate:"ascii"` ASCII string `validate:"ascii"`
PrintableASCII string `validate:"printascii"` PrintableASCII string `validate:"printascii"`
MultiByte string `validate:"multibyte"` MultiByte string `validate:"multibyte"`
@ -307,10 +306,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.UUID5", ns: "Test.UUID5",
expected: "UUID5 doit être un UUID version 5 valid", expected: "UUID5 doit être un UUID version 5 valid",
}, },
{
ns: "Test.ULID",
expected: "ULID doit être une ULID valide",
},
{ {
ns: "Test.ISBN", ns: "Test.ISBN",
expected: "ISBN doit être un numéro ISBN valid", expected: "ISBN doit être un numéro ISBN valid",
@ -541,7 +536,7 @@ func TestTranslations(t *testing.T) {
}, },
{ {
ns: "Test.MaxNumber", ns: "Test.MaxNumber",
expected: "MaxNumber doit être égal à 1113,00 ou moins", expected: "MaxNumber doit être égal à 1 113,00 ou moins",
}, },
{ {
ns: "Test.MaxMultiple", ns: "Test.MaxMultiple",
@ -553,7 +548,7 @@ func TestTranslations(t *testing.T) {
}, },
{ {
ns: "Test.MinNumber", ns: "Test.MinNumber",
expected: "MinNumber doit être égal à 1113,00 ou plus", expected: "MinNumber doit être égal à 1 113,00 ou plus",
}, },
{ {
ns: "Test.MinMultiple", ns: "Test.MinMultiple",
@ -565,7 +560,7 @@ func TestTranslations(t *testing.T) {
}, },
{ {
ns: "Test.LenNumber", ns: "Test.LenNumber",
expected: "LenNumber doit être égal à 1113,00", expected: "LenNumber doit être égal à 1 113,00",
}, },
{ {
ns: "Test.LenMultiple", ns: "Test.LenMultiple",

@ -1173,11 +1173,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} harus berupa UUID versi 5 yang valid", translation: "{0} harus berupa UUID versi 5 yang valid",
override: false, override: false,
}, },
{
tag: "ulid",
translation: "{0} harus berupa ULID yang valid",
override: false,
},
{ {
tag: "ascii", tag: "ascii",
translation: "{0} hanya boleh berisi karakter ascii", translation: "{0} hanya boleh berisi karakter ascii",

@ -4,9 +4,9 @@ import (
"testing" "testing"
"time" "time"
. "github.com/go-playground/assert/v2"
indonesia "github.com/go-playground/locales/id" indonesia "github.com/go-playground/locales/id"
ut "github.com/go-playground/universal-translator" ut "github.com/go-playground/universal-translator"
. "github.com/go-playground/assert/v2"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
) )
@ -104,7 +104,6 @@ func TestTranslations(t *testing.T) {
UUID3 string `validate:"uuid3"` UUID3 string `validate:"uuid3"`
UUID4 string `validate:"uuid4"` UUID4 string `validate:"uuid4"`
UUID5 string `validate:"uuid5"` UUID5 string `validate:"uuid5"`
ULID string `validate:"ulid"`
ASCII string `validate:"ascii"` ASCII string `validate:"ascii"`
PrintableASCII string `validate:"printascii"` PrintableASCII string `validate:"printascii"`
MultiByte string `validate:"multibyte"` MultiByte string `validate:"multibyte"`
@ -307,10 +306,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.UUID5", ns: "Test.UUID5",
expected: "UUID5 harus berupa UUID versi 5 yang valid", expected: "UUID5 harus berupa UUID versi 5 yang valid",
}, },
{
ns: "Test.ULID",
expected: "ULID harus berupa ULID yang valid",
},
{ {
ns: "Test.ISBN", ns: "Test.ISBN",
expected: "ISBN harus berupa nomor ISBN yang valid", expected: "ISBN harus berupa nomor ISBN yang valid",

File diff suppressed because it is too large Load Diff

@ -1,725 +0,0 @@
package it
import (
"testing"
"time"
. "github.com/go-playground/assert/v2"
italian "github.com/go-playground/locales/it"
ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
)
func TestTranslations(t *testing.T) {
ita := italian.New()
uni := ut.New(ita, ita)
trans, _ := uni.GetTranslator("it")
validate := validator.New()
err := RegisterDefaultTranslations(validate, trans)
Equal(t, err, nil)
type Inner struct {
EqCSFieldString string
NeCSFieldString string
GtCSFieldString string
GteCSFieldString string
LtCSFieldString string
LteCSFieldString string
}
type Test struct {
Inner Inner
RequiredString string `validate:"required"`
RequiredNumber int `validate:"required"`
RequiredMultiple []string `validate:"required"`
LenString string `validate:"len=1"`
LenNumber float64 `validate:"len=1113.00"`
LenMultiple []string `validate:"len=7"`
MinString string `validate:"min=1"`
MinNumber float64 `validate:"min=1113.00"`
MinMultiple []string `validate:"min=7"`
MaxString string `validate:"max=3"`
MaxNumber float64 `validate:"max=1113.00"`
MaxMultiple []string `validate:"max=7"`
EqString string `validate:"eq=3"`
EqNumber float64 `validate:"eq=2.33"`
EqMultiple []string `validate:"eq=7"`
NeString string `validate:"ne="`
NeNumber float64 `validate:"ne=0.00"`
NeMultiple []string `validate:"ne=0"`
LtString string `validate:"lt=3"`
LtNumber float64 `validate:"lt=5.56"`
LtMultiple []string `validate:"lt=2"`
LtTime time.Time `validate:"lt"`
LteString string `validate:"lte=3"`
LteNumber float64 `validate:"lte=5.56"`
LteMultiple []string `validate:"lte=2"`
LteTime time.Time `validate:"lte"`
GtString string `validate:"gt=3"`
GtNumber float64 `validate:"gt=5.56"`
GtMultiple []string `validate:"gt=2"`
GtTime time.Time `validate:"gt"`
GteString string `validate:"gte=3"`
GteNumber float64 `validate:"gte=5.56"`
GteMultiple []string `validate:"gte=2"`
GteTime time.Time `validate:"gte"`
EqFieldString string `validate:"eqfield=MaxString"`
EqCSFieldString string `validate:"eqcsfield=Inner.EqCSFieldString"`
NeCSFieldString string `validate:"necsfield=Inner.NeCSFieldString"`
GtCSFieldString string `validate:"gtcsfield=Inner.GtCSFieldString"`
GteCSFieldString string `validate:"gtecsfield=Inner.GteCSFieldString"`
LtCSFieldString string `validate:"ltcsfield=Inner.LtCSFieldString"`
LteCSFieldString string `validate:"ltecsfield=Inner.LteCSFieldString"`
NeFieldString string `validate:"nefield=EqFieldString"`
GtFieldString string `validate:"gtfield=MaxString"`
GteFieldString string `validate:"gtefield=MaxString"`
LtFieldString string `validate:"ltfield=MaxString"`
LteFieldString string `validate:"ltefield=MaxString"`
AlphaString string `validate:"alpha"`
AlphanumString string `validate:"alphanum"`
NumericString string `validate:"numeric"`
NumberString string `validate:"number"`
HexadecimalString string `validate:"hexadecimal"`
HexColorString string `validate:"hexcolor"`
RGBColorString string `validate:"rgb"`
RGBAColorString string `validate:"rgba"`
HSLColorString string `validate:"hsl"`
HSLAColorString string `validate:"hsla"`
Email string `validate:"email"`
URL string `validate:"url"`
URI string `validate:"uri"`
Base64 string `validate:"base64"`
Contains string `validate:"contains=purpose"`
ContainsAny string `validate:"containsany=!@#$"`
Excludes string `validate:"excludes=text"`
ExcludesAll string `validate:"excludesall=!@#$"`
ExcludesRune string `validate:"excludesrune=☻"`
ISBN string `validate:"isbn"`
ISBN10 string `validate:"isbn10"`
ISBN13 string `validate:"isbn13"`
UUID string `validate:"uuid"`
UUID3 string `validate:"uuid3"`
UUID4 string `validate:"uuid4"`
UUID5 string `validate:"uuid5"`
ULID string `validate:"ulid"`
ASCII string `validate:"ascii"`
PrintableASCII string `validate:"printascii"`
MultiByte string `validate:"multibyte"`
DataURI string `validate:"datauri"`
Latitude string `validate:"latitude"`
Longitude string `validate:"longitude"`
SSN string `validate:"ssn"`
IP string `validate:"ip"`
IPv4 string `validate:"ipv4"`
IPv6 string `validate:"ipv6"`
CIDR string `validate:"cidr"`
CIDRv4 string `validate:"cidrv4"`
CIDRv6 string `validate:"cidrv6"`
TCPAddr string `validate:"tcp_addr"`
TCPAddrv4 string `validate:"tcp4_addr"`
TCPAddrv6 string `validate:"tcp6_addr"`
UDPAddr string `validate:"udp_addr"`
UDPAddrv4 string `validate:"udp4_addr"`
UDPAddrv6 string `validate:"udp6_addr"`
IPAddr string `validate:"ip_addr"`
IPAddrv4 string `validate:"ip4_addr"`
IPAddrv6 string `validate:"ip6_addr"`
UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future
MAC string `validate:"mac"`
IsColor string `validate:"iscolor"`
StrPtrMinLen *string `validate:"min=10"`
StrPtrMaxLen *string `validate:"max=1"`
StrPtrLen *string `validate:"len=2"`
StrPtrLt *string `validate:"lt=1"`
StrPtrLte *string `validate:"lte=1"`
StrPtrGt *string `validate:"gt=10"`
StrPtrGte *string `validate:"gte=10"`
OneOfString string `validate:"oneof=red green"`
OneOfInt int `validate:"oneof=5 63"`
UniqueSlice []string `validate:"unique"`
UniqueArray [3]string `validate:"unique"`
UniqueMap map[string]string `validate:"unique"`
BooleanString string `validate:"boolean"`
JSONString string `validate:"json"`
JWTString string `validate:"jwt"`
LowercaseString string `validate:"lowercase"`
UppercaseString string `validate:"uppercase"`
StartsWithString string `validate:"startswith=foo"`
StartsNotWithString string `validate:"startsnotwith=foo"`
EndsWithString string `validate:"endswith=foo"`
EndsNotWithString string `validate:"endsnotwith=foo"`
Datetime string `validate:"datetime=2006-01-02"`
PostCode string `validate:"postcode_iso3166_alpha2=SG"`
PostCodeCountry string
PostCodeByField string `validate:"postcode_iso3166_alpha2_field=PostCodeCountry"`
}
var test Test
test.Inner.EqCSFieldString = "1234"
test.Inner.GtCSFieldString = "1234"
test.Inner.GteCSFieldString = "1234"
test.MaxString = "1234"
test.MaxNumber = 2000
test.MaxMultiple = make([]string, 9)
test.LtString = "1234"
test.LtNumber = 6
test.LtMultiple = make([]string, 3)
test.LtTime = time.Now().Add(time.Hour * 24)
test.LteString = "1234"
test.LteNumber = 6
test.LteMultiple = make([]string, 3)
test.LteTime = time.Now().Add(time.Hour * 24)
test.LtFieldString = "12345"
test.LteFieldString = "12345"
test.LtCSFieldString = "1234"
test.LteCSFieldString = "1234"
test.AlphaString = "abc3"
test.AlphanumString = "abc3!"
test.NumericString = "12E.00"
test.NumberString = "12E"
test.Excludes = "this is some test text"
test.ExcludesAll = "This is Great!"
test.ExcludesRune = "Love it ☻"
test.ASCII = "カタカナ"
test.PrintableASCII = "カタカナ"
test.MultiByte = "1234feerf"
test.LowercaseString = "ABCDEFG"
test.UppercaseString = "abcdefg"
test.StartsWithString = "hello"
test.StartsNotWithString = "foo-hello"
test.EndsWithString = "hello"
test.EndsNotWithString = "hello-foo"
s := "toolong"
test.StrPtrMaxLen = &s
test.StrPtrLen = &s
test.UniqueSlice = []string{"1234", "1234"}
test.UniqueMap = map[string]string{"key1": "1234", "key2": "1234"}
test.Datetime = "2008-Feb-01"
err = validate.Struct(test)
NotEqual(t, err, nil)
errs, ok := err.(validator.ValidationErrors)
Equal(t, ok, true)
tests := []struct {
ns string
expected string
}{
{
ns: "Test.IsColor",
expected: "IsColor deve essere un colore valido",
},
{
ns: "Test.MAC",
expected: "MAC deve contenere un indirizzo MAC valido",
},
{
ns: "Test.IPAddr",
expected: "IPAddr deve essere un indirizzo IP risolvibile",
},
{
ns: "Test.IPAddrv4",
expected: "IPAddrv4 deve essere un indirizzo IPv4 risolvibile",
},
{
ns: "Test.IPAddrv6",
expected: "IPAddrv6 deve essere un indirizzo IPv6 risolvibile",
},
{
ns: "Test.UDPAddr",
expected: "UDPAddr deve essere un indirizzo UDP valido",
},
{
ns: "Test.UDPAddrv4",
expected: "UDPAddrv4 deve essere un indirizzo IPv4 UDP valido",
},
{
ns: "Test.UDPAddrv6",
expected: "UDPAddrv6 deve essere un indirizzo IPv6 UDP valido",
},
{
ns: "Test.TCPAddr",
expected: "TCPAddr deve essere un indirizzo TCP valido",
},
{
ns: "Test.TCPAddrv4",
expected: "TCPAddrv4 deve essere un indirizzo IPv4 TCP valido",
},
{
ns: "Test.TCPAddrv6",
expected: "TCPAddrv6 deve essere un indirizzo IPv6 TCP valido",
},
{
ns: "Test.CIDR",
expected: "CIDR deve contenere una notazione CIDR valida",
},
{
ns: "Test.CIDRv4",
expected: "CIDRv4 deve contenere una notazione CIDR per un indirizzo IPv4 valida",
},
{
ns: "Test.CIDRv6",
expected: "CIDRv6 deve contenere una notazione CIDR per un indirizzo IPv6 valida",
},
{
ns: "Test.SSN",
expected: "SSN deve essere un numero SSN valido",
},
{
ns: "Test.IP",
expected: "IP deve essere un indirizzo IP valido",
},
{
ns: "Test.IPv4",
expected: "IPv4 deve essere un indirizzo IPv4 valido",
},
{
ns: "Test.IPv6",
expected: "IPv6 deve essere un indirizzo IPv6 valido",
},
{
ns: "Test.DataURI",
expected: "DataURI deve contenere un Data URI valido",
},
{
ns: "Test.Latitude",
expected: "Latitude deve contenere una latitudine valida",
},
{
ns: "Test.Longitude",
expected: "Longitude deve contenere una longitudine valida",
},
{
ns: "Test.MultiByte",
expected: "MultiByte deve contenere caratteri multibyte",
},
{
ns: "Test.ASCII",
expected: "ASCII deve contenere solo caratteri ascii",
},
{
ns: "Test.PrintableASCII",
expected: "PrintableASCII deve contenere solo caratteri ascii stampabili",
},
{
ns: "Test.UUID",
expected: "UUID deve essere un UUID valido",
},
{
ns: "Test.UUID3",
expected: "UUID3 deve essere un UUID versione 3 valido",
},
{
ns: "Test.UUID4",
expected: "UUID4 deve essere un UUID versione 4 valido",
},
{
ns: "Test.UUID5",
expected: "UUID5 deve essere un UUID versione 5 valido",
},
{
ns: "Test.ULID",
expected: "ULID deve essere un ULID valido",
},
{
ns: "Test.ISBN",
expected: "ISBN deve essere un numero ISBN valido",
},
{
ns: "Test.ISBN10",
expected: "ISBN10 deve essere un numero ISBN-10 valido",
},
{
ns: "Test.ISBN13",
expected: "ISBN13 deve essere un numero ISBN-13 valido",
},
{
ns: "Test.Excludes",
expected: "Excludes non deve contenere il testo 'text'",
},
{
ns: "Test.ExcludesAll",
expected: "ExcludesAll non deve contenere alcuno dei seguenti caratteri '!@#$'",
},
{
ns: "Test.ExcludesRune",
expected: "ExcludesRune non deve contenere '☻'",
},
{
ns: "Test.ContainsAny",
expected: "ContainsAny deve contenere almeno uno dei seguenti caratteri '!@#$'",
},
{
ns: "Test.Contains",
expected: "Contains deve contenere il testo 'purpose'",
},
{
ns: "Test.Base64",
expected: "Base64 deve essere una stringa Base64 valida",
},
{
ns: "Test.Email",
expected: "Email deve essere un indirizzo email valido",
},
{
ns: "Test.URL",
expected: "URL deve essere un URL valido",
},
{
ns: "Test.URI",
expected: "URI deve essere un URI valido",
},
{
ns: "Test.RGBColorString",
expected: "RGBColorString deve essere un colore RGB valido",
},
{
ns: "Test.RGBAColorString",
expected: "RGBAColorString deve essere un colore RGBA valido",
},
{
ns: "Test.HSLColorString",
expected: "HSLColorString deve essere un colore HSL valido",
},
{
ns: "Test.HSLAColorString",
expected: "HSLAColorString deve essere un colore HSLA valido",
},
{
ns: "Test.HexadecimalString",
expected: "HexadecimalString deve essere un esadecimale valido",
},
{
ns: "Test.HexColorString",
expected: "HexColorString deve essere un colore HEX valido",
},
{
ns: "Test.NumberString",
expected: "NumberString deve essere un numero valido",
},
{
ns: "Test.NumericString",
expected: "NumericString deve essere un valore numerico valido",
},
{
ns: "Test.AlphanumString",
expected: "AlphanumString può contenere solo caratteri alfanumerici",
},
{
ns: "Test.AlphaString",
expected: "AlphaString può contenere solo caratteri alfabetici",
},
{
ns: "Test.LtFieldString",
expected: "LtFieldString deve essere minore di MaxString",
},
{
ns: "Test.LteFieldString",
expected: "LteFieldString deve essere minore o uguale a MaxString",
},
{
ns: "Test.GtFieldString",
expected: "GtFieldString deve essere maggiore di MaxString",
},
{
ns: "Test.GteFieldString",
expected: "GteFieldString deve essere maggiore o uguale a MaxString",
},
{
ns: "Test.NeFieldString",
expected: "NeFieldString deve essere diverso da EqFieldString",
},
{
ns: "Test.LtCSFieldString",
expected: "LtCSFieldString deve essere minore di Inner.LtCSFieldString",
},
{
ns: "Test.LteCSFieldString",
expected: "LteCSFieldString deve essere minore o uguale a Inner.LteCSFieldString",
},
{
ns: "Test.GtCSFieldString",
expected: "GtCSFieldString deve essere maggiore di Inner.GtCSFieldString",
},
{
ns: "Test.GteCSFieldString",
expected: "GteCSFieldString deve essere maggiore o uguale a Inner.GteCSFieldString",
},
{
ns: "Test.NeCSFieldString",
expected: "NeCSFieldString deve essere diverso da Inner.NeCSFieldString",
},
{
ns: "Test.EqCSFieldString",
expected: "EqCSFieldString deve essere uguale a Inner.EqCSFieldString",
},
{
ns: "Test.EqFieldString",
expected: "EqFieldString deve essere uguale a MaxString",
},
{
ns: "Test.GteString",
expected: "GteString deve essere lungo almeno 3 caratteri",
},
{
ns: "Test.GteNumber",
expected: "GteNumber deve essere maggiore o uguale a 5,56",
},
{
ns: "Test.GteMultiple",
expected: "GteMultiple deve contenere almeno 2 elementi",
},
{
ns: "Test.GteTime",
expected: "GteTime deve essere uguale o successivo alla Data/Ora corrente",
},
{
ns: "Test.GtString",
expected: "GtString deve essere lungo più di 3 caratteri",
},
{
ns: "Test.GtNumber",
expected: "GtNumber deve essere maggiore di 5,56",
},
{
ns: "Test.GtMultiple",
expected: "GtMultiple deve contenere più di 2 elementi",
},
{
ns: "Test.GtTime",
expected: "GtTime deve essere successivo alla Data/Ora corrente",
},
{
ns: "Test.LteString",
expected: "LteString deve essere lungo al massimo 3 caratteri",
},
{
ns: "Test.LteNumber",
expected: "LteNumber deve essere minore o uguale a 5,56",
},
{
ns: "Test.LteMultiple",
expected: "LteMultiple deve contenere al massimo 2 elementi",
},
{
ns: "Test.LteTime",
expected: "LteTime deve essere uguale o precedente alla Data/Ora corrente",
},
{
ns: "Test.LtString",
expected: "LtString deve essere lungo meno di 3 caratteri",
},
{
ns: "Test.LtNumber",
expected: "LtNumber deve essere minore di 5,56",
},
{
ns: "Test.LtMultiple",
expected: "LtMultiple deve contenere meno di 2 elementi",
},
{
ns: "Test.LtTime",
expected: "LtTime deve essere precedente alla Data/Ora corrente",
},
{
ns: "Test.NeString",
expected: "NeString deve essere diverso da ",
},
{
ns: "Test.NeNumber",
expected: "NeNumber deve essere diverso da 0.00",
},
{
ns: "Test.NeMultiple",
expected: "NeMultiple deve essere diverso da 0",
},
{
ns: "Test.EqString",
expected: "EqString non è uguale a 3",
},
{
ns: "Test.EqNumber",
expected: "EqNumber non è uguale a 2.33",
},
{
ns: "Test.EqMultiple",
expected: "EqMultiple non è uguale a 7",
},
{
ns: "Test.MaxString",
expected: "MaxString deve essere lungo al massimo 3 caratteri",
},
{
ns: "Test.MaxNumber",
expected: "MaxNumber deve essere minore o uguale a 1.113,00",
},
{
ns: "Test.MaxMultiple",
expected: "MaxMultiple deve contenere al massimo 7 elementi",
},
{
ns: "Test.MinString",
expected: "MinString deve essere lungo almeno 1 carattere",
},
{
ns: "Test.MinNumber",
expected: "MinNumber deve essere maggiore o uguale a 1.113,00",
},
{
ns: "Test.MinMultiple",
expected: "MinMultiple deve contenere almeno 7 elementi",
},
{
ns: "Test.LenString",
expected: "LenString deve essere lungo 1 carattere",
},
{
ns: "Test.LenNumber",
expected: "LenNumber deve essere uguale a 1.113,00",
},
{
ns: "Test.LenMultiple",
expected: "LenMultiple deve contenere 7 elementi",
},
{
ns: "Test.RequiredString",
expected: "RequiredString è un campo obbligatorio",
},
{
ns: "Test.RequiredNumber",
expected: "RequiredNumber è un campo obbligatorio",
},
{
ns: "Test.RequiredMultiple",
expected: "RequiredMultiple è un campo obbligatorio",
},
{
ns: "Test.StrPtrMinLen",
expected: "StrPtrMinLen deve essere lungo almeno 10 caratteri",
},
{
ns: "Test.StrPtrMaxLen",
expected: "StrPtrMaxLen deve essere lungo al massimo 1 carattere",
},
{
ns: "Test.StrPtrLen",
expected: "StrPtrLen deve essere lungo 2 caratteri",
},
{
ns: "Test.StrPtrLt",
expected: "StrPtrLt deve essere lungo meno di 1 carattere",
},
{
ns: "Test.StrPtrLte",
expected: "StrPtrLte deve essere lungo al massimo 1 carattere",
},
{
ns: "Test.StrPtrGt",
expected: "StrPtrGt deve essere lungo più di 10 caratteri",
},
{
ns: "Test.StrPtrGte",
expected: "StrPtrGte deve essere lungo almeno 10 caratteri",
},
{
ns: "Test.OneOfString",
expected: "OneOfString deve essere uno di [red green]",
},
{
ns: "Test.OneOfInt",
expected: "OneOfInt deve essere uno di [5 63]",
},
{
ns: "Test.UniqueSlice",
expected: "UniqueSlice deve contenere valori unici",
},
{
ns: "Test.UniqueArray",
expected: "UniqueArray deve contenere valori unici",
},
{
ns: "Test.UniqueMap",
expected: "UniqueMap deve contenere valori unici",
},
{
ns: "Test.BooleanString",
expected: "BooleanString deve rappresentare un valore booleano",
},
{
ns: "Test.JSONString",
expected: "JSONString deve essere una stringa json valida",
},
{
ns: "Test.JWTString",
expected: "JWTString deve essere una stringa jwt valida",
},
{
ns: "Test.LowercaseString",
expected: "LowercaseString deve essere una stringa minuscola",
},
{
ns: "Test.UppercaseString",
expected: "UppercaseString deve essere una stringa maiuscola",
},
{
ns: "Test.StartsWithString",
expected: "StartsWithString deve iniziare con foo",
},
{
ns: "Test.StartsNotWithString",
expected: "StartsNotWithString non deve iniziare con foo",
},
{
ns: "Test.EndsWithString",
expected: "EndsWithString deve terminare con foo",
},
{
ns: "Test.EndsNotWithString",
expected: "EndsNotWithString non deve terminare con foo",
},
{
ns: "Test.Datetime",
expected: "Datetime non corrisponde al formato 2006-01-02",
},
{
ns: "Test.PostCode",
expected: "PostCode non corrisponde al formato del codice postale dello stato SG",
},
{
ns: "Test.PostCodeByField",
expected: "PostCodeByField non corrisponde al formato del codice postale dello stato nel campo PostCodeCountry",
},
}
for _, tt := range tests {
var fe validator.FieldError
for _, e := range errs {
if tt.ns == e.Namespace() {
fe = e
break
}
}
NotEqual(t, fe, nil)
Equal(t, tt.expected, fe.Translate(trans))
}
}

@ -16,6 +16,7 @@ import (
// RegisterDefaultTranslations registers a set of default translations // RegisterDefaultTranslations registers a set of default translations
// for all built in tag's in validator; you may add your own as desired. // for all built in tag's in validator; you may add your own as desired.
func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (err error) { func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (err error) {
translations := []struct { translations := []struct {
tag string tag string
translation string translation string
@ -28,14 +29,10 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}は必須フィールドです", translation: "{0}は必須フィールドです",
override: false, override: false,
}, },
{
tag: "required_if",
translation: "{0}は必須フィールドです",
override: false,
},
{ {
tag: "len", tag: "len",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("len-string", "{0}の長さは{1}でなければなりません", false); err != nil { if err = ut.Add("len-string", "{0}の長さは{1}でなければなりません", false); err != nil {
return return
} }
@ -67,6 +64,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
}, },
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
var err error var err error
var t string var t string
@ -125,6 +123,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{ {
tag: "min", tag: "min",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("min-string", "{0}の長さは少なくとも{1}はなければなりません", false); err != nil { if err = ut.Add("min-string", "{0}の長さは少なくとも{1}はなければなりません", false); err != nil {
return return
} }
@ -137,7 +136,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
if err = ut.Add("min-number", "{0}は{1}以上でなければなりません", false); err != nil { if err = ut.Add("min-number", "{0}は{1}かより大きくなければなりません", false); err != nil {
return return
} }
@ -156,6 +155,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
}, },
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
var err error var err error
var t string var t string
@ -214,6 +214,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{ {
tag: "max", tag: "max",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("max-string", "{0}の長さは最大でも{1}でなければなりません", false); err != nil { if err = ut.Add("max-string", "{0}の長さは最大でも{1}でなければなりません", false); err != nil {
return return
} }
@ -226,7 +227,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
if err = ut.Add("max-number", "{0}は{1}以下でなければなりません", false); err != nil { if err = ut.Add("max-number", "{0}は{1}かより小さくなければなりません", false); err != nil {
return return
} }
@ -306,6 +307,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}は{1}と等しくありません", translation: "{0}は{1}と等しくありません",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
fmt.Printf("warning: error translating FieldError: %#v", fe) fmt.Printf("warning: error translating FieldError: %#v", fe)
@ -389,6 +391,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{ {
tag: "lt", tag: "lt",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("lt-string", "{0}の長さは{1}よりも少なくなければなりません", false); err != nil { if err = ut.Add("lt-string", "{0}の長さは{1}よりも少なくなければなりません", false); err != nil {
return return
} }
@ -509,6 +512,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{ {
tag: "lte", tag: "lte",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("lte-string", "{0}の長さは最大でも{1}でなければなりません", false); err != nil { if err = ut.Add("lte-string", "{0}の長さは最大でも{1}でなければなりません", false); err != nil {
return return
} }
@ -521,7 +525,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
if err = ut.Add("lte-number", "{0}は{1}以下でなければなりません", false); err != nil { if err = ut.Add("lte-number", "{0}は{1}かより小さくなければなりません", false); err != nil {
return return
} }
@ -628,6 +632,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{ {
tag: "gt", tag: "gt",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("gt-string", "{0}の長さは{1}よりも多くなければなりません", false); err != nil { if err = ut.Add("gt-string", "{0}の長さは{1}よりも多くなければなりません", false); err != nil {
return return
} }
@ -747,6 +752,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{ {
tag: "gte", tag: "gte",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("gte-string", "{0}の長さは少なくとも{1}以上はなければなりません", false); err != nil { if err = ut.Add("gte-string", "{0}の長さは少なくとも{1}以上はなければなりません", false); err != nil {
return return
} }
@ -759,7 +765,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
if err = ut.Add("gte-number", "{0}は{1}以上でなければなりません", false); err != nil { if err = ut.Add("gte-number", "{0}は{1}かより大きくなければなりません", false); err != nil {
return return
} }
@ -868,6 +874,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}は{1}と等しくなければなりません", translation: "{0}は{1}と等しくなければなりません",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -882,6 +889,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}は{1}と等しくなければなりません", translation: "{0}は{1}と等しくなければなりません",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -896,6 +904,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}は{1}とは異ならなければなりません", translation: "{0}は{1}とは異ならなければなりません",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -910,6 +919,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}は{1}よりも大きくなければなりません", translation: "{0}は{1}よりも大きくなければなりません",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -924,6 +934,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}は{1}以上でなければなりません", translation: "{0}は{1}以上でなければなりません",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -938,6 +949,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}は{1}よりも小さくなければなりません", translation: "{0}は{1}よりも小さくなければなりません",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -952,6 +964,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}は{1}以下でなければなりません", translation: "{0}は{1}以下でなければなりません",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -966,6 +979,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}は{1}とは異ならなければなりません", translation: "{0}は{1}とは異ならなければなりません",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -980,6 +994,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}は{1}よりも大きくなければなりません", translation: "{0}は{1}よりも大きくなければなりません",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -994,6 +1009,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}は{1}以上でなければなりません", translation: "{0}は{1}以上でなければなりません",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1008,6 +1024,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}は{1}よりも小さくなければなりません", translation: "{0}は{1}よりも小さくなければなりません",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1022,6 +1039,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}は{1}以下でなければなりません", translation: "{0}は{1}以下でなければなりません",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1106,6 +1124,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}は'{1}'を含まなければなりません", translation: "{0}は'{1}'を含まなければなりません",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1120,6 +1139,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}は'{1}'の少なくとも1つを含まなければなりません", translation: "{0}は'{1}'の少なくとも1つを含まなければなりません",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1134,6 +1154,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}には'{1}'というテキストを含むことはできません", translation: "{0}には'{1}'というテキストを含むことはできません",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1148,6 +1169,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}には'{1}'のどれも含めることはできません", translation: "{0}には'{1}'のどれも含めることはできません",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1162,6 +1184,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}には'{1}'を含めることはできません", translation: "{0}には'{1}'を含めることはできません",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1203,12 +1226,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
}, },
{ {
tag: "uuid5", tag: "uuid5",
translation: "{0}はバージョンが5の正しいUUIDでなければなりません", translation: "{0}はバージョンが4の正しいUUIDでなければなりません",
override: false,
},
{
tag: "ulid",
translation: "{0}は正しいULIDでなければなりません",
override: false, override: false,
}, },
{ {
@ -1331,11 +1349,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}は正しいMACアドレスを含まなければなりません", translation: "{0}は正しいMACアドレスを含まなければなりません",
override: false, override: false,
}, },
{
tag: "unique",
translation: "{0}は一意な値のみを含まなければなりません",
override: false,
},
{ {
tag: "iscolor", tag: "iscolor",
translation: "{0}は正しい色でなければなりません", translation: "{0}は正しい色でなければなりません",
@ -1354,83 +1367,22 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return s return s
}, },
}, },
{
tag: "json",
translation: "{0}は正しいJSON文字列でなければなりません",
override: false,
},
{
tag: "jwt",
translation: "{0}は正しいJWT文字列でなければなりません",
override: false,
},
{
tag: "lowercase",
translation: "{0}は小文字でなければなりません",
override: false,
},
{
tag: "uppercase",
translation: "{0}は大文字でなければなりません",
override: false,
},
{
tag: "datetime",
translation: "{0}は{1}の書式と一致しません",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
return fe.(error).Error()
}
return t
},
},
{
tag: "postcode_iso3166_alpha2",
translation: "{0}は国名コード{1}の郵便番号形式と一致しません",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
return fe.(error).Error()
}
return t
},
},
{
tag: "postcode_iso3166_alpha2_field",
translation: "{0}は{1}フィールドで指定された国名コードの郵便番号形式と一致しません",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
return fe.(error).Error()
}
return t
},
},
{
tag: "boolean",
translation: "{0}は正しいブール値でなければなりません",
override: false,
},
} }
for _, t := range translations { for _, t := range translations {
if t.customTransFunc != nil && t.customRegisFunc != nil { if t.customTransFunc != nil && t.customRegisFunc != nil {
err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, t.customTransFunc) err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, t.customTransFunc)
} else if t.customTransFunc != nil && t.customRegisFunc == nil { } else if t.customTransFunc != nil && t.customRegisFunc == nil {
err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), t.customTransFunc) err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), t.customTransFunc)
} else if t.customTransFunc == nil && t.customRegisFunc != nil { } else if t.customTransFunc == nil && t.customRegisFunc != nil {
err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, translateFunc) err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, translateFunc)
} else { } else {
err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), translateFunc) err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), translateFunc)
} }
@ -1444,7 +1396,9 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
} }
func registrationFunc(tag string, translation string, override bool) validator.RegisterTranslationsFunc { func registrationFunc(tag string, translation string, override bool) validator.RegisterTranslationsFunc {
return func(ut ut.Translator) (err error) { return func(ut ut.Translator) (err error) {
if err = ut.Add(tag, translation, override); err != nil { if err = ut.Add(tag, translation, override); err != nil {
return return
} }
@ -1456,6 +1410,7 @@ func registrationFunc(tag string, translation string, override bool) validator.R
} }
func translateFunc(ut ut.Translator, fe validator.FieldError) string { func translateFunc(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field()) t, err := ut.T(fe.Tag(), fe.Field())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)

@ -4,13 +4,14 @@ import (
"testing" "testing"
"time" "time"
. "github.com/go-playground/assert/v2"
ja_locale "github.com/go-playground/locales/ja" ja_locale "github.com/go-playground/locales/ja"
ut "github.com/go-playground/universal-translator" ut "github.com/go-playground/universal-translator"
. "github.com/go-playground/assert/v2"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
) )
func TestTranslations(t *testing.T) { func TestTranslations(t *testing.T) {
japanese := ja_locale.New() japanese := ja_locale.New()
uni := ut.New(japanese, japanese) uni := ut.New(japanese, japanese)
trans, _ := uni.GetTranslator("ja") trans, _ := uni.GetTranslator("ja")
@ -27,131 +28,116 @@ func TestTranslations(t *testing.T) {
GteCSFieldString string GteCSFieldString string
LtCSFieldString string LtCSFieldString string
LteCSFieldString string LteCSFieldString string
RequiredIf string
} }
type Test struct { type Test struct {
Inner Inner Inner Inner
RequiredString string `validate:"required"` RequiredString string `validate:"required"`
RequiredNumber int `validate:"required"` RequiredNumber int `validate:"required"`
RequiredMultiple []string `validate:"required"` RequiredMultiple []string `validate:"required"`
RequiredIf string `validate:"required_if=Inner.RequiredIf abcd"` LenString string `validate:"len=1"`
LenString string `validate:"len=1"` LenNumber float64 `validate:"len=1113.00"`
LenNumber float64 `validate:"len=1113.00"` LenMultiple []string `validate:"len=7"`
LenMultiple []string `validate:"len=7"` MinString string `validate:"min=1"`
MinString string `validate:"min=1"` MinNumber float64 `validate:"min=1113.00"`
MinNumber float64 `validate:"min=1113.00"` MinMultiple []string `validate:"min=7"`
MinMultiple []string `validate:"min=7"` MaxString string `validate:"max=3"`
MaxString string `validate:"max=3"` MaxNumber float64 `validate:"max=1113.00"`
MaxNumber float64 `validate:"max=1113.00"` MaxMultiple []string `validate:"max=7"`
MaxMultiple []string `validate:"max=7"` EqString string `validate:"eq=3"`
EqString string `validate:"eq=3"` EqNumber float64 `validate:"eq=2.33"`
EqNumber float64 `validate:"eq=2.33"` EqMultiple []string `validate:"eq=7"`
EqMultiple []string `validate:"eq=7"` NeString string `validate:"ne="`
NeString string `validate:"ne="` NeNumber float64 `validate:"ne=0.00"`
NeNumber float64 `validate:"ne=0.00"` NeMultiple []string `validate:"ne=0"`
NeMultiple []string `validate:"ne=0"` LtString string `validate:"lt=3"`
LtString string `validate:"lt=3"` LtNumber float64 `validate:"lt=5.56"`
LtNumber float64 `validate:"lt=5.56"` LtMultiple []string `validate:"lt=2"`
LtMultiple []string `validate:"lt=2"` LtTime time.Time `validate:"lt"`
LtTime time.Time `validate:"lt"` LteString string `validate:"lte=3"`
LteString string `validate:"lte=3"` LteNumber float64 `validate:"lte=5.56"`
LteNumber float64 `validate:"lte=5.56"` LteMultiple []string `validate:"lte=2"`
LteMultiple []string `validate:"lte=2"` LteTime time.Time `validate:"lte"`
LteTime time.Time `validate:"lte"` GtString string `validate:"gt=3"`
GtString string `validate:"gt=3"` GtNumber float64 `validate:"gt=5.56"`
GtNumber float64 `validate:"gt=5.56"` GtMultiple []string `validate:"gt=2"`
GtMultiple []string `validate:"gt=2"` GtTime time.Time `validate:"gt"`
GtTime time.Time `validate:"gt"` GteString string `validate:"gte=3"`
GteString string `validate:"gte=3"` GteNumber float64 `validate:"gte=5.56"`
GteNumber float64 `validate:"gte=5.56"` GteMultiple []string `validate:"gte=2"`
GteMultiple []string `validate:"gte=2"` GteTime time.Time `validate:"gte"`
GteTime time.Time `validate:"gte"` EqFieldString string `validate:"eqfield=MaxString"`
EqFieldString string `validate:"eqfield=MaxString"` EqCSFieldString string `validate:"eqcsfield=Inner.EqCSFieldString"`
EqCSFieldString string `validate:"eqcsfield=Inner.EqCSFieldString"` NeCSFieldString string `validate:"necsfield=Inner.NeCSFieldString"`
NeCSFieldString string `validate:"necsfield=Inner.NeCSFieldString"` GtCSFieldString string `validate:"gtcsfield=Inner.GtCSFieldString"`
GtCSFieldString string `validate:"gtcsfield=Inner.GtCSFieldString"` GteCSFieldString string `validate:"gtecsfield=Inner.GteCSFieldString"`
GteCSFieldString string `validate:"gtecsfield=Inner.GteCSFieldString"` LtCSFieldString string `validate:"ltcsfield=Inner.LtCSFieldString"`
LtCSFieldString string `validate:"ltcsfield=Inner.LtCSFieldString"` LteCSFieldString string `validate:"ltecsfield=Inner.LteCSFieldString"`
LteCSFieldString string `validate:"ltecsfield=Inner.LteCSFieldString"` NeFieldString string `validate:"nefield=EqFieldString"`
NeFieldString string `validate:"nefield=EqFieldString"` GtFieldString string `validate:"gtfield=MaxString"`
GtFieldString string `validate:"gtfield=MaxString"` GteFieldString string `validate:"gtefield=MaxString"`
GteFieldString string `validate:"gtefield=MaxString"` LtFieldString string `validate:"ltfield=MaxString"`
LtFieldString string `validate:"ltfield=MaxString"` LteFieldString string `validate:"ltefield=MaxString"`
LteFieldString string `validate:"ltefield=MaxString"` AlphaString string `validate:"alpha"`
AlphaString string `validate:"alpha"` AlphanumString string `validate:"alphanum"`
AlphanumString string `validate:"alphanum"` NumericString string `validate:"numeric"`
NumericString string `validate:"numeric"` NumberString string `validate:"number"`
NumberString string `validate:"number"` HexadecimalString string `validate:"hexadecimal"`
HexadecimalString string `validate:"hexadecimal"` HexColorString string `validate:"hexcolor"`
HexColorString string `validate:"hexcolor"` RGBColorString string `validate:"rgb"`
RGBColorString string `validate:"rgb"` RGBAColorString string `validate:"rgba"`
RGBAColorString string `validate:"rgba"` HSLColorString string `validate:"hsl"`
HSLColorString string `validate:"hsl"` HSLAColorString string `validate:"hsla"`
HSLAColorString string `validate:"hsla"` Email string `validate:"email"`
Email string `validate:"email"` URL string `validate:"url"`
URL string `validate:"url"` URI string `validate:"uri"`
URI string `validate:"uri"` Base64 string `validate:"base64"`
Base64 string `validate:"base64"` Contains string `validate:"contains=purpose"`
Contains string `validate:"contains=purpose"` ContainsAny string `validate:"containsany=!@#$"`
ContainsAny string `validate:"containsany=!@#$"` Excludes string `validate:"excludes=text"`
Excludes string `validate:"excludes=text"` ExcludesAll string `validate:"excludesall=!@#$"`
ExcludesAll string `validate:"excludesall=!@#$"` ExcludesRune string `validate:"excludesrune=☻"`
ExcludesRune string `validate:"excludesrune=☻"` ISBN string `validate:"isbn"`
ISBN string `validate:"isbn"` ISBN10 string `validate:"isbn10"`
ISBN10 string `validate:"isbn10"` ISBN13 string `validate:"isbn13"`
ISBN13 string `validate:"isbn13"` UUID string `validate:"uuid"`
UUID string `validate:"uuid"` UUID3 string `validate:"uuid3"`
UUID3 string `validate:"uuid3"` UUID4 string `validate:"uuid4"`
UUID4 string `validate:"uuid4"` UUID5 string `validate:"uuid5"`
UUID5 string `validate:"uuid5"` ASCII string `validate:"ascii"`
ULID string `validate:"ulid"` PrintableASCII string `validate:"printascii"`
ASCII string `validate:"ascii"` MultiByte string `validate:"multibyte"`
PrintableASCII string `validate:"printascii"` DataURI string `validate:"datauri"`
MultiByte string `validate:"multibyte"` Latitude string `validate:"latitude"`
DataURI string `validate:"datauri"` Longitude string `validate:"longitude"`
Latitude string `validate:"latitude"` SSN string `validate:"ssn"`
Longitude string `validate:"longitude"` IP string `validate:"ip"`
SSN string `validate:"ssn"` IPv4 string `validate:"ipv4"`
IP string `validate:"ip"` IPv6 string `validate:"ipv6"`
IPv4 string `validate:"ipv4"` CIDR string `validate:"cidr"`
IPv6 string `validate:"ipv6"` CIDRv4 string `validate:"cidrv4"`
CIDR string `validate:"cidr"` CIDRv6 string `validate:"cidrv6"`
CIDRv4 string `validate:"cidrv4"` TCPAddr string `validate:"tcp_addr"`
CIDRv6 string `validate:"cidrv6"` TCPAddrv4 string `validate:"tcp4_addr"`
TCPAddr string `validate:"tcp_addr"` TCPAddrv6 string `validate:"tcp6_addr"`
TCPAddrv4 string `validate:"tcp4_addr"` UDPAddr string `validate:"udp_addr"`
TCPAddrv6 string `validate:"tcp6_addr"` UDPAddrv4 string `validate:"udp4_addr"`
UDPAddr string `validate:"udp_addr"` UDPAddrv6 string `validate:"udp6_addr"`
UDPAddrv4 string `validate:"udp4_addr"` IPAddr string `validate:"ip_addr"`
UDPAddrv6 string `validate:"udp6_addr"` IPAddrv4 string `validate:"ip4_addr"`
IPAddr string `validate:"ip_addr"` IPAddrv6 string `validate:"ip6_addr"`
IPAddrv4 string `validate:"ip4_addr"` UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future
IPAddrv6 string `validate:"ip6_addr"` MAC string `validate:"mac"`
UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future IsColor string `validate:"iscolor"`
MAC string `validate:"mac"` StrPtrMinLen *string `validate:"min=10"`
IsColor string `validate:"iscolor"` StrPtrMaxLen *string `validate:"max=1"`
StrPtrMinLen *string `validate:"min=10"` StrPtrLen *string `validate:"len=2"`
StrPtrMaxLen *string `validate:"max=1"` StrPtrLt *string `validate:"lt=1"`
StrPtrLen *string `validate:"len=2"` StrPtrLte *string `validate:"lte=1"`
StrPtrLt *string `validate:"lt=1"` StrPtrGt *string `validate:"gt=10"`
StrPtrLte *string `validate:"lte=1"` StrPtrGte *string `validate:"gte=10"`
StrPtrGt *string `validate:"gt=10"` OneOfString string `validate:"oneof=red green"`
StrPtrGte *string `validate:"gte=10"` OneOfInt int `validate:"oneof=5 63"`
OneOfString string `validate:"oneof=red green"`
OneOfInt int `validate:"oneof=5 63"`
UniqueSlice []string `validate:"unique"`
UniqueArray [3]string `validate:"unique"`
UniqueMap map[string]string `validate:"unique"`
JSONString string `validate:"json"`
JWTString string `validate:"jwt"`
LowercaseString string `validate:"lowercase"`
UppercaseString string `validate:"uppercase"`
Datetime string `validate:"datetime=2006-01-02"`
PostCode string `validate:"postcode_iso3166_alpha2=SG"`
PostCodeCountry string
PostCodeByField string `validate:"postcode_iso3166_alpha2_field=PostCodeCountry"`
BooleanString string `validate:"boolean"`
} }
var test Test var test Test
@ -194,20 +180,10 @@ func TestTranslations(t *testing.T) {
test.MultiByte = "1234feerf" test.MultiByte = "1234feerf"
test.LowercaseString = "ABCDEFG"
test.UppercaseString = "abcdefg"
s := "toolong" s := "toolong"
test.StrPtrMaxLen = &s test.StrPtrMaxLen = &s
test.StrPtrLen = &s test.StrPtrLen = &s
test.UniqueSlice = []string{"1234", "1234"}
test.UniqueMap = map[string]string{"key1": "1234", "key2": "1234"}
test.Datetime = "2008-Feb-01"
test.BooleanString = "A"
test.Inner.RequiredIf = "abcd"
err = validate.Struct(test) err = validate.Struct(test)
NotEqual(t, err, nil) NotEqual(t, err, nil)
@ -328,11 +304,7 @@ func TestTranslations(t *testing.T) {
}, },
{ {
ns: "Test.UUID5", ns: "Test.UUID5",
expected: "UUID5はバージョンが5の正しいUUIDでなければなりません", expected: "UUID5はバージョンが4の正しいUUIDでなければなりません",
},
{
ns: "Test.ULID",
expected: "ULIDは正しいULIDでなければなりません",
}, },
{ {
ns: "Test.ISBN", ns: "Test.ISBN",
@ -476,7 +448,7 @@ func TestTranslations(t *testing.T) {
}, },
{ {
ns: "Test.GteNumber", ns: "Test.GteNumber",
expected: "GteNumberは5.56以上でなければなりません", expected: "GteNumberは5.56かより大きくなければなりません",
}, },
{ {
ns: "Test.GteMultiple", ns: "Test.GteMultiple",
@ -508,7 +480,7 @@ func TestTranslations(t *testing.T) {
}, },
{ {
ns: "Test.LteNumber", ns: "Test.LteNumber",
expected: "LteNumberは5.56以下でなければなりません", expected: "LteNumberは5.56かより小さくなければなりません",
}, },
{ {
ns: "Test.LteMultiple", ns: "Test.LteMultiple",
@ -564,7 +536,7 @@ func TestTranslations(t *testing.T) {
}, },
{ {
ns: "Test.MaxNumber", ns: "Test.MaxNumber",
expected: "MaxNumberは1,113.00以下でなければなりません", expected: "MaxNumberは1,113.00かより小さくなければなりません",
}, },
{ {
ns: "Test.MaxMultiple", ns: "Test.MaxMultiple",
@ -576,7 +548,7 @@ func TestTranslations(t *testing.T) {
}, },
{ {
ns: "Test.MinNumber", ns: "Test.MinNumber",
expected: "MinNumberは1,113.00以上でなければなりません", expected: "MinNumberは1,113.00かより大きくなければなりません",
}, },
{ {
ns: "Test.MinMultiple", ns: "Test.MinMultiple",
@ -598,10 +570,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.RequiredString", ns: "Test.RequiredString",
expected: "RequiredStringは必須フィールドです", expected: "RequiredStringは必須フィールドです",
}, },
{
ns: "Test.RequiredIf",
expected: "RequiredIfは必須フィールドです",
},
{ {
ns: "Test.RequiredNumber", ns: "Test.RequiredNumber",
expected: "RequiredNumberは必須フィールドです", expected: "RequiredNumberは必須フィールドです",
@ -646,50 +614,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.OneOfInt", ns: "Test.OneOfInt",
expected: "OneOfIntは[5 63]のうちのいずれかでなければなりません", expected: "OneOfIntは[5 63]のうちのいずれかでなければなりません",
}, },
{
ns: "Test.UniqueSlice",
expected: "UniqueSliceは一意な値のみを含まなければなりません",
},
{
ns: "Test.UniqueArray",
expected: "UniqueArrayは一意な値のみを含まなければなりません",
},
{
ns: "Test.UniqueMap",
expected: "UniqueMapは一意な値のみを含まなければなりません",
},
{
ns: "Test.JSONString",
expected: "JSONStringは正しいJSON文字列でなければなりません",
},
{
ns: "Test.JWTString",
expected: "JWTStringは正しいJWT文字列でなければなりません",
},
{
ns: "Test.LowercaseString",
expected: "LowercaseStringは小文字でなければなりません",
},
{
ns: "Test.UppercaseString",
expected: "UppercaseStringは大文字でなければなりません",
},
{
ns: "Test.Datetime",
expected: "Datetimeは2006-01-02の書式と一致しません",
},
{
ns: "Test.PostCode",
expected: "PostCodeは国名コードSGの郵便番号形式と一致しません",
},
{
ns: "Test.PostCodeByField",
expected: "PostCodeByFieldはPostCodeCountryフィールドで指定された国名コードの郵便番号形式と一致しません",
},
{
ns: "Test.BooleanString",
expected: "BooleanStringは正しいブール値でなければなりません",
},
} }
for _, tt := range tests { for _, tt := range tests {

File diff suppressed because it is too large Load Diff

@ -1,709 +0,0 @@
package lv
import (
"testing"
"time"
. "github.com/go-playground/assert/v2"
english "github.com/go-playground/locales/en"
ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
)
func TestTranslations(t *testing.T) {
eng := english.New()
uni := ut.New(eng, eng)
trans, _ := uni.GetTranslator("en")
validate := validator.New()
err := RegisterDefaultTranslations(validate, trans)
Equal(t, err, nil)
type Inner struct {
EqCSFieldString string
NeCSFieldString string
GtCSFieldString string
GteCSFieldString string
LtCSFieldString string
LteCSFieldString string
RequiredIf string
}
type Test struct {
Inner Inner
RequiredString string `validate:"required"`
RequiredNumber int `validate:"required"`
RequiredMultiple []string `validate:"required"`
RequiredIf string `validate:"required_if=Inner.RequiredIf abcd"`
LenString string `validate:"len=1"`
LenNumber float64 `validate:"len=1113.00"`
LenMultiple []string `validate:"len=7"`
MinString string `validate:"min=1"`
MinNumber float64 `validate:"min=1113.00"`
MinMultiple []string `validate:"min=7"`
MaxString string `validate:"max=3"`
MaxNumber float64 `validate:"max=1113.00"`
MaxMultiple []string `validate:"max=7"`
EqString string `validate:"eq=3"`
EqNumber float64 `validate:"eq=2.33"`
EqMultiple []string `validate:"eq=7"`
NeString string `validate:"ne="`
NeNumber float64 `validate:"ne=0.00"`
NeMultiple []string `validate:"ne=0"`
LtString string `validate:"lt=3"`
LtNumber float64 `validate:"lt=5.56"`
LtMultiple []string `validate:"lt=2"`
LtTime time.Time `validate:"lt"`
LteString string `validate:"lte=3"`
LteNumber float64 `validate:"lte=5.56"`
LteMultiple []string `validate:"lte=2"`
LteTime time.Time `validate:"lte"`
GtString string `validate:"gt=3"`
GtNumber float64 `validate:"gt=5.56"`
GtMultiple []string `validate:"gt=2"`
GtTime time.Time `validate:"gt"`
GteString string `validate:"gte=3"`
GteNumber float64 `validate:"gte=5.56"`
GteMultiple []string `validate:"gte=2"`
GteTime time.Time `validate:"gte"`
EqFieldString string `validate:"eqfield=MaxString"`
EqCSFieldString string `validate:"eqcsfield=Inner.EqCSFieldString"`
NeCSFieldString string `validate:"necsfield=Inner.NeCSFieldString"`
GtCSFieldString string `validate:"gtcsfield=Inner.GtCSFieldString"`
GteCSFieldString string `validate:"gtecsfield=Inner.GteCSFieldString"`
LtCSFieldString string `validate:"ltcsfield=Inner.LtCSFieldString"`
LteCSFieldString string `validate:"ltecsfield=Inner.LteCSFieldString"`
NeFieldString string `validate:"nefield=EqFieldString"`
GtFieldString string `validate:"gtfield=MaxString"`
GteFieldString string `validate:"gtefield=MaxString"`
LtFieldString string `validate:"ltfield=MaxString"`
LteFieldString string `validate:"ltefield=MaxString"`
AlphaString string `validate:"alpha"`
AlphanumString string `validate:"alphanum"`
NumericString string `validate:"numeric"`
NumberString string `validate:"number"`
HexadecimalString string `validate:"hexadecimal"`
HexColorString string `validate:"hexcolor"`
RGBColorString string `validate:"rgb"`
RGBAColorString string `validate:"rgba"`
HSLColorString string `validate:"hsl"`
HSLAColorString string `validate:"hsla"`
Email string `validate:"email"`
URL string `validate:"url"`
URI string `validate:"uri"`
Base64 string `validate:"base64"`
Contains string `validate:"contains=purpose"`
ContainsAny string `validate:"containsany=!@#$"`
Excludes string `validate:"excludes=text"`
ExcludesAll string `validate:"excludesall=!@#$"`
ExcludesRune string `validate:"excludesrune=☻"`
ISBN string `validate:"isbn"`
ISBN10 string `validate:"isbn10"`
ISBN13 string `validate:"isbn13"`
UUID string `validate:"uuid"`
UUID3 string `validate:"uuid3"`
UUID4 string `validate:"uuid4"`
UUID5 string `validate:"uuid5"`
ULID string `validate:"ulid"`
ASCII string `validate:"ascii"`
PrintableASCII string `validate:"printascii"`
MultiByte string `validate:"multibyte"`
DataURI string `validate:"datauri"`
Latitude string `validate:"latitude"`
Longitude string `validate:"longitude"`
SSN string `validate:"ssn"`
IP string `validate:"ip"`
IPv4 string `validate:"ipv4"`
IPv6 string `validate:"ipv6"`
CIDR string `validate:"cidr"`
CIDRv4 string `validate:"cidrv4"`
CIDRv6 string `validate:"cidrv6"`
TCPAddr string `validate:"tcp_addr"`
TCPAddrv4 string `validate:"tcp4_addr"`
TCPAddrv6 string `validate:"tcp6_addr"`
UDPAddr string `validate:"udp_addr"`
UDPAddrv4 string `validate:"udp4_addr"`
UDPAddrv6 string `validate:"udp6_addr"`
IPAddr string `validate:"ip_addr"`
IPAddrv4 string `validate:"ip4_addr"`
IPAddrv6 string `validate:"ip6_addr"`
UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future
MAC string `validate:"mac"`
IsColor string `validate:"iscolor"`
StrPtrMinLen *string `validate:"min=10"`
StrPtrMaxLen *string `validate:"max=1"`
StrPtrLen *string `validate:"len=2"`
StrPtrLt *string `validate:"lt=1"`
StrPtrLte *string `validate:"lte=1"`
StrPtrGt *string `validate:"gt=10"`
StrPtrGte *string `validate:"gte=10"`
OneOfString string `validate:"oneof=red green"`
OneOfInt int `validate:"oneof=5 63"`
UniqueSlice []string `validate:"unique"`
UniqueArray [3]string `validate:"unique"`
UniqueMap map[string]string `validate:"unique"`
JSONString string `validate:"json"`
JWTString string `validate:"jwt"`
LowercaseString string `validate:"lowercase"`
UppercaseString string `validate:"uppercase"`
Datetime string `validate:"datetime=2006-01-02"`
PostCode string `validate:"postcode_iso3166_alpha2=SG"`
PostCodeCountry string
PostCodeByField string `validate:"postcode_iso3166_alpha2_field=PostCodeCountry"`
BooleanString string `validate:"boolean"`
}
var test Test
test.Inner.EqCSFieldString = "1234"
test.Inner.GtCSFieldString = "1234"
test.Inner.GteCSFieldString = "1234"
test.MaxString = "1234"
test.MaxNumber = 2000
test.MaxMultiple = make([]string, 9)
test.LtString = "1234"
test.LtNumber = 6
test.LtMultiple = make([]string, 3)
test.LtTime = time.Now().Add(time.Hour * 24)
test.LteString = "1234"
test.LteNumber = 6
test.LteMultiple = make([]string, 3)
test.LteTime = time.Now().Add(time.Hour * 24)
test.LtFieldString = "12345"
test.LteFieldString = "12345"
test.LtCSFieldString = "1234"
test.LteCSFieldString = "1234"
test.AlphaString = "abc3"
test.AlphanumString = "abc3!"
test.NumericString = "12E.00"
test.NumberString = "12E"
test.Excludes = "this is some test text"
test.ExcludesAll = "This is Great!"
test.ExcludesRune = "Love it ☻"
test.ASCII = "カタカナ"
test.PrintableASCII = "カタカナ"
test.MultiByte = "1234feerf"
test.LowercaseString = "ABCDEFG"
test.UppercaseString = "abcdefg"
s := "toolong"
test.StrPtrMaxLen = &s
test.StrPtrLen = &s
test.UniqueSlice = []string{"1234", "1234"}
test.UniqueMap = map[string]string{"key1": "1234", "key2": "1234"}
test.Datetime = "2008-Feb-01"
test.BooleanString = "A"
test.Inner.RequiredIf = "abcd"
err = validate.Struct(test)
NotEqual(t, err, nil)
errs, ok := err.(validator.ValidationErrors)
Equal(t, ok, true)
tests := []struct {
ns string
expected string
}{
{
ns: "Test.IsColor",
expected: "IsColor jābūt derīgai krāsai",
},
{
ns: "Test.MAC",
expected: "MAC jābūt derīgai MAC adresei",
},
{
ns: "Test.IPAddr",
expected: "IPAddr jābūt atrisināmai IP adresei",
},
{
ns: "Test.IPAddrv4",
expected: "IPAddrv4 jābūt atrisināmai IPv4 adresei",
},
{
ns: "Test.IPAddrv6",
expected: "IPAddrv6 jābūt atrisināmai IPv6 adresei",
},
{
ns: "Test.UDPAddr",
expected: "UDPAddr jābūt derīgai UDP adresei",
},
{
ns: "Test.UDPAddrv4",
expected: "UDPAddrv4 jābūt derīgai IPv4 UDP adresei",
},
{
ns: "Test.UDPAddrv6",
expected: "UDPAddrv6 jābūt derīgai IPv6 UDP adresei",
},
{
ns: "Test.TCPAddr",
expected: "TCPAddr jābūt derīgai TCP adresei",
},
{
ns: "Test.TCPAddrv4",
expected: "TCPAddrv4 jābūt derīgai IPv4 TCP adresei",
},
{
ns: "Test.TCPAddrv6",
expected: "TCPAddrv6 jābūt derīgai IPv6 TCP adresei",
},
{
ns: "Test.CIDR",
expected: "CIDR jāsatur derīgu CIDR notāciju",
},
{
ns: "Test.CIDRv4",
expected: "CIDRv4 jāsatur derīgu CIDR notāciju IPv4 adresei",
},
{
ns: "Test.CIDRv6",
expected: "CIDRv6 jāsatur derīgu CIDR notāciju IPv6 adresei",
},
{
ns: "Test.SSN",
expected: "SSN jābūt derīgam SSN numuram",
},
{
ns: "Test.IP",
expected: "IP jābūt derīgai IP adresei",
},
{
ns: "Test.IPv4",
expected: "IPv4 jābūt derīgai IPv4 adresei",
},
{
ns: "Test.IPv6",
expected: "IPv6 jābūt derīgai IPv6 adresei",
},
{
ns: "Test.DataURI",
expected: "DataURI jāsatur derīgs Data URI",
},
{
ns: "Test.Latitude",
expected: "Latitude jāsatur derīgus platuma grādus",
},
{
ns: "Test.Longitude",
expected: "Longitude jāsatur derīgus garuma grādus",
},
{
ns: "Test.MultiByte",
expected: "MultiByte jāsatur multibyte rakstu zīmes",
},
{
ns: "Test.ASCII",
expected: "ASCII jāsatur tikai ascii rakstu zīmes",
},
{
ns: "Test.PrintableASCII",
expected: "PrintableASCII jāsatur tikai drukājamas ascii rakstu zīmes",
},
{
ns: "Test.UUID",
expected: "UUID jābūt derīgam UUID",
},
{
ns: "Test.UUID3",
expected: "UUID3 jābūt derīgam 3. versijas UUID",
},
{
ns: "Test.UUID4",
expected: "UUID4 jābūt derīgam 4. versijas UUID",
},
{
ns: "Test.UUID5",
expected: "UUID5 jābūt derīgam 5. versijas UUID",
},
{
ns: "Test.ULID",
expected: "ULID jābūt derīgam ULID",
},
{
ns: "Test.ISBN",
expected: "ISBN jābūt derīgam ISBN numuram",
},
{
ns: "Test.ISBN10",
expected: "ISBN10 jābūt derīgam ISBN-10 numuram",
},
{
ns: "Test.ISBN13",
expected: "ISBN13 jābūt derīgam ISBN-13 numuram",
},
{
ns: "Test.Excludes",
expected: "Excludes nedrīkst saturēt tekstu 'text'",
},
{
ns: "Test.ExcludesAll",
expected: "ExcludesAll nedrīkst saturēt nevienu no sekojošām rakstu zīmēm '!@#$'",
},
{
ns: "Test.ExcludesRune",
expected: "ExcludesRune nedrīkst saturēt sekojošo '☻'",
},
{
ns: "Test.ContainsAny",
expected: "ContainsAny jāsatur minimums 1 no rakstu zīmēm '!@#$'",
},
{
ns: "Test.Contains",
expected: "Contains jāsatur teksts 'purpose'",
},
{
ns: "Test.Base64",
expected: "Base64 jābūt derīgai Base64 virknei",
},
{
ns: "Test.Email",
expected: "Email jābūt derīgai e-pasta adresei",
},
{
ns: "Test.URL",
expected: "URL jābūt derīgam URL",
},
{
ns: "Test.URI",
expected: "URI jābūt derīgam URI",
},
{
ns: "Test.RGBColorString",
expected: "RGBColorString jābūt derīgai RGB krāsai",
},
{
ns: "Test.RGBAColorString",
expected: "RGBAColorString jābūt derīgai RGBA krāsai",
},
{
ns: "Test.HSLColorString",
expected: "HSLColorString jābūt derīgai HSL krāsai",
},
{
ns: "Test.HSLAColorString",
expected: "HSLAColorString jābūt derīgai HSLA krāsai",
},
{
ns: "Test.HexadecimalString",
expected: "HexadecimalString jābūt heksadecimālam skaitlim",
},
{
ns: "Test.HexColorString",
expected: "HexColorString jābūt derīgai HEX krāsai",
},
{
ns: "Test.NumberString",
expected: "NumberString jāsatur derīgs skaitlis",
},
{
ns: "Test.NumericString",
expected: "NumericString jāsatur tikai cipari",
},
{
ns: "Test.AlphanumString",
expected: "AlphanumString jāsatur tikai simboli no alfabēta vai cipari (Alphanumeric)",
},
{
ns: "Test.AlphaString",
expected: "AlphaString jāsatur tikai simboli no alfabēta",
},
{
ns: "Test.LtFieldString",
expected: "LtFieldString jābūt mazākam par MaxString",
},
{
ns: "Test.LteFieldString",
expected: "LteFieldString jābūt mazākam par MaxString vai vienādam",
},
{
ns: "Test.GtFieldString",
expected: "GtFieldString jābūt lielākam par MaxString",
},
{
ns: "Test.GteFieldString",
expected: "GteFieldString jābūt lielākam par MaxString vai vienādam",
},
{
ns: "Test.NeFieldString",
expected: "NeFieldString nedrīkst būt vienāds ar EqFieldString",
},
{
ns: "Test.LtCSFieldString",
expected: "LtCSFieldString jābūt mazākam par Inner.LtCSFieldString",
},
{
ns: "Test.LteCSFieldString",
expected: "LteCSFieldString jābūt mazākam par Inner.LteCSFieldString vai vienādam",
},
{
ns: "Test.GtCSFieldString",
expected: "GtCSFieldString jābūt lielākam par Inner.GtCSFieldString",
},
{
ns: "Test.GteCSFieldString",
expected: "GteCSFieldString jābūt lielākam par Inner.GteCSFieldString vai vienādam",
},
{
ns: "Test.NeCSFieldString",
expected: "NeCSFieldString nedrīkst būt vienāds ar Inner.NeCSFieldString",
},
{
ns: "Test.EqCSFieldString",
expected: "EqCSFieldString jābūt vienādam ar Inner.EqCSFieldString",
},
{
ns: "Test.EqFieldString",
expected: "EqFieldString jābūt vienādam ar MaxString",
},
{
ns: "Test.GteString",
expected: "GteString garumam jābūt minimums 3 rakstu zīmes",
},
{
ns: "Test.GteNumber",
expected: "GteNumber jābūt 5.56 vai lielākam",
},
{
ns: "Test.GteMultiple",
expected: "GteMultiple jāsatur minimums 2 elementi",
},
{
ns: "Test.GteTime",
expected: "GteTime jābūt lielākam par šī brīža Datumu un laiku vai vienādam",
},
{
ns: "Test.GtString",
expected: "GtString ir jābūt garākam par 3 rakstu zīmēm",
},
{
ns: "Test.GtNumber",
expected: "GtNumber jābūt lielākam par 5.56",
},
{
ns: "Test.GtMultiple",
expected: "GtMultiple jāsatur vairāk par 2 elementiem",
},
{
ns: "Test.GtTime",
expected: "GtTime jābūt lielākam par šī brīža Datumu un laiku",
},
{
ns: "Test.LteString",
expected: "LteString garumam jābūt maksimums 3 rakstu zīmes",
},
{
ns: "Test.LteNumber",
expected: "LteNumber jābūt 5.56 vai mazākam",
},
{
ns: "Test.LteMultiple",
expected: "LteMultiple jāsatur maksimums 2 elementi",
},
{
ns: "Test.LteTime",
expected: "LteTime jābūt mazākam par šī brīža Datumu un laiku vai vienādam",
},
{
ns: "Test.LtString",
expected: "LtString garumam jābūt mazākam par 3 rakstu zīmēm",
},
{
ns: "Test.LtNumber",
expected: "LtNumber jābūt mazākam par 5.56",
},
{
ns: "Test.LtMultiple",
expected: "LtMultiple jāsatur mazāk par 2 elementiem",
},
{
ns: "Test.LtTime",
expected: "LtTime jābūt mazākam par šī brīža Datumu un laiku",
},
{
ns: "Test.NeString",
expected: "NeString nedrīkst būt vienāds ar ",
},
{
ns: "Test.NeNumber",
expected: "NeNumber nedrīkst būt vienāds ar 0.00",
},
{
ns: "Test.NeMultiple",
expected: "NeMultiple nedrīkst būt vienāds ar 0",
},
{
ns: "Test.EqString",
expected: "EqString nav vienāds ar 3",
},
{
ns: "Test.EqNumber",
expected: "EqNumber nav vienāds ar 2.33",
},
{
ns: "Test.EqMultiple",
expected: "EqMultiple nav vienāds ar 7",
},
{
ns: "Test.MaxString",
expected: "MaxString vērtība pārsniedz maksimālo garumu 3 rakstu zīmes",
},
{
ns: "Test.MaxNumber",
expected: "MaxNumber vērtībai jābūt 1,113.00 vai mazākai",
},
{
ns: "Test.MaxMultiple",
expected: "MaxMultiple jāsatur maksimums 7 elementi",
},
{
ns: "Test.MinString",
expected: "MinString garumam jābūt minimums 1 rakstu zīme",
},
{
ns: "Test.MinNumber",
expected: "MinNumber vērtībai jābūt 1,113.00 vai lielākai",
},
{
ns: "Test.MinMultiple",
expected: "MinMultiple jāsatur minimums 7 elementi",
},
{
ns: "Test.LenString",
expected: "LenString garumam jābūt 1 rakstu zīme",
},
{
ns: "Test.LenNumber",
expected: "LenNumber vērtībai jābūt 1,113.00",
},
{
ns: "Test.LenMultiple",
expected: "LenMultiple vērtībai jāsatur 7 elementi",
},
{
ns: "Test.RequiredString",
expected: "RequiredString ir obligāts lauks",
},
{
ns: "Test.RequiredIf",
expected: "RequiredIf ir obligāts lauks",
},
{
ns: "Test.RequiredNumber",
expected: "RequiredNumber ir obligāts lauks",
},
{
ns: "Test.RequiredMultiple",
expected: "RequiredMultiple ir obligāts lauks",
},
{
ns: "Test.StrPtrMinLen",
expected: "StrPtrMinLen garumam jābūt minimums 10 rakstu zīmes",
},
{
ns: "Test.StrPtrMaxLen",
expected: "StrPtrMaxLen vērtība pārsniedz maksimālo garumu 1 rakstu zīme",
},
{
ns: "Test.StrPtrLen",
expected: "StrPtrLen garumam jābūt 2 rakstu zīmes",
},
{
ns: "Test.StrPtrLt",
expected: "StrPtrLt garumam jābūt mazākam par 1 rakstu zīmi",
},
{
ns: "Test.StrPtrLte",
expected: "StrPtrLte garumam jābūt maksimums 1 rakstu zīme",
},
{
ns: "Test.StrPtrGt",
expected: "StrPtrGt ir jābūt garākam par 10 rakstu zīmēm",
},
{
ns: "Test.StrPtrGte",
expected: "StrPtrGte garumam jābūt minimums 10 rakstu zīmes",
},
{
ns: "Test.OneOfString",
expected: "OneOfString jābūt vienam no [red green]",
},
{
ns: "Test.OneOfInt",
expected: "OneOfInt jābūt vienam no [5 63]",
},
{
ns: "Test.UniqueSlice",
expected: "UniqueSlice jāsatur unikālas vērtības",
},
{
ns: "Test.UniqueArray",
expected: "UniqueArray jāsatur unikālas vērtības",
},
{
ns: "Test.UniqueMap",
expected: "UniqueMap jāsatur unikālas vērtības",
},
{
ns: "Test.JSONString",
expected: "JSONString jābūt derīgai json virknei",
},
{
ns: "Test.JWTString",
expected: "JWTString jābūt derīgai jwt virknei",
},
{
ns: "Test.LowercaseString",
expected: "LowercaseString jābūt mazo burtu virknei",
},
{
ns: "Test.UppercaseString",
expected: "UppercaseString jābūt lielo burtu virknei",
},
{
ns: "Test.Datetime",
expected: "Datetime neatbilst formātam 2006-01-02",
},
{
ns: "Test.PostCode",
expected: "PostCode neatbilst pasta indeksa formātam valstī SG",
},
{
ns: "Test.PostCodeByField",
expected: "PostCodeByField neatbilst pasta indeksa formātam valstī, kura norādīta laukā PostCodeCountry",
},
{
ns: "Test.BooleanString",
expected: "BooleanString jābūt derīgai boolean vērtībai",
},
}
for _, tt := range tests {
var fe validator.FieldError
for _, e := range errs {
if tt.ns == e.Namespace() {
fe = e
break
}
}
NotEqual(t, fe, nil)
Equal(t, tt.expected, fe.Translate(trans))
}
}

@ -1173,11 +1173,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} moet een geldige versie 5 UUID zijn", translation: "{0} moet een geldige versie 5 UUID zijn",
override: false, override: false,
}, },
{
tag: "ulid",
translation: "{0} moet een geldige ULID zijn",
override: false,
},
{ {
tag: "ascii", tag: "ascii",
translation: "{0} mag alleen ascii karakters bevatten", translation: "{0} mag alleen ascii karakters bevatten",

@ -4,9 +4,9 @@ import (
"testing" "testing"
"time" "time"
. "github.com/go-playground/assert/v2"
english "github.com/go-playground/locales/en" english "github.com/go-playground/locales/en"
ut "github.com/go-playground/universal-translator" ut "github.com/go-playground/universal-translator"
. "github.com/go-playground/assert/v2"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
) )
@ -104,7 +104,6 @@ func TestTranslations(t *testing.T) {
UUID3 string `validate:"uuid3"` UUID3 string `validate:"uuid3"`
UUID4 string `validate:"uuid4"` UUID4 string `validate:"uuid4"`
UUID5 string `validate:"uuid5"` UUID5 string `validate:"uuid5"`
ULID string `validate:"ulid"`
ASCII string `validate:"ascii"` ASCII string `validate:"ascii"`
PrintableASCII string `validate:"printascii"` PrintableASCII string `validate:"printascii"`
MultiByte string `validate:"multibyte"` MultiByte string `validate:"multibyte"`
@ -307,10 +306,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.UUID5", ns: "Test.UUID5",
expected: "UUID5 moet een geldige versie 5 UUID zijn", expected: "UUID5 moet een geldige versie 5 UUID zijn",
}, },
{
ns: "Test.ULID",
expected: "ULID moet een geldige ULID zijn",
},
{ {
ns: "Test.ISBN", ns: "Test.ISBN",
expected: "ISBN moet een geldig ISBN nummer zijn", expected: "ISBN moet een geldig ISBN nummer zijn",

@ -1178,11 +1178,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} deve ser um UUID versão 5 válido", translation: "{0} deve ser um UUID versão 5 válido",
override: false, override: false,
}, },
{
tag: "ulid",
translation: "{0} deve ser um ULID válido",
override: false,
},
{ {
tag: "ascii", tag: "ascii",
translation: "{0} deve conter apenas caracteres ascii", translation: "{0} deve conter apenas caracteres ascii",

@ -105,7 +105,6 @@ func TestTranslations(t *testing.T) {
UUID3 string `validate:"uuid3"` UUID3 string `validate:"uuid3"`
UUID4 string `validate:"uuid4"` UUID4 string `validate:"uuid4"`
UUID5 string `validate:"uuid5"` UUID5 string `validate:"uuid5"`
ULID string `validate:"ulid"`
ASCII string `validate:"ascii"` ASCII string `validate:"ascii"`
PrintableASCII string `validate:"printascii"` PrintableASCII string `validate:"printascii"`
MultiByte string `validate:"multibyte"` MultiByte string `validate:"multibyte"`
@ -322,10 +321,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.UUID5", ns: "Test.UUID5",
expected: "UUID5 deve ser um UUID versão 5 válido", expected: "UUID5 deve ser um UUID versão 5 válido",
}, },
{
ns: "Test.ULID",
expected: "ULID deve ser um ULID válido",
},
{ {
ns: "Test.ISBN", ns: "Test.ISBN",
expected: "ISBN deve ser um número de ISBN válido", expected: "ISBN deve ser um número de ISBN válido",

@ -26,7 +26,7 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
}{ }{
{ {
tag: "required", tag: "required",
translation: "{0} é um campo obrigatório", translation: "{0} é um campo requerido",
override: false, override: false,
}, },
{ {
@ -1173,11 +1173,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} deve ser um UUID versão 5 válido", translation: "{0} deve ser um UUID versão 5 válido",
override: false, override: false,
}, },
{
tag: "ulid",
translation: "{0} deve ser uma ULID válida",
override: false,
},
{ {
tag: "ascii", tag: "ascii",
translation: "{0} deve conter apenas caracteres ascii", translation: "{0} deve conter apenas caracteres ascii",
@ -1316,16 +1311,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return s return s
}, },
}, },
{
tag: "boolean",
translation: "{0} deve ser um valor booleano válido",
override: false,
},
{
tag: "cve",
translation: "{0} deve ser um identificador cve válido",
override: false,
},
} }
for _, t := range translations { for _, t := range translations {

@ -4,10 +4,10 @@ import (
"testing" "testing"
"time" "time"
. "github.com/go-playground/assert/v2"
brazilian_portuguese "github.com/go-playground/locales/pt_BR" brazilian_portuguese "github.com/go-playground/locales/pt_BR"
ut "github.com/go-playground/universal-translator" ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
. "github.com/go-playground/assert/v2"
) )
func TestTranslations(t *testing.T) { func TestTranslations(t *testing.T) {
@ -104,7 +104,6 @@ func TestTranslations(t *testing.T) {
UUID3 string `validate:"uuid3"` UUID3 string `validate:"uuid3"`
UUID4 string `validate:"uuid4"` UUID4 string `validate:"uuid4"`
UUID5 string `validate:"uuid5"` UUID5 string `validate:"uuid5"`
ULID string `validate:"ulid"`
ASCII string `validate:"ascii"` ASCII string `validate:"ascii"`
PrintableASCII string `validate:"printascii"` PrintableASCII string `validate:"printascii"`
MultiByte string `validate:"multibyte"` MultiByte string `validate:"multibyte"`
@ -139,8 +138,6 @@ func TestTranslations(t *testing.T) {
StrPtrGte *string `validate:"gte=10"` StrPtrGte *string `validate:"gte=10"`
OneOfString string `validate:"oneof=red green"` OneOfString string `validate:"oneof=red green"`
OneOfInt int `validate:"oneof=5 63"` OneOfInt int `validate:"oneof=5 63"`
BooleanString string `validate:"boolean"`
CveString string `validate:"cve"`
} }
var test Test var test Test
@ -173,8 +170,6 @@ func TestTranslations(t *testing.T) {
test.AlphanumString = "abc3!" test.AlphanumString = "abc3!"
test.NumericString = "12E.00" test.NumericString = "12E.00"
test.NumberString = "12E" test.NumberString = "12E"
test.BooleanString = "A"
test.CveString = "A"
test.Excludes = "este é um texto de teste" test.Excludes = "este é um texto de teste"
test.ExcludesAll = "Isso é Ótimo!" test.ExcludesAll = "Isso é Ótimo!"
@ -311,10 +306,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.UUID5", ns: "Test.UUID5",
expected: "UUID5 deve ser um UUID versão 5 válido", expected: "UUID5 deve ser um UUID versão 5 válido",
}, },
{
ns: "Test.ULID",
expected: "ULID deve ser uma ULID válida",
},
{ {
ns: "Test.ISBN", ns: "Test.ISBN",
expected: "ISBN deve ser um número ISBN válido", expected: "ISBN deve ser um número ISBN válido",
@ -577,15 +568,15 @@ func TestTranslations(t *testing.T) {
}, },
{ {
ns: "Test.RequiredString", ns: "Test.RequiredString",
expected: "RequiredString é um campo obrigatório", expected: "RequiredString é um campo requerido",
}, },
{ {
ns: "Test.RequiredNumber", ns: "Test.RequiredNumber",
expected: "RequiredNumber é um campo obrigatório", expected: "RequiredNumber é um campo requerido",
}, },
{ {
ns: "Test.RequiredMultiple", ns: "Test.RequiredMultiple",
expected: "RequiredMultiple é um campo obrigatório", expected: "RequiredMultiple é um campo requerido",
}, },
{ {
ns: "Test.StrPtrMinLen", ns: "Test.StrPtrMinLen",
@ -623,14 +614,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.OneOfInt", ns: "Test.OneOfInt",
expected: "OneOfInt deve ser um de [5 63]", expected: "OneOfInt deve ser um de [5 63]",
}, },
{
ns: "Test.BooleanString",
expected: "BooleanString deve ser um valor booleano válido",
},
{
ns: "Test.CveString",
expected: "CveString deve ser um identificador cve válido",
},
} }
for _, tt := range tests { for _, tt := range tests {

@ -41,14 +41,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
if err = ut.AddCardinal("len-string-character", "{0} символа", locales.PluralRuleFew, false); err != nil {
return
}
if err = ut.AddCardinal("len-string-character", "{0} символов", locales.PluralRuleMany, false); err != nil {
return
}
if err = ut.AddCardinal("len-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil { if err = ut.AddCardinal("len-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil {
return return
} }
@ -60,19 +52,10 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
if err = ut.Add("len-items", "{0} должен содержать {1}", false); err != nil { if err = ut.Add("len-items", "{0} должен содержать {1}", false); err != nil {
return return
} }
if err = ut.AddCardinal("len-items-item", "{0} элемент", locales.PluralRuleOne, false); err != nil { if err = ut.AddCardinal("len-items-item", "{0} элемент", locales.PluralRuleOne, false); err != nil {
return return
} }
if err = ut.AddCardinal("len-items-item", "{0} элемента", locales.PluralRuleFew, false); err != nil {
return
}
if err = ut.AddCardinal("len-items-item", "{0} элементов", locales.PluralRuleMany, false); err != nil {
return
}
if err = ut.AddCardinal("len-items-item", "{0} элементы", locales.PluralRuleOther, false); err != nil { if err = ut.AddCardinal("len-items-item", "{0} элементы", locales.PluralRuleOther, false); err != nil {
return return
} }
@ -149,14 +132,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
if err = ut.AddCardinal("min-string-character", "{0} символа", locales.PluralRuleFew, false); err != nil {
return
}
if err = ut.AddCardinal("min-string-character", "{0} символов", locales.PluralRuleMany, false); err != nil {
return
}
if err = ut.AddCardinal("min-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil { if err = ut.AddCardinal("min-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil {
return return
} }
@ -172,14 +147,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
if err = ut.AddCardinal("min-items-item", "{0} элемента", locales.PluralRuleFew, false); err != nil {
return
}
if err = ut.AddCardinal("min-items-item", "{0} элементов", locales.PluralRuleMany, false); err != nil {
return
}
if err = ut.AddCardinal("min-items-item", "{0} элементы", locales.PluralRuleOther, false); err != nil { if err = ut.AddCardinal("min-items-item", "{0} элементы", locales.PluralRuleOther, false); err != nil {
return return
} }
@ -256,14 +223,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
if err = ut.AddCardinal("max-string-character", "{0} символа", locales.PluralRuleFew, false); err != nil {
return
}
if err = ut.AddCardinal("max-string-character", "{0} символов", locales.PluralRuleMany, false); err != nil {
return
}
if err = ut.AddCardinal("max-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil { if err = ut.AddCardinal("max-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil {
return return
} }
@ -279,14 +238,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
if err = ut.AddCardinal("max-items-item", "{0} элемента", locales.PluralRuleFew, false); err != nil {
return
}
if err = ut.AddCardinal("max-items-item", "{0} элементов", locales.PluralRuleMany, false); err != nil {
return
}
if err = ut.AddCardinal("max-items-item", "{0} элементы", locales.PluralRuleOther, false); err != nil { if err = ut.AddCardinal("max-items-item", "{0} элементы", locales.PluralRuleOther, false); err != nil {
return return
} }
@ -393,14 +344,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
if err = ut.AddCardinal("lt-string-character", "{0} символов", locales.PluralRuleFew, false); err != nil {
return
}
if err = ut.AddCardinal("lt-string-character", "{0} символов", locales.PluralRuleMany, false); err != nil {
return
}
if err = ut.AddCardinal("lt-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil { if err = ut.AddCardinal("lt-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil {
return return
} }
@ -417,14 +360,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
if err = ut.AddCardinal("lt-items-item", "{0} элементов", locales.PluralRuleFew, false); err != nil {
return
}
if err = ut.AddCardinal("lt-items-item", "{0} элементов", locales.PluralRuleMany, false); err != nil {
return
}
if err = ut.AddCardinal("lt-items-item", "{0} элементы", locales.PluralRuleOther, false); err != nil { if err = ut.AddCardinal("lt-items-item", "{0} элементы", locales.PluralRuleOther, false); err != nil {
return return
} }
@ -530,14 +465,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
if err = ut.AddCardinal("lte-string-character", "{0} символа", locales.PluralRuleFew, false); err != nil {
return
}
if err = ut.AddCardinal("lte-string-character", "{0} символов", locales.PluralRuleMany, false); err != nil {
return
}
if err = ut.AddCardinal("lte-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil { if err = ut.AddCardinal("lte-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil {
return return
} }
@ -554,14 +481,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
if err = ut.AddCardinal("lte-items-item", "{0} элемента", locales.PluralRuleFew, false); err != nil {
return
}
if err = ut.AddCardinal("lte-items-item", "{0} элементов", locales.PluralRuleMany, false); err != nil {
return
}
if err = ut.AddCardinal("lte-items-item", "{0} элементы", locales.PluralRuleOther, false); err != nil { if err = ut.AddCardinal("lte-items-item", "{0} элементы", locales.PluralRuleOther, false); err != nil {
return return
} }
@ -666,14 +585,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
if err = ut.AddCardinal("gt-string-character", "{0} символов", locales.PluralRuleFew, false); err != nil {
return
}
if err = ut.AddCardinal("gt-string-character", "{0} символов", locales.PluralRuleMany, false); err != nil {
return
}
if err = ut.AddCardinal("gt-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil { if err = ut.AddCardinal("gt-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil {
return return
} }
@ -690,14 +601,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
if err = ut.AddCardinal("gt-items-item", "{0} элементов", locales.PluralRuleFew, false); err != nil {
return
}
if err = ut.AddCardinal("gt-items-item", "{0} элементов", locales.PluralRuleMany, false); err != nil {
return
}
if err = ut.AddCardinal("gt-items-item", "{0} элементы", locales.PluralRuleOther, false); err != nil { if err = ut.AddCardinal("gt-items-item", "{0} элементы", locales.PluralRuleOther, false); err != nil {
return return
} }
@ -802,14 +705,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
if err = ut.AddCardinal("gte-string-character", "{0} символа", locales.PluralRuleFew, false); err != nil {
return
}
if err = ut.AddCardinal("gte-string-character", "{0} символов", locales.PluralRuleMany, false); err != nil {
return
}
if err = ut.AddCardinal("gte-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil { if err = ut.AddCardinal("gte-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil {
return return
} }
@ -826,14 +721,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
} }
if err = ut.AddCardinal("gte-items-item", "{0} элемента", locales.PluralRuleFew, false); err != nil {
return
}
if err = ut.AddCardinal("gte-items-item", "{0} элементов", locales.PluralRuleMany, false); err != nil {
return
}
if err = ut.AddCardinal("gte-items-item", "{0} элементы", locales.PluralRuleOther, false); err != nil { if err = ut.AddCardinal("gte-items-item", "{0} элементы", locales.PluralRuleOther, false); err != nil {
return return
} }
@ -1291,11 +1178,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} должен быть UUID 5 версии", translation: "{0} должен быть UUID 5 версии",
override: false, override: false,
}, },
{
tag: "ulid",
translation: "{0} должен быть ULID",
override: false,
},
{ {
tag: "ascii", tag: "ascii",
translation: "{0} должен содержать только ascii символы", translation: "{0} должен содержать только ascii символы",

@ -7,7 +7,7 @@ import (
"time" "time"
. "github.com/go-playground/assert/v2" . "github.com/go-playground/assert/v2"
russian "github.com/go-playground/locales/ru" russian "github.com/go-playground/locales/en"
ut "github.com/go-playground/universal-translator" ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
) )
@ -33,137 +33,116 @@ func TestTranslations(t *testing.T) {
} }
type Test struct { type Test struct {
Inner Inner Inner Inner
RequiredString string `validate:"required"` RequiredString string `validate:"required"`
RequiredNumber int `validate:"required"` RequiredNumber int `validate:"required"`
RequiredMultiple []string `validate:"required"` RequiredMultiple []string `validate:"required"`
LenString string `validate:"len=1"` LenString string `validate:"len=1"`
LenNumber float64 `validate:"len=1113.00"` LenNumber float64 `validate:"len=1113.00"`
LenMultiple []string `validate:"len=7"` LenMultiple []string `validate:"len=7"`
LenMultipleSecond []string `validate:"len=2"` MinString string `validate:"min=1"`
MinString string `validate:"min=1"` MinNumber float64 `validate:"min=1113.00"`
MinStringMultiple string `validate:"min=2"` MinMultiple []string `validate:"min=7"`
MinStringMultipleSecond string `validate:"min=7"` MaxString string `validate:"max=3"`
MinNumber float64 `validate:"min=1113.00"` MaxNumber float64 `validate:"max=1113.00"`
MinMultiple []string `validate:"min=7"` MaxMultiple []string `validate:"max=7"`
MinMultipleSecond []string `validate:"min=2"` EqString string `validate:"eq=3"`
MaxString string `validate:"max=3"` EqNumber float64 `validate:"eq=2.33"`
MaxStringSecond string `validate:"max=7"` EqMultiple []string `validate:"eq=7"`
MaxNumber float64 `validate:"max=1113.00"` NeString string `validate:"ne="`
MaxMultiple []string `validate:"max=7"` NeNumber float64 `validate:"ne=0.00"`
MaxMultipleSecond []string `validate:"max=2"` NeMultiple []string `validate:"ne=0"`
EqString string `validate:"eq=3"` LtString string `validate:"lt=3"`
EqNumber float64 `validate:"eq=2.33"` LtNumber float64 `validate:"lt=5.56"`
EqMultiple []string `validate:"eq=7"` LtMultiple []string `validate:"lt=2"`
NeString string `validate:"ne="` LtTime time.Time `validate:"lt"`
NeNumber float64 `validate:"ne=0.00"` LteString string `validate:"lte=3"`
NeMultiple []string `validate:"ne=0"` LteNumber float64 `validate:"lte=5.56"`
LtString string `validate:"lt=3"` LteMultiple []string `validate:"lte=2"`
LtStringSecond string `validate:"lt=7"` LteTime time.Time `validate:"lte"`
LtNumber float64 `validate:"lt=5.56"` GtString string `validate:"gt=3"`
LtMultiple []string `validate:"lt=2"` GtNumber float64 `validate:"gt=5.56"`
LtMultipleSecond []string `validate:"lt=7"` GtMultiple []string `validate:"gt=2"`
LtTime time.Time `validate:"lt"` GtTime time.Time `validate:"gt"`
LteString string `validate:"lte=3"` GteString string `validate:"gte=3"`
LteStringSecond string `validate:"lte=7"` GteNumber float64 `validate:"gte=5.56"`
LteNumber float64 `validate:"lte=5.56"` GteMultiple []string `validate:"gte=2"`
LteMultiple []string `validate:"lte=2"` GteTime time.Time `validate:"gte"`
LteMultipleSecond []string `validate:"lte=7"` EqFieldString string `validate:"eqfield=MaxString"`
LteTime time.Time `validate:"lte"` EqCSFieldString string `validate:"eqcsfield=Inner.EqCSFieldString"`
GtString string `validate:"gt=3"` NeCSFieldString string `validate:"necsfield=Inner.NeCSFieldString"`
GtStringSecond string `validate:"gt=7"` GtCSFieldString string `validate:"gtcsfield=Inner.GtCSFieldString"`
GtNumber float64 `validate:"gt=5.56"` GteCSFieldString string `validate:"gtecsfield=Inner.GteCSFieldString"`
GtMultiple []string `validate:"gt=2"` LtCSFieldString string `validate:"ltcsfield=Inner.LtCSFieldString"`
GtMultipleSecond []string `validate:"gt=7"` LteCSFieldString string `validate:"ltecsfield=Inner.LteCSFieldString"`
GtTime time.Time `validate:"gt"` NeFieldString string `validate:"nefield=EqFieldString"`
GteString string `validate:"gte=3"` GtFieldString string `validate:"gtfield=MaxString"`
GteStringSecond string `validate:"gte=7"` GteFieldString string `validate:"gtefield=MaxString"`
GteNumber float64 `validate:"gte=5.56"` LtFieldString string `validate:"ltfield=MaxString"`
GteMultiple []string `validate:"gte=2"` LteFieldString string `validate:"ltefield=MaxString"`
GteMultipleSecond []string `validate:"gte=7"` AlphaString string `validate:"alpha"`
GteTime time.Time `validate:"gte"` AlphanumString string `validate:"alphanum"`
EqFieldString string `validate:"eqfield=MaxString"` NumericString string `validate:"numeric"`
EqCSFieldString string `validate:"eqcsfield=Inner.EqCSFieldString"` NumberString string `validate:"number"`
NeCSFieldString string `validate:"necsfield=Inner.NeCSFieldString"` HexadecimalString string `validate:"hexadecimal"`
GtCSFieldString string `validate:"gtcsfield=Inner.GtCSFieldString"` HexColorString string `validate:"hexcolor"`
GteCSFieldString string `validate:"gtecsfield=Inner.GteCSFieldString"` RGBColorString string `validate:"rgb"`
LtCSFieldString string `validate:"ltcsfield=Inner.LtCSFieldString"` RGBAColorString string `validate:"rgba"`
LteCSFieldString string `validate:"ltecsfield=Inner.LteCSFieldString"` HSLColorString string `validate:"hsl"`
NeFieldString string `validate:"nefield=EqFieldString"` HSLAColorString string `validate:"hsla"`
GtFieldString string `validate:"gtfield=MaxString"` Email string `validate:"email"`
GteFieldString string `validate:"gtefield=MaxString"` URL string `validate:"url"`
LtFieldString string `validate:"ltfield=MaxString"` URI string `validate:"uri"`
LteFieldString string `validate:"ltefield=MaxString"` Base64 string `validate:"base64"`
AlphaString string `validate:"alpha"` Contains string `validate:"contains=purpose"`
AlphanumString string `validate:"alphanum"` ContainsAny string `validate:"containsany=!@#$"`
NumericString string `validate:"numeric"` Excludes string `validate:"excludes=text"`
NumberString string `validate:"number"` ExcludesAll string `validate:"excludesall=!@#$"`
HexadecimalString string `validate:"hexadecimal"` ExcludesRune string `validate:"excludesrune=☻"`
HexColorString string `validate:"hexcolor"` ISBN string `validate:"isbn"`
RGBColorString string `validate:"rgb"` ISBN10 string `validate:"isbn10"`
RGBAColorString string `validate:"rgba"` ISBN13 string `validate:"isbn13"`
HSLColorString string `validate:"hsl"` UUID string `validate:"uuid"`
HSLAColorString string `validate:"hsla"` UUID3 string `validate:"uuid3"`
Email string `validate:"email"` UUID4 string `validate:"uuid4"`
URL string `validate:"url"` UUID5 string `validate:"uuid5"`
URI string `validate:"uri"` ASCII string `validate:"ascii"`
Base64 string `validate:"base64"` PrintableASCII string `validate:"printascii"`
Contains string `validate:"contains=purpose"` MultiByte string `validate:"multibyte"`
ContainsAny string `validate:"containsany=!@#$"` DataURI string `validate:"datauri"`
Excludes string `validate:"excludes=text"` Latitude string `validate:"latitude"`
ExcludesAll string `validate:"excludesall=!@#$"` Longitude string `validate:"longitude"`
ExcludesRune string `validate:"excludesrune=☻"` SSN string `validate:"ssn"`
ISBN string `validate:"isbn"` IP string `validate:"ip"`
ISBN10 string `validate:"isbn10"` IPv4 string `validate:"ipv4"`
ISBN13 string `validate:"isbn13"` IPv6 string `validate:"ipv6"`
UUID string `validate:"uuid"` CIDR string `validate:"cidr"`
UUID3 string `validate:"uuid3"` CIDRv4 string `validate:"cidrv4"`
UUID4 string `validate:"uuid4"` CIDRv6 string `validate:"cidrv6"`
UUID5 string `validate:"uuid5"` TCPAddr string `validate:"tcp_addr"`
ULID string `validate:"ulid"` TCPAddrv4 string `validate:"tcp4_addr"`
ASCII string `validate:"ascii"` TCPAddrv6 string `validate:"tcp6_addr"`
PrintableASCII string `validate:"printascii"` UDPAddr string `validate:"udp_addr"`
MultiByte string `validate:"multibyte"` UDPAddrv4 string `validate:"udp4_addr"`
DataURI string `validate:"datauri"` UDPAddrv6 string `validate:"udp6_addr"`
Latitude string `validate:"latitude"` IPAddr string `validate:"ip_addr"`
Longitude string `validate:"longitude"` IPAddrv4 string `validate:"ip4_addr"`
SSN string `validate:"ssn"` IPAddrv6 string `validate:"ip6_addr"`
IP string `validate:"ip"` UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future
IPv4 string `validate:"ipv4"` MAC string `validate:"mac"`
IPv6 string `validate:"ipv6"` IsColor string `validate:"iscolor"`
CIDR string `validate:"cidr"` StrPtrMinLen *string `validate:"min=10"`
CIDRv4 string `validate:"cidrv4"` StrPtrMaxLen *string `validate:"max=1"`
CIDRv6 string `validate:"cidrv6"` StrPtrLen *string `validate:"len=2"`
TCPAddr string `validate:"tcp_addr"` StrPtrLt *string `validate:"lt=1"`
TCPAddrv4 string `validate:"tcp4_addr"` StrPtrLte *string `validate:"lte=1"`
TCPAddrv6 string `validate:"tcp6_addr"` StrPtrGt *string `validate:"gt=10"`
UDPAddr string `validate:"udp_addr"` StrPtrGte *string `validate:"gte=10"`
UDPAddrv4 string `validate:"udp4_addr"` OneOfString string `validate:"oneof=red green"`
UDPAddrv6 string `validate:"udp6_addr"` OneOfInt int `validate:"oneof=5 63"`
IPAddr string `validate:"ip_addr"` UniqueSlice []string `validate:"unique"`
IPAddrv4 string `validate:"ip4_addr"` UniqueArray [3]string `validate:"unique"`
IPAddrv6 string `validate:"ip6_addr"` UniqueMap map[string]string `validate:"unique"`
UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future
MAC string `validate:"mac"`
IsColor string `validate:"iscolor"`
StrPtrMinLen *string `validate:"min=10"`
StrPtrMinLenSecond *string `validate:"min=2"`
StrPtrMaxLen *string `validate:"max=1"`
StrPtrLen *string `validate:"len=2"`
StrPtrLenSecond *string `validate:"len=7"`
StrPtrLt *string `validate:"lt=1"`
StrPtrLte *string `validate:"lte=1"`
StrPtrLteMultiple *string `validate:"lte=2"`
StrPtrLteMultipleSecond *string `validate:"lte=7"`
StrPtrGt *string `validate:"gt=10"`
StrPtrGte *string `validate:"gte=10"`
StrPtrGtSecond *string `validate:"gt=2"`
StrPtrGteSecond *string `validate:"gte=2"`
OneOfString string `validate:"oneof=red green"`
OneOfInt int `validate:"oneof=5 63"`
UniqueSlice []string `validate:"unique"`
UniqueArray [3]string `validate:"unique"`
UniqueMap map[string]string `validate:"unique"`
} }
var test Test var test Test
@ -173,23 +152,17 @@ func TestTranslations(t *testing.T) {
test.Inner.GteCSFieldString = "1234" test.Inner.GteCSFieldString = "1234"
test.MaxString = "1234" test.MaxString = "1234"
test.MaxStringSecond = "12345678"
test.MaxNumber = 2000 test.MaxNumber = 2000
test.MaxMultiple = make([]string, 9) test.MaxMultiple = make([]string, 9)
test.MaxMultipleSecond = make([]string, 3)
test.LtString = "1234" test.LtString = "1234"
test.LtStringSecond = "12345678"
test.LtNumber = 6 test.LtNumber = 6
test.LtMultiple = make([]string, 3) test.LtMultiple = make([]string, 3)
test.LtMultipleSecond = make([]string, 8)
test.LtTime = time.Now().Add(time.Hour * 24) test.LtTime = time.Now().Add(time.Hour * 24)
test.LteString = "1234" test.LteString = "1234"
test.LteStringSecond = "12345678"
test.LteNumber = 6 test.LteNumber = 6
test.LteMultiple = make([]string, 3) test.LteMultiple = make([]string, 3)
test.LteMultipleSecond = make([]string, 8)
test.LteTime = time.Now().Add(time.Hour * 24) test.LteTime = time.Now().Add(time.Hour * 24)
test.LtFieldString = "12345" test.LtFieldString = "12345"
@ -341,10 +314,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.UUID5", ns: "Test.UUID5",
expected: "UUID5 должен быть UUID 5 версии", expected: "UUID5 должен быть UUID 5 версии",
}, },
{
ns: "Test.ULID",
expected: "ULID должен быть ULID",
},
{ {
ns: "Test.ISBN", ns: "Test.ISBN",
expected: "ISBN должен быть ISBN номером", expected: "ISBN должен быть ISBN номером",
@ -483,23 +452,15 @@ func TestTranslations(t *testing.T) {
}, },
{ {
ns: "Test.GteString", ns: "Test.GteString",
expected: "GteString должен содержать минимум 3 символа", expected: "GteString должен содержать минимум 3 символы",
},
{
ns: "Test.GteStringSecond",
expected: "GteStringSecond должен содержать минимум 7 символов",
}, },
{ {
ns: "Test.GteNumber", ns: "Test.GteNumber",
expected: "GteNumber должен быть больше или равно 5,56", expected: "GteNumber должен быть больше или равно 5.56",
}, },
{ {
ns: "Test.GteMultiple", ns: "Test.GteMultiple",
expected: "GteMultiple должен содержать минимум 2 элемента", expected: "GteMultiple должен содержать минимум 2 элементы",
},
{
ns: "Test.GteMultipleSecond",
expected: "GteMultipleSecond должен содержать минимум 7 элементов",
}, },
{ {
ns: "Test.GteTime", ns: "Test.GteTime",
@ -507,23 +468,15 @@ func TestTranslations(t *testing.T) {
}, },
{ {
ns: "Test.GtString", ns: "Test.GtString",
expected: "GtString должен быть длиннее 3 символов", expected: "GtString должен быть длиннее 3 символы",
},
{
ns: "Test.GtStringSecond",
expected: "GtStringSecond должен быть длиннее 7 символов",
}, },
{ {
ns: "Test.GtNumber", ns: "Test.GtNumber",
expected: "GtNumber должен быть больше 5,56", expected: "GtNumber должен быть больше 5.56",
}, },
{ {
ns: "Test.GtMultiple", ns: "Test.GtMultiple",
expected: "GtMultiple должен содержать более 2 элементов", expected: "GtMultiple должен содержать более 2 элементы",
},
{
ns: "Test.GtMultipleSecond",
expected: "GtMultipleSecond должен содержать более 7 элементов",
}, },
{ {
ns: "Test.GtTime", ns: "Test.GtTime",
@ -531,23 +484,15 @@ func TestTranslations(t *testing.T) {
}, },
{ {
ns: "Test.LteString", ns: "Test.LteString",
expected: "LteString должен содержать максимум 3 символа", expected: "LteString должен содержать максимум 3 символы",
},
{
ns: "Test.LteStringSecond",
expected: "LteStringSecond должен содержать максимум 7 символов",
}, },
{ {
ns: "Test.LteNumber", ns: "Test.LteNumber",
expected: "LteNumber должен быть менее или равен 5,56", expected: "LteNumber должен быть менее или равен 5.56",
}, },
{ {
ns: "Test.LteMultiple", ns: "Test.LteMultiple",
expected: "LteMultiple должен содержать максимум 2 элемента", expected: "LteMultiple должен содержать максимум 2 элементы",
},
{
ns: "Test.LteMultipleSecond",
expected: "LteMultipleSecond должен содержать максимум 7 элементов",
}, },
{ {
ns: "Test.LteTime", ns: "Test.LteTime",
@ -555,23 +500,15 @@ func TestTranslations(t *testing.T) {
}, },
{ {
ns: "Test.LtString", ns: "Test.LtString",
expected: "LtString должен иметь менее 3 символов", expected: "LtString должен иметь менее 3 символы",
},
{
ns: "Test.LtStringSecond",
expected: "LtStringSecond должен иметь менее 7 символов",
}, },
{ {
ns: "Test.LtNumber", ns: "Test.LtNumber",
expected: "LtNumber должен быть менее 5,56", expected: "LtNumber должен быть менее 5.56",
}, },
{ {
ns: "Test.LtMultiple", ns: "Test.LtMultiple",
expected: "LtMultiple должен содержать менее 2 элементов", expected: "LtMultiple должен содержать менее 2 элементы",
},
{
ns: "Test.LtMultipleSecond",
expected: "LtMultipleSecond должен содержать менее 7 элементов",
}, },
{ {
ns: "Test.LtTime", ns: "Test.LtTime",
@ -603,47 +540,27 @@ func TestTranslations(t *testing.T) {
}, },
{ {
ns: "Test.MaxString", ns: "Test.MaxString",
expected: "MaxString должен содержать максимум 3 символа", expected: "MaxString должен содержать максимум 3 символы",
},
{
ns: "Test.MaxStringSecond",
expected: "MaxStringSecond должен содержать максимум 7 символов",
}, },
{ {
ns: "Test.MaxNumber", ns: "Test.MaxNumber",
expected: "MaxNumber должен быть меньше или равно 1 113,00", expected: "MaxNumber должен быть меньше или равно 1,113.00",
}, },
{ {
ns: "Test.MaxMultiple", ns: "Test.MaxMultiple",
expected: "MaxMultiple должен содержать максимум 7 элементов", expected: "MaxMultiple должен содержать максимум 7 элементы",
},
{
ns: "Test.MaxMultipleSecond",
expected: "MaxMultipleSecond должен содержать максимум 2 элемента",
}, },
{ {
ns: "Test.MinString", ns: "Test.MinString",
expected: "MinString должен содержать минимум 1 символ", expected: "MinString должен содержать минимум 1 символ",
}, },
{
ns: "Test.MinStringMultiple",
expected: "MinStringMultiple должен содержать минимум 2 символа",
},
{
ns: "Test.MinStringMultipleSecond",
expected: "MinStringMultipleSecond должен содержать минимум 7 символов",
},
{ {
ns: "Test.MinNumber", ns: "Test.MinNumber",
expected: "MinNumber должен быть больше или равно 1 113,00", expected: "MinNumber должен быть больше или равно 1,113.00",
}, },
{ {
ns: "Test.MinMultiple", ns: "Test.MinMultiple",
expected: "MinMultiple должен содержать минимум 7 элементов", expected: "MinMultiple должен содержать минимум 7 элементы",
},
{
ns: "Test.MinMultipleSecond",
expected: "MinMultipleSecond должен содержать минимум 2 элемента",
}, },
{ {
ns: "Test.LenString", ns: "Test.LenString",
@ -651,15 +568,11 @@ func TestTranslations(t *testing.T) {
}, },
{ {
ns: "Test.LenNumber", ns: "Test.LenNumber",
expected: "LenNumber должен быть равен 1 113,00", expected: "LenNumber должен быть равен 1,113.00",
}, },
{ {
ns: "Test.LenMultiple", ns: "Test.LenMultiple",
expected: "LenMultiple должен содержать 7 элементов", expected: "LenMultiple должен содержать 7 элементы",
},
{
ns: "Test.LenMultipleSecond",
expected: "LenMultipleSecond должен содержать 2 элемента",
}, },
{ {
ns: "Test.RequiredString", ns: "Test.RequiredString",
@ -675,11 +588,7 @@ func TestTranslations(t *testing.T) {
}, },
{ {
ns: "Test.StrPtrMinLen", ns: "Test.StrPtrMinLen",
expected: "StrPtrMinLen должен содержать минимум 10 символов", expected: "StrPtrMinLen должен содержать минимум 10 символы",
},
{
ns: "Test.StrPtrMinLenSecond",
expected: "StrPtrMinLenSecond должен содержать минимум 2 символа",
}, },
{ {
ns: "Test.StrPtrMaxLen", ns: "Test.StrPtrMaxLen",
@ -687,11 +596,7 @@ func TestTranslations(t *testing.T) {
}, },
{ {
ns: "Test.StrPtrLen", ns: "Test.StrPtrLen",
expected: "StrPtrLen должен быть длиной в 2 символа", expected: "StrPtrLen должен быть длиной в 2 символы",
},
{
ns: "Test.StrPtrLenSecond",
expected: "StrPtrLenSecond должен быть длиной в 7 символов",
}, },
{ {
ns: "Test.StrPtrLt", ns: "Test.StrPtrLt",
@ -701,29 +606,13 @@ func TestTranslations(t *testing.T) {
ns: "Test.StrPtrLte", ns: "Test.StrPtrLte",
expected: "StrPtrLte должен содержать максимум 1 символ", expected: "StrPtrLte должен содержать максимум 1 символ",
}, },
{
ns: "Test.StrPtrLteMultiple",
expected: "StrPtrLteMultiple должен содержать максимум 2 символа",
},
{
ns: "Test.StrPtrLteMultipleSecond",
expected: "StrPtrLteMultipleSecond должен содержать максимум 7 символов",
},
{ {
ns: "Test.StrPtrGt", ns: "Test.StrPtrGt",
expected: "StrPtrGt должен быть длиннее 10 символов", expected: "StrPtrGt должен быть длиннее 10 символы",
},
{
ns: "Test.StrPtrGtSecond",
expected: "StrPtrGtSecond должен быть длиннее 2 символов",
}, },
{ {
ns: "Test.StrPtrGte", ns: "Test.StrPtrGte",
expected: "StrPtrGte должен содержать минимум 10 символов", expected: "StrPtrGte должен содержать минимум 10 символы",
},
{
ns: "Test.StrPtrGteSecond",
expected: "StrPtrGteSecond должен содержать минимум 2 символа",
}, },
{ {
ns: "Test.OneOfString", ns: "Test.OneOfString",

@ -1173,11 +1173,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} geçerli bir sürüm 5 UUID olmalıdır", translation: "{0} geçerli bir sürüm 5 UUID olmalıdır",
override: false, override: false,
}, },
{
tag: "ulid",
translation: "{0} geçerli bir ULID olmalıdır",
override: false,
},
{ {
tag: "ascii", tag: "ascii",
translation: "{0} yalnızca ascii karakterler içermelidir", translation: "{0} yalnızca ascii karakterler içermelidir",

@ -4,9 +4,9 @@ import (
"testing" "testing"
"time" "time"
. "github.com/go-playground/assert/v2"
turkish "github.com/go-playground/locales/tr" turkish "github.com/go-playground/locales/tr"
ut "github.com/go-playground/universal-translator" ut "github.com/go-playground/universal-translator"
. "github.com/go-playground/assert/v2"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
) )
@ -104,7 +104,6 @@ func TestTranslations(t *testing.T) {
UUID3 string `validate:"uuid3"` UUID3 string `validate:"uuid3"`
UUID4 string `validate:"uuid4"` UUID4 string `validate:"uuid4"`
UUID5 string `validate:"uuid5"` UUID5 string `validate:"uuid5"`
ULID string `validate:"ulid"`
ASCII string `validate:"ascii"` ASCII string `validate:"ascii"`
PrintableASCII string `validate:"printascii"` PrintableASCII string `validate:"printascii"`
MultiByte string `validate:"multibyte"` MultiByte string `validate:"multibyte"`
@ -313,10 +312,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.UUID5", ns: "Test.UUID5",
expected: "UUID5 geçerli bir sürüm 5 UUID olmalıdır", expected: "UUID5 geçerli bir sürüm 5 UUID olmalıdır",
}, },
{
ns: "Test.ULID",
expected: "ULID geçerli bir ULID olmalıdır",
},
{ {
ns: "Test.ISBN", ns: "Test.ISBN",
expected: "ISBN geçerli bir ISBN numarası olmalıdır", expected: "ISBN geçerli bir ISBN numarası olmalıdır",

File diff suppressed because it is too large Load Diff

@ -1,690 +0,0 @@
package vi
import (
"testing"
"time"
. "github.com/go-playground/assert/v2"
vietnamese "github.com/go-playground/locales/vi"
ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
)
func TestTranslations(t *testing.T) {
vie := vietnamese.New()
uni := ut.New(vie, vie)
trans, _ := uni.GetTranslator("vi")
validate := validator.New()
err := RegisterDefaultTranslations(validate, trans)
Equal(t, err, nil)
type Inner struct {
EqCSFieldString string
NeCSFieldString string
GtCSFieldString string
GteCSFieldString string
LtCSFieldString string
LteCSFieldString string
}
type Test struct {
Inner Inner
RequiredString string `validate:"required"`
RequiredNumber int `validate:"required"`
RequiredMultiple []string `validate:"required"`
LenString string `validate:"len=1"`
LenNumber float64 `validate:"len=1113.00"`
LenMultiple []string `validate:"len=7"`
MinString string `validate:"min=1"`
MinNumber float64 `validate:"min=1113.00"`
MinMultiple []string `validate:"min=7"`
MaxString string `validate:"max=3"`
MaxNumber float64 `validate:"max=1113.00"`
MaxMultiple []string `validate:"max=7"`
EqString string `validate:"eq=3"`
EqNumber float64 `validate:"eq=2.33"`
EqMultiple []string `validate:"eq=7"`
NeString string `validate:"ne="`
NeNumber float64 `validate:"ne=0.00"`
NeMultiple []string `validate:"ne=0"`
LtString string `validate:"lt=3"`
LtNumber float64 `validate:"lt=5.56"`
LtMultiple []string `validate:"lt=2"`
LtTime time.Time `validate:"lt"`
LteString string `validate:"lte=3"`
LteNumber float64 `validate:"lte=5.56"`
LteMultiple []string `validate:"lte=2"`
LteTime time.Time `validate:"lte"`
GtString string `validate:"gt=3"`
GtNumber float64 `validate:"gt=5.56"`
GtMultiple []string `validate:"gt=2"`
GtTime time.Time `validate:"gt"`
GteString string `validate:"gte=3"`
GteNumber float64 `validate:"gte=5.56"`
GteMultiple []string `validate:"gte=2"`
GteTime time.Time `validate:"gte"`
EqFieldString string `validate:"eqfield=MaxString"`
EqCSFieldString string `validate:"eqcsfield=Inner.EqCSFieldString"`
NeCSFieldString string `validate:"necsfield=Inner.NeCSFieldString"`
GtCSFieldString string `validate:"gtcsfield=Inner.GtCSFieldString"`
GteCSFieldString string `validate:"gtecsfield=Inner.GteCSFieldString"`
LtCSFieldString string `validate:"ltcsfield=Inner.LtCSFieldString"`
LteCSFieldString string `validate:"ltecsfield=Inner.LteCSFieldString"`
NeFieldString string `validate:"nefield=EqFieldString"`
GtFieldString string `validate:"gtfield=MaxString"`
GteFieldString string `validate:"gtefield=MaxString"`
LtFieldString string `validate:"ltfield=MaxString"`
LteFieldString string `validate:"ltefield=MaxString"`
AlphaString string `validate:"alpha"`
AlphanumString string `validate:"alphanum"`
NumericString string `validate:"numeric"`
NumberString string `validate:"number"`
HexadecimalString string `validate:"hexadecimal"`
HexColorString string `validate:"hexcolor"`
RGBColorString string `validate:"rgb"`
RGBAColorString string `validate:"rgba"`
HSLColorString string `validate:"hsl"`
HSLAColorString string `validate:"hsla"`
Email string `validate:"email"`
URL string `validate:"url"`
URI string `validate:"uri"`
Base64 string `validate:"base64"`
Contains string `validate:"contains=purpose"`
ContainsAny string `validate:"containsany=!@#$"`
Excludes string `validate:"excludes=text"`
ExcludesAll string `validate:"excludesall=!@#$"`
ExcludesRune string `validate:"excludesrune=☻"`
ISBN string `validate:"isbn"`
ISBN10 string `validate:"isbn10"`
ISBN13 string `validate:"isbn13"`
UUID string `validate:"uuid"`
UUID3 string `validate:"uuid3"`
UUID4 string `validate:"uuid4"`
UUID5 string `validate:"uuid5"`
ASCII string `validate:"ascii"`
PrintableASCII string `validate:"printascii"`
MultiByte string `validate:"multibyte"`
DataURI string `validate:"datauri"`
Latitude string `validate:"latitude"`
Longitude string `validate:"longitude"`
SSN string `validate:"ssn"`
IP string `validate:"ip"`
IPv4 string `validate:"ipv4"`
IPv6 string `validate:"ipv6"`
CIDR string `validate:"cidr"`
CIDRv4 string `validate:"cidrv4"`
CIDRv6 string `validate:"cidrv6"`
TCPAddr string `validate:"tcp_addr"`
TCPAddrv4 string `validate:"tcp4_addr"`
TCPAddrv6 string `validate:"tcp6_addr"`
UDPAddr string `validate:"udp_addr"`
UDPAddrv4 string `validate:"udp4_addr"`
UDPAddrv6 string `validate:"udp6_addr"`
IPAddr string `validate:"ip_addr"`
IPAddrv4 string `validate:"ip4_addr"`
IPAddrv6 string `validate:"ip6_addr"`
UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future
MAC string `validate:"mac"`
IsColor string `validate:"iscolor"`
StrPtrMinLen *string `validate:"min=10"`
StrPtrMaxLen *string `validate:"max=1"`
StrPtrLen *string `validate:"len=2"`
StrPtrLt *string `validate:"lt=1"`
StrPtrLte *string `validate:"lte=1"`
StrPtrGt *string `validate:"gt=10"`
StrPtrGte *string `validate:"gte=10"`
OneOfString string `validate:"oneof=red green"`
OneOfInt int `validate:"oneof=5 63"`
UniqueSlice []string `validate:"unique"`
UniqueArray [3]string `validate:"unique"`
UniqueMap map[string]string `validate:"unique"`
JSONString string `validate:"json"`
JWTString string `validate:"jwt"`
LowercaseString string `validate:"lowercase"`
UppercaseString string `validate:"uppercase"`
Datetime string `validate:"datetime=2006-01-02"`
PostCode string `validate:"postcode_iso3166_alpha2=SG"`
PostCodeCountry string
PostCodeByField string `validate:"postcode_iso3166_alpha2_field=PostCodeCountry"`
}
var test Test
test.Inner.EqCSFieldString = "1234"
test.Inner.GtCSFieldString = "1234"
test.Inner.GteCSFieldString = "1234"
test.MaxString = "1234"
test.MaxNumber = 2000
test.MaxMultiple = make([]string, 9)
test.LtString = "1234"
test.LtNumber = 6
test.LtMultiple = make([]string, 3)
test.LtTime = time.Now().Add(time.Hour * 24)
test.LteString = "1234"
test.LteNumber = 6
test.LteMultiple = make([]string, 3)
test.LteTime = time.Now().Add(time.Hour * 24)
test.LtFieldString = "12345"
test.LteFieldString = "12345"
test.LtCSFieldString = "1234"
test.LteCSFieldString = "1234"
test.AlphaString = "abc3"
test.AlphanumString = "abc3!"
test.NumericString = "12E.00"
test.NumberString = "12E"
test.Excludes = "this is some test text"
test.ExcludesAll = "This is Great!"
test.ExcludesRune = "Love it ☻"
test.ASCII = "カタカナ"
test.PrintableASCII = "カタカナ"
test.MultiByte = "1234feerf"
test.LowercaseString = "ABCDEFG"
test.UppercaseString = "abcdefg"
s := "toolong"
test.StrPtrMaxLen = &s
test.StrPtrLen = &s
test.UniqueSlice = []string{"1234", "1234"}
test.UniqueMap = map[string]string{"key1": "1234", "key2": "1234"}
test.Datetime = "2008-Feb-01"
err = validate.Struct(test)
NotEqual(t, err, nil)
errs, ok := err.(validator.ValidationErrors)
Equal(t, ok, true)
tests := []struct {
ns string
expected string
}{
{
ns: "Test.IsColor",
expected: "IsColor phải là màu sắc hợp lệ",
},
{
ns: "Test.MAC",
expected: "MAC chỉ được chứa địa chỉ MAC",
},
{
ns: "Test.IPAddr",
expected: "IPAddr phải là địa chỉ IP có thể phân giải",
},
{
ns: "Test.IPAddrv4",
expected: "IPAddrv4 phải là địa chỉ IPv4 có thể phân giải",
},
{
ns: "Test.IPAddrv6",
expected: "IPAddrv6 phải là địa chỉ IPv6 có thể phân giải",
},
{
ns: "Test.UDPAddr",
expected: "UDPAddr phải là địa chỉ UDP",
},
{
ns: "Test.UDPAddrv4",
expected: "UDPAddrv4 phải là địa chỉ IPv4 UDP",
},
{
ns: "Test.UDPAddrv6",
expected: "UDPAddrv6 phải là địa chỉ IPv6 UDP",
},
{
ns: "Test.TCPAddr",
expected: "TCPAddr phải là địa chỉ TCP",
},
{
ns: "Test.TCPAddrv4",
expected: "TCPAddrv4 phải là địa chỉ IPv4 TCP",
},
{
ns: "Test.TCPAddrv6",
expected: "TCPAddrv6 phải là địa chỉ IPv6 TCP",
},
{
ns: "Test.CIDR",
expected: "CIDR chỉ được chứa CIDR notation",
},
{
ns: "Test.CIDRv4",
expected: "CIDRv4 chỉ được chứa CIDR notation của một địa chỉ IPv4",
},
{
ns: "Test.CIDRv6",
expected: "CIDRv6 chỉ được chứa CIDR notation của một địa chỉ IPv6",
},
{
ns: "Test.SSN",
expected: "SSN phải là SSN number",
},
{
ns: "Test.IP",
expected: "IP phải là địa chỉ IP",
},
{
ns: "Test.IPv4",
expected: "IPv4 phải là địa chỉ IPv4",
},
{
ns: "Test.IPv6",
expected: "IPv6 phải là địa chỉ IPv6",
},
{
ns: "Test.DataURI",
expected: "DataURI chỉ được chứa Data URI",
},
{
ns: "Test.Latitude",
expected: "Latitude chỉ được chứa latitude (vỹ độ)",
},
{
ns: "Test.Longitude",
expected: "Longitude chỉ được chứa longitude (kinh độ)",
},
{
ns: "Test.MultiByte",
expected: "MultiByte chỉ được chứa ký tự multibyte",
},
{
ns: "Test.ASCII",
expected: "ASCII chỉ được chứa ký tự ASCII",
},
{
ns: "Test.PrintableASCII",
expected: "PrintableASCII chỉ được chứa ký tự ASCII có thể in ấn",
},
{
ns: "Test.UUID",
expected: "UUID phải là giá trị UUID",
},
{
ns: "Test.UUID3",
expected: "UUID3 phải là giá trị UUID phiên bản 3",
},
{
ns: "Test.UUID4",
expected: "UUID4 phải là giá trị UUID phiên bản 4",
},
{
ns: "Test.UUID5",
expected: "UUID5 phải là giá trị UUID phiên bản 5",
},
{
ns: "Test.ISBN",
expected: "ISBN phải là số ISBN",
},
{
ns: "Test.ISBN10",
expected: "ISBN10 phải là số ISBN-10",
},
{
ns: "Test.ISBN13",
expected: "ISBN13 phải là số ISBN-13",
},
{
ns: "Test.Excludes",
expected: "Excludes không được chứa chuỗi 'text'",
},
{
ns: "Test.ExcludesAll",
expected: "ExcludesAll không được chứa bất kỳ ký tự nào trong nhóm ký tự '!@#$'",
},
{
ns: "Test.ExcludesRune",
expected: "ExcludesRune không được chứa '☻'",
},
{
ns: "Test.ContainsAny",
expected: "ContainsAny phải chứa ít nhất 1 trong cách ký tự sau '!@#$'",
},
{
ns: "Test.Contains",
expected: "Contains phải chứa chuỗi 'purpose'",
},
{
ns: "Test.Base64",
expected: "Base64 phải là giá trị chuỗi Base64",
},
{
ns: "Test.Email",
expected: "Email phải là giá trị email address",
},
{
ns: "Test.URL",
expected: "URL phải là giá trị URL",
},
{
ns: "Test.URI",
expected: "URI phải là giá trị URI",
},
{
ns: "Test.RGBColorString",
expected: "RGBColorString phải là giá trị RGB color",
},
{
ns: "Test.RGBAColorString",
expected: "RGBAColorString phải là giá trị RGBA color",
},
{
ns: "Test.HSLColorString",
expected: "HSLColorString phải là giá trị HSL color",
},
{
ns: "Test.HSLAColorString",
expected: "HSLAColorString phải là giá trị HSLA color",
},
{
ns: "Test.HexadecimalString",
expected: "HexadecimalString phải là giá trị hexadecimal",
},
{
ns: "Test.HexColorString",
expected: "HexColorString phải là giá trị HEX color",
},
{
ns: "Test.NumberString",
expected: "NumberString chỉ được chứa giá trị số",
},
{
ns: "Test.NumericString",
expected: "NumericString chỉ được chứa giá trị số hoặc số dưới dạng chữ",
},
{
ns: "Test.AlphanumString",
expected: "AlphanumString chỉ được chứa ký tự dạng alphanumeric",
},
{
ns: "Test.AlphaString",
expected: "AlphaString chỉ được chứa ký tự dạng alphabetic",
},
{
ns: "Test.LtFieldString",
expected: "LtFieldString chỉ được nhỏ hơn MaxString",
},
{
ns: "Test.LteFieldString",
expected: "LteFieldString chỉ được nhỏ hơn hoặc bằng MaxString",
},
{
ns: "Test.GtFieldString",
expected: "GtFieldString phải lớn hơn MaxString",
},
{
ns: "Test.GteFieldString",
expected: "GteFieldString phải lớn hơn hoặc bằng MaxString",
},
{
ns: "Test.NeFieldString",
expected: "NeFieldString không được phép bằng EqFieldString",
},
{
ns: "Test.LtCSFieldString",
expected: "LtCSFieldString chỉ được nhỏ hơn Inner.LtCSFieldString",
},
{
ns: "Test.LteCSFieldString",
expected: "LteCSFieldString chỉ được nhỏ hơn hoặc bằng Inner.LteCSFieldString",
},
{
ns: "Test.GtCSFieldString",
expected: "GtCSFieldString phải lớn hơn Inner.GtCSFieldString",
},
{
ns: "Test.GteCSFieldString",
expected: "GteCSFieldString phải lớn hơn hoặc bằng Inner.GteCSFieldString",
},
{
ns: "Test.NeCSFieldString",
expected: "NeCSFieldString không được phép bằng Inner.NeCSFieldString",
},
{
ns: "Test.EqCSFieldString",
expected: "EqCSFieldString phải bằng Inner.EqCSFieldString",
},
{
ns: "Test.EqFieldString",
expected: "EqFieldString phải bằng MaxString",
},
{
ns: "Test.GteString",
expected: "GteString phải có độ dài ít nhất 3 ký tự",
},
{
ns: "Test.GteNumber",
expected: "GteNumber phải là 5,56 hoặc lớn hơn",
},
{
ns: "Test.GteMultiple",
expected: "GteMultiple phải chứa ít nhất 2 phần tử",
},
{
ns: "Test.GteTime",
expected: "GteTime phải lớn hơn hoặc bằng Ngày & Giờ hiện tại",
},
{
ns: "Test.GtString",
expected: "GtString phải có độ dài lớn hơn 3 ký tự",
},
{
ns: "Test.GtNumber",
expected: "GtNumber phải lớn hơn 5,56",
},
{
ns: "Test.GtMultiple",
expected: "GtMultiple phải chứa nhiều hơn 2 phần tử",
},
{
ns: "Test.GtTime",
expected: "GtTime phải lớn hơn Ngày & Giờ hiện tại",
},
{
ns: "Test.LteString",
expected: "LteString chỉ được có độ dài tối đa là 3 ký tự",
},
{
ns: "Test.LteNumber",
expected: "LteNumber phải là 5,56 hoặc nhỏ hơn",
},
{
ns: "Test.LteMultiple",
expected: "LteMultiple chỉ được chứa nhiều nhất 2 phần tử",
},
{
ns: "Test.LteTime",
expected: "LteTime chỉ được nhỏ hơn hoặc bằng Ngày & Giờ hiện tại",
},
{
ns: "Test.LtString",
expected: "LtString phải có độ dài nhỏ hơn 3 ký tự",
},
{
ns: "Test.LtNumber",
expected: "LtNumber phải nhỏ hơn 5,56",
},
{
ns: "Test.LtMultiple",
expected: "LtMultiple chỉ được chứa ít hơn 2 phần tử",
},
{
ns: "Test.LtTime",
expected: "LtTime phải nhỏ hơn Ngày & Giờ hiện tại",
},
{
ns: "Test.NeString",
expected: "NeString không được bằng ",
},
{
ns: "Test.NeNumber",
expected: "NeNumber không được bằng 0.00",
},
{
ns: "Test.NeMultiple",
expected: "NeMultiple không được bằng 0",
},
{
ns: "Test.EqString",
expected: "EqString không bằng 3",
},
{
ns: "Test.EqNumber",
expected: "EqNumber không bằng 2.33",
},
{
ns: "Test.EqMultiple",
expected: "EqMultiple không bằng 7",
},
{
ns: "Test.MaxString",
expected: "MaxString chỉ được chứa tối đa 3 ký tự",
},
{
ns: "Test.MaxNumber",
expected: "MaxNumber phải là 1.113,00 hoặc nhỏ hơn",
},
{
ns: "Test.MaxMultiple",
expected: "MaxMultiple chỉ được chứa tối đa 7 phần tử",
},
{
ns: "Test.MinString",
expected: "MinString phải chứa ít nhất 1 ký tự",
},
{
ns: "Test.MinNumber",
expected: "MinNumber phải bằng 1.113,00 hoặc lớn hơn",
},
{
ns: "Test.MinMultiple",
expected: "MinMultiple phải chứa ít nhất 7 phần tử",
},
{
ns: "Test.LenString",
expected: "LenString phải có độ dài là 1 ký tự",
},
{
ns: "Test.LenNumber",
expected: "LenNumber phải bằng 1.113,00",
},
{
ns: "Test.LenMultiple",
expected: "LenMultiple phải chứa 7 phần tử",
},
{
ns: "Test.RequiredString",
expected: "RequiredString không được bỏ trống",
},
{
ns: "Test.RequiredNumber",
expected: "RequiredNumber không được bỏ trống",
},
{
ns: "Test.RequiredMultiple",
expected: "RequiredMultiple không được bỏ trống",
},
{
ns: "Test.StrPtrMinLen",
expected: "StrPtrMinLen phải chứa ít nhất 10 ký tự",
},
{
ns: "Test.StrPtrMaxLen",
expected: "StrPtrMaxLen chỉ được chứa tối đa 1 ký tự",
},
{
ns: "Test.StrPtrLen",
expected: "StrPtrLen phải có độ dài là 2 ký tự",
},
{
ns: "Test.StrPtrLt",
expected: "StrPtrLt phải có độ dài nhỏ hơn 1 ký tự",
},
{
ns: "Test.StrPtrLte",
expected: "StrPtrLte chỉ được có độ dài tối đa là 1 ký tự",
},
{
ns: "Test.StrPtrGt",
expected: "StrPtrGt phải có độ dài lớn hơn 10 ký tự",
},
{
ns: "Test.StrPtrGte",
expected: "StrPtrGte phải có độ dài ít nhất 10 ký tự",
},
{
ns: "Test.OneOfString",
expected: "OneOfString phải là trong những giá trị [red green]",
},
{
ns: "Test.OneOfInt",
expected: "OneOfInt phải là trong những giá trị [5 63]",
},
{
ns: "Test.UniqueSlice",
expected: "UniqueSlice chỉ được chứa những giá trị không trùng lặp",
},
{
ns: "Test.UniqueArray",
expected: "UniqueArray chỉ được chứa những giá trị không trùng lặp",
},
{
ns: "Test.UniqueMap",
expected: "UniqueMap chỉ được chứa những giá trị không trùng lặp",
},
{
ns: "Test.JSONString",
expected: "JSONString phải là một chuỗi json hợp lệ",
},
{
ns: "Test.JWTString",
expected: "JWTString phải là một chuỗi jwt hợp lệ",
},
{
ns: "Test.LowercaseString",
expected: "LowercaseString phải được viết thường",
},
{
ns: "Test.UppercaseString",
expected: "UppercaseString phải được viết hoa",
},
{
ns: "Test.Datetime",
expected: "Datetime không trùng định dạng ngày tháng 2006-01-02",
},
{
ns: "Test.PostCode",
expected: "PostCode sai định dạng postcode của quốc gia SG",
},
{
ns: "Test.PostCodeByField",
expected: "PostCodeByField sai định dạng postcode của quốc gia tương ứng thuộc trường PostCodeCountry",
},
}
for _, tt := range tests {
var fe validator.FieldError
for _, e := range errs {
if tt.ns == e.Namespace() {
fe = e
break
}
}
NotEqual(t, fe, nil)
Equal(t, tt.expected, fe.Translate(trans))
}
}

@ -29,36 +29,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}为必填字段", translation: "{0}为必填字段",
override: false, override: false,
}, },
{
tag: "required_if",
translation: "{0}为必填字段",
override: false,
},
{
tag: "required_unless",
translation: "{0}为必填字段",
override: false,
},
{
tag: "required_with",
translation: "{0}为必填字段",
override: false,
},
{
tag: "required_with_all",
translation: "{0}为必填字段",
override: false,
},
{
tag: "required_without",
translation: "{0}为必填字段",
override: false,
},
{
tag: "required_without_all",
translation: "{0}为必填字段",
override: false,
},
{ {
tag: "len", tag: "len",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
@ -1030,16 +1000,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}只能包含字母和数字", translation: "{0}只能包含字母和数字",
override: false, override: false,
}, },
{
tag: "alphanumunicode",
translation: "{0}只能包含字母数字和Unicode字符",
override: false,
},
{
tag: "alphaunicode",
translation: "{0}只能包含字母和Unicode字符",
override: false,
},
{ {
tag: "numeric", tag: "numeric",
translation: "{0}必须是一个有效的数值", translation: "{0}必须是一个有效的数值",
@ -1130,21 +1090,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return t return t
}, },
}, },
{
tag: "containsrune",
translation: "{0}必须包含字符'{1}'",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("警告: 翻译字段错误: %#v", fe)
return fe.(error).Error()
}
return t
},
},
{ {
tag: "excludes", tag: "excludes",
translation: "{0}不能包含文本'{1}'", translation: "{0}不能包含文本'{1}'",
@ -1190,36 +1135,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return t return t
}, },
}, },
{
tag: "endswith",
translation: "{0}必须以文本'{1}'结尾",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("警告: 翻译字段错误: %#v", fe)
return fe.(error).Error()
}
return t
},
},
{
tag: "startswith",
translation: "{0}必须以文本'{1}'开头",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("警告: 翻译字段错误: %#v", fe)
return fe.(error).Error()
}
return t
},
},
{ {
tag: "isbn", tag: "isbn",
translation: "{0}必须是一个有效的ISBN编号", translation: "{0}必须是一个有效的ISBN编号",
@ -1255,11 +1170,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}必须是一个有效的V5 UUID", translation: "{0}必须是一个有效的V5 UUID",
override: false, override: false,
}, },
{
tag: "ulid",
translation: "{0}必须是一个有效的ULID",
override: false,
},
{ {
tag: "ascii", tag: "ascii",
translation: "{0}必须只包含ascii字符", translation: "{0}必须只包含ascii字符",

@ -31,123 +31,117 @@ func TestTranslations(t *testing.T) {
} }
type Test struct { type Test struct {
Inner Inner Inner Inner
RequiredString string `validate:"required"` RequiredString string `validate:"required"`
RequiredNumber int `validate:"required"` RequiredNumber int `validate:"required"`
RequiredMultiple []string `validate:"required"` RequiredMultiple []string `validate:"required"`
LenString string `validate:"len=1"` LenString string `validate:"len=1"`
LenNumber float64 `validate:"len=1113.00"` LenNumber float64 `validate:"len=1113.00"`
LenMultiple []string `validate:"len=7"` LenMultiple []string `validate:"len=7"`
MinString string `validate:"min=1"` MinString string `validate:"min=1"`
MinNumber float64 `validate:"min=1113.00"` MinNumber float64 `validate:"min=1113.00"`
MinMultiple []string `validate:"min=7"` MinMultiple []string `validate:"min=7"`
MaxString string `validate:"max=3"` MaxString string `validate:"max=3"`
MaxNumber float64 `validate:"max=1113.00"` MaxNumber float64 `validate:"max=1113.00"`
MaxMultiple []string `validate:"max=7"` MaxMultiple []string `validate:"max=7"`
EqString string `validate:"eq=3"` EqString string `validate:"eq=3"`
EqNumber float64 `validate:"eq=2.33"` EqNumber float64 `validate:"eq=2.33"`
EqMultiple []string `validate:"eq=7"` EqMultiple []string `validate:"eq=7"`
NeString string `validate:"ne="` NeString string `validate:"ne="`
NeNumber float64 `validate:"ne=0.00"` NeNumber float64 `validate:"ne=0.00"`
NeMultiple []string `validate:"ne=0"` NeMultiple []string `validate:"ne=0"`
LtString string `validate:"lt=3"` LtString string `validate:"lt=3"`
LtNumber float64 `validate:"lt=5.56"` LtNumber float64 `validate:"lt=5.56"`
LtMultiple []string `validate:"lt=2"` LtMultiple []string `validate:"lt=2"`
LtTime time.Time `validate:"lt"` LtTime time.Time `validate:"lt"`
LteString string `validate:"lte=3"` LteString string `validate:"lte=3"`
LteNumber float64 `validate:"lte=5.56"` LteNumber float64 `validate:"lte=5.56"`
LteMultiple []string `validate:"lte=2"` LteMultiple []string `validate:"lte=2"`
LteTime time.Time `validate:"lte"` LteTime time.Time `validate:"lte"`
GtString string `validate:"gt=3"` GtString string `validate:"gt=3"`
GtNumber float64 `validate:"gt=5.56"` GtNumber float64 `validate:"gt=5.56"`
GtMultiple []string `validate:"gt=2"` GtMultiple []string `validate:"gt=2"`
GtTime time.Time `validate:"gt"` GtTime time.Time `validate:"gt"`
GteString string `validate:"gte=3"` GteString string `validate:"gte=3"`
GteNumber float64 `validate:"gte=5.56"` GteNumber float64 `validate:"gte=5.56"`
GteMultiple []string `validate:"gte=2"` GteMultiple []string `validate:"gte=2"`
GteTime time.Time `validate:"gte"` GteTime time.Time `validate:"gte"`
EqFieldString string `validate:"eqfield=MaxString"` EqFieldString string `validate:"eqfield=MaxString"`
EqCSFieldString string `validate:"eqcsfield=Inner.EqCSFieldString"` EqCSFieldString string `validate:"eqcsfield=Inner.EqCSFieldString"`
NeCSFieldString string `validate:"necsfield=Inner.NeCSFieldString"` NeCSFieldString string `validate:"necsfield=Inner.NeCSFieldString"`
GtCSFieldString string `validate:"gtcsfield=Inner.GtCSFieldString"` GtCSFieldString string `validate:"gtcsfield=Inner.GtCSFieldString"`
GteCSFieldString string `validate:"gtecsfield=Inner.GteCSFieldString"` GteCSFieldString string `validate:"gtecsfield=Inner.GteCSFieldString"`
LtCSFieldString string `validate:"ltcsfield=Inner.LtCSFieldString"` LtCSFieldString string `validate:"ltcsfield=Inner.LtCSFieldString"`
LteCSFieldString string `validate:"ltecsfield=Inner.LteCSFieldString"` LteCSFieldString string `validate:"ltecsfield=Inner.LteCSFieldString"`
NeFieldString string `validate:"nefield=EqFieldString"` NeFieldString string `validate:"nefield=EqFieldString"`
GtFieldString string `validate:"gtfield=MaxString"` GtFieldString string `validate:"gtfield=MaxString"`
GteFieldString string `validate:"gtefield=MaxString"` GteFieldString string `validate:"gtefield=MaxString"`
LtFieldString string `validate:"ltfield=MaxString"` LtFieldString string `validate:"ltfield=MaxString"`
LteFieldString string `validate:"ltefield=MaxString"` LteFieldString string `validate:"ltefield=MaxString"`
AlphaString string `validate:"alpha"` AlphaString string `validate:"alpha"`
AlphanumString string `validate:"alphanum"` AlphanumString string `validate:"alphanum"`
AlphanumUnicodeString string `validate:"alphanumunicode"` NumericString string `validate:"numeric"`
AlphaUnicodeString string `validate:"alphaunicode"` NumberString string `validate:"number"`
NumericString string `validate:"numeric"` HexadecimalString string `validate:"hexadecimal"`
NumberString string `validate:"number"` HexColorString string `validate:"hexcolor"`
HexadecimalString string `validate:"hexadecimal"` RGBColorString string `validate:"rgb"`
HexColorString string `validate:"hexcolor"` RGBAColorString string `validate:"rgba"`
RGBColorString string `validate:"rgb"` HSLColorString string `validate:"hsl"`
RGBAColorString string `validate:"rgba"` HSLAColorString string `validate:"hsla"`
HSLColorString string `validate:"hsl"` Email string `validate:"email"`
HSLAColorString string `validate:"hsla"` URL string `validate:"url"`
Email string `validate:"email"` URI string `validate:"uri"`
URL string `validate:"url"` Base64 string `validate:"base64"`
URI string `validate:"uri"` Contains string `validate:"contains=purpose"`
Base64 string `validate:"base64"` ContainsAny string `validate:"containsany=!@#$"`
Contains string `validate:"contains=purpose"` Excludes string `validate:"excludes=text"`
ContainsAny string `validate:"containsany=!@#$"` ExcludesAll string `validate:"excludesall=!@#$"`
ContainsRune string `validate:"containsrune=☻"` ExcludesRune string `validate:"excludesrune=☻"`
Excludes string `validate:"excludes=text"` ISBN string `validate:"isbn"`
ExcludesAll string `validate:"excludesall=!@#$"` ISBN10 string `validate:"isbn10"`
ExcludesRune string `validate:"excludesrune=☻"` ISBN13 string `validate:"isbn13"`
EndsWith string `validate:"endswith=end"` UUID string `validate:"uuid"`
StartsWith string `validate:"startswith=start"` UUID3 string `validate:"uuid3"`
ISBN string `validate:"isbn"` UUID4 string `validate:"uuid4"`
ISBN10 string `validate:"isbn10"` UUID5 string `validate:"uuid5"`
ISBN13 string `validate:"isbn13"` ASCII string `validate:"ascii"`
UUID string `validate:"uuid"` PrintableASCII string `validate:"printascii"`
UUID3 string `validate:"uuid3"` MultiByte string `validate:"multibyte"`
UUID4 string `validate:"uuid4"` DataURI string `validate:"datauri"`
UUID5 string `validate:"uuid5"` Latitude string `validate:"latitude"`
ULID string `validate:"ulid"` Longitude string `validate:"longitude"`
ASCII string `validate:"ascii"` SSN string `validate:"ssn"`
PrintableASCII string `validate:"printascii"` IP string `validate:"ip"`
MultiByte string `validate:"multibyte"` IPv4 string `validate:"ipv4"`
DataURI string `validate:"datauri"` IPv6 string `validate:"ipv6"`
Latitude string `validate:"latitude"` CIDR string `validate:"cidr"`
Longitude string `validate:"longitude"` CIDRv4 string `validate:"cidrv4"`
SSN string `validate:"ssn"` CIDRv6 string `validate:"cidrv6"`
IP string `validate:"ip"` TCPAddr string `validate:"tcp_addr"`
IPv4 string `validate:"ipv4"` TCPAddrv4 string `validate:"tcp4_addr"`
IPv6 string `validate:"ipv6"` TCPAddrv6 string `validate:"tcp6_addr"`
CIDR string `validate:"cidr"` UDPAddr string `validate:"udp_addr"`
CIDRv4 string `validate:"cidrv4"` UDPAddrv4 string `validate:"udp4_addr"`
CIDRv6 string `validate:"cidrv6"` UDPAddrv6 string `validate:"udp6_addr"`
TCPAddr string `validate:"tcp_addr"` IPAddr string `validate:"ip_addr"`
TCPAddrv4 string `validate:"tcp4_addr"` IPAddrv4 string `validate:"ip4_addr"`
TCPAddrv6 string `validate:"tcp6_addr"` IPAddrv6 string `validate:"ip6_addr"`
UDPAddr string `validate:"udp_addr"` UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future
UDPAddrv4 string `validate:"udp4_addr"` MAC string `validate:"mac"`
UDPAddrv6 string `validate:"udp6_addr"` IsColor string `validate:"iscolor"`
IPAddr string `validate:"ip_addr"` StrPtrMinLen *string `validate:"min=10"`
IPAddrv4 string `validate:"ip4_addr"` StrPtrMaxLen *string `validate:"max=1"`
IPAddrv6 string `validate:"ip6_addr"` StrPtrLen *string `validate:"len=2"`
UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future StrPtrLt *string `validate:"lt=1"`
MAC string `validate:"mac"` StrPtrLte *string `validate:"lte=1"`
IsColor string `validate:"iscolor"` StrPtrGt *string `validate:"gt=10"`
StrPtrMinLen *string `validate:"min=10"` StrPtrGte *string `validate:"gte=10"`
StrPtrMaxLen *string `validate:"max=1"` OneOfString string `validate:"oneof=red green"`
StrPtrLen *string `validate:"len=2"` OneOfInt int `validate:"oneof=5 63"`
StrPtrLt *string `validate:"lt=1"` JsonString string `validate:"json"`
StrPtrLte *string `validate:"lte=1"` LowercaseString string `validate:"lowercase"`
StrPtrGt *string `validate:"gt=10"` UppercaseString string `validate:"uppercase"`
StrPtrGte *string `validate:"gte=10"` Datetime string `validate:"datetime=2006-01-02"`
OneOfString string `validate:"oneof=red green"`
OneOfInt int `validate:"oneof=5 63"`
JsonString string `validate:"json"`
LowercaseString string `validate:"lowercase"`
UppercaseString string `validate:"uppercase"`
Datetime string `validate:"datetime=2006-01-02"`
} }
var test Test var test Test
@ -178,8 +172,6 @@ func TestTranslations(t *testing.T) {
test.AlphaString = "abc3" test.AlphaString = "abc3"
test.AlphanumString = "abc3!" test.AlphanumString = "abc3!"
test.AlphanumUnicodeString = "abc3啊!"
test.AlphaUnicodeString = "abc3啊"
test.NumericString = "12E.00" test.NumericString = "12E.00"
test.NumberString = "12E" test.NumberString = "12E"
@ -187,9 +179,6 @@ func TestTranslations(t *testing.T) {
test.ExcludesAll = "This is Great!" test.ExcludesAll = "This is Great!"
test.ExcludesRune = "Love it ☻" test.ExcludesRune = "Love it ☻"
test.EndsWith = "this is some test text"
test.StartsWith = "this is some test text"
test.ASCII = "カタカナ" test.ASCII = "カタカナ"
test.PrintableASCII = "カタカナ" test.PrintableASCII = "カタカナ"
@ -328,10 +317,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.UUID5", ns: "Test.UUID5",
expected: "UUID5必须是一个有效的V5 UUID", expected: "UUID5必须是一个有效的V5 UUID",
}, },
{
ns: "Test.ULID",
expected: "ULID必须是一个有效的ULID",
},
{ {
ns: "Test.ISBN", ns: "Test.ISBN",
expected: "ISBN必须是一个有效的ISBN编号", expected: "ISBN必须是一个有效的ISBN编号",
@ -344,14 +329,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.ISBN13", ns: "Test.ISBN13",
expected: "ISBN13必须是一个有效的ISBN-13编号", expected: "ISBN13必须是一个有效的ISBN-13编号",
}, },
{
ns: "Test.EndsWith",
expected: "EndsWith必须以文本'end'结尾",
},
{
ns: "Test.StartsWith",
expected: "StartsWith必须以文本'start'开头",
},
{ {
ns: "Test.Excludes", ns: "Test.Excludes",
expected: "Excludes不能包含文本'text'", expected: "Excludes不能包含文本'text'",
@ -364,10 +341,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.ExcludesRune", ns: "Test.ExcludesRune",
expected: "ExcludesRune不能包含'☻'", expected: "ExcludesRune不能包含'☻'",
}, },
{
ns: "Test.ContainsRune",
expected: "ContainsRune必须包含字符'☻'",
},
{ {
ns: "Test.ContainsAny", ns: "Test.ContainsAny",
expected: "ContainsAny必须包含至少一个以下字符'!@#$'", expected: "ContainsAny必须包含至少一个以下字符'!@#$'",
@ -424,14 +397,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.NumericString", ns: "Test.NumericString",
expected: "NumericString必须是一个有效的数值", expected: "NumericString必须是一个有效的数值",
}, },
{
ns: "Test.AlphaUnicodeString",
expected: "AlphaUnicodeString只能包含字母和Unicode字符",
},
{
ns: "Test.AlphanumUnicodeString",
expected: "AlphanumUnicodeString只能包含字母数字和Unicode字符",
},
{ {
ns: "Test.AlphanumString", ns: "Test.AlphanumString",
expected: "AlphanumString只能包含字母和数字", expected: "AlphanumString只能包含字母和数字",

@ -1166,11 +1166,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0}必須是一個有效的V5 UUID", translation: "{0}必須是一個有效的V5 UUID",
override: false, override: false,
}, },
{
tag: "ulid",
translation: "{0}必須是一個有效的ULID",
override: false,
},
{ {
tag: "ascii", tag: "ascii",
translation: "{0}必須只包含ascii字元", translation: "{0}必須只包含ascii字元",

@ -104,7 +104,6 @@ func TestTranslations(t *testing.T) {
UUID3 string `validate:"uuid3"` UUID3 string `validate:"uuid3"`
UUID4 string `validate:"uuid4"` UUID4 string `validate:"uuid4"`
UUID5 string `validate:"uuid5"` UUID5 string `validate:"uuid5"`
ULID string `validate:"ulid"`
ASCII string `validate:"ascii"` ASCII string `validate:"ascii"`
PrintableASCII string `validate:"printascii"` PrintableASCII string `validate:"printascii"`
MultiByte string `validate:"multibyte"` MultiByte string `validate:"multibyte"`
@ -310,10 +309,6 @@ func TestTranslations(t *testing.T) {
ns: "Test.UUID5", ns: "Test.UUID5",
expected: "UUID5必須是一個有效的V5 UUID", expected: "UUID5必須是一個有效的V5 UUID",
}, },
{
ns: "Test.ULID",
expected: "ULID必須是一個有效的ULID",
},
{ {
ns: "Test.ISBN", ns: "Test.ISBN",
expected: "ISBN必須是一個有效的ISBN編號", expected: "ISBN必須是一個有效的ISBN編號",

@ -82,7 +82,7 @@ BEGIN:
fld := namespace fld := namespace
var ns string var ns string
if !typ.ConvertibleTo(timeType) { if typ != timeType {
idx := strings.Index(namespace, namespaceSeparator) idx := strings.Index(namespace, namespaceSeparator)

@ -74,7 +74,7 @@ func (v *validate) validateStruct(ctx context.Context, parent reflect.Value, cur
} }
} }
v.traverseField(ctx, current, current.Field(f.idx), ns, structNs, f, f.cTags) v.traverseField(ctx, parent, current.Field(f.idx), ns, structNs, f, f.cTags)
} }
} }
@ -164,7 +164,7 @@ func (v *validate) traverseField(ctx context.Context, parent reflect.Value, curr
typ = current.Type() typ = current.Type()
if !typ.ConvertibleTo(timeType) { if typ != timeType {
if ct != nil { if ct != nil {
@ -222,12 +222,12 @@ func (v *validate) traverseField(ctx context.Context, parent reflect.Value, curr
structNs = append(append(structNs, cf.name...), '.') structNs = append(append(structNs, cf.name...), '.')
} }
v.validateStruct(ctx, parent, current, typ, ns, structNs, ct) v.validateStruct(ctx, current, current, typ, ns, structNs, ct)
return return
} }
} }
if ct == nil || !ct.hasTag { if !ct.hasTag {
return return
} }
@ -355,10 +355,6 @@ OUTER:
v.ct = ct v.ct = ct
if ct.fn(ctx, v) { if ct.fn(ctx, v) {
if ct.isBlockEnd {
ct = ct.next
continue OUTER
}
// drain rest of the 'or' values, then continue or leave // drain rest of the 'or' values, then continue or leave
for { for {
@ -372,11 +368,6 @@ OUTER:
if ct.typeof != typeOr { if ct.typeof != typeOr {
continue OUTER continue OUTER
} }
if ct.isBlockEnd {
ct = ct.next
continue OUTER
}
} }
} }
@ -452,6 +443,7 @@ OUTER:
v.ct = ct v.ct = ct
if !ct.fn(ctx, v) { if !ct.fn(ctx, v) {
v.str1 = string(append(ns, cf.altName...)) v.str1 = string(append(ns, cf.altName...))
if v.v.hasTagNameFunc { if v.v.hasTagNameFunc {

@ -29,12 +29,6 @@ const (
requiredWithAllTag = "required_with_all" requiredWithAllTag = "required_with_all"
requiredIfTag = "required_if" requiredIfTag = "required_if"
requiredUnlessTag = "required_unless" requiredUnlessTag = "required_unless"
excludedWithoutAllTag = "excluded_without_all"
excludedWithoutTag = "excluded_without"
excludedWithTag = "excluded_with"
excludedWithAllTag = "excluded_with_all"
excludedIfTag = "excluded_if"
excludedUnlessTag = "excluded_unless"
skipValidationTag = "-" skipValidationTag = "-"
diveTag = "dive" diveTag = "dive"
keysTag = "keys" keysTag = "keys"
@ -86,16 +80,11 @@ type Validate struct {
aliases map[string]string aliases map[string]string
validations map[string]internalValidationFuncWrapper validations map[string]internalValidationFuncWrapper
transTagFunc map[ut.Translator]map[string]TranslationFunc // map[<locale>]map[<tag>]TranslationFunc transTagFunc map[ut.Translator]map[string]TranslationFunc // map[<locale>]map[<tag>]TranslationFunc
rules map[reflect.Type]map[string]string
tagCache *tagCache tagCache *tagCache
structCache *structCache structCache *structCache
} }
// New returns a new instance of 'validate' with sane defaults. // New returns a new instance of 'validate' with sane defaults.
// Validate is designed to be thread-safe and used as a singleton instance.
// It caches information about your struct and validations,
// in essence only parsing your validation tags once per struct type.
// Using multiple instances neglects the benefit of caching.
func New() *Validate { func New() *Validate {
tc := new(tagCache) tc := new(tagCache)
@ -122,8 +111,7 @@ func New() *Validate {
switch k { switch k {
// these require that even if the value is nil that the validation should run, omitempty still overrides this behaviour // these require that even if the value is nil that the validation should run, omitempty still overrides this behaviour
case requiredIfTag, requiredUnlessTag, requiredWithTag, requiredWithAllTag, requiredWithoutTag, requiredWithoutAllTag, case requiredIfTag, requiredUnlessTag, requiredWithTag, requiredWithAllTag, requiredWithoutTag, requiredWithoutAllTag:
excludedIfTag, excludedUnlessTag, excludedWithTag, excludedWithAllTag, excludedWithoutTag, excludedWithoutAllTag:
_ = v.registerValidation(k, wrapFunc(val), true, true) _ = v.registerValidation(k, wrapFunc(val), true, true)
default: default:
// no need to error check here, baked in will always be valid // no need to error check here, baked in will always be valid
@ -150,54 +138,17 @@ func (v *Validate) SetTagName(name string) {
v.tagName = name v.tagName = name
} }
// ValidateMapCtx validates a map using a map of validation rules and allows passing of contextual
// validation validation information via context.Context.
func (v Validate) ValidateMapCtx(ctx context.Context, data map[string]interface{}, rules map[string]interface{}) map[string]interface{} {
errs := make(map[string]interface{})
for field, rule := range rules {
if ruleObj, ok := rule.(map[string]interface{}); ok {
if dataObj, ok := data[field].(map[string]interface{}); ok {
err := v.ValidateMapCtx(ctx, dataObj, ruleObj)
if len(err) > 0 {
errs[field] = err
}
} else if dataObjs, ok := data[field].([]map[string]interface{}); ok {
for _, obj := range dataObjs {
err := v.ValidateMapCtx(ctx, obj, ruleObj)
if len(err) > 0 {
errs[field] = err
}
}
} else {
errs[field] = errors.New("The field: '" + field + "' is not a map to dive")
}
} else if ruleStr, ok := rule.(string); ok {
err := v.VarCtx(ctx, data[field], ruleStr)
if err != nil {
errs[field] = err
}
}
}
return errs
}
// ValidateMap validates map data from a map of tags
func (v *Validate) ValidateMap(data map[string]interface{}, rules map[string]interface{}) map[string]interface{} {
return v.ValidateMapCtx(context.Background(), data, rules)
}
// RegisterTagNameFunc registers a function to get alternate names for StructFields. // RegisterTagNameFunc registers a function to get alternate names for StructFields.
// //
// eg. to use the names which have been specified for JSON representations of structs, rather than normal Go field names: // eg. to use the names which have been specified for JSON representations of structs, rather than normal Go field names:
// //
// validate.RegisterTagNameFunc(func(fld reflect.StructField) string { // validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
// name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] // name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
// // skip if tag key says it should be ignored // if name == "-" {
// if name == "-" { // return ""
// return "" // }
// } // return name
// return name // })
// })
func (v *Validate) RegisterTagNameFunc(fn TagNameFunc) { func (v *Validate) RegisterTagNameFunc(fn TagNameFunc) {
v.tagNameFunc = fn v.tagNameFunc = fn
v.hasTagNameFunc = true v.hasTagNameFunc = true
@ -224,11 +175,11 @@ func (v *Validate) RegisterValidationCtx(tag string, fn FuncCtx, callValidationE
func (v *Validate) registerValidation(tag string, fn FuncCtx, bakedIn bool, nilCheckable bool) error { func (v *Validate) registerValidation(tag string, fn FuncCtx, bakedIn bool, nilCheckable bool) error {
if len(tag) == 0 { if len(tag) == 0 {
return errors.New("function Key cannot be empty") return errors.New("Function Key cannot be empty")
} }
if fn == nil { if fn == nil {
return errors.New("function cannot be empty") return errors.New("Function cannot be empty")
} }
_, ok := restrictedTags[tag] _, ok := restrictedTags[tag]
@ -284,34 +235,6 @@ func (v *Validate) RegisterStructValidationCtx(fn StructLevelFuncCtx, types ...i
} }
} }
// RegisterStructValidationMapRules registers validate map rules.
// Be aware that map validation rules supersede those defined on a/the struct if present.
//
// NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation
func (v *Validate) RegisterStructValidationMapRules(rules map[string]string, types ...interface{}) {
if v.rules == nil {
v.rules = make(map[reflect.Type]map[string]string)
}
deepCopyRules := make(map[string]string)
for i, rule := range rules {
deepCopyRules[i] = rule
}
for _, t := range types {
typ := reflect.TypeOf(t)
if typ.Kind() == reflect.Ptr {
typ = typ.Elem()
}
if typ.Kind() != reflect.Struct {
continue
}
v.rules[typ] = deepCopyRules
}
}
// RegisterCustomTypeFunc registers a CustomTypeFunc against a number of types // RegisterCustomTypeFunc registers a CustomTypeFunc against a number of types
// //
// NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation // NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation
@ -372,7 +295,7 @@ func (v *Validate) StructCtx(ctx context.Context, s interface{}) (err error) {
val = val.Elem() val = val.Elem()
} }
if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) { if val.Kind() != reflect.Struct || val.Type() == timeType {
return &InvalidValidationError{Type: reflect.TypeOf(s)} return &InvalidValidationError{Type: reflect.TypeOf(s)}
} }
@ -417,7 +340,7 @@ func (v *Validate) StructFilteredCtx(ctx context.Context, s interface{}, fn Filt
val = val.Elem() val = val.Elem()
} }
if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) { if val.Kind() != reflect.Struct || val.Type() == timeType {
return &InvalidValidationError{Type: reflect.TypeOf(s)} return &InvalidValidationError{Type: reflect.TypeOf(s)}
} }
@ -465,7 +388,7 @@ func (v *Validate) StructPartialCtx(ctx context.Context, s interface{}, fields .
val = val.Elem() val = val.Elem()
} }
if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) { if val.Kind() != reflect.Struct || val.Type() == timeType {
return &InvalidValidationError{Type: reflect.TypeOf(s)} return &InvalidValidationError{Type: reflect.TypeOf(s)}
} }
@ -486,10 +409,7 @@ func (v *Validate) StructPartialCtx(ctx context.Context, s interface{}, fields .
if len(flds) > 0 { if len(flds) > 0 {
vd.misc = append(vd.misc[0:0], name...) vd.misc = append(vd.misc[0:0], name...)
// Don't append empty name for unnamed structs vd.misc = append(vd.misc, '.')
if len(vd.misc) != 0 {
vd.misc = append(vd.misc, '.')
}
for _, s := range flds { for _, s := range flds {
@ -555,7 +475,7 @@ func (v *Validate) StructExceptCtx(ctx context.Context, s interface{}, fields ..
val = val.Elem() val = val.Elem()
} }
if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) { if val.Kind() != reflect.Struct || val.Type() == timeType {
return &InvalidValidationError{Type: reflect.TypeOf(s)} return &InvalidValidationError{Type: reflect.TypeOf(s)}
} }
@ -613,7 +533,7 @@ func (v *Validate) Var(field interface{}, tag string) error {
} }
// VarCtx validates a single variable using tag style validation and allows passing of contextual // VarCtx validates a single variable using tag style validation and allows passing of contextual
// validation information via context.Context. // validation validation information via context.Context.
// eg. // eg.
// var i int // var i int
// validate.Var(i, "gt=1,lt=10") // validate.Var(i, "gt=1,lt=10")
@ -632,7 +552,6 @@ func (v *Validate) VarCtx(ctx context.Context, field interface{}, tag string) (e
} }
ctag := v.fetchCacheTag(tag) ctag := v.fetchCacheTag(tag)
val := reflect.ValueOf(field) val := reflect.ValueOf(field)
vd := v.pool.Get().(*validate) vd := v.pool.Get().(*validate)
vd.top = val vd.top = val

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save