Import upstream version 10.8.0
Debian Janitor
2 years ago
0 | * @go-playground/validator-maintainers⏎ |
1 | 1 | |
2 | 2 | ## Quality Standard |
3 | 3 | |
4 | To ensure the continued stability of this package, tests are required to be written or already exist in order for a pull request to be merged. | |
4 | To ensure the continued stability of this package, tests are required that cover the change in order for a pull request to be merged. | |
5 | 5 | |
6 | 6 | ## Reporting issues |
7 | 7 |
0 | ### Package version eg. v8, v9: | |
0 | - [ ] I have looked at the documentation [here](https://pkg.go.dev/github.com/go-playground/validator/v10#section-documentation) first? | |
1 | - [ ] I have looked at the examples provided that may showcase my question [here](/_examples)? | |
2 | ||
3 | ### Package version eg. v9, v10: | |
1 | 4 | |
2 | 5 | |
3 | 6 |
0 | Fixes Or Enhances # . | |
0 | ## Fixes Or Enhances | |
1 | ||
1 | 2 | |
2 | 3 | **Make sure that you've checked the boxes below before you submit PR:** |
3 | 4 | - [ ] Tests exist or have been written that cover this particular change. |
4 | 5 | |
5 | Change Details: | |
6 | ||
7 | - | |
8 | - | |
9 | - | |
10 | ||
11 | ||
12 | @go-playground/admins⏎ | |
6 | @go-playground/validator-maintainers⏎ |
0 | on: | |
1 | push: | |
2 | branches: | |
3 | - master | |
4 | pull_request: | |
5 | name: Test | |
6 | jobs: | |
7 | test: | |
8 | strategy: | |
9 | matrix: | |
10 | go-version: [1.15.x, 1.16.x] | |
11 | os: [ubuntu-latest, macos-latest, windows-latest] | |
12 | runs-on: ${{ matrix.os }} | |
13 | steps: | |
14 | - name: Install Go | |
15 | uses: actions/setup-go@v2 | |
16 | with: | |
17 | go-version: ${{ matrix.go-version }} | |
18 | ||
19 | - name: Checkout code | |
20 | uses: actions/checkout@v2 | |
21 | ||
22 | - name: Restore Cache | |
23 | uses: actions/cache@v2 | |
24 | with: | |
25 | path: ~/go/pkg/mod | |
26 | key: ${{ runner.os }}-v1-go-${{ hashFiles('**/go.sum') }} | |
27 | restore-keys: | | |
28 | ${{ runner.os }}-v1-go- | |
29 | ||
30 | - name: Test | |
31 | run: go test -race -covermode=atomic -coverprofile="profile.cov" ./... | |
32 | ||
33 | - name: Send Coverage | |
34 | if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.16.x' | |
35 | uses: shogo82148/actions-goveralls@v1 | |
36 | with: | |
37 | path-to-profile: profile.cov | |
38 | ||
39 | golangci: | |
40 | name: lint | |
41 | runs-on: ubuntu-latest | |
42 | steps: | |
43 | - uses: actions/checkout@v2 | |
44 | - name: golangci-lint | |
45 | uses: golangci/golangci-lint-action@v2 | |
46 | with: | |
47 | version: v1.39 |
0 | language: go | |
1 | go: | |
2 | - 1.15.2 | |
3 | - tip | |
4 | matrix: | |
5 | allow_failures: | |
6 | - go: tip | |
7 | ||
8 | notifications: | |
9 | email: | |
10 | recipients: dean.karn@gmail.com | |
11 | on_success: change | |
12 | on_failure: always | |
13 | ||
14 | before_install: | |
15 | - go install github.com/mattn/goveralls | |
16 | - mkdir -p $GOPATH/src/gopkg.in | |
17 | - ln -s $GOPATH/src/github.com/$TRAVIS_REPO_SLUG $GOPATH/src/gopkg.in/validator.v9 | |
18 | ||
19 | # Only clone the most recent commit. | |
20 | git: | |
21 | depth: 1 | |
22 | ||
23 | script: | |
24 | - go test -v -race -covermode=atomic -coverprofile=coverage.coverprofile ./... | |
25 | ||
26 | after_success: | | |
27 | [ $TRAVIS_GO_VERSION = 1.15.2 ] && | |
28 | goveralls -coverprofile=coverage.coverprofile -service travis-ci -repotoken $COVERALLS_TOKEN |
0 | ## Maintainers Guide | |
1 | ||
2 | ### Semantic Versioning | |
3 | Semantic versioning as defined [here](https://semver.org) must be strictly adhered to. | |
4 | ||
5 | ### External Dependencies | |
6 | Any new external dependencies MUST: | |
7 | - Have a compatible LICENSE present. | |
8 | - Be actively maintained. | |
9 | - Be approved by @go-playground/admins | |
10 | ||
11 | ### PR Merge Requirements | |
12 | - Up-to-date branch. | |
13 | - Passing tests and linting. | |
14 | - CODEOWNERS approval. | |
15 | - Tests that cover both the Happy and Unhappy paths.⏎ |
2 | 2 | linters-install: |
3 | 3 | @golangci-lint --version >/dev/null 2>&1 || { \ |
4 | 4 | echo "installing linting tools..."; \ |
5 | curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v1.21.0; \ | |
5 | curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v1.39.0; \ | |
6 | 6 | } |
7 | 7 | |
8 | 8 | lint: linters-install |
9 | $(PWD)/bin/golangci-lint run | |
9 | golangci-lint run | |
10 | 10 | |
11 | 11 | test: |
12 | 12 | $(GOCMD) test -cover -race ./... |
0 | 0 | Package validator |
1 | ================ | |
1 | ================= | |
2 | 2 | <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) |
3 | ![Project status](https://img.shields.io/badge/version-10.4.1-green.svg) | |
3 | ![Project status](https://img.shields.io/badge/version-10.8.0-green.svg) | |
4 | 4 | [![Build Status](https://travis-ci.org/go-playground/validator.svg?branch=master)](https://travis-ci.org/go-playground/validator) |
5 | 5 | [![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=master&service=github)](https://coveralls.io/github/go-playground/validator?branch=master) |
6 | 6 | [![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator) |
42 | 42 | * http://stackoverflow.com/a/29138676/3158232 |
43 | 43 | * https://github.com/go-playground/validator/issues/134 |
44 | 44 | |
45 | 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: | |
45 | 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: | |
46 | 46 | |
47 | 47 | ```go |
48 | 48 | err := validate.Struct(mystruct) |
52 | 52 | Usage and documentation |
53 | 53 | ------ |
54 | 54 | |
55 | Please see https://godoc.org/github.com/go-playground/validator for detailed usage docs. | |
55 | Please see https://pkg.go.dev/github.com/go-playground/validator/v10 for detailed usage docs. | |
56 | 56 | |
57 | 57 | ##### Examples: |
58 | 58 | |
99 | 99 | | hostname_rfc1123 | Hostname RFC 1123 | |
100 | 100 | | ip | Internet Protocol Address IP | |
101 | 101 | | ip4_addr | Internet Protocol Address IPv4 | |
102 | | ip6_addr |Internet Protocol Address IPv6 | | |
102 | | ip6_addr | Internet Protocol Address IPv6 | | |
103 | 103 | | ip_addr | Internet Protocol Address IP | |
104 | 104 | | ipv4 | Internet Protocol Address IPv4 | |
105 | 105 | | ipv6 | Internet Protocol Address IPv6 | |
128 | 128 | | contains | Contains | |
129 | 129 | | containsany | Contains Any | |
130 | 130 | | containsrune | Contains Rune | |
131 | | endsnotwith | Ends With | | |
131 | 132 | | endswith | Ends With | |
133 | | excludes | Excludes | | |
134 | | excludesall | Excludes All | | |
135 | | excludesrune | Excludes Rune | | |
132 | 136 | | lowercase | Lowercase | |
133 | 137 | | multibyte | Multi-Byte Characters | |
134 | 138 | | number | NOT DOCUMENTED IN doc.go | |
135 | 139 | | numeric | Numeric | |
136 | 140 | | printascii | Printable ASCII | |
141 | | startsnotwith | Starts Not With | | |
137 | 142 | | startswith | Starts With | |
138 | 143 | | uppercase | Uppercase | |
139 | 144 | |
142 | 147 | | - | - | |
143 | 148 | | base64 | Base64 String | |
144 | 149 | | base64url | Base64URL String | |
150 | | bic | Business Identifier Code (ISO 9362) | | |
151 | | bcp47_language_tag | Language tag (BCP 47) | | |
145 | 152 | | btc_addr | Bitcoin Address | |
146 | 153 | | btc_addr_bech32 | Bitcoin Bech32 Address (segwit) | |
147 | 154 | | datetime | Datetime | |
157 | 164 | | isbn | International Standard Book Number | |
158 | 165 | | isbn10 | International Standard Book Number 10 | |
159 | 166 | | isbn13 | International Standard Book Number 13 | |
167 | | iso3166_1_alpha2 | Two-letter country code (ISO 3166-1 alpha-2) | | |
168 | | iso3166_1_alpha3 | Three-letter country code (ISO 3166-1 alpha-3) | | |
169 | | iso3166_1_alpha_numeric | Numeric country code (ISO 3166-1 numeric) | | |
170 | | iso3166_2 | Country subdivision code (ISO 3166-2) | | |
160 | 171 | | json | JSON | |
172 | | jwt | JSON Web Token (JWT) | | |
161 | 173 | | latitude | Latitude | |
162 | 174 | | longitude | Longitude | |
175 | | postcode_iso3166_alpha2 | Postcode | | |
176 | | postcode_iso3166_alpha2_field | Postcode | | |
163 | 177 | | rgb | RGB String | |
164 | 178 | | rgba | RGBA String | |
165 | 179 | | ssn | Social Security Number SSN | |
180 | | timezone | Timezone | | |
166 | 181 | | uuid | Universally Unique Identifier UUID | |
167 | 182 | | uuid3 | Universally Unique Identifier UUID v3 | |
168 | 183 | | uuid3_rfc4122 | Universally Unique Identifier UUID v3 RFC4122 | |
177 | 192 | | - | - | |
178 | 193 | | eq | Equals | |
179 | 194 | | gt | Greater than| |
180 | | gte |Greater than or equal | | |
195 | | gte | Greater than or equal | | |
181 | 196 | | lt | Less Than | |
182 | 197 | | lte | Less Than or Equal | |
183 | 198 | | ne | Not Equal | |
186 | 201 | | Tag | Description | |
187 | 202 | | - | - | |
188 | 203 | | dir | Directory | |
189 | | endswith | Ends With | | |
190 | | excludes | Excludes | | |
191 | | excludesall | Excludes All | | |
192 | | excludesrune | Excludes Rune | | |
193 | 204 | | file | File path | |
194 | 205 | | isdefault | Is Default | |
195 | 206 | | len | Length | |
208 | 219 | | excluded_without | Excluded Without | |
209 | 220 | | excluded_without_all | Excluded Without All | |
210 | 221 | | unique | Unique | |
222 | ||
223 | #### Aliases: | |
224 | | Tag | Description | | |
225 | | - | - | | |
226 | | iscolor | hexcolor\|rgb\|rgba\|hsl\|hsla | | |
227 | | country_code | iso3166_1_alpha2\|iso3166_1_alpha3\|iso3166_1_alpha_numeric | | |
211 | 228 | |
212 | 229 | Benchmarks |
213 | 230 | ------ |
294 | 311 | Make a pull request... |
295 | 312 | |
296 | 313 | License |
297 | ------ | |
314 | ------- | |
298 | 315 | Distributed under MIT License, please see license file within the code for more details. |
316 | ||
317 | Maintainers | |
318 | ----------- | |
319 | This project has grown large enough that more than one person is required to properly support the community. | |
320 | If you are interested in becoming a maintainer please reach out to me https://github.com/deankarn |
0 | package main | |
1 | ||
2 | import ( | |
3 | "fmt" | |
4 | "github.com/go-playground/validator/v10" | |
5 | ) | |
6 | ||
7 | var validate *validator.Validate | |
8 | ||
9 | func main() { | |
10 | validate = validator.New() | |
11 | ||
12 | validateMap() | |
13 | validateNestedMap() | |
14 | } | |
15 | ||
16 | func validateMap() { | |
17 | user := map[string]interface{}{"name": "Arshiya Kiani", "email": "zytel3301@gmail.com"} | |
18 | ||
19 | // Every rule will be applied to the item of the data that the offset of rule is pointing to. | |
20 | // So if you have a field "email": "omitempty,required,email", the validator will apply these | |
21 | // rules to offset of email in user data | |
22 | rules := map[string]interface{}{"name": "required,min=8,max=32", "email": "omitempty,required,email"} | |
23 | ||
24 | // ValidateMap will return map[string]error. | |
25 | // The offset of every item in errs is the name of invalid field and the value | |
26 | // is the message of error. If there was no error, ValidateMap method will | |
27 | // return an EMPTY map of errors, not nil. If you want to check that | |
28 | // if there was an error or not, you must check the length of the return value | |
29 | errs := validate.ValidateMap(user, rules) | |
30 | ||
31 | if len(errs) > 0 { | |
32 | fmt.Println(errs) | |
33 | // The user is invalid | |
34 | } | |
35 | ||
36 | // The user is valid | |
37 | } | |
38 | ||
39 | func validateNestedMap() { | |
40 | ||
41 | data := map[string]interface{}{ | |
42 | "name": "Arshiya Kiani", | |
43 | "email": "zytel3301@gmail.com", | |
44 | "details": map[string]interface{}{ | |
45 | "family_members": map[string]interface{}{ | |
46 | "father_name": "Micheal", | |
47 | "mother_name": "Hannah", | |
48 | }, | |
49 | "salary": "1000", | |
50 | }, | |
51 | } | |
52 | ||
53 | // Rules must be set as the structure as the data itself. If you want to dive into the | |
54 | // map, just declare its rules as a map | |
55 | rules := map[string]interface{}{ | |
56 | "name": "min=4,max=32", | |
57 | "email": "required,email", | |
58 | "details": map[string]interface{}{ | |
59 | "family_members": map[string]interface{}{ | |
60 | "father_name": "required,min=4,max=32", | |
61 | "mother_name": "required,min=4,max=32", | |
62 | }, | |
63 | "salary": "number", | |
64 | }, | |
65 | } | |
66 | ||
67 | if len(validate.ValidateMap(data, rules)) == 0 { | |
68 | // Data is valid | |
69 | } | |
70 | ||
71 | // Data is invalid | |
72 | } |
43 | 43 | |
44 | 44 | // register validation for 'User' |
45 | 45 | // NOTE: only have to register a non-pointer type for 'User', validator |
46 | // interanlly dereferences during it's type checks. | |
46 | // internally dereferences during it's type checks. | |
47 | 47 | validate.RegisterStructValidation(UserStructLevelValidation, User{}) |
48 | 48 | |
49 | 49 | // build 'User' info, normally posted data etc... |
17 | 17 | "unicode/utf8" |
18 | 18 | |
19 | 19 | "golang.org/x/crypto/sha3" |
20 | "golang.org/x/text/language" | |
20 | 21 | |
21 | 22 | urn "github.com/leodido/go-urn" |
22 | 23 | ) |
54 | 55 | isdefault: {}, |
55 | 56 | } |
56 | 57 | |
57 | // BakedInAliasValidators is a default mapping of a single validation tag that | |
58 | // bakedInAliases is a default mapping of a single validation tag that | |
58 | 59 | // defines a common or complex set of validation(s) to simplify |
59 | 60 | // adding validation to structs. |
60 | 61 | bakedInAliases = map[string]string{ |
62 | 63 | "country_code": "iso3166_1_alpha2|iso3166_1_alpha3|iso3166_1_alpha_numeric", |
63 | 64 | } |
64 | 65 | |
65 | // BakedInValidators is the default map of ValidationFunc | |
66 | // bakedInValidators is the default map of ValidationFunc | |
66 | 67 | // you can add, remove or even replace items to suite your needs, |
67 | 68 | // or even disregard and use your own map if so desired. |
68 | 69 | bakedInValidators = map[string]Func{ |
69 | "required": hasValue, | |
70 | "required_if": requiredIf, | |
71 | "required_unless": requiredUnless, | |
72 | "required_with": requiredWith, | |
73 | "required_with_all": requiredWithAll, | |
74 | "required_without": requiredWithout, | |
75 | "required_without_all": requiredWithoutAll, | |
76 | "excluded_with": excludedWith, | |
77 | "excluded_with_all": excludedWithAll, | |
78 | "excluded_without": excludedWithout, | |
79 | "excluded_without_all": excludedWithoutAll, | |
80 | "isdefault": isDefault, | |
81 | "len": hasLengthOf, | |
82 | "min": hasMinOf, | |
83 | "max": hasMaxOf, | |
84 | "eq": isEq, | |
85 | "ne": isNe, | |
86 | "lt": isLt, | |
87 | "lte": isLte, | |
88 | "gt": isGt, | |
89 | "gte": isGte, | |
90 | "eqfield": isEqField, | |
91 | "eqcsfield": isEqCrossStructField, | |
92 | "necsfield": isNeCrossStructField, | |
93 | "gtcsfield": isGtCrossStructField, | |
94 | "gtecsfield": isGteCrossStructField, | |
95 | "ltcsfield": isLtCrossStructField, | |
96 | "ltecsfield": isLteCrossStructField, | |
97 | "nefield": isNeField, | |
98 | "gtefield": isGteField, | |
99 | "gtfield": isGtField, | |
100 | "ltefield": isLteField, | |
101 | "ltfield": isLtField, | |
102 | "fieldcontains": fieldContains, | |
103 | "fieldexcludes": fieldExcludes, | |
104 | "alpha": isAlpha, | |
105 | "alphanum": isAlphanum, | |
106 | "alphaunicode": isAlphaUnicode, | |
107 | "alphanumunicode": isAlphanumUnicode, | |
108 | "numeric": isNumeric, | |
109 | "number": isNumber, | |
110 | "hexadecimal": isHexadecimal, | |
111 | "hexcolor": isHEXColor, | |
112 | "rgb": isRGB, | |
113 | "rgba": isRGBA, | |
114 | "hsl": isHSL, | |
115 | "hsla": isHSLA, | |
116 | "e164": isE164, | |
117 | "email": isEmail, | |
118 | "url": isURL, | |
119 | "uri": isURI, | |
120 | "urn_rfc2141": isUrnRFC2141, // RFC 2141 | |
121 | "file": isFile, | |
122 | "base64": isBase64, | |
123 | "base64url": isBase64URL, | |
124 | "contains": contains, | |
125 | "containsany": containsAny, | |
126 | "containsrune": containsRune, | |
127 | "excludes": excludes, | |
128 | "excludesall": excludesAll, | |
129 | "excludesrune": excludesRune, | |
130 | "startswith": startsWith, | |
131 | "endswith": endsWith, | |
132 | "startsnotwith": startsNotWith, | |
133 | "endsnotwith": endsNotWith, | |
134 | "isbn": isISBN, | |
135 | "isbn10": isISBN10, | |
136 | "isbn13": isISBN13, | |
137 | "eth_addr": isEthereumAddress, | |
138 | "btc_addr": isBitcoinAddress, | |
139 | "btc_addr_bech32": isBitcoinBech32Address, | |
140 | "uuid": isUUID, | |
141 | "uuid3": isUUID3, | |
142 | "uuid4": isUUID4, | |
143 | "uuid5": isUUID5, | |
144 | "uuid_rfc4122": isUUIDRFC4122, | |
145 | "uuid3_rfc4122": isUUID3RFC4122, | |
146 | "uuid4_rfc4122": isUUID4RFC4122, | |
147 | "uuid5_rfc4122": isUUID5RFC4122, | |
148 | "ascii": isASCII, | |
149 | "printascii": isPrintableASCII, | |
150 | "multibyte": hasMultiByteCharacter, | |
151 | "datauri": isDataURI, | |
152 | "latitude": isLatitude, | |
153 | "longitude": isLongitude, | |
154 | "ssn": isSSN, | |
155 | "ipv4": isIPv4, | |
156 | "ipv6": isIPv6, | |
157 | "ip": isIP, | |
158 | "cidrv4": isCIDRv4, | |
159 | "cidrv6": isCIDRv6, | |
160 | "cidr": isCIDR, | |
161 | "tcp4_addr": isTCP4AddrResolvable, | |
162 | "tcp6_addr": isTCP6AddrResolvable, | |
163 | "tcp_addr": isTCPAddrResolvable, | |
164 | "udp4_addr": isUDP4AddrResolvable, | |
165 | "udp6_addr": isUDP6AddrResolvable, | |
166 | "udp_addr": isUDPAddrResolvable, | |
167 | "ip4_addr": isIP4AddrResolvable, | |
168 | "ip6_addr": isIP6AddrResolvable, | |
169 | "ip_addr": isIPAddrResolvable, | |
170 | "unix_addr": isUnixAddrResolvable, | |
171 | "mac": isMAC, | |
172 | "hostname": isHostnameRFC952, // RFC 952 | |
173 | "hostname_rfc1123": isHostnameRFC1123, // RFC 1123 | |
174 | "fqdn": isFQDN, | |
175 | "unique": isUnique, | |
176 | "oneof": isOneOf, | |
177 | "html": isHTML, | |
178 | "html_encoded": isHTMLEncoded, | |
179 | "url_encoded": isURLEncoded, | |
180 | "dir": isDir, | |
181 | "json": isJSON, | |
182 | "hostname_port": isHostnamePort, | |
183 | "lowercase": isLowercase, | |
184 | "uppercase": isUppercase, | |
185 | "datetime": isDatetime, | |
186 | "timezone": isTimeZone, | |
187 | "iso3166_1_alpha2": isIso3166Alpha2, | |
188 | "iso3166_1_alpha3": isIso3166Alpha3, | |
189 | "iso3166_1_alpha_numeric": isIso3166AlphaNumeric, | |
70 | "required": hasValue, | |
71 | "required_if": requiredIf, | |
72 | "required_unless": requiredUnless, | |
73 | "required_with": requiredWith, | |
74 | "required_with_all": requiredWithAll, | |
75 | "required_without": requiredWithout, | |
76 | "required_without_all": requiredWithoutAll, | |
77 | "excluded_with": excludedWith, | |
78 | "excluded_with_all": excludedWithAll, | |
79 | "excluded_without": excludedWithout, | |
80 | "excluded_without_all": excludedWithoutAll, | |
81 | "isdefault": isDefault, | |
82 | "len": hasLengthOf, | |
83 | "min": hasMinOf, | |
84 | "max": hasMaxOf, | |
85 | "eq": isEq, | |
86 | "ne": isNe, | |
87 | "lt": isLt, | |
88 | "lte": isLte, | |
89 | "gt": isGt, | |
90 | "gte": isGte, | |
91 | "eqfield": isEqField, | |
92 | "eqcsfield": isEqCrossStructField, | |
93 | "necsfield": isNeCrossStructField, | |
94 | "gtcsfield": isGtCrossStructField, | |
95 | "gtecsfield": isGteCrossStructField, | |
96 | "ltcsfield": isLtCrossStructField, | |
97 | "ltecsfield": isLteCrossStructField, | |
98 | "nefield": isNeField, | |
99 | "gtefield": isGteField, | |
100 | "gtfield": isGtField, | |
101 | "ltefield": isLteField, | |
102 | "ltfield": isLtField, | |
103 | "fieldcontains": fieldContains, | |
104 | "fieldexcludes": fieldExcludes, | |
105 | "alpha": isAlpha, | |
106 | "alphanum": isAlphanum, | |
107 | "alphaunicode": isAlphaUnicode, | |
108 | "alphanumunicode": isAlphanumUnicode, | |
109 | "numeric": isNumeric, | |
110 | "number": isNumber, | |
111 | "hexadecimal": isHexadecimal, | |
112 | "hexcolor": isHEXColor, | |
113 | "rgb": isRGB, | |
114 | "rgba": isRGBA, | |
115 | "hsl": isHSL, | |
116 | "hsla": isHSLA, | |
117 | "e164": isE164, | |
118 | "email": isEmail, | |
119 | "url": isURL, | |
120 | "uri": isURI, | |
121 | "urn_rfc2141": isUrnRFC2141, // RFC 2141 | |
122 | "file": isFile, | |
123 | "base64": isBase64, | |
124 | "base64url": isBase64URL, | |
125 | "contains": contains, | |
126 | "containsany": containsAny, | |
127 | "containsrune": containsRune, | |
128 | "excludes": excludes, | |
129 | "excludesall": excludesAll, | |
130 | "excludesrune": excludesRune, | |
131 | "startswith": startsWith, | |
132 | "endswith": endsWith, | |
133 | "startsnotwith": startsNotWith, | |
134 | "endsnotwith": endsNotWith, | |
135 | "isbn": isISBN, | |
136 | "isbn10": isISBN10, | |
137 | "isbn13": isISBN13, | |
138 | "eth_addr": isEthereumAddress, | |
139 | "btc_addr": isBitcoinAddress, | |
140 | "btc_addr_bech32": isBitcoinBech32Address, | |
141 | "uuid": isUUID, | |
142 | "uuid3": isUUID3, | |
143 | "uuid4": isUUID4, | |
144 | "uuid5": isUUID5, | |
145 | "uuid_rfc4122": isUUIDRFC4122, | |
146 | "uuid3_rfc4122": isUUID3RFC4122, | |
147 | "uuid4_rfc4122": isUUID4RFC4122, | |
148 | "uuid5_rfc4122": isUUID5RFC4122, | |
149 | "ascii": isASCII, | |
150 | "printascii": isPrintableASCII, | |
151 | "multibyte": hasMultiByteCharacter, | |
152 | "datauri": isDataURI, | |
153 | "latitude": isLatitude, | |
154 | "longitude": isLongitude, | |
155 | "ssn": isSSN, | |
156 | "ipv4": isIPv4, | |
157 | "ipv6": isIPv6, | |
158 | "ip": isIP, | |
159 | "cidrv4": isCIDRv4, | |
160 | "cidrv6": isCIDRv6, | |
161 | "cidr": isCIDR, | |
162 | "tcp4_addr": isTCP4AddrResolvable, | |
163 | "tcp6_addr": isTCP6AddrResolvable, | |
164 | "tcp_addr": isTCPAddrResolvable, | |
165 | "udp4_addr": isUDP4AddrResolvable, | |
166 | "udp6_addr": isUDP6AddrResolvable, | |
167 | "udp_addr": isUDPAddrResolvable, | |
168 | "ip4_addr": isIP4AddrResolvable, | |
169 | "ip6_addr": isIP6AddrResolvable, | |
170 | "ip_addr": isIPAddrResolvable, | |
171 | "unix_addr": isUnixAddrResolvable, | |
172 | "mac": isMAC, | |
173 | "hostname": isHostnameRFC952, // RFC 952 | |
174 | "hostname_rfc1123": isHostnameRFC1123, // RFC 1123 | |
175 | "fqdn": isFQDN, | |
176 | "unique": isUnique, | |
177 | "oneof": isOneOf, | |
178 | "html": isHTML, | |
179 | "html_encoded": isHTMLEncoded, | |
180 | "url_encoded": isURLEncoded, | |
181 | "dir": isDir, | |
182 | "json": isJSON, | |
183 | "jwt": isJWT, | |
184 | "hostname_port": isHostnamePort, | |
185 | "lowercase": isLowercase, | |
186 | "uppercase": isUppercase, | |
187 | "datetime": isDatetime, | |
188 | "timezone": isTimeZone, | |
189 | "iso3166_1_alpha2": isIso3166Alpha2, | |
190 | "iso3166_1_alpha3": isIso3166Alpha3, | |
191 | "iso3166_1_alpha_numeric": isIso3166AlphaNumeric, | |
192 | "iso3166_2": isIso31662, | |
193 | "bcp47_language_tag": isBCP47LanguageTag, | |
194 | "postcode_iso3166_alpha2": isPostcodeByIso3166Alpha2, | |
195 | "postcode_iso3166_alpha2_field": isPostcodeByIso3166Alpha2Field, | |
196 | "bic": isIsoBicFormat, | |
190 | 197 | } |
191 | 198 | ) |
192 | 199 | |
295 | 302 | } |
296 | 303 | } |
297 | 304 | |
298 | // IsMAC is the validation function for validating if the field's value is a valid MAC address. | |
305 | // isMAC is the validation function for validating if the field's value is a valid MAC address. | |
299 | 306 | func isMAC(fl FieldLevel) bool { |
300 | 307 | |
301 | 308 | _, err := net.ParseMAC(fl.Field().String()) |
303 | 310 | return err == nil |
304 | 311 | } |
305 | 312 | |
306 | // IsCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address. | |
313 | // isCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address. | |
307 | 314 | func isCIDRv4(fl FieldLevel) bool { |
308 | 315 | |
309 | 316 | ip, _, err := net.ParseCIDR(fl.Field().String()) |
311 | 318 | return err == nil && ip.To4() != nil |
312 | 319 | } |
313 | 320 | |
314 | // IsCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address. | |
321 | // isCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address. | |
315 | 322 | func isCIDRv6(fl FieldLevel) bool { |
316 | 323 | |
317 | 324 | ip, _, err := net.ParseCIDR(fl.Field().String()) |
319 | 326 | return err == nil && ip.To4() == nil |
320 | 327 | } |
321 | 328 | |
322 | // IsCIDR is the validation function for validating if the field's value is a valid v4 or v6 CIDR address. | |
329 | // isCIDR is the validation function for validating if the field's value is a valid v4 or v6 CIDR address. | |
323 | 330 | func isCIDR(fl FieldLevel) bool { |
324 | 331 | |
325 | 332 | _, _, err := net.ParseCIDR(fl.Field().String()) |
327 | 334 | return err == nil |
328 | 335 | } |
329 | 336 | |
330 | // IsIPv4 is the validation function for validating if a value is a valid v4 IP address. | |
337 | // isIPv4 is the validation function for validating if a value is a valid v4 IP address. | |
331 | 338 | func isIPv4(fl FieldLevel) bool { |
332 | 339 | |
333 | 340 | ip := net.ParseIP(fl.Field().String()) |
335 | 342 | return ip != nil && ip.To4() != nil |
336 | 343 | } |
337 | 344 | |
338 | // IsIPv6 is the validation function for validating if the field's value is a valid v6 IP address. | |
345 | // isIPv6 is the validation function for validating if the field's value is a valid v6 IP address. | |
339 | 346 | func isIPv6(fl FieldLevel) bool { |
340 | 347 | |
341 | 348 | ip := net.ParseIP(fl.Field().String()) |
343 | 350 | return ip != nil && ip.To4() == nil |
344 | 351 | } |
345 | 352 | |
346 | // IsIP is the validation function for validating if the field's value is a valid v4 or v6 IP address. | |
353 | // isIP is the validation function for validating if the field's value is a valid v4 or v6 IP address. | |
347 | 354 | func isIP(fl FieldLevel) bool { |
348 | 355 | |
349 | 356 | ip := net.ParseIP(fl.Field().String()) |
351 | 358 | return ip != nil |
352 | 359 | } |
353 | 360 | |
354 | // IsSSN is the validation function for validating if the field's value is a valid SSN. | |
361 | // isSSN is the validation function for validating if the field's value is a valid SSN. | |
355 | 362 | func isSSN(fl FieldLevel) bool { |
356 | 363 | |
357 | 364 | field := fl.Field() |
363 | 370 | return sSNRegex.MatchString(field.String()) |
364 | 371 | } |
365 | 372 | |
366 | // IsLongitude is the validation function for validating if the field's value is a valid longitude coordinate. | |
373 | // isLongitude is the validation function for validating if the field's value is a valid longitude coordinate. | |
367 | 374 | func isLongitude(fl FieldLevel) bool { |
368 | 375 | field := fl.Field() |
369 | 376 | |
386 | 393 | return longitudeRegex.MatchString(v) |
387 | 394 | } |
388 | 395 | |
389 | // IsLatitude is the validation function for validating if the field's value is a valid latitude coordinate. | |
396 | // isLatitude is the validation function for validating if the field's value is a valid latitude coordinate. | |
390 | 397 | func isLatitude(fl FieldLevel) bool { |
391 | 398 | field := fl.Field() |
392 | 399 | |
409 | 416 | return latitudeRegex.MatchString(v) |
410 | 417 | } |
411 | 418 | |
412 | // IsDataURI is the validation function for validating if the field's value is a valid data URI. | |
419 | // isDataURI is the validation function for validating if the field's value is a valid data URI. | |
413 | 420 | func isDataURI(fl FieldLevel) bool { |
414 | 421 | |
415 | 422 | uri := strings.SplitN(fl.Field().String(), ",", 2) |
425 | 432 | return base64Regex.MatchString(uri[1]) |
426 | 433 | } |
427 | 434 | |
428 | // HasMultiByteCharacter is the validation function for validating if the field's value has a multi byte character. | |
435 | // hasMultiByteCharacter is the validation function for validating if the field's value has a multi byte character. | |
429 | 436 | func hasMultiByteCharacter(fl FieldLevel) bool { |
430 | 437 | |
431 | 438 | field := fl.Field() |
437 | 444 | return multibyteRegex.MatchString(field.String()) |
438 | 445 | } |
439 | 446 | |
440 | // IsPrintableASCII is the validation function for validating if the field's value is a valid printable ASCII character. | |
447 | // isPrintableASCII is the validation function for validating if the field's value is a valid printable ASCII character. | |
441 | 448 | func isPrintableASCII(fl FieldLevel) bool { |
442 | 449 | return printableASCIIRegex.MatchString(fl.Field().String()) |
443 | 450 | } |
444 | 451 | |
445 | // IsASCII is the validation function for validating if the field's value is a valid ASCII character. | |
452 | // isASCII is the validation function for validating if the field's value is a valid ASCII character. | |
446 | 453 | func isASCII(fl FieldLevel) bool { |
447 | 454 | return aSCIIRegex.MatchString(fl.Field().String()) |
448 | 455 | } |
449 | 456 | |
450 | // IsUUID5 is the validation function for validating if the field's value is a valid v5 UUID. | |
457 | // isUUID5 is the validation function for validating if the field's value is a valid v5 UUID. | |
451 | 458 | func isUUID5(fl FieldLevel) bool { |
452 | 459 | return uUID5Regex.MatchString(fl.Field().String()) |
453 | 460 | } |
454 | 461 | |
455 | // IsUUID4 is the validation function for validating if the field's value is a valid v4 UUID. | |
462 | // isUUID4 is the validation function for validating if the field's value is a valid v4 UUID. | |
456 | 463 | func isUUID4(fl FieldLevel) bool { |
457 | 464 | return uUID4Regex.MatchString(fl.Field().String()) |
458 | 465 | } |
459 | 466 | |
460 | // IsUUID3 is the validation function for validating if the field's value is a valid v3 UUID. | |
467 | // isUUID3 is the validation function for validating if the field's value is a valid v3 UUID. | |
461 | 468 | func isUUID3(fl FieldLevel) bool { |
462 | 469 | return uUID3Regex.MatchString(fl.Field().String()) |
463 | 470 | } |
464 | 471 | |
465 | // IsUUID is the validation function for validating if the field's value is a valid UUID of any version. | |
472 | // isUUID is the validation function for validating if the field's value is a valid UUID of any version. | |
466 | 473 | func isUUID(fl FieldLevel) bool { |
467 | 474 | return uUIDRegex.MatchString(fl.Field().String()) |
468 | 475 | } |
469 | 476 | |
470 | // IsUUID5RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v5 UUID. | |
477 | // isUUID5RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v5 UUID. | |
471 | 478 | func isUUID5RFC4122(fl FieldLevel) bool { |
472 | 479 | return uUID5RFC4122Regex.MatchString(fl.Field().String()) |
473 | 480 | } |
474 | 481 | |
475 | // IsUUID4RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v4 UUID. | |
482 | // isUUID4RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v4 UUID. | |
476 | 483 | func isUUID4RFC4122(fl FieldLevel) bool { |
477 | 484 | return uUID4RFC4122Regex.MatchString(fl.Field().String()) |
478 | 485 | } |
479 | 486 | |
480 | // IsUUID3RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v3 UUID. | |
487 | // isUUID3RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v3 UUID. | |
481 | 488 | func isUUID3RFC4122(fl FieldLevel) bool { |
482 | 489 | return uUID3RFC4122Regex.MatchString(fl.Field().String()) |
483 | 490 | } |
484 | 491 | |
485 | // IsUUIDRFC4122 is the validation function for validating if the field's value is a valid RFC4122 UUID of any version. | |
492 | // isUUIDRFC4122 is the validation function for validating if the field's value is a valid RFC4122 UUID of any version. | |
486 | 493 | func isUUIDRFC4122(fl FieldLevel) bool { |
487 | 494 | return uUIDRFC4122Regex.MatchString(fl.Field().String()) |
488 | 495 | } |
489 | 496 | |
490 | // IsISBN is the validation function for validating if the field's value is a valid v10 or v13 ISBN. | |
497 | // isISBN is the validation function for validating if the field's value is a valid v10 or v13 ISBN. | |
491 | 498 | func isISBN(fl FieldLevel) bool { |
492 | 499 | return isISBN10(fl) || isISBN13(fl) |
493 | 500 | } |
494 | 501 | |
495 | // IsISBN13 is the validation function for validating if the field's value is a valid v13 ISBN. | |
502 | // isISBN13 is the validation function for validating if the field's value is a valid v13 ISBN. | |
496 | 503 | func isISBN13(fl FieldLevel) bool { |
497 | 504 | |
498 | 505 | s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 4), " ", "", 4) |
513 | 520 | return (int32(s[12]-'0'))-((10-(checksum%10))%10) == 0 |
514 | 521 | } |
515 | 522 | |
516 | // IsISBN10 is the validation function for validating if the field's value is a valid v10 ISBN. | |
523 | // isISBN10 is the validation function for validating if the field's value is a valid v10 ISBN. | |
517 | 524 | func isISBN10(fl FieldLevel) bool { |
518 | 525 | |
519 | 526 | s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 3), " ", "", 3) |
538 | 545 | return checksum%11 == 0 |
539 | 546 | } |
540 | 547 | |
541 | // IsEthereumAddress is the validation function for validating if the field's value is a valid Ethereum address. | |
548 | // isEthereumAddress is the validation function for validating if the field's value is a valid Ethereum address. | |
542 | 549 | func isEthereumAddress(fl FieldLevel) bool { |
543 | 550 | address := fl.Field().String() |
544 | 551 | |
546 | 553 | return false |
547 | 554 | } |
548 | 555 | |
549 | if ethaddressRegexUpper.MatchString(address) || ethAddressRegexLower.MatchString(address) { | |
556 | if ethAddressRegexUpper.MatchString(address) || ethAddressRegexLower.MatchString(address) { | |
550 | 557 | return true |
551 | 558 | } |
552 | 559 | |
569 | 576 | return true |
570 | 577 | } |
571 | 578 | |
572 | // IsBitcoinAddress is the validation function for validating if the field's value is a valid btc address | |
579 | // isBitcoinAddress is the validation function for validating if the field's value is a valid btc address | |
573 | 580 | func isBitcoinAddress(fl FieldLevel) bool { |
574 | 581 | address := fl.Field().String() |
575 | 582 | |
606 | 613 | return validchecksum == computedchecksum |
607 | 614 | } |
608 | 615 | |
609 | // IsBitcoinBech32Address is the validation function for validating if the field's value is a valid bech32 btc address | |
616 | // isBitcoinBech32Address is the validation function for validating if the field's value is a valid bech32 btc address | |
610 | 617 | func isBitcoinBech32Address(fl FieldLevel) bool { |
611 | 618 | address := fl.Field().String() |
612 | 619 | |
686 | 693 | return true |
687 | 694 | } |
688 | 695 | |
689 | // ExcludesRune is the validation function for validating that the field's value does not contain the rune specified within the param. | |
696 | // excludesRune is the validation function for validating that the field's value does not contain the rune specified within the param. | |
690 | 697 | func excludesRune(fl FieldLevel) bool { |
691 | 698 | return !containsRune(fl) |
692 | 699 | } |
693 | 700 | |
694 | // ExcludesAll is the validation function for validating that the field's value does not contain any of the characters specified within the param. | |
701 | // excludesAll is the validation function for validating that the field's value does not contain any of the characters specified within the param. | |
695 | 702 | func excludesAll(fl FieldLevel) bool { |
696 | 703 | return !containsAny(fl) |
697 | 704 | } |
698 | 705 | |
699 | // Excludes is the validation function for validating that the field's value does not contain the text specified within the param. | |
706 | // excludes is the validation function for validating that the field's value does not contain the text specified within the param. | |
700 | 707 | func excludes(fl FieldLevel) bool { |
701 | 708 | return !contains(fl) |
702 | 709 | } |
703 | 710 | |
704 | // ContainsRune is the validation function for validating that the field's value contains the rune specified within the param. | |
711 | // containsRune is the validation function for validating that the field's value contains the rune specified within the param. | |
705 | 712 | func containsRune(fl FieldLevel) bool { |
706 | 713 | |
707 | 714 | r, _ := utf8.DecodeRuneInString(fl.Param()) |
709 | 716 | return strings.ContainsRune(fl.Field().String(), r) |
710 | 717 | } |
711 | 718 | |
712 | // ContainsAny is the validation function for validating that the field's value contains any of the characters specified within the param. | |
719 | // containsAny is the validation function for validating that the field's value contains any of the characters specified within the param. | |
713 | 720 | func containsAny(fl FieldLevel) bool { |
714 | 721 | return strings.ContainsAny(fl.Field().String(), fl.Param()) |
715 | 722 | } |
716 | 723 | |
717 | // Contains is the validation function for validating that the field's value contains the text specified within the param. | |
724 | // contains is the validation function for validating that the field's value contains the text specified within the param. | |
718 | 725 | func contains(fl FieldLevel) bool { |
719 | 726 | return strings.Contains(fl.Field().String(), fl.Param()) |
720 | 727 | } |
721 | 728 | |
722 | // StartsWith is the validation function for validating that the field's value starts with the text specified within the param. | |
729 | // startsWith is the validation function for validating that the field's value starts with the text specified within the param. | |
723 | 730 | func startsWith(fl FieldLevel) bool { |
724 | 731 | return strings.HasPrefix(fl.Field().String(), fl.Param()) |
725 | 732 | } |
726 | 733 | |
727 | // EndsWith is the validation function for validating that the field's value ends with the text specified within the param. | |
734 | // endsWith is the validation function for validating that the field's value ends with the text specified within the param. | |
728 | 735 | func endsWith(fl FieldLevel) bool { |
729 | 736 | return strings.HasSuffix(fl.Field().String(), fl.Param()) |
730 | 737 | } |
731 | 738 | |
732 | // StartsNotWith is the validation function for validating that the field's value does not start with the text specified within the param. | |
739 | // startsNotWith is the validation function for validating that the field's value does not start with the text specified within the param. | |
733 | 740 | func startsNotWith(fl FieldLevel) bool { |
734 | 741 | return !startsWith(fl) |
735 | 742 | } |
736 | 743 | |
737 | // EndsNotWith is the validation function for validating that the field's value does not end with the text specified within the param. | |
744 | // endsNotWith is the validation function for validating that the field's value does not end with the text specified within the param. | |
738 | 745 | func endsNotWith(fl FieldLevel) bool { |
739 | 746 | return !endsWith(fl) |
740 | 747 | } |
741 | 748 | |
742 | // FieldContains is the validation function for validating if the current field's value contains the field specified by the param's value. | |
749 | // fieldContains is the validation function for validating if the current field's value contains the field specified by the param's value. | |
743 | 750 | func fieldContains(fl FieldLevel) bool { |
744 | 751 | field := fl.Field() |
745 | 752 | |
752 | 759 | return strings.Contains(field.String(), currentField.String()) |
753 | 760 | } |
754 | 761 | |
755 | // FieldExcludes is the validation function for validating if the current field's value excludes the field specified by the param's value. | |
762 | // fieldExcludes is the validation function for validating if the current field's value excludes the field specified by the param's value. | |
756 | 763 | func fieldExcludes(fl FieldLevel) bool { |
757 | 764 | field := fl.Field() |
758 | 765 | |
764 | 771 | return !strings.Contains(field.String(), currentField.String()) |
765 | 772 | } |
766 | 773 | |
767 | // IsNeField is the validation function for validating if the current field's value is not equal to the field specified by the param's value. | |
774 | // isNeField is the validation function for validating if the current field's value is not equal to the field specified by the param's value. | |
768 | 775 | func isNeField(fl FieldLevel) bool { |
769 | 776 | |
770 | 777 | field := fl.Field() |
789 | 796 | |
790 | 797 | case reflect.Slice, reflect.Map, reflect.Array: |
791 | 798 | return int64(field.Len()) != int64(currentField.Len()) |
799 | ||
800 | case reflect.Bool: | |
801 | return field.Bool() != currentField.Bool() | |
792 | 802 | |
793 | 803 | case reflect.Struct: |
794 | 804 | |
813 | 823 | return field.String() != currentField.String() |
814 | 824 | } |
815 | 825 | |
816 | // IsNe is the validation function for validating that the field's value does not equal the provided param value. | |
826 | // isNe is the validation function for validating that the field's value does not equal the provided param value. | |
817 | 827 | func isNe(fl FieldLevel) bool { |
818 | 828 | return !isEq(fl) |
819 | 829 | } |
820 | 830 | |
821 | // IsLteCrossStructField is the validation function for validating if the current field's value is less than or equal to the field, within a separate struct, specified by the param's value. | |
831 | // isLteCrossStructField is the validation function for validating if the current field's value is less than or equal to the field, within a separate struct, specified by the param's value. | |
822 | 832 | func isLteCrossStructField(fl FieldLevel) bool { |
823 | 833 | |
824 | 834 | field := fl.Field() |
865 | 875 | return field.String() <= topField.String() |
866 | 876 | } |
867 | 877 | |
868 | // IsLtCrossStructField is the validation function for validating if the current field's value is less than the field, within a separate struct, specified by the param's value. | |
878 | // isLtCrossStructField is the validation function for validating if the current field's value is less than the field, within a separate struct, specified by the param's value. | |
869 | 879 | // NOTE: This is exposed for use within your own custom functions and not intended to be called directly. |
870 | 880 | func isLtCrossStructField(fl FieldLevel) bool { |
871 | 881 | |
913 | 923 | return field.String() < topField.String() |
914 | 924 | } |
915 | 925 | |
916 | // IsGteCrossStructField is the validation function for validating if the current field's value is greater than or equal to the field, within a separate struct, specified by the param's value. | |
926 | // isGteCrossStructField is the validation function for validating if the current field's value is greater than or equal to the field, within a separate struct, specified by the param's value. | |
917 | 927 | func isGteCrossStructField(fl FieldLevel) bool { |
918 | 928 | |
919 | 929 | field := fl.Field() |
960 | 970 | return field.String() >= topField.String() |
961 | 971 | } |
962 | 972 | |
963 | // IsGtCrossStructField is the validation function for validating if the current field's value is greater than the field, within a separate struct, specified by the param's value. | |
973 | // isGtCrossStructField is the validation function for validating if the current field's value is greater than the field, within a separate struct, specified by the param's value. | |
964 | 974 | func isGtCrossStructField(fl FieldLevel) bool { |
965 | 975 | |
966 | 976 | field := fl.Field() |
1007 | 1017 | return field.String() > topField.String() |
1008 | 1018 | } |
1009 | 1019 | |
1010 | // IsNeCrossStructField is the validation function for validating that the current field's value is not equal to the field, within a separate struct, specified by the param's value. | |
1020 | // isNeCrossStructField is the validation function for validating that the current field's value is not equal to the field, within a separate struct, specified by the param's value. | |
1011 | 1021 | func isNeCrossStructField(fl FieldLevel) bool { |
1012 | 1022 | |
1013 | 1023 | field := fl.Field() |
1032 | 1042 | case reflect.Slice, reflect.Map, reflect.Array: |
1033 | 1043 | return int64(topField.Len()) != int64(field.Len()) |
1034 | 1044 | |
1045 | case reflect.Bool: | |
1046 | return topField.Bool() != field.Bool() | |
1047 | ||
1035 | 1048 | case reflect.Struct: |
1036 | 1049 | |
1037 | 1050 | fieldType := field.Type() |
1054 | 1067 | return topField.String() != field.String() |
1055 | 1068 | } |
1056 | 1069 | |
1057 | // IsEqCrossStructField is the validation function for validating that the current field's value is equal to the field, within a separate struct, specified by the param's value. | |
1070 | // isEqCrossStructField is the validation function for validating that the current field's value is equal to the field, within a separate struct, specified by the param's value. | |
1058 | 1071 | func isEqCrossStructField(fl FieldLevel) bool { |
1059 | 1072 | |
1060 | 1073 | field := fl.Field() |
1078 | 1091 | |
1079 | 1092 | case reflect.Slice, reflect.Map, reflect.Array: |
1080 | 1093 | return int64(topField.Len()) == int64(field.Len()) |
1094 | ||
1095 | case reflect.Bool: | |
1096 | return topField.Bool() == field.Bool() | |
1081 | 1097 | |
1082 | 1098 | case reflect.Struct: |
1083 | 1099 | |
1101 | 1117 | return topField.String() == field.String() |
1102 | 1118 | } |
1103 | 1119 | |
1104 | // IsEqField is the validation function for validating if the current field's value is equal to the field specified by the param's value. | |
1120 | // isEqField is the validation function for validating if the current field's value is equal to the field specified by the param's value. | |
1105 | 1121 | func isEqField(fl FieldLevel) bool { |
1106 | 1122 | |
1107 | 1123 | field := fl.Field() |
1125 | 1141 | |
1126 | 1142 | case reflect.Slice, reflect.Map, reflect.Array: |
1127 | 1143 | return int64(field.Len()) == int64(currentField.Len()) |
1144 | ||
1145 | case reflect.Bool: | |
1146 | return field.Bool() == currentField.Bool() | |
1128 | 1147 | |
1129 | 1148 | case reflect.Struct: |
1130 | 1149 | |
1149 | 1168 | return field.String() == currentField.String() |
1150 | 1169 | } |
1151 | 1170 | |
1152 | // IsEq is the validation function for validating if the current field's value is equal to the param's value. | |
1171 | // isEq is the validation function for validating if the current field's value is equal to the param's value. | |
1153 | 1172 | func isEq(fl FieldLevel) bool { |
1154 | 1173 | |
1155 | 1174 | field := fl.Field() |
1189 | 1208 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) |
1190 | 1209 | } |
1191 | 1210 | |
1192 | // IsBase64 is the validation function for validating if the current field's value is a valid base 64. | |
1211 | // isPostcodeByIso3166Alpha2 validates by value which is country code in iso 3166 alpha 2 | |
1212 | // example: `postcode_iso3166_alpha2=US` | |
1213 | func isPostcodeByIso3166Alpha2(fl FieldLevel) bool { | |
1214 | field := fl.Field() | |
1215 | param := fl.Param() | |
1216 | ||
1217 | reg, found := postCodeRegexDict[param] | |
1218 | if !found { | |
1219 | return false | |
1220 | } | |
1221 | ||
1222 | return reg.MatchString(field.String()) | |
1223 | } | |
1224 | ||
1225 | // isPostcodeByIso3166Alpha2 validates by field which represents for a value of country code in iso 3166 alpha 2 | |
1226 | // example: `postcode_iso3166_alpha2_field=CountryCode` | |
1227 | func isPostcodeByIso3166Alpha2Field(fl FieldLevel) bool { | |
1228 | field := fl.Field() | |
1229 | params := parseOneOfParam2(fl.Param()) | |
1230 | ||
1231 | if len(params) != 1 { | |
1232 | return false | |
1233 | } | |
1234 | ||
1235 | currentField, kind, _, found := fl.GetStructFieldOKAdvanced2(fl.Parent(), params[0]) | |
1236 | if !found { | |
1237 | return false | |
1238 | } | |
1239 | ||
1240 | if kind != reflect.String { | |
1241 | panic(fmt.Sprintf("Bad field type %T", currentField.Interface())) | |
1242 | } | |
1243 | ||
1244 | reg, found := postCodeRegexDict[currentField.String()] | |
1245 | if !found { | |
1246 | return false | |
1247 | } | |
1248 | ||
1249 | return reg.MatchString(field.String()) | |
1250 | } | |
1251 | ||
1252 | // isBase64 is the validation function for validating if the current field's value is a valid base 64. | |
1193 | 1253 | func isBase64(fl FieldLevel) bool { |
1194 | 1254 | return base64Regex.MatchString(fl.Field().String()) |
1195 | 1255 | } |
1196 | 1256 | |
1197 | // IsBase64URL is the validation function for validating if the current field's value is a valid base64 URL safe string. | |
1257 | // isBase64URL is the validation function for validating if the current field's value is a valid base64 URL safe string. | |
1198 | 1258 | func isBase64URL(fl FieldLevel) bool { |
1199 | 1259 | return base64URLRegex.MatchString(fl.Field().String()) |
1200 | 1260 | } |
1201 | 1261 | |
1202 | // IsURI is the validation function for validating if the current field's value is a valid URI. | |
1262 | // isURI is the validation function for validating if the current field's value is a valid URI. | |
1203 | 1263 | func isURI(fl FieldLevel) bool { |
1204 | 1264 | |
1205 | 1265 | field := fl.Field() |
1228 | 1288 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) |
1229 | 1289 | } |
1230 | 1290 | |
1231 | // IsURL is the validation function for validating if the current field's value is a valid URL. | |
1291 | // isURL is the validation function for validating if the current field's value is a valid URL. | |
1232 | 1292 | func isURL(fl FieldLevel) bool { |
1233 | 1293 | |
1234 | 1294 | field := fl.Field() |
1280 | 1340 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) |
1281 | 1341 | } |
1282 | 1342 | |
1283 | // IsFile is the validation function for validating if the current field's value is a valid file path. | |
1343 | // isFile is the validation function for validating if the current field's value is a valid file path. | |
1284 | 1344 | func isFile(fl FieldLevel) bool { |
1285 | 1345 | field := fl.Field() |
1286 | 1346 | |
1297 | 1357 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) |
1298 | 1358 | } |
1299 | 1359 | |
1300 | // IsE164 is the validation function for validating if the current field's value is a valid e.164 formatted phone number. | |
1360 | // isE164 is the validation function for validating if the current field's value is a valid e.164 formatted phone number. | |
1301 | 1361 | func isE164(fl FieldLevel) bool { |
1302 | 1362 | return e164Regex.MatchString(fl.Field().String()) |
1303 | 1363 | } |
1304 | 1364 | |
1305 | // IsEmail is the validation function for validating if the current field's value is a valid email address. | |
1365 | // isEmail is the validation function for validating if the current field's value is a valid email address. | |
1306 | 1366 | func isEmail(fl FieldLevel) bool { |
1307 | 1367 | return emailRegex.MatchString(fl.Field().String()) |
1308 | 1368 | } |
1309 | 1369 | |
1310 | // IsHSLA is the validation function for validating if the current field's value is a valid HSLA color. | |
1370 | // isHSLA is the validation function for validating if the current field's value is a valid HSLA color. | |
1311 | 1371 | func isHSLA(fl FieldLevel) bool { |
1312 | 1372 | return hslaRegex.MatchString(fl.Field().String()) |
1313 | 1373 | } |
1314 | 1374 | |
1315 | // IsHSL is the validation function for validating if the current field's value is a valid HSL color. | |
1375 | // isHSL is the validation function for validating if the current field's value is a valid HSL color. | |
1316 | 1376 | func isHSL(fl FieldLevel) bool { |
1317 | 1377 | return hslRegex.MatchString(fl.Field().String()) |
1318 | 1378 | } |
1319 | 1379 | |
1320 | // IsRGBA is the validation function for validating if the current field's value is a valid RGBA color. | |
1380 | // isRGBA is the validation function for validating if the current field's value is a valid RGBA color. | |
1321 | 1381 | func isRGBA(fl FieldLevel) bool { |
1322 | 1382 | return rgbaRegex.MatchString(fl.Field().String()) |
1323 | 1383 | } |
1324 | 1384 | |
1325 | // IsRGB is the validation function for validating if the current field's value is a valid RGB color. | |
1385 | // isRGB is the validation function for validating if the current field's value is a valid RGB color. | |
1326 | 1386 | func isRGB(fl FieldLevel) bool { |
1327 | 1387 | return rgbRegex.MatchString(fl.Field().String()) |
1328 | 1388 | } |
1329 | 1389 | |
1330 | // IsHEXColor is the validation function for validating if the current field's value is a valid HEX color. | |
1390 | // isHEXColor is the validation function for validating if the current field's value is a valid HEX color. | |
1331 | 1391 | func isHEXColor(fl FieldLevel) bool { |
1332 | return hexcolorRegex.MatchString(fl.Field().String()) | |
1333 | } | |
1334 | ||
1335 | // IsHexadecimal is the validation function for validating if the current field's value is a valid hexadecimal. | |
1392 | return hexColorRegex.MatchString(fl.Field().String()) | |
1393 | } | |
1394 | ||
1395 | // isHexadecimal is the validation function for validating if the current field's value is a valid hexadecimal. | |
1336 | 1396 | func isHexadecimal(fl FieldLevel) bool { |
1337 | 1397 | return hexadecimalRegex.MatchString(fl.Field().String()) |
1338 | 1398 | } |
1339 | 1399 | |
1340 | // IsNumber is the validation function for validating if the current field's value is a valid number. | |
1400 | // isNumber is the validation function for validating if the current field's value is a valid number. | |
1341 | 1401 | func isNumber(fl FieldLevel) bool { |
1342 | 1402 | switch fl.Field().Kind() { |
1343 | 1403 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64: |
1347 | 1407 | } |
1348 | 1408 | } |
1349 | 1409 | |
1350 | // IsNumeric is the validation function for validating if the current field's value is a valid numeric value. | |
1410 | // isNumeric is the validation function for validating if the current field's value is a valid numeric value. | |
1351 | 1411 | func isNumeric(fl FieldLevel) bool { |
1352 | 1412 | switch fl.Field().Kind() { |
1353 | 1413 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64: |
1357 | 1417 | } |
1358 | 1418 | } |
1359 | 1419 | |
1360 | // IsAlphanum is the validation function for validating if the current field's value is a valid alphanumeric value. | |
1420 | // isAlphanum is the validation function for validating if the current field's value is a valid alphanumeric value. | |
1361 | 1421 | func isAlphanum(fl FieldLevel) bool { |
1362 | 1422 | return alphaNumericRegex.MatchString(fl.Field().String()) |
1363 | 1423 | } |
1364 | 1424 | |
1365 | // IsAlpha is the validation function for validating if the current field's value is a valid alpha value. | |
1425 | // isAlpha is the validation function for validating if the current field's value is a valid alpha value. | |
1366 | 1426 | func isAlpha(fl FieldLevel) bool { |
1367 | 1427 | return alphaRegex.MatchString(fl.Field().String()) |
1368 | 1428 | } |
1369 | 1429 | |
1370 | // IsAlphanumUnicode is the validation function for validating if the current field's value is a valid alphanumeric unicode value. | |
1430 | // isAlphanumUnicode is the validation function for validating if the current field's value is a valid alphanumeric unicode value. | |
1371 | 1431 | func isAlphanumUnicode(fl FieldLevel) bool { |
1372 | 1432 | return alphaUnicodeNumericRegex.MatchString(fl.Field().String()) |
1373 | 1433 | } |
1374 | 1434 | |
1375 | // IsAlphaUnicode is the validation function for validating if the current field's value is a valid alpha unicode value. | |
1435 | // isAlphaUnicode is the validation function for validating if the current field's value is a valid alpha unicode value. | |
1376 | 1436 | func isAlphaUnicode(fl FieldLevel) bool { |
1377 | 1437 | return alphaUnicodeRegex.MatchString(fl.Field().String()) |
1378 | 1438 | } |
1382 | 1442 | return !hasValue(fl) |
1383 | 1443 | } |
1384 | 1444 | |
1385 | // HasValue is the validation function for validating if the current field's value is not the default static value. | |
1445 | // hasValue is the validation function for validating if the current field's value is not the default static value. | |
1386 | 1446 | func hasValue(fl FieldLevel) bool { |
1387 | 1447 | field := fl.Field() |
1388 | 1448 | switch field.Kind() { |
1440 | 1500 | |
1441 | 1501 | case reflect.Slice, reflect.Map, reflect.Array: |
1442 | 1502 | return int64(field.Len()) == asInt(value) |
1503 | ||
1504 | case reflect.Bool: | |
1505 | return field.Bool() == asBool(value) | |
1443 | 1506 | } |
1444 | 1507 | |
1445 | 1508 | // default reflect.String: |
1477 | 1540 | return hasValue(fl) |
1478 | 1541 | } |
1479 | 1542 | |
1480 | // ExcludedWith is the validation function | |
1543 | // excludedWith is the validation function | |
1481 | 1544 | // The field under validation must not be present or is empty if any of the other specified fields are present. |
1482 | 1545 | func excludedWith(fl FieldLevel) bool { |
1483 | 1546 | params := parseOneOfParam2(fl.Param()) |
1489 | 1552 | return true |
1490 | 1553 | } |
1491 | 1554 | |
1492 | // RequiredWith is the validation function | |
1555 | // requiredWith is the validation function | |
1493 | 1556 | // The field under validation must be present and not empty only if any of the other specified fields are present. |
1494 | 1557 | func requiredWith(fl FieldLevel) bool { |
1495 | 1558 | params := parseOneOfParam2(fl.Param()) |
1501 | 1564 | return true |
1502 | 1565 | } |
1503 | 1566 | |
1504 | // ExcludedWithAll is the validation function | |
1567 | // excludedWithAll is the validation function | |
1505 | 1568 | // The field under validation must not be present or is empty if all of the other specified fields are present. |
1506 | 1569 | func excludedWithAll(fl FieldLevel) bool { |
1507 | 1570 | params := parseOneOfParam2(fl.Param()) |
1513 | 1576 | return !hasValue(fl) |
1514 | 1577 | } |
1515 | 1578 | |
1516 | // RequiredWithAll is the validation function | |
1579 | // requiredWithAll is the validation function | |
1517 | 1580 | // The field under validation must be present and not empty only if all of the other specified fields are present. |
1518 | 1581 | func requiredWithAll(fl FieldLevel) bool { |
1519 | 1582 | params := parseOneOfParam2(fl.Param()) |
1525 | 1588 | return hasValue(fl) |
1526 | 1589 | } |
1527 | 1590 | |
1528 | // ExcludedWithout is the validation function | |
1591 | // excludedWithout is the validation function | |
1529 | 1592 | // The field under validation must not be present or is empty when any of the other specified fields are not present. |
1530 | 1593 | func excludedWithout(fl FieldLevel) bool { |
1531 | 1594 | if requireCheckFieldKind(fl, strings.TrimSpace(fl.Param()), true) { |
1534 | 1597 | return true |
1535 | 1598 | } |
1536 | 1599 | |
1537 | // RequiredWithout is the validation function | |
1600 | // requiredWithout is the validation function | |
1538 | 1601 | // The field under validation must be present and not empty only when any of the other specified fields are not present. |
1539 | 1602 | func requiredWithout(fl FieldLevel) bool { |
1540 | 1603 | if requireCheckFieldKind(fl, strings.TrimSpace(fl.Param()), true) { |
1543 | 1606 | return true |
1544 | 1607 | } |
1545 | 1608 | |
1546 | // RequiredWithoutAll is the validation function | |
1609 | // excludedWithoutAll is the validation function | |
1547 | 1610 | // The field under validation must not be present or is empty when all of the other specified fields are not present. |
1548 | 1611 | func excludedWithoutAll(fl FieldLevel) bool { |
1549 | 1612 | params := parseOneOfParam2(fl.Param()) |
1555 | 1618 | return !hasValue(fl) |
1556 | 1619 | } |
1557 | 1620 | |
1558 | // RequiredWithoutAll is the validation function | |
1621 | // requiredWithoutAll is the validation function | |
1559 | 1622 | // The field under validation must be present and not empty only when all of the other specified fields are not present. |
1560 | 1623 | func requiredWithoutAll(fl FieldLevel) bool { |
1561 | 1624 | params := parseOneOfParam2(fl.Param()) |
1567 | 1630 | return hasValue(fl) |
1568 | 1631 | } |
1569 | 1632 | |
1570 | // IsGteField is the validation function for validating if the current field's value is greater than or equal to the field specified by the param's value. | |
1633 | // isGteField is the validation function for validating if the current field's value is greater than or equal to the field specified by the param's value. | |
1571 | 1634 | func isGteField(fl FieldLevel) bool { |
1572 | 1635 | |
1573 | 1636 | field := fl.Field() |
1614 | 1677 | return len(field.String()) >= len(currentField.String()) |
1615 | 1678 | } |
1616 | 1679 | |
1617 | // IsGtField is the validation function for validating if the current field's value is greater than the field specified by the param's value. | |
1680 | // isGtField is the validation function for validating if the current field's value is greater than the field specified by the param's value. | |
1618 | 1681 | func isGtField(fl FieldLevel) bool { |
1619 | 1682 | |
1620 | 1683 | field := fl.Field() |
1661 | 1724 | return len(field.String()) > len(currentField.String()) |
1662 | 1725 | } |
1663 | 1726 | |
1664 | // IsGte is the validation function for validating if the current field's value is greater than or equal to the param's value. | |
1727 | // isGte is the validation function for validating if the current field's value is greater than or equal to the param's value. | |
1665 | 1728 | func isGte(fl FieldLevel) bool { |
1666 | 1729 | |
1667 | 1730 | field := fl.Field() |
1708 | 1771 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) |
1709 | 1772 | } |
1710 | 1773 | |
1711 | // IsGt is the validation function for validating if the current field's value is greater than the param's value. | |
1774 | // isGt is the validation function for validating if the current field's value is greater than the param's value. | |
1712 | 1775 | func isGt(fl FieldLevel) bool { |
1713 | 1776 | |
1714 | 1777 | field := fl.Field() |
1751 | 1814 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) |
1752 | 1815 | } |
1753 | 1816 | |
1754 | // HasLengthOf is the validation function for validating if the current field's value is equal to the param's value. | |
1817 | // hasLengthOf is the validation function for validating if the current field's value is equal to the param's value. | |
1755 | 1818 | func hasLengthOf(fl FieldLevel) bool { |
1756 | 1819 | |
1757 | 1820 | field := fl.Field() |
1788 | 1851 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) |
1789 | 1852 | } |
1790 | 1853 | |
1791 | // HasMinOf is the validation function for validating if the current field's value is greater than or equal to the param's value. | |
1854 | // hasMinOf is the validation function for validating if the current field's value is greater than or equal to the param's value. | |
1792 | 1855 | func hasMinOf(fl FieldLevel) bool { |
1793 | 1856 | return isGte(fl) |
1794 | 1857 | } |
1795 | 1858 | |
1796 | // IsLteField is the validation function for validating if the current field's value is less than or equal to the field specified by the param's value. | |
1859 | // isLteField is the validation function for validating if the current field's value is less than or equal to the field specified by the param's value. | |
1797 | 1860 | func isLteField(fl FieldLevel) bool { |
1798 | 1861 | |
1799 | 1862 | field := fl.Field() |
1840 | 1903 | return len(field.String()) <= len(currentField.String()) |
1841 | 1904 | } |
1842 | 1905 | |
1843 | // IsLtField is the validation function for validating if the current field's value is less than the field specified by the param's value. | |
1906 | // isLtField is the validation function for validating if the current field's value is less than the field specified by the param's value. | |
1844 | 1907 | func isLtField(fl FieldLevel) bool { |
1845 | 1908 | |
1846 | 1909 | field := fl.Field() |
1887 | 1950 | return len(field.String()) < len(currentField.String()) |
1888 | 1951 | } |
1889 | 1952 | |
1890 | // IsLte is the validation function for validating if the current field's value is less than or equal to the param's value. | |
1953 | // isLte is the validation function for validating if the current field's value is less than or equal to the param's value. | |
1891 | 1954 | func isLte(fl FieldLevel) bool { |
1892 | 1955 | |
1893 | 1956 | field := fl.Field() |
1934 | 1997 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) |
1935 | 1998 | } |
1936 | 1999 | |
1937 | // IsLt is the validation function for validating if the current field's value is less than the param's value. | |
2000 | // isLt is the validation function for validating if the current field's value is less than the param's value. | |
1938 | 2001 | func isLt(fl FieldLevel) bool { |
1939 | 2002 | |
1940 | 2003 | field := fl.Field() |
1978 | 2041 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) |
1979 | 2042 | } |
1980 | 2043 | |
1981 | // HasMaxOf is the validation function for validating if the current field's value is less than or equal to the param's value. | |
2044 | // hasMaxOf is the validation function for validating if the current field's value is less than or equal to the param's value. | |
1982 | 2045 | func hasMaxOf(fl FieldLevel) bool { |
1983 | 2046 | return isLte(fl) |
1984 | 2047 | } |
1985 | 2048 | |
1986 | // IsTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address. | |
2049 | // isTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address. | |
1987 | 2050 | func isTCP4AddrResolvable(fl FieldLevel) bool { |
1988 | 2051 | |
1989 | 2052 | if !isIP4Addr(fl) { |
1994 | 2057 | return err == nil |
1995 | 2058 | } |
1996 | 2059 | |
1997 | // IsTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address. | |
2060 | // isTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address. | |
1998 | 2061 | func isTCP6AddrResolvable(fl FieldLevel) bool { |
1999 | 2062 | |
2000 | 2063 | if !isIP6Addr(fl) { |
2006 | 2069 | return err == nil |
2007 | 2070 | } |
2008 | 2071 | |
2009 | // IsTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address. | |
2072 | // isTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address. | |
2010 | 2073 | func isTCPAddrResolvable(fl FieldLevel) bool { |
2011 | 2074 | |
2012 | 2075 | if !isIP4Addr(fl) && !isIP6Addr(fl) { |
2018 | 2081 | return err == nil |
2019 | 2082 | } |
2020 | 2083 | |
2021 | // IsUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address. | |
2084 | // isUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address. | |
2022 | 2085 | func isUDP4AddrResolvable(fl FieldLevel) bool { |
2023 | 2086 | |
2024 | 2087 | if !isIP4Addr(fl) { |
2030 | 2093 | return err == nil |
2031 | 2094 | } |
2032 | 2095 | |
2033 | // IsUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address. | |
2096 | // isUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address. | |
2034 | 2097 | func isUDP6AddrResolvable(fl FieldLevel) bool { |
2035 | 2098 | |
2036 | 2099 | if !isIP6Addr(fl) { |
2042 | 2105 | return err == nil |
2043 | 2106 | } |
2044 | 2107 | |
2045 | // IsUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address. | |
2108 | // isUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address. | |
2046 | 2109 | func isUDPAddrResolvable(fl FieldLevel) bool { |
2047 | 2110 | |
2048 | 2111 | if !isIP4Addr(fl) && !isIP6Addr(fl) { |
2054 | 2117 | return err == nil |
2055 | 2118 | } |
2056 | 2119 | |
2057 | // IsIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address. | |
2120 | // isIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address. | |
2058 | 2121 | func isIP4AddrResolvable(fl FieldLevel) bool { |
2059 | 2122 | |
2060 | 2123 | if !isIPv4(fl) { |
2066 | 2129 | return err == nil |
2067 | 2130 | } |
2068 | 2131 | |
2069 | // IsIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address. | |
2132 | // isIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address. | |
2070 | 2133 | func isIP6AddrResolvable(fl FieldLevel) bool { |
2071 | 2134 | |
2072 | 2135 | if !isIPv6(fl) { |
2078 | 2141 | return err == nil |
2079 | 2142 | } |
2080 | 2143 | |
2081 | // IsIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address. | |
2144 | // isIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address. | |
2082 | 2145 | func isIPAddrResolvable(fl FieldLevel) bool { |
2083 | 2146 | |
2084 | 2147 | if !isIP(fl) { |
2090 | 2153 | return err == nil |
2091 | 2154 | } |
2092 | 2155 | |
2093 | // IsUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address. | |
2156 | // isUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address. | |
2094 | 2157 | func isUnixAddrResolvable(fl FieldLevel) bool { |
2095 | 2158 | |
2096 | 2159 | _, err := net.ResolveUnixAddr("unix", fl.Field().String()) |
2144 | 2207 | return fqdnRegexRFC1123.MatchString(val) |
2145 | 2208 | } |
2146 | 2209 | |
2147 | // IsDir is the validation function for validating if the current field's value is a valid directory. | |
2210 | // isDir is the validation function for validating if the current field's value is a valid directory. | |
2148 | 2211 | func isDir(fl FieldLevel) bool { |
2149 | 2212 | field := fl.Field() |
2150 | 2213 | |
2170 | 2233 | } |
2171 | 2234 | |
2172 | 2235 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) |
2236 | } | |
2237 | ||
2238 | // isJWT is the validation function for validating if the current field's value is a valid JWT string. | |
2239 | func isJWT(fl FieldLevel) bool { | |
2240 | return jWTRegex.MatchString(fl.Field().String()) | |
2173 | 2241 | } |
2174 | 2242 | |
2175 | 2243 | // isHostnamePort validates a <dns>:<port> combination for fields typically used for socket address. |
2282 | 2350 | } |
2283 | 2351 | return iso3166_1_alpha_numeric[code] |
2284 | 2352 | } |
2353 | ||
2354 | // isIso31662 is the validation function for validating if the current field's value is a valid iso3166-2 code. | |
2355 | func isIso31662(fl FieldLevel) bool { | |
2356 | val := fl.Field().String() | |
2357 | return iso3166_2[val] | |
2358 | } | |
2359 | ||
2360 | // isBCP47LanguageTag is the validation function for validating if the current field's value is a valid BCP 47 language tag, as parsed by language.Parse | |
2361 | func isBCP47LanguageTag(fl FieldLevel) bool { | |
2362 | field := fl.Field() | |
2363 | ||
2364 | if field.Kind() == reflect.String { | |
2365 | _, err := language.Parse(field.String()) | |
2366 | return err == nil | |
2367 | } | |
2368 | ||
2369 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) | |
2370 | } | |
2371 | ||
2372 | // isIsoBicFormat is the validation function for validating if the current field's value is a valid Business Identifier Code (SWIFT code), defined in ISO 9362 | |
2373 | func isIsoBicFormat(fl FieldLevel) bool { | |
2374 | bicString := fl.Field().String() | |
2375 | ||
2376 | return bicRegex.MatchString(bicString) | |
2377 | } |
159 | 159 | 704: true, 92: true, 850: true, 876: true, 732: true, |
160 | 160 | 887: true, 894: true, 716: true, 248: true, |
161 | 161 | } |
162 | ||
163 | var iso3166_2 = map[string]bool{ | |
164 | "AD-02" : true, "AD-03" : true, "AD-04" : true, "AD-05" : true, "AD-06" : true, | |
165 | "AD-07" : true, "AD-08" : true, "AE-AJ" : true, "AE-AZ" : true, "AE-DU" : true, | |
166 | "AE-FU" : true, "AE-RK" : true, "AE-SH" : true, "AE-UQ" : true, "AF-BAL" : true, | |
167 | "AF-BAM" : true, "AF-BDG" : true, "AF-BDS" : true, "AF-BGL" : true, "AF-DAY" : true, | |
168 | "AF-FRA" : true, "AF-FYB" : true, "AF-GHA" : true, "AF-GHO" : true, "AF-HEL" : true, | |
169 | "AF-HER" : true, "AF-JOW" : true, "AF-KAB" : true, "AF-KAN" : true, "AF-KAP" : true, | |
170 | "AF-KDZ" : true, "AF-KHO" : true, "AF-KNR" : true, "AF-LAG" : true, "AF-LOG" : true, | |
171 | "AF-NAN" : true, "AF-NIM" : true, "AF-NUR" : true, "AF-PAN" : true, "AF-PAR" : true, | |
172 | "AF-PIA" : true, "AF-PKA" : true, "AF-SAM" : true, "AF-SAR" : true, "AF-TAK" : true, | |
173 | "AF-URU" : true, "AF-WAR" : true, "AF-ZAB" : true, "AG-03" : true, "AG-04" : true, | |
174 | "AG-05" : true, "AG-06" : true, "AG-07" : true, "AG-08" : true, "AG-10" : true, | |
175 | "AG-11" : true, "AL-01" : true, "AL-02" : true, "AL-03" : true, "AL-04" : true, | |
176 | "AL-05" : true, "AL-06" : true, "AL-07" : true, "AL-08" : true, "AL-09" : true, | |
177 | "AL-10" : true, "AL-11" : true, "AL-12" : true, "AL-BR" : true, "AL-BU" : true, | |
178 | "AL-DI" : true, "AL-DL" : true, "AL-DR" : true, "AL-DV" : true, "AL-EL" : true, | |
179 | "AL-ER" : true, "AL-FR" : true, "AL-GJ" : true, "AL-GR" : true, "AL-HA" : true, | |
180 | "AL-KA" : true, "AL-KB" : true, "AL-KC" : true, "AL-KO" : true, "AL-KR" : true, | |
181 | "AL-KU" : true, "AL-LB" : true, "AL-LE" : true, "AL-LU" : true, "AL-MK" : true, | |
182 | "AL-MM" : true, "AL-MR" : true, "AL-MT" : true, "AL-PG" : true, "AL-PQ" : true, | |
183 | "AL-PR" : true, "AL-PU" : true, "AL-SH" : true, "AL-SK" : true, "AL-SR" : true, | |
184 | "AL-TE" : true, "AL-TP" : true, "AL-TR" : true, "AL-VL" : true, "AM-AG" : true, | |
185 | "AM-AR" : true, "AM-AV" : true, "AM-ER" : true, "AM-GR" : true, "AM-KT" : true, | |
186 | "AM-LO" : true, "AM-SH" : true, "AM-SU" : true, "AM-TV" : true, "AM-VD" : true, | |
187 | "AO-BGO" : true, "AO-BGU" : true, "AO-BIE" : true, "AO-CAB" : true, "AO-CCU" : true, | |
188 | "AO-CNN" : true, "AO-CNO" : true, "AO-CUS" : true, "AO-HUA" : true, "AO-HUI" : true, | |
189 | "AO-LNO" : true, "AO-LSU" : true, "AO-LUA" : true, "AO-MAL" : true, "AO-MOX" : true, | |
190 | "AO-NAM" : true, "AO-UIG" : true, "AO-ZAI" : true, "AR-A" : true, "AR-B" : true, | |
191 | "AR-C" : true, "AR-D" : true, "AR-E" : true, "AR-G" : true, "AR-H" : true, | |
192 | "AR-J" : true, "AR-K" : true, "AR-L" : true, "AR-M" : true, "AR-N" : true, | |
193 | "AR-P" : true, "AR-Q" : true, "AR-R" : true, "AR-S" : true, "AR-T" : true, | |
194 | "AR-U" : true, "AR-V" : true, "AR-W" : true, "AR-X" : true, "AR-Y" : true, | |
195 | "AR-Z" : true, "AT-1" : true, "AT-2" : true, "AT-3" : true, "AT-4" : true, | |
196 | "AT-5" : true, "AT-6" : true, "AT-7" : true, "AT-8" : true, "AT-9" : true, | |
197 | "AU-ACT" : true, "AU-NSW" : true, "AU-NT" : true, "AU-QLD" : true, "AU-SA" : true, | |
198 | "AU-TAS" : true, "AU-VIC" : true, "AU-WA" : true, "AZ-ABS" : true, "AZ-AGA" : true, | |
199 | "AZ-AGC" : true, "AZ-AGM" : true, "AZ-AGS" : true, "AZ-AGU" : true, "AZ-AST" : true, | |
200 | "AZ-BA" : true, "AZ-BAB" : true, "AZ-BAL" : true, "AZ-BAR" : true, "AZ-BEY" : true, | |
201 | "AZ-BIL" : true, "AZ-CAB" : true, "AZ-CAL" : true, "AZ-CUL" : true, "AZ-DAS" : true, | |
202 | "AZ-FUZ" : true, "AZ-GA" : true, "AZ-GAD" : true, "AZ-GOR" : true, "AZ-GOY" : true, | |
203 | "AZ-GYG" : true, "AZ-HAC" : true, "AZ-IMI" : true, "AZ-ISM" : true, "AZ-KAL" : true, | |
204 | "AZ-KAN" : true, "AZ-KUR" : true, "AZ-LA" : true, "AZ-LAC" : true, "AZ-LAN" : true, | |
205 | "AZ-LER" : true, "AZ-MAS" : true, "AZ-MI" : true, "AZ-NA" : true, "AZ-NEF" : true, | |
206 | "AZ-NV" : true, "AZ-NX" : true, "AZ-OGU" : true, "AZ-ORD" : true, "AZ-QAB" : true, | |
207 | "AZ-QAX" : true, "AZ-QAZ" : true, "AZ-QBA" : true, "AZ-QBI" : true, "AZ-QOB" : true, | |
208 | "AZ-QUS" : true, "AZ-SA" : true, "AZ-SAB" : true, "AZ-SAD" : true, "AZ-SAH" : true, | |
209 | "AZ-SAK" : true, "AZ-SAL" : true, "AZ-SAR" : true, "AZ-SAT" : true, "AZ-SBN" : true, | |
210 | "AZ-SIY" : true, "AZ-SKR" : true, "AZ-SM" : true, "AZ-SMI" : true, "AZ-SMX" : true, | |
211 | "AZ-SR" : true, "AZ-SUS" : true, "AZ-TAR" : true, "AZ-TOV" : true, "AZ-UCA" : true, | |
212 | "AZ-XA" : true, "AZ-XAC" : true, "AZ-XCI" : true, "AZ-XIZ" : true, "AZ-XVD" : true, | |
213 | "AZ-YAR" : true, "AZ-YE" : true, "AZ-YEV" : true, "AZ-ZAN" : true, "AZ-ZAQ" : true, | |
214 | "AZ-ZAR" : true, "BA-01" : true, "BA-02" : true, "BA-03" : true, "BA-04" : true, | |
215 | "BA-05" : true, "BA-06" : true, "BA-07" : true, "BA-08" : true, "BA-09" : true, | |
216 | "BA-10" : true, "BA-BIH" : true, "BA-BRC" : true, "BA-SRP" : true, "BB-01" : true, | |
217 | "BB-02" : true, "BB-03" : true, "BB-04" : true, "BB-05" : true, "BB-06" : true, | |
218 | "BB-07" : true, "BB-08" : true, "BB-09" : true, "BB-10" : true, "BB-11" : true, | |
219 | "BD-01" : true, "BD-02" : true, "BD-03" : true, "BD-04" : true, "BD-05" : true, | |
220 | "BD-06" : true, "BD-07" : true, "BD-08" : true, "BD-09" : true, "BD-10" : true, | |
221 | "BD-11" : true, "BD-12" : true, "BD-13" : true, "BD-14" : true, "BD-15" : true, | |
222 | "BD-16" : true, "BD-17" : true, "BD-18" : true, "BD-19" : true, "BD-20" : true, | |
223 | "BD-21" : true, "BD-22" : true, "BD-23" : true, "BD-24" : true, "BD-25" : true, | |
224 | "BD-26" : true, "BD-27" : true, "BD-28" : true, "BD-29" : true, "BD-30" : true, | |
225 | "BD-31" : true, "BD-32" : true, "BD-33" : true, "BD-34" : true, "BD-35" : true, | |
226 | "BD-36" : true, "BD-37" : true, "BD-38" : true, "BD-39" : true, "BD-40" : true, | |
227 | "BD-41" : true, "BD-42" : true, "BD-43" : true, "BD-44" : true, "BD-45" : true, | |
228 | "BD-46" : true, "BD-47" : true, "BD-48" : true, "BD-49" : true, "BD-50" : true, | |
229 | "BD-51" : true, "BD-52" : true, "BD-53" : true, "BD-54" : true, "BD-55" : true, | |
230 | "BD-56" : true, "BD-57" : true, "BD-58" : true, "BD-59" : true, "BD-60" : true, | |
231 | "BD-61" : true, "BD-62" : true, "BD-63" : true, "BD-64" : true, "BD-A" : true, | |
232 | "BD-B" : true, "BD-C" : true, "BD-D" : true, "BD-E" : true, "BD-F" : true, | |
233 | "BD-G" : true, "BE-BRU" : true, "BE-VAN" : true, "BE-VBR" : true, "BE-VLG" : true, | |
234 | "BE-VLI" : true, "BE-VOV" : true, "BE-VWV" : true, "BE-WAL" : true, "BE-WBR" : true, | |
235 | "BE-WHT" : true, "BE-WLG" : true, "BE-WLX" : true, "BE-WNA" : true, "BF-01" : true, | |
236 | "BF-02" : true, "BF-03" : true, "BF-04" : true, "BF-05" : true, "BF-06" : true, | |
237 | "BF-07" : true, "BF-08" : true, "BF-09" : true, "BF-10" : true, "BF-11" : true, | |
238 | "BF-12" : true, "BF-13" : true, "BF-BAL" : true, "BF-BAM" : true, "BF-BAN" : true, | |
239 | "BF-BAZ" : true, "BF-BGR" : true, "BF-BLG" : true, "BF-BLK" : true, "BF-COM" : true, | |
240 | "BF-GAN" : true, "BF-GNA" : true, "BF-GOU" : true, "BF-HOU" : true, "BF-IOB" : true, | |
241 | "BF-KAD" : true, "BF-KEN" : true, "BF-KMD" : true, "BF-KMP" : true, "BF-KOP" : true, | |
242 | "BF-KOS" : true, "BF-KOT" : true, "BF-KOW" : true, "BF-LER" : true, "BF-LOR" : true, | |
243 | "BF-MOU" : true, "BF-NAM" : true, "BF-NAO" : true, "BF-NAY" : true, "BF-NOU" : true, | |
244 | "BF-OUB" : true, "BF-OUD" : true, "BF-PAS" : true, "BF-PON" : true, "BF-SEN" : true, | |
245 | "BF-SIS" : true, "BF-SMT" : true, "BF-SNG" : true, "BF-SOM" : true, "BF-SOR" : true, | |
246 | "BF-TAP" : true, "BF-TUI" : true, "BF-YAG" : true, "BF-YAT" : true, "BF-ZIR" : true, | |
247 | "BF-ZON" : true, "BF-ZOU" : true, "BG-01" : true, "BG-02" : true, "BG-03" : true, | |
248 | "BG-04" : true, "BG-05" : true, "BG-06" : true, "BG-07" : true, "BG-08" : true, | |
249 | "BG-09" : true, "BG-10" : true, "BG-11" : true, "BG-12" : true, "BG-13" : true, | |
250 | "BG-14" : true, "BG-15" : true, "BG-16" : true, "BG-17" : true, "BG-18" : true, | |
251 | "BG-19" : true, "BG-20" : true, "BG-21" : true, "BG-22" : true, "BG-23" : true, | |
252 | "BG-24" : true, "BG-25" : true, "BG-26" : true, "BG-27" : true, "BG-28" : true, | |
253 | "BH-13" : true, "BH-14" : true, "BH-15" : true, "BH-16" : true, "BH-17" : true, | |
254 | "BI-BB" : true, "BI-BL" : true, "BI-BM" : true, "BI-BR" : true, "BI-CA" : true, | |
255 | "BI-CI" : true, "BI-GI" : true, "BI-KI" : true, "BI-KR" : true, "BI-KY" : true, | |
256 | "BI-MA" : true, "BI-MU" : true, "BI-MW" : true, "BI-NG" : true, "BI-RT" : true, | |
257 | "BI-RY" : true, "BJ-AK" : true, "BJ-AL" : true, "BJ-AQ" : true, "BJ-BO" : true, | |
258 | "BJ-CO" : true, "BJ-DO" : true, "BJ-KO" : true, "BJ-LI" : true, "BJ-MO" : true, | |
259 | "BJ-OU" : true, "BJ-PL" : true, "BJ-ZO" : true, "BN-BE" : true, "BN-BM" : true, | |
260 | "BN-TE" : true, "BN-TU" : true, "BO-B" : true, "BO-C" : true, "BO-H" : true, | |
261 | "BO-L" : true, "BO-N" : true, "BO-O" : true, "BO-P" : true, "BO-S" : true, | |
262 | "BO-T" : true, "BQ-BO" : true, "BQ-SA" : true, "BQ-SE" : true, "BR-AC" : true, | |
263 | "BR-AL" : true, "BR-AM" : true, "BR-AP" : true, "BR-BA" : true, "BR-CE" : true, | |
264 | "BR-DF" : true, "BR-ES" : true, "BR-FN" : true, "BR-GO" : true, "BR-MA" : true, | |
265 | "BR-MG" : true, "BR-MS" : true, "BR-MT" : true, "BR-PA" : true, "BR-PB" : true, | |
266 | "BR-PE" : true, "BR-PI" : true, "BR-PR" : true, "BR-RJ" : true, "BR-RN" : true, | |
267 | "BR-RO" : true, "BR-RR" : true, "BR-RS" : true, "BR-SC" : true, "BR-SE" : true, | |
268 | "BR-SP" : true, "BR-TO" : true, "BS-AK" : true, "BS-BI" : true, "BS-BP" : true, | |
269 | "BS-BY" : true, "BS-CE" : true, "BS-CI" : true, "BS-CK" : true, "BS-CO" : true, | |
270 | "BS-CS" : true, "BS-EG" : true, "BS-EX" : true, "BS-FP" : true, "BS-GC" : true, | |
271 | "BS-HI" : true, "BS-HT" : true, "BS-IN" : true, "BS-LI" : true, "BS-MC" : true, | |
272 | "BS-MG" : true, "BS-MI" : true, "BS-NE" : true, "BS-NO" : true, "BS-NS" : true, | |
273 | "BS-RC" : true, "BS-RI" : true, "BS-SA" : true, "BS-SE" : true, "BS-SO" : true, | |
274 | "BS-SS" : true, "BS-SW" : true, "BS-WG" : true, "BT-11" : true, "BT-12" : true, | |
275 | "BT-13" : true, "BT-14" : true, "BT-15" : true, "BT-21" : true, "BT-22" : true, | |
276 | "BT-23" : true, "BT-24" : true, "BT-31" : true, "BT-32" : true, "BT-33" : true, | |
277 | "BT-34" : true, "BT-41" : true, "BT-42" : true, "BT-43" : true, "BT-44" : true, | |
278 | "BT-45" : true, "BT-GA" : true, "BT-TY" : true, "BW-CE" : true, "BW-GH" : true, | |
279 | "BW-KG" : true, "BW-KL" : true, "BW-KW" : true, "BW-NE" : true, "BW-NW" : true, | |
280 | "BW-SE" : true, "BW-SO" : true, "BY-BR" : true, "BY-HM" : true, "BY-HO" : true, | |
281 | "BY-HR" : true, "BY-MA" : true, "BY-MI" : true, "BY-VI" : true, "BZ-BZ" : true, | |
282 | "BZ-CY" : true, "BZ-CZL" : true, "BZ-OW" : true, "BZ-SC" : true, "BZ-TOL" : true, | |
283 | "CA-AB" : true, "CA-BC" : true, "CA-MB" : true, "CA-NB" : true, "CA-NL" : true, | |
284 | "CA-NS" : true, "CA-NT" : true, "CA-NU" : true, "CA-ON" : true, "CA-PE" : true, | |
285 | "CA-QC" : true, "CA-SK" : true, "CA-YT" : true, "CD-BC" : true, "CD-BN" : true, | |
286 | "CD-EQ" : true, "CD-KA" : true, "CD-KE" : true, "CD-KN" : true, "CD-KW" : true, | |
287 | "CD-MA" : true, "CD-NK" : true, "CD-OR" : true, "CD-SK" : true, "CF-AC" : true, | |
288 | "CF-BB" : true, "CF-BGF" : true, "CF-BK" : true, "CF-HK" : true, "CF-HM" : true, | |
289 | "CF-HS" : true, "CF-KB" : true, "CF-KG" : true, "CF-LB" : true, "CF-MB" : true, | |
290 | "CF-MP" : true, "CF-NM" : true, "CF-OP" : true, "CF-SE" : true, "CF-UK" : true, | |
291 | "CF-VK" : true, "CG-11" : true, "CG-12" : true, "CG-13" : true, "CG-14" : true, | |
292 | "CG-15" : true, "CG-2" : true, "CG-5" : true, "CG-7" : true, "CG-8" : true, | |
293 | "CG-9" : true, "CG-BZV" : true, "CH-AG" : true, "CH-AI" : true, "CH-AR" : true, | |
294 | "CH-BE" : true, "CH-BL" : true, "CH-BS" : true, "CH-FR" : true, "CH-GE" : true, | |
295 | "CH-GL" : true, "CH-GR" : true, "CH-JU" : true, "CH-LU" : true, "CH-NE" : true, | |
296 | "CH-NW" : true, "CH-OW" : true, "CH-SG" : true, "CH-SH" : true, "CH-SO" : true, | |
297 | "CH-SZ" : true, "CH-TG" : true, "CH-TI" : true, "CH-UR" : true, "CH-VD" : true, | |
298 | "CH-VS" : true, "CH-ZG" : true, "CH-ZH" : true, "CI-01" : true, "CI-02" : true, | |
299 | "CI-03" : true, "CI-04" : true, "CI-05" : true, "CI-06" : true, "CI-07" : true, | |
300 | "CI-08" : true, "CI-09" : true, "CI-10" : true, "CI-11" : true, "CI-12" : true, | |
301 | "CI-13" : true, "CI-14" : true, "CI-15" : true, "CI-16" : true, "CI-17" : true, | |
302 | "CI-18" : true, "CI-19" : true, "CL-AI" : true, "CL-AN" : true, "CL-AP" : true, | |
303 | "CL-AR" : true, "CL-AT" : true, "CL-BI" : true, "CL-CO" : true, "CL-LI" : true, | |
304 | "CL-LL" : true, "CL-LR" : true, "CL-MA" : true, "CL-ML" : true, "CL-RM" : true, | |
305 | "CL-TA" : true, "CL-VS" : true, "CM-AD" : true, "CM-CE" : true, "CM-EN" : true, | |
306 | "CM-ES" : true, "CM-LT" : true, "CM-NO" : true, "CM-NW" : true, "CM-OU" : true, | |
307 | "CM-SU" : true, "CM-SW" : true, "CN-11" : true, "CN-12" : true, "CN-13" : true, | |
308 | "CN-14" : true, "CN-15" : true, "CN-21" : true, "CN-22" : true, "CN-23" : true, | |
309 | "CN-31" : true, "CN-32" : true, "CN-33" : true, "CN-34" : true, "CN-35" : true, | |
310 | "CN-36" : true, "CN-37" : true, "CN-41" : true, "CN-42" : true, "CN-43" : true, | |
311 | "CN-44" : true, "CN-45" : true, "CN-46" : true, "CN-50" : true, "CN-51" : true, | |
312 | "CN-52" : true, "CN-53" : true, "CN-54" : true, "CN-61" : true, "CN-62" : true, | |
313 | "CN-63" : true, "CN-64" : true, "CN-65" : true, "CN-71" : true, "CN-91" : true, | |
314 | "CN-92" : true, "CO-AMA" : true, "CO-ANT" : true, "CO-ARA" : true, "CO-ATL" : true, | |
315 | "CO-BOL" : true, "CO-BOY" : true, "CO-CAL" : true, "CO-CAQ" : true, "CO-CAS" : true, | |
316 | "CO-CAU" : true, "CO-CES" : true, "CO-CHO" : true, "CO-COR" : true, "CO-CUN" : true, | |
317 | "CO-DC" : true, "CO-GUA" : true, "CO-GUV" : true, "CO-HUI" : true, "CO-LAG" : true, | |
318 | "CO-MAG" : true, "CO-MET" : true, "CO-NAR" : true, "CO-NSA" : true, "CO-PUT" : true, | |
319 | "CO-QUI" : true, "CO-RIS" : true, "CO-SAN" : true, "CO-SAP" : true, "CO-SUC" : true, | |
320 | "CO-TOL" : true, "CO-VAC" : true, "CO-VAU" : true, "CO-VID" : true, "CR-A" : true, | |
321 | "CR-C" : true, "CR-G" : true, "CR-H" : true, "CR-L" : true, "CR-P" : true, | |
322 | "CR-SJ" : true, "CU-01" : true, "CU-02" : true, "CU-03" : true, "CU-04" : true, | |
323 | "CU-05" : true, "CU-06" : true, "CU-07" : true, "CU-08" : true, "CU-09" : true, | |
324 | "CU-10" : true, "CU-11" : true, "CU-12" : true, "CU-13" : true, "CU-14" : true, | |
325 | "CU-99" : true, "CV-B" : true, "CV-BR" : true, "CV-BV" : true, "CV-CA" : true, | |
326 | "CV-CF" : true, "CV-CR" : true, "CV-MA" : true, "CV-MO" : true, "CV-PA" : true, | |
327 | "CV-PN" : true, "CV-PR" : true, "CV-RB" : true, "CV-RG" : true, "CV-RS" : true, | |
328 | "CV-S" : true, "CV-SD" : true, "CV-SF" : true, "CV-SL" : true, "CV-SM" : true, | |
329 | "CV-SO" : true, "CV-SS" : true, "CV-SV" : true, "CV-TA" : true, "CV-TS" : true, | |
330 | "CY-01" : true, "CY-02" : true, "CY-03" : true, "CY-04" : true, "CY-05" : true, | |
331 | "CY-06" : true, "CZ-10" : true, "CZ-101" : true, "CZ-102" : true, "CZ-103" : true, | |
332 | "CZ-104" : true, "CZ-105" : true, "CZ-106" : true, "CZ-107" : true, "CZ-108" : true, | |
333 | "CZ-109" : true, "CZ-110" : true, "CZ-111" : true, "CZ-112" : true, "CZ-113" : true, | |
334 | "CZ-114" : true, "CZ-115" : true, "CZ-116" : true, "CZ-117" : true, "CZ-118" : true, | |
335 | "CZ-119" : true, "CZ-120" : true, "CZ-121" : true, "CZ-122" : true, "CZ-20" : true, | |
336 | "CZ-201" : true, "CZ-202" : true, "CZ-203" : true, "CZ-204" : true, "CZ-205" : true, | |
337 | "CZ-206" : true, "CZ-207" : true, "CZ-208" : true, "CZ-209" : true, "CZ-20A" : true, | |
338 | "CZ-20B" : true, "CZ-20C" : true, "CZ-31" : true, "CZ-311" : true, "CZ-312" : true, | |
339 | "CZ-313" : true, "CZ-314" : true, "CZ-315" : true, "CZ-316" : true, "CZ-317" : true, | |
340 | "CZ-32" : true, "CZ-321" : true, "CZ-322" : true, "CZ-323" : true, "CZ-324" : true, | |
341 | "CZ-325" : true, "CZ-326" : true, "CZ-327" : true, "CZ-41" : true, "CZ-411" : true, | |
342 | "CZ-412" : true, "CZ-413" : true, "CZ-42" : true, "CZ-421" : true, "CZ-422" : true, | |
343 | "CZ-423" : true, "CZ-424" : true, "CZ-425" : true, "CZ-426" : true, "CZ-427" : true, | |
344 | "CZ-51" : true, "CZ-511" : true, "CZ-512" : true, "CZ-513" : true, "CZ-514" : true, | |
345 | "CZ-52" : true, "CZ-521" : true, "CZ-522" : true, "CZ-523" : true, "CZ-524" : true, | |
346 | "CZ-525" : true, "CZ-53" : true, "CZ-531" : true, "CZ-532" : true, "CZ-533" : true, | |
347 | "CZ-534" : true, "CZ-63" : true, "CZ-631" : true, "CZ-632" : true, "CZ-633" : true, | |
348 | "CZ-634" : true, "CZ-635" : true, "CZ-64" : true, "CZ-641" : true, "CZ-642" : true, | |
349 | "CZ-643" : true, "CZ-644" : true, "CZ-645" : true, "CZ-646" : true, "CZ-647" : true, | |
350 | "CZ-71" : true, "CZ-711" : true, "CZ-712" : true, "CZ-713" : true, "CZ-714" : true, | |
351 | "CZ-715" : true, "CZ-72" : true, "CZ-721" : true, "CZ-722" : true, "CZ-723" : true, | |
352 | "CZ-724" : true, "CZ-80" : true, "CZ-801" : true, "CZ-802" : true, "CZ-803" : true, | |
353 | "CZ-804" : true, "CZ-805" : true, "CZ-806" : true, "DE-BB" : true, "DE-BE" : true, | |
354 | "DE-BW" : true, "DE-BY" : true, "DE-HB" : true, "DE-HE" : true, "DE-HH" : true, | |
355 | "DE-MV" : true, "DE-NI" : true, "DE-NW" : true, "DE-RP" : true, "DE-SH" : true, | |
356 | "DE-SL" : true, "DE-SN" : true, "DE-ST" : true, "DE-TH" : true, "DJ-AR" : true, | |
357 | "DJ-AS" : true, "DJ-DI" : true, "DJ-DJ" : true, "DJ-OB" : true, "DJ-TA" : true, | |
358 | "DK-81" : true, "DK-82" : true, "DK-83" : true, "DK-84" : true, "DK-85" : true, | |
359 | "DM-01" : true, "DM-02" : true, "DM-03" : true, "DM-04" : true, "DM-05" : true, | |
360 | "DM-06" : true, "DM-07" : true, "DM-08" : true, "DM-09" : true, "DM-10" : true, | |
361 | "DO-01" : true, "DO-02" : true, "DO-03" : true, "DO-04" : true, "DO-05" : true, | |
362 | "DO-06" : true, "DO-07" : true, "DO-08" : true, "DO-09" : true, "DO-10" : true, | |
363 | "DO-11" : true, "DO-12" : true, "DO-13" : true, "DO-14" : true, "DO-15" : true, | |
364 | "DO-16" : true, "DO-17" : true, "DO-18" : true, "DO-19" : true, "DO-20" : true, | |
365 | "DO-21" : true, "DO-22" : true, "DO-23" : true, "DO-24" : true, "DO-25" : true, | |
366 | "DO-26" : true, "DO-27" : true, "DO-28" : true, "DO-29" : true, "DO-30" : true, | |
367 | "DZ-01" : true, "DZ-02" : true, "DZ-03" : true, "DZ-04" : true, "DZ-05" : true, | |
368 | "DZ-06" : true, "DZ-07" : true, "DZ-08" : true, "DZ-09" : true, "DZ-10" : true, | |
369 | "DZ-11" : true, "DZ-12" : true, "DZ-13" : true, "DZ-14" : true, "DZ-15" : true, | |
370 | "DZ-16" : true, "DZ-17" : true, "DZ-18" : true, "DZ-19" : true, "DZ-20" : true, | |
371 | "DZ-21" : true, "DZ-22" : true, "DZ-23" : true, "DZ-24" : true, "DZ-25" : true, | |
372 | "DZ-26" : true, "DZ-27" : true, "DZ-28" : true, "DZ-29" : true, "DZ-30" : true, | |
373 | "DZ-31" : true, "DZ-32" : true, "DZ-33" : true, "DZ-34" : true, "DZ-35" : true, | |
374 | "DZ-36" : true, "DZ-37" : true, "DZ-38" : true, "DZ-39" : true, "DZ-40" : true, | |
375 | "DZ-41" : true, "DZ-42" : true, "DZ-43" : true, "DZ-44" : true, "DZ-45" : true, | |
376 | "DZ-46" : true, "DZ-47" : true, "DZ-48" : true, "EC-A" : true, "EC-B" : true, | |
377 | "EC-C" : true, "EC-D" : true, "EC-E" : true, "EC-F" : true, "EC-G" : true, | |
378 | "EC-H" : true, "EC-I" : true, "EC-L" : true, "EC-M" : true, "EC-N" : true, | |
379 | "EC-O" : true, "EC-P" : true, "EC-R" : true, "EC-S" : true, "EC-SD" : true, | |
380 | "EC-SE" : true, "EC-T" : true, "EC-U" : true, "EC-W" : true, "EC-X" : true, | |
381 | "EC-Y" : true, "EC-Z" : true, "EE-37" : true, "EE-39" : true, "EE-44" : true, | |
382 | "EE-49" : true, "EE-51" : true, "EE-57" : true, "EE-59" : true, "EE-65" : true, | |
383 | "EE-67" : true, "EE-70" : true, "EE-74" : true, "EE-78" : true, "EE-82" : true, | |
384 | "EE-84" : true, "EE-86" : true, "EG-ALX" : true, "EG-ASN" : true, "EG-AST" : true, | |
385 | "EG-BA" : true, "EG-BH" : true, "EG-BNS" : true, "EG-C" : true, "EG-DK" : true, | |
386 | "EG-DT" : true, "EG-FYM" : true, "EG-GH" : true, "EG-GZ" : true, "EG-HU" : true, | |
387 | "EG-IS" : true, "EG-JS" : true, "EG-KB" : true, "EG-KFS" : true, "EG-KN" : true, | |
388 | "EG-MN" : true, "EG-MNF" : true, "EG-MT" : true, "EG-PTS" : true, "EG-SHG" : true, | |
389 | "EG-SHR" : true, "EG-SIN" : true, "EG-SU" : true, "EG-SUZ" : true, "EG-WAD" : true, | |
390 | "ER-AN" : true, "ER-DK" : true, "ER-DU" : true, "ER-GB" : true, "ER-MA" : true, | |
391 | "ER-SK" : true, "ES-A" : true, "ES-AB" : true, "ES-AL" : true, "ES-AN" : true, | |
392 | "ES-AR" : true, "ES-AS" : true, "ES-AV" : true, "ES-B" : true, "ES-BA" : true, | |
393 | "ES-BI" : true, "ES-BU" : true, "ES-C" : true, "ES-CA" : true, "ES-CB" : true, | |
394 | "ES-CC" : true, "ES-CE" : true, "ES-CL" : true, "ES-CM" : true, "ES-CN" : true, | |
395 | "ES-CO" : true, "ES-CR" : true, "ES-CS" : true, "ES-CT" : true, "ES-CU" : true, | |
396 | "ES-EX" : true, "ES-GA" : true, "ES-GC" : true, "ES-GI" : true, "ES-GR" : true, | |
397 | "ES-GU" : true, "ES-H" : true, "ES-HU" : true, "ES-IB" : true, "ES-J" : true, | |
398 | "ES-L" : true, "ES-LE" : true, "ES-LO" : true, "ES-LU" : true, "ES-M" : true, | |
399 | "ES-MA" : true, "ES-MC" : true, "ES-MD" : true, "ES-ML" : true, "ES-MU" : true, | |
400 | "ES-NA" : true, "ES-NC" : true, "ES-O" : true, "ES-OR" : true, "ES-P" : true, | |
401 | "ES-PM" : true, "ES-PO" : true, "ES-PV" : true, "ES-RI" : true, "ES-S" : true, | |
402 | "ES-SA" : true, "ES-SE" : true, "ES-SG" : true, "ES-SO" : true, "ES-SS" : true, | |
403 | "ES-T" : true, "ES-TE" : true, "ES-TF" : true, "ES-TO" : true, "ES-V" : true, | |
404 | "ES-VA" : true, "ES-VC" : true, "ES-VI" : true, "ES-Z" : true, "ES-ZA" : true, | |
405 | "ET-AA" : true, "ET-AF" : true, "ET-AM" : true, "ET-BE" : true, "ET-DD" : true, | |
406 | "ET-GA" : true, "ET-HA" : true, "ET-OR" : true, "ET-SN" : true, "ET-SO" : true, | |
407 | "ET-TI" : true, "FI-01" : true, "FI-02" : true, "FI-03" : true, "FI-04" : true, | |
408 | "FI-05" : true, "FI-06" : true, "FI-07" : true, "FI-08" : true, "FI-09" : true, | |
409 | "FI-10" : true, "FI-11" : true, "FI-12" : true, "FI-13" : true, "FI-14" : true, | |
410 | "FI-15" : true, "FI-16" : true, "FI-17" : true, "FI-18" : true, "FI-19" : true, | |
411 | "FJ-C" : true, "FJ-E" : true, "FJ-N" : true, "FJ-R" : true, "FJ-W" : true, | |
412 | "FM-KSA" : true, "FM-PNI" : true, "FM-TRK" : true, "FM-YAP" : true, "FR-01" : true, | |
413 | "FR-02" : true, "FR-03" : true, "FR-04" : true, "FR-05" : true, "FR-06" : true, | |
414 | "FR-07" : true, "FR-08" : true, "FR-09" : true, "FR-10" : true, "FR-11" : true, | |
415 | "FR-12" : true, "FR-13" : true, "FR-14" : true, "FR-15" : true, "FR-16" : true, | |
416 | "FR-17" : true, "FR-18" : true, "FR-19" : true, "FR-21" : true, "FR-22" : true, | |
417 | "FR-23" : true, "FR-24" : true, "FR-25" : true, "FR-26" : true, "FR-27" : true, | |
418 | "FR-28" : true, "FR-29" : true, "FR-2A" : true, "FR-2B" : true, "FR-30" : true, | |
419 | "FR-31" : true, "FR-32" : true, "FR-33" : true, "FR-34" : true, "FR-35" : true, | |
420 | "FR-36" : true, "FR-37" : true, "FR-38" : true, "FR-39" : true, "FR-40" : true, | |
421 | "FR-41" : true, "FR-42" : true, "FR-43" : true, "FR-44" : true, "FR-45" : true, | |
422 | "FR-46" : true, "FR-47" : true, "FR-48" : true, "FR-49" : true, "FR-50" : true, | |
423 | "FR-51" : true, "FR-52" : true, "FR-53" : true, "FR-54" : true, "FR-55" : true, | |
424 | "FR-56" : true, "FR-57" : true, "FR-58" : true, "FR-59" : true, "FR-60" : true, | |
425 | "FR-61" : true, "FR-62" : true, "FR-63" : true, "FR-64" : true, "FR-65" : true, | |
426 | "FR-66" : true, "FR-67" : true, "FR-68" : true, "FR-69" : true, "FR-70" : true, | |
427 | "FR-71" : true, "FR-72" : true, "FR-73" : true, "FR-74" : true, "FR-75" : true, | |
428 | "FR-76" : true, "FR-77" : true, "FR-78" : true, "FR-79" : true, "FR-80" : true, | |
429 | "FR-81" : true, "FR-82" : true, "FR-83" : true, "FR-84" : true, "FR-85" : true, | |
430 | "FR-86" : true, "FR-87" : true, "FR-88" : true, "FR-89" : true, "FR-90" : true, | |
431 | "FR-91" : true, "FR-92" : true, "FR-93" : true, "FR-94" : true, "FR-95" : true, | |
432 | "FR-ARA" : true, "FR-BFC" : true, "FR-BL" : true, "FR-BRE" : true, "FR-COR" : true, | |
433 | "FR-CP" : true, "FR-CVL" : true, "FR-GES" : true, "FR-GF" : true, "FR-GP" : true, | |
434 | "FR-GUA" : true, "FR-HDF" : true, "FR-IDF" : true, "FR-LRE" : true, "FR-MAY" : true, | |
435 | "FR-MF" : true, "FR-MQ" : true, "FR-NAQ" : true, "FR-NC" : true, "FR-NOR" : true, | |
436 | "FR-OCC" : true, "FR-PAC" : true, "FR-PDL" : true, "FR-PF" : true, "FR-PM" : true, | |
437 | "FR-RE" : true, "FR-TF" : true, "FR-WF" : true, "FR-YT" : true, "GA-1" : true, | |
438 | "GA-2" : true, "GA-3" : true, "GA-4" : true, "GA-5" : true, "GA-6" : true, | |
439 | "GA-7" : true, "GA-8" : true, "GA-9" : true, "GB-ABC" : true, "GB-ABD" : true, | |
440 | "GB-ABE" : true, "GB-AGB" : true, "GB-AGY" : true, "GB-AND" : true, "GB-ANN" : true, | |
441 | "GB-ANS" : true, "GB-BAS" : true, "GB-BBD" : true, "GB-BDF" : true, "GB-BDG" : true, | |
442 | "GB-BEN" : true, "GB-BEX" : true, "GB-BFS" : true, "GB-BGE" : true, "GB-BGW" : true, | |
443 | "GB-BIR" : true, "GB-BKM" : true, "GB-BMH" : true, "GB-BNE" : true, "GB-BNH" : true, | |
444 | "GB-BNS" : true, "GB-BOL" : true, "GB-BPL" : true, "GB-BRC" : true, "GB-BRD" : true, | |
445 | "GB-BRY" : true, "GB-BST" : true, "GB-BUR" : true, "GB-CAM" : true, "GB-CAY" : true, | |
446 | "GB-CBF" : true, "GB-CCG" : true, "GB-CGN" : true, "GB-CHE" : true, "GB-CHW" : true, | |
447 | "GB-CLD" : true, "GB-CLK" : true, "GB-CMA" : true, "GB-CMD" : true, "GB-CMN" : true, | |
448 | "GB-CON" : true, "GB-COV" : true, "GB-CRF" : true, "GB-CRY" : true, "GB-CWY" : true, | |
449 | "GB-DAL" : true, "GB-DBY" : true, "GB-DEN" : true, "GB-DER" : true, "GB-DEV" : true, | |
450 | "GB-DGY" : true, "GB-DNC" : true, "GB-DND" : true, "GB-DOR" : true, "GB-DRS" : true, | |
451 | "GB-DUD" : true, "GB-DUR" : true, "GB-EAL" : true, "GB-EAW" : true, "GB-EAY" : true, | |
452 | "GB-EDH" : true, "GB-EDU" : true, "GB-ELN" : true, "GB-ELS" : true, "GB-ENF" : true, | |
453 | "GB-ENG" : true, "GB-ERW" : true, "GB-ERY" : true, "GB-ESS" : true, "GB-ESX" : true, | |
454 | "GB-FAL" : true, "GB-FIF" : true, "GB-FLN" : true, "GB-FMO" : true, "GB-GAT" : true, | |
455 | "GB-GBN" : true, "GB-GLG" : true, "GB-GLS" : true, "GB-GRE" : true, "GB-GWN" : true, | |
456 | "GB-HAL" : true, "GB-HAM" : true, "GB-HAV" : true, "GB-HCK" : true, "GB-HEF" : true, | |
457 | "GB-HIL" : true, "GB-HLD" : true, "GB-HMF" : true, "GB-HNS" : true, "GB-HPL" : true, | |
458 | "GB-HRT" : true, "GB-HRW" : true, "GB-HRY" : true, "GB-IOS" : true, "GB-IOW" : true, | |
459 | "GB-ISL" : true, "GB-IVC" : true, "GB-KEC" : true, "GB-KEN" : true, "GB-KHL" : true, | |
460 | "GB-KIR" : true, "GB-KTT" : true, "GB-KWL" : true, "GB-LAN" : true, "GB-LBC" : true, | |
461 | "GB-LBH" : true, "GB-LCE" : true, "GB-LDS" : true, "GB-LEC" : true, "GB-LEW" : true, | |
462 | "GB-LIN" : true, "GB-LIV" : true, "GB-LND" : true, "GB-LUT" : true, "GB-MAN" : true, | |
463 | "GB-MDB" : true, "GB-MDW" : true, "GB-MEA" : true, "GB-MIK" : true, "GD-01" : true, | |
464 | "GB-MLN" : true, "GB-MON" : true, "GB-MRT" : true, "GB-MRY" : true, "GB-MTY" : true, | |
465 | "GB-MUL" : true, "GB-NAY" : true, "GB-NBL" : true, "GB-NEL" : true, "GB-NET" : true, | |
466 | "GB-NFK" : true, "GB-NGM" : true, "GB-NIR" : true, "GB-NLK" : true, "GB-NLN" : true, | |
467 | "GB-NMD" : true, "GB-NSM" : true, "GB-NTH" : true, "GB-NTL" : true, "GB-NTT" : true, | |
468 | "GB-NTY" : true, "GB-NWM" : true, "GB-NWP" : true, "GB-NYK" : true, "GB-OLD" : true, | |
469 | "GB-ORK" : true, "GB-OXF" : true, "GB-PEM" : true, "GB-PKN" : true, "GB-PLY" : true, | |
470 | "GB-POL" : true, "GB-POR" : true, "GB-POW" : true, "GB-PTE" : true, "GB-RCC" : true, | |
471 | "GB-RCH" : true, "GB-RCT" : true, "GB-RDB" : true, "GB-RDG" : true, "GB-RFW" : true, | |
472 | "GB-RIC" : true, "GB-ROT" : true, "GB-RUT" : true, "GB-SAW" : true, "GB-SAY" : true, | |
473 | "GB-SCB" : true, "GB-SCT" : true, "GB-SFK" : true, "GB-SFT" : true, "GB-SGC" : true, | |
474 | "GB-SHF" : true, "GB-SHN" : true, "GB-SHR" : true, "GB-SKP" : true, "GB-SLF" : true, | |
475 | "GB-SLG" : true, "GB-SLK" : true, "GB-SND" : true, "GB-SOL" : true, "GB-SOM" : true, | |
476 | "GB-SOS" : true, "GB-SRY" : true, "GB-STE" : true, "GB-STG" : true, "GB-STH" : true, | |
477 | "GB-STN" : true, "GB-STS" : true, "GB-STT" : true, "GB-STY" : true, "GB-SWA" : true, | |
478 | "GB-SWD" : true, "GB-SWK" : true, "GB-TAM" : true, "GB-TFW" : true, "GB-THR" : true, | |
479 | "GB-TOB" : true, "GB-TOF" : true, "GB-TRF" : true, "GB-TWH" : true, "GB-UKM" : true, | |
480 | "GB-VGL" : true, "GB-WAR" : true, "GB-WBK" : true, "GB-WDU" : true, "GB-WFT" : true, | |
481 | "GB-WGN" : true, "GB-WIL" : true, "GB-WKF" : true, "GB-WLL" : true, "GB-WLN" : true, | |
482 | "GB-WLS" : true, "GB-WLV" : true, "GB-WND" : true, "GB-WNM" : true, "GB-WOK" : true, | |
483 | "GB-WOR" : true, "GB-WRL" : true, "GB-WRT" : true, "GB-WRX" : true, "GB-WSM" : true, | |
484 | "GB-WSX" : true, "GB-YOR" : true, "GB-ZET" : true, "GD-02" : true, "GD-03" : true, | |
485 | "GD-04" : true, "GD-05" : true, "GD-06" : true, "GD-10" : true, "GE-AB" : true, | |
486 | "GE-AJ" : true, "GE-GU" : true, "GE-IM" : true, "GE-KA" : true, "GE-KK" : true, | |
487 | "GE-MM" : true, "GE-RL" : true, "GE-SJ" : true, "GE-SK" : true, "GE-SZ" : true, | |
488 | "GE-TB" : true, "GH-AA" : true, "GH-AH" : true, "GH-BA" : true, "GH-CP" : true, | |
489 | "GH-EP" : true, "GH-NP" : true, "GH-TV" : true, "GH-UE" : true, "GH-UW" : true, | |
490 | "GH-WP" : true, "GL-KU" : true, "GL-QA" : true, "GL-QE" : true, "GL-SM" : true, | |
491 | "GM-B" : true, "GM-L" : true, "GM-M" : true, "GM-N" : true, "GM-U" : true, | |
492 | "GM-W" : true, "GN-B" : true, "GN-BE" : true, "GN-BF" : true, "GN-BK" : true, | |
493 | "GN-C" : true, "GN-CO" : true, "GN-D" : true, "GN-DB" : true, "GN-DI" : true, | |
494 | "GN-DL" : true, "GN-DU" : true, "GN-F" : true, "GN-FA" : true, "GN-FO" : true, | |
495 | "GN-FR" : true, "GN-GA" : true, "GN-GU" : true, "GN-K" : true, "GN-KA" : true, | |
496 | "GN-KB" : true, "GN-KD" : true, "GN-KE" : true, "GN-KN" : true, "GN-KO" : true, | |
497 | "GN-KS" : true, "GN-L" : true, "GN-LA" : true, "GN-LE" : true, "GN-LO" : true, | |
498 | "GN-M" : true, "GN-MC" : true, "GN-MD" : true, "GN-ML" : true, "GN-MM" : true, | |
499 | "GN-N" : true, "GN-NZ" : true, "GN-PI" : true, "GN-SI" : true, "GN-TE" : true, | |
500 | "GN-TO" : true, "GN-YO" : true, "GQ-AN" : true, "GQ-BN" : true, "GQ-BS" : true, | |
501 | "GQ-C" : true, "GQ-CS" : true, "GQ-I" : true, "GQ-KN" : true, "GQ-LI" : true, | |
502 | "GQ-WN" : true, "GR-01" : true, "GR-03" : true, "GR-04" : true, "GR-05" : true, | |
503 | "GR-06" : true, "GR-07" : true, "GR-11" : true, "GR-12" : true, "GR-13" : true, | |
504 | "GR-14" : true, "GR-15" : true, "GR-16" : true, "GR-17" : true, "GR-21" : true, | |
505 | "GR-22" : true, "GR-23" : true, "GR-24" : true, "GR-31" : true, "GR-32" : true, | |
506 | "GR-33" : true, "GR-34" : true, "GR-41" : true, "GR-42" : true, "GR-43" : true, | |
507 | "GR-44" : true, "GR-51" : true, "GR-52" : true, "GR-53" : true, "GR-54" : true, | |
508 | "GR-55" : true, "GR-56" : true, "GR-57" : true, "GR-58" : true, "GR-59" : true, | |
509 | "GR-61" : true, "GR-62" : true, "GR-63" : true, "GR-64" : true, "GR-69" : true, | |
510 | "GR-71" : true, "GR-72" : true, "GR-73" : true, "GR-81" : true, "GR-82" : true, | |
511 | "GR-83" : true, "GR-84" : true, "GR-85" : true, "GR-91" : true, "GR-92" : true, | |
512 | "GR-93" : true, "GR-94" : true, "GR-A" : true, "GR-A1" : true, "GR-B" : true, | |
513 | "GR-C" : true, "GR-D" : true, "GR-E" : true, "GR-F" : true, "GR-G" : true, | |
514 | "GR-H" : true, "GR-I" : true, "GR-J" : true, "GR-K" : true, "GR-L" : true, | |
515 | "GR-M" : true, "GT-AV" : true, "GT-BV" : true, "GT-CM" : true, "GT-CQ" : true, | |
516 | "GT-ES" : true, "GT-GU" : true, "GT-HU" : true, "GT-IZ" : true, "GT-JA" : true, | |
517 | "GT-JU" : true, "GT-PE" : true, "GT-PR" : true, "GT-QC" : true, "GT-QZ" : true, | |
518 | "GT-RE" : true, "GT-SA" : true, "GT-SM" : true, "GT-SO" : true, "GT-SR" : true, | |
519 | "GT-SU" : true, "GT-TO" : true, "GT-ZA" : true, "GW-BA" : true, "GW-BL" : true, | |
520 | "GW-BM" : true, "GW-BS" : true, "GW-CA" : true, "GW-GA" : true, "GW-L" : true, | |
521 | "GW-N" : true, "GW-OI" : true, "GW-QU" : true, "GW-S" : true, "GW-TO" : true, | |
522 | "GY-BA" : true, "GY-CU" : true, "GY-DE" : true, "GY-EB" : true, "GY-ES" : true, | |
523 | "GY-MA" : true, "GY-PM" : true, "GY-PT" : true, "GY-UD" : true, "GY-UT" : true, | |
524 | "HN-AT" : true, "HN-CH" : true, "HN-CL" : true, "HN-CM" : true, "HN-CP" : true, | |
525 | "HN-CR" : true, "HN-EP" : true, "HN-FM" : true, "HN-GD" : true, "HN-IB" : true, | |
526 | "HN-IN" : true, "HN-LE" : true, "HN-LP" : true, "HN-OC" : true, "HN-OL" : true, | |
527 | "HN-SB" : true, "HN-VA" : true, "HN-YO" : true, "HR-01" : true, "HR-02" : true, | |
528 | "HR-03" : true, "HR-04" : true, "HR-05" : true, "HR-06" : true, "HR-07" : true, | |
529 | "HR-08" : true, "HR-09" : true, "HR-10" : true, "HR-11" : true, "HR-12" : true, | |
530 | "HR-13" : true, "HR-14" : true, "HR-15" : true, "HR-16" : true, "HR-17" : true, | |
531 | "HR-18" : true, "HR-19" : true, "HR-20" : true, "HR-21" : true, "HT-AR" : true, | |
532 | "HT-CE" : true, "HT-GA" : true, "HT-ND" : true, "HT-NE" : true, "HT-NO" : true, | |
533 | "HT-OU" : true, "HT-SD" : true, "HT-SE" : true, "HU-BA" : true, "HU-BC" : true, | |
534 | "HU-BE" : true, "HU-BK" : true, "HU-BU" : true, "HU-BZ" : true, "HU-CS" : true, | |
535 | "HU-DE" : true, "HU-DU" : true, "HU-EG" : true, "HU-ER" : true, "HU-FE" : true, | |
536 | "HU-GS" : true, "HU-GY" : true, "HU-HB" : true, "HU-HE" : true, "HU-HV" : true, | |
537 | "HU-JN" : true, "HU-KE" : true, "HU-KM" : true, "HU-KV" : true, "HU-MI" : true, | |
538 | "HU-NK" : true, "HU-NO" : true, "HU-NY" : true, "HU-PE" : true, "HU-PS" : true, | |
539 | "HU-SD" : true, "HU-SF" : true, "HU-SH" : true, "HU-SK" : true, "HU-SN" : true, | |
540 | "HU-SO" : true, "HU-SS" : true, "HU-ST" : true, "HU-SZ" : true, "HU-TB" : true, | |
541 | "HU-TO" : true, "HU-VA" : true, "HU-VE" : true, "HU-VM" : true, "HU-ZA" : true, | |
542 | "HU-ZE" : true, "ID-AC" : true, "ID-BA" : true, "ID-BB" : true, "ID-BE" : true, | |
543 | "ID-BT" : true, "ID-GO" : true, "ID-IJ" : true, "ID-JA" : true, "ID-JB" : true, | |
544 | "ID-JI" : true, "ID-JK" : true, "ID-JT" : true, "ID-JW" : true, "ID-KA" : true, | |
545 | "ID-KB" : true, "ID-KI" : true, "ID-KR" : true, "ID-KS" : true, "ID-KT" : true, | |
546 | "ID-LA" : true, "ID-MA" : true, "ID-ML" : true, "ID-MU" : true, "ID-NB" : true, | |
547 | "ID-NT" : true, "ID-NU" : true, "ID-PA" : true, "ID-PB" : true, "ID-RI" : true, | |
548 | "ID-SA" : true, "ID-SB" : true, "ID-SG" : true, "ID-SL" : true, "ID-SM" : true, | |
549 | "ID-SN" : true, "ID-SR" : true, "ID-SS" : true, "ID-ST" : true, "ID-SU" : true, | |
550 | "ID-YO" : true, "IE-C" : true, "IE-CE" : true, "IE-CN" : true, "IE-CO" : true, | |
551 | "IE-CW" : true, "IE-D" : true, "IE-DL" : true, "IE-G" : true, "IE-KE" : true, | |
552 | "IE-KK" : true, "IE-KY" : true, "IE-L" : true, "IE-LD" : true, "IE-LH" : true, | |
553 | "IE-LK" : true, "IE-LM" : true, "IE-LS" : true, "IE-M" : true, "IE-MH" : true, | |
554 | "IE-MN" : true, "IE-MO" : true, "IE-OY" : true, "IE-RN" : true, "IE-SO" : true, | |
555 | "IE-TA" : true, "IE-U" : true, "IE-WD" : true, "IE-WH" : true, "IE-WW" : true, | |
556 | "IE-WX" : true, "IL-D" : true, "IL-HA" : true, "IL-JM" : true, "IL-M" : true, | |
557 | "IL-TA" : true, "IL-Z" : true, "IN-AN" : true, "IN-AP" : true, "IN-AR" : true, | |
558 | "IN-AS" : true, "IN-BR" : true, "IN-CH" : true, "IN-CT" : true, "IN-DD" : true, | |
559 | "IN-DL" : true, "IN-DN" : true, "IN-GA" : true, "IN-GJ" : true, "IN-HP" : true, | |
560 | "IN-HR" : true, "IN-JH" : true, "IN-JK" : true, "IN-KA" : true, "IN-KL" : true, | |
561 | "IN-LD" : true, "IN-MH" : true, "IN-ML" : true, "IN-MN" : true, "IN-MP" : true, | |
562 | "IN-MZ" : true, "IN-NL" : true, "IN-OR" : true, "IN-PB" : true, "IN-PY" : true, | |
563 | "IN-RJ" : true, "IN-SK" : true, "IN-TN" : true, "IN-TR" : true, "IN-UP" : true, | |
564 | "IN-UT" : true, "IN-WB" : true, "IQ-AN" : true, "IQ-AR" : true, "IQ-BA" : true, | |
565 | "IQ-BB" : true, "IQ-BG" : true, "IQ-DA" : true, "IQ-DI" : true, "IQ-DQ" : true, | |
566 | "IQ-KA" : true, "IQ-MA" : true, "IQ-MU" : true, "IQ-NA" : true, "IQ-NI" : true, | |
567 | "IQ-QA" : true, "IQ-SD" : true, "IQ-SW" : true, "IQ-TS" : true, "IQ-WA" : true, | |
568 | "IR-01" : true, "IR-02" : true, "IR-03" : true, "IR-04" : true, "IR-05" : true, | |
569 | "IR-06" : true, "IR-07" : true, "IR-08" : true, "IR-10" : true, "IR-11" : true, | |
570 | "IR-12" : true, "IR-13" : true, "IR-14" : true, "IR-15" : true, "IR-16" : true, | |
571 | "IR-17" : true, "IR-18" : true, "IR-19" : true, "IR-20" : true, "IR-21" : true, | |
572 | "IR-22" : true, "IR-23" : true, "IR-24" : true, "IR-25" : true, "IR-26" : true, | |
573 | "IR-27" : true, "IR-28" : true, "IR-29" : true, "IR-30" : true, "IR-31" : true, | |
574 | "IS-0" : true, "IS-1" : true, "IS-2" : true, "IS-3" : true, "IS-4" : true, | |
575 | "IS-5" : true, "IS-6" : true, "IS-7" : true, "IS-8" : true, "IT-21" : true, | |
576 | "IT-23" : true, "IT-25" : true, "IT-32" : true, "IT-34" : true, "IT-36" : true, | |
577 | "IT-42" : true, "IT-45" : true, "IT-52" : true, "IT-55" : true, "IT-57" : true, | |
578 | "IT-62" : true, "IT-65" : true, "IT-67" : true, "IT-72" : true, "IT-75" : true, | |
579 | "IT-77" : true, "IT-78" : true, "IT-82" : true, "IT-88" : true, "IT-AG" : true, | |
580 | "IT-AL" : true, "IT-AN" : true, "IT-AO" : true, "IT-AP" : true, "IT-AQ" : true, | |
581 | "IT-AR" : true, "IT-AT" : true, "IT-AV" : true, "IT-BA" : true, "IT-BG" : true, | |
582 | "IT-BI" : true, "IT-BL" : true, "IT-BN" : true, "IT-BO" : true, "IT-BR" : true, | |
583 | "IT-BS" : true, "IT-BT" : true, "IT-BZ" : true, "IT-CA" : true, "IT-CB" : true, | |
584 | "IT-CE" : true, "IT-CH" : true, "IT-CI" : true, "IT-CL" : true, "IT-CN" : true, | |
585 | "IT-CO" : true, "IT-CR" : true, "IT-CS" : true, "IT-CT" : true, "IT-CZ" : true, | |
586 | "IT-EN" : true, "IT-FC" : true, "IT-FE" : true, "IT-FG" : true, "IT-FI" : true, | |
587 | "IT-FM" : true, "IT-FR" : true, "IT-GE" : true, "IT-GO" : true, "IT-GR" : true, | |
588 | "IT-IM" : true, "IT-IS" : true, "IT-KR" : true, "IT-LC" : true, "IT-LE" : true, | |
589 | "IT-LI" : true, "IT-LO" : true, "IT-LT" : true, "IT-LU" : true, "IT-MB" : true, | |
590 | "IT-MC" : true, "IT-ME" : true, "IT-MI" : true, "IT-MN" : true, "IT-MO" : true, | |
591 | "IT-MS" : true, "IT-MT" : true, "IT-NA" : true, "IT-NO" : true, "IT-NU" : true, | |
592 | "IT-OG" : true, "IT-OR" : true, "IT-OT" : true, "IT-PA" : true, "IT-PC" : true, | |
593 | "IT-PD" : true, "IT-PE" : true, "IT-PG" : true, "IT-PI" : true, "IT-PN" : true, | |
594 | "IT-PO" : true, "IT-PR" : true, "IT-PT" : true, "IT-PU" : true, "IT-PV" : true, | |
595 | "IT-PZ" : true, "IT-RA" : true, "IT-RC" : true, "IT-RE" : true, "IT-RG" : true, | |
596 | "IT-RI" : true, "IT-RM" : true, "IT-RN" : true, "IT-RO" : true, "IT-SA" : true, | |
597 | "IT-SI" : true, "IT-SO" : true, "IT-SP" : true, "IT-SR" : true, "IT-SS" : true, | |
598 | "IT-SV" : true, "IT-TA" : true, "IT-TE" : true, "IT-TN" : true, "IT-TO" : true, | |
599 | "IT-TP" : true, "IT-TR" : true, "IT-TS" : true, "IT-TV" : true, "IT-UD" : true, | |
600 | "IT-VA" : true, "IT-VB" : true, "IT-VC" : true, "IT-VE" : true, "IT-VI" : true, | |
601 | "IT-VR" : true, "IT-VS" : true, "IT-VT" : true, "IT-VV" : true, "JM-01" : true, | |
602 | "JM-02" : true, "JM-03" : true, "JM-04" : true, "JM-05" : true, "JM-06" : true, | |
603 | "JM-07" : true, "JM-08" : true, "JM-09" : true, "JM-10" : true, "JM-11" : true, | |
604 | "JM-12" : true, "JM-13" : true, "JM-14" : true, "JO-AJ" : true, "JO-AM" : true, | |
605 | "JO-AQ" : true, "JO-AT" : true, "JO-AZ" : true, "JO-BA" : true, "JO-IR" : true, | |
606 | "JO-JA" : true, "JO-KA" : true, "JO-MA" : true, "JO-MD" : true, "JO-MN" : true, | |
607 | "JP-01" : true, "JP-02" : true, "JP-03" : true, "JP-04" : true, "JP-05" : true, | |
608 | "JP-06" : true, "JP-07" : true, "JP-08" : true, "JP-09" : true, "JP-10" : true, | |
609 | "JP-11" : true, "JP-12" : true, "JP-13" : true, "JP-14" : true, "JP-15" : true, | |
610 | "JP-16" : true, "JP-17" : true, "JP-18" : true, "JP-19" : true, "JP-20" : true, | |
611 | "JP-21" : true, "JP-22" : true, "JP-23" : true, "JP-24" : true, "JP-25" : true, | |
612 | "JP-26" : true, "JP-27" : true, "JP-28" : true, "JP-29" : true, "JP-30" : true, | |
613 | "JP-31" : true, "JP-32" : true, "JP-33" : true, "JP-34" : true, "JP-35" : true, | |
614 | "JP-36" : true, "JP-37" : true, "JP-38" : true, "JP-39" : true, "JP-40" : true, | |
615 | "JP-41" : true, "JP-42" : true, "JP-43" : true, "JP-44" : true, "JP-45" : true, | |
616 | "JP-46" : true, "JP-47" : true, "KE-110" : true, "KE-200" : true, "KE-300" : true, | |
617 | "KE-400" : true, "KE-500" : true, "KE-700" : true, "KE-800" : true, "KG-B" : true, | |
618 | "KG-C" : true, "KG-GB" : true, "KG-J" : true, "KG-N" : true, "KG-O" : true, | |
619 | "KG-T" : true, "KG-Y" : true, "KH-1" : true, "KH-10" : true, "KH-11" : true, | |
620 | "KH-12" : true, "KH-13" : true, "KH-14" : true, "KH-15" : true, "KH-16" : true, | |
621 | "KH-17" : true, "KH-18" : true, "KH-19" : true, "KH-2" : true, "KH-20" : true, | |
622 | "KH-21" : true, "KH-22" : true, "KH-23" : true, "KH-24" : true, "KH-3" : true, | |
623 | "KH-4" : true, "KH-5" : true, "KH-6" : true, "KH-7" : true, "KH-8" : true, | |
624 | "KH-9" : true, "KI-G" : true, "KI-L" : true, "KI-P" : true, "KM-A" : true, | |
625 | "KM-G" : true, "KM-M" : true, "KN-01" : true, "KN-02" : true, "KN-03" : true, | |
626 | "KN-04" : true, "KN-05" : true, "KN-06" : true, "KN-07" : true, "KN-08" : true, | |
627 | "KN-09" : true, "KN-10" : true, "KN-11" : true, "KN-12" : true, "KN-13" : true, | |
628 | "KN-15" : true, "KN-K" : true, "KN-N" : true, "KP-01" : true, "KP-02" : true, | |
629 | "KP-03" : true, "KP-04" : true, "KP-05" : true, "KP-06" : true, "KP-07" : true, | |
630 | "KP-08" : true, "KP-09" : true, "KP-10" : true, "KP-13" : true, "KR-11" : true, | |
631 | "KR-26" : true, "KR-27" : true, "KR-28" : true, "KR-29" : true, "KR-30" : true, | |
632 | "KR-31" : true, "KR-41" : true, "KR-42" : true, "KR-43" : true, "KR-44" : true, | |
633 | "KR-45" : true, "KR-46" : true, "KR-47" : true, "KR-48" : true, "KR-49" : true, | |
634 | "KW-AH" : true, "KW-FA" : true, "KW-HA" : true, "KW-JA" : true, "KW-KU" : true, | |
635 | "KW-MU" : true, "KZ-AKM" : true, "KZ-AKT" : true, "KZ-ALA" : true, "KZ-ALM" : true, | |
636 | "KZ-AST" : true, "KZ-ATY" : true, "KZ-KAR" : true, "KZ-KUS" : true, "KZ-KZY" : true, | |
637 | "KZ-MAN" : true, "KZ-PAV" : true, "KZ-SEV" : true, "KZ-VOS" : true, "KZ-YUZ" : true, | |
638 | "KZ-ZAP" : true, "KZ-ZHA" : true, "LA-AT" : true, "LA-BK" : true, "LA-BL" : true, | |
639 | "LA-CH" : true, "LA-HO" : true, "LA-KH" : true, "LA-LM" : true, "LA-LP" : true, | |
640 | "LA-OU" : true, "LA-PH" : true, "LA-SL" : true, "LA-SV" : true, "LA-VI" : true, | |
641 | "LA-VT" : true, "LA-XA" : true, "LA-XE" : true, "LA-XI" : true, "LA-XS" : true, | |
642 | "LB-AK" : true, "LB-AS" : true, "LB-BA" : true, "LB-BH" : true, "LB-BI" : true, | |
643 | "LB-JA" : true, "LB-JL" : true, "LB-NA" : true, "LI-01" : true, "LI-02" : true, | |
644 | "LI-03" : true, "LI-04" : true, "LI-05" : true, "LI-06" : true, "LI-07" : true, | |
645 | "LI-08" : true, "LI-09" : true, "LI-10" : true, "LI-11" : true, "LK-1" : true, | |
646 | "LK-11" : true, "LK-12" : true, "LK-13" : true, "LK-2" : true, "LK-21" : true, | |
647 | "LK-22" : true, "LK-23" : true, "LK-3" : true, "LK-31" : true, "LK-32" : true, | |
648 | "LK-33" : true, "LK-4" : true, "LK-41" : true, "LK-42" : true, "LK-43" : true, | |
649 | "LK-44" : true, "LK-45" : true, "LK-5" : true, "LK-51" : true, "LK-52" : true, | |
650 | "LK-53" : true, "LK-6" : true, "LK-61" : true, "LK-62" : true, "LK-7" : true, | |
651 | "LK-71" : true, "LK-72" : true, "LK-8" : true, "LK-81" : true, "LK-82" : true, | |
652 | "LK-9" : true, "LK-91" : true, "LK-92" : true, "LR-BG" : true, "LR-BM" : true, | |
653 | "LR-CM" : true, "LR-GB" : true, "LR-GG" : true, "LR-GK" : true, "LR-LO" : true, | |
654 | "LR-MG" : true, "LR-MO" : true, "LR-MY" : true, "LR-NI" : true, "LR-RI" : true, | |
655 | "LR-SI" : true, "LS-A" : true, "LS-B" : true, "LS-C" : true, "LS-D" : true, | |
656 | "LS-E" : true, "LS-F" : true, "LS-G" : true, "LS-H" : true, "LS-J" : true, | |
657 | "LS-K" : true, "LT-AL" : true, "LT-KL" : true, "LT-KU" : true, "LT-MR" : true, | |
658 | "LT-PN" : true, "LT-SA" : true, "LT-TA" : true, "LT-TE" : true, "LT-UT" : true, | |
659 | "LT-VL" : true, "LU-D" : true, "LU-G" : true, "LU-L" : true, "LV-001" : true, | |
660 | "LV-002" : true, "LV-003" : true, "LV-004" : true, "LV-005" : true, "LV-006" : true, | |
661 | "LV-007" : true, "LV-008" : true, "LV-009" : true, "LV-010" : true, "LV-011" : true, | |
662 | "LV-012" : true, "LV-013" : true, "LV-014" : true, "LV-015" : true, "LV-016" : true, | |
663 | "LV-017" : true, "LV-018" : true, "LV-019" : true, "LV-020" : true, "LV-021" : true, | |
664 | "LV-022" : true, "LV-023" : true, "LV-024" : true, "LV-025" : true, "LV-026" : true, | |
665 | "LV-027" : true, "LV-028" : true, "LV-029" : true, "LV-030" : true, "LV-031" : true, | |
666 | "LV-032" : true, "LV-033" : true, "LV-034" : true, "LV-035" : true, "LV-036" : true, | |
667 | "LV-037" : true, "LV-038" : true, "LV-039" : true, "LV-040" : true, "LV-041" : true, | |
668 | "LV-042" : true, "LV-043" : true, "LV-044" : true, "LV-045" : true, "LV-046" : true, | |
669 | "LV-047" : true, "LV-048" : true, "LV-049" : true, "LV-050" : true, "LV-051" : true, | |
670 | "LV-052" : true, "LV-053" : true, "LV-054" : true, "LV-055" : true, "LV-056" : true, | |
671 | "LV-057" : true, "LV-058" : true, "LV-059" : true, "LV-060" : true, "LV-061" : true, | |
672 | "LV-062" : true, "LV-063" : true, "LV-064" : true, "LV-065" : true, "LV-066" : true, | |
673 | "LV-067" : true, "LV-068" : true, "LV-069" : true, "LV-070" : true, "LV-071" : true, | |
674 | "LV-072" : true, "LV-073" : true, "LV-074" : true, "LV-075" : true, "LV-076" : true, | |
675 | "LV-077" : true, "LV-078" : true, "LV-079" : true, "LV-080" : true, "LV-081" : true, | |
676 | "LV-082" : true, "LV-083" : true, "LV-084" : true, "LV-085" : true, "LV-086" : true, | |
677 | "LV-087" : true, "LV-088" : true, "LV-089" : true, "LV-090" : true, "LV-091" : true, | |
678 | "LV-092" : true, "LV-093" : true, "LV-094" : true, "LV-095" : true, "LV-096" : true, | |
679 | "LV-097" : true, "LV-098" : true, "LV-099" : true, "LV-100" : true, "LV-101" : true, | |
680 | "LV-102" : true, "LV-103" : true, "LV-104" : true, "LV-105" : true, "LV-106" : true, | |
681 | "LV-107" : true, "LV-108" : true, "LV-109" : true, "LV-110" : true, "LV-DGV" : true, | |
682 | "LV-JEL" : true, "LV-JKB" : true, "LV-JUR" : true, "LV-LPX" : true, "LV-REZ" : true, | |
683 | "LV-RIX" : true, "LV-VEN" : true, "LV-VMR" : true, "LY-BA" : true, "LY-BU" : true, | |
684 | "LY-DR" : true, "LY-GT" : true, "LY-JA" : true, "LY-JB" : true, "LY-JG" : true, | |
685 | "LY-JI" : true, "LY-JU" : true, "LY-KF" : true, "LY-MB" : true, "LY-MI" : true, | |
686 | "LY-MJ" : true, "LY-MQ" : true, "LY-NL" : true, "LY-NQ" : true, "LY-SB" : true, | |
687 | "LY-SR" : true, "LY-TB" : true, "LY-WA" : true, "LY-WD" : true, "LY-WS" : true, | |
688 | "LY-ZA" : true, "MA-01" : true, "MA-02" : true, "MA-03" : true, "MA-04" : true, | |
689 | "MA-05" : true, "MA-06" : true, "MA-07" : true, "MA-08" : true, "MA-09" : true, | |
690 | "MA-10" : true, "MA-11" : true, "MA-12" : true, "MA-13" : true, "MA-14" : true, | |
691 | "MA-15" : true, "MA-16" : true, "MA-AGD" : true, "MA-AOU" : true, "MA-ASZ" : true, | |
692 | "MA-AZI" : true, "MA-BEM" : true, "MA-BER" : true, "MA-BES" : true, "MA-BOD" : true, | |
693 | "MA-BOM" : true, "MA-CAS" : true, "MA-CHE" : true, "MA-CHI" : true, "MA-CHT" : true, | |
694 | "MA-ERR" : true, "MA-ESI" : true, "MA-ESM" : true, "MA-FAH" : true, "MA-FES" : true, | |
695 | "MA-FIG" : true, "MA-GUE" : true, "MA-HAJ" : true, "MA-HAO" : true, "MA-HOC" : true, | |
696 | "MA-IFR" : true, "MA-INE" : true, "MA-JDI" : true, "MA-JRA" : true, "MA-KEN" : true, | |
697 | "MA-KES" : true, "MA-KHE" : true, "MA-KHN" : true, "MA-KHO" : true, "MA-LAA" : true, | |
698 | "MA-LAR" : true, "MA-MED" : true, "MA-MEK" : true, "MA-MMD" : true, "MA-MMN" : true, | |
699 | "MA-MOH" : true, "MA-MOU" : true, "MA-NAD" : true, "MA-NOU" : true, "MA-OUA" : true, | |
700 | "MA-OUD" : true, "MA-OUJ" : true, "MA-RAB" : true, "MA-SAF" : true, "MA-SAL" : true, | |
701 | "MA-SEF" : true, "MA-SET" : true, "MA-SIK" : true, "MA-SKH" : true, "MA-SYB" : true, | |
702 | "MA-TAI" : true, "MA-TAO" : true, "MA-TAR" : true, "MA-TAT" : true, "MA-TAZ" : true, | |
703 | "MA-TET" : true, "MA-TIZ" : true, "MA-TNG" : true, "MA-TNT" : true, "MA-ZAG" : true, | |
704 | "MC-CL" : true, "MC-CO" : true, "MC-FO" : true, "MC-GA" : true, "MC-JE" : true, | |
705 | "MC-LA" : true, "MC-MA" : true, "MC-MC" : true, "MC-MG" : true, "MC-MO" : true, | |
706 | "MC-MU" : true, "MC-PH" : true, "MC-SD" : true, "MC-SO" : true, "MC-SP" : true, | |
707 | "MC-SR" : true, "MC-VR" : true, "MD-AN" : true, "MD-BA" : true, "MD-BD" : true, | |
708 | "MD-BR" : true, "MD-BS" : true, "MD-CA" : true, "MD-CL" : true, "MD-CM" : true, | |
709 | "MD-CR" : true, "MD-CS" : true, "MD-CT" : true, "MD-CU" : true, "MD-DO" : true, | |
710 | "MD-DR" : true, "MD-DU" : true, "MD-ED" : true, "MD-FA" : true, "MD-FL" : true, | |
711 | "MD-GA" : true, "MD-GL" : true, "MD-HI" : true, "MD-IA" : true, "MD-LE" : true, | |
712 | "MD-NI" : true, "MD-OC" : true, "MD-OR" : true, "MD-RE" : true, "MD-RI" : true, | |
713 | "MD-SD" : true, "MD-SI" : true, "MD-SN" : true, "MD-SO" : true, "MD-ST" : true, | |
714 | "MD-SV" : true, "MD-TA" : true, "MD-TE" : true, "MD-UN" : true, "ME-01" : true, | |
715 | "ME-02" : true, "ME-03" : true, "ME-04" : true, "ME-05" : true, "ME-06" : true, | |
716 | "ME-07" : true, "ME-08" : true, "ME-09" : true, "ME-10" : true, "ME-11" : true, | |
717 | "ME-12" : true, "ME-13" : true, "ME-14" : true, "ME-15" : true, "ME-16" : true, | |
718 | "ME-17" : true, "ME-18" : true, "ME-19" : true, "ME-20" : true, "ME-21" : true, | |
719 | "MG-A" : true, "MG-D" : true, "MG-F" : true, "MG-M" : true, "MG-T" : true, | |
720 | "MG-U" : true, "MH-ALK" : true, "MH-ALL" : true, "MH-ARN" : true, "MH-AUR" : true, | |
721 | "MH-EBO" : true, "MH-ENI" : true, "MH-JAB" : true, "MH-JAL" : true, "MH-KIL" : true, | |
722 | "MH-KWA" : true, "MH-L" : true, "MH-LAE" : true, "MH-LIB" : true, "MH-LIK" : true, | |
723 | "MH-MAJ" : true, "MH-MAL" : true, "MH-MEJ" : true, "MH-MIL" : true, "MH-NMK" : true, | |
724 | "MH-NMU" : true, "MH-RON" : true, "MH-T" : true, "MH-UJA" : true, "MH-UTI" : true, | |
725 | "MH-WTJ" : true, "MH-WTN" : true, "MK-01" : true, "MK-02" : true, "MK-03" : true, | |
726 | "MK-04" : true, "MK-05" : true, "MK-06" : true, "MK-07" : true, "MK-08" : true, | |
727 | "MK-09" : true, "MK-10" : true, "MK-11" : true, "MK-12" : true, "MK-13" : true, | |
728 | "MK-14" : true, "MK-15" : true, "MK-16" : true, "MK-17" : true, "MK-18" : true, | |
729 | "MK-19" : true, "MK-20" : true, "MK-21" : true, "MK-22" : true, "MK-23" : true, | |
730 | "MK-24" : true, "MK-25" : true, "MK-26" : true, "MK-27" : true, "MK-28" : true, | |
731 | "MK-29" : true, "MK-30" : true, "MK-31" : true, "MK-32" : true, "MK-33" : true, | |
732 | "MK-34" : true, "MK-35" : true, "MK-36" : true, "MK-37" : true, "MK-38" : true, | |
733 | "MK-39" : true, "MK-40" : true, "MK-41" : true, "MK-42" : true, "MK-43" : true, | |
734 | "MK-44" : true, "MK-45" : true, "MK-46" : true, "MK-47" : true, "MK-48" : true, | |
735 | "MK-49" : true, "MK-50" : true, "MK-51" : true, "MK-52" : true, "MK-53" : true, | |
736 | "MK-54" : true, "MK-55" : true, "MK-56" : true, "MK-57" : true, "MK-58" : true, | |
737 | "MK-59" : true, "MK-60" : true, "MK-61" : true, "MK-62" : true, "MK-63" : true, | |
738 | "MK-64" : true, "MK-65" : true, "MK-66" : true, "MK-67" : true, "MK-68" : true, | |
739 | "MK-69" : true, "MK-70" : true, "MK-71" : true, "MK-72" : true, "MK-73" : true, | |
740 | "MK-74" : true, "MK-75" : true, "MK-76" : true, "MK-77" : true, "MK-78" : true, | |
741 | "MK-79" : true, "MK-80" : true, "MK-81" : true, "MK-82" : true, "MK-83" : true, | |
742 | "MK-84" : true, "ML-1" : true, "ML-2" : true, "ML-3" : true, "ML-4" : true, | |
743 | "ML-5" : true, "ML-6" : true, "ML-7" : true, "ML-8" : true, "ML-BK0" : true, | |
744 | "MM-01" : true, "MM-02" : true, "MM-03" : true, "MM-04" : true, "MM-05" : true, | |
745 | "MM-06" : true, "MM-07" : true, "MM-11" : true, "MM-12" : true, "MM-13" : true, | |
746 | "MM-14" : true, "MM-15" : true, "MM-16" : true, "MM-17" : true, "MN-035" : true, | |
747 | "MN-037" : true, "MN-039" : true, "MN-041" : true, "MN-043" : true, "MN-046" : true, | |
748 | "MN-047" : true, "MN-049" : true, "MN-051" : true, "MN-053" : true, "MN-055" : true, | |
749 | "MN-057" : true, "MN-059" : true, "MN-061" : true, "MN-063" : true, "MN-064" : true, | |
750 | "MN-065" : true, "MN-067" : true, "MN-069" : true, "MN-071" : true, "MN-073" : true, | |
751 | "MN-1" : true, "MR-01" : true, "MR-02" : true, "MR-03" : true, "MR-04" : true, | |
752 | "MR-05" : true, "MR-06" : true, "MR-07" : true, "MR-08" : true, "MR-09" : true, | |
753 | "MR-10" : true, "MR-11" : true, "MR-12" : true, "MR-NKC" : true, "MT-01" : true, | |
754 | "MT-02" : true, "MT-03" : true, "MT-04" : true, "MT-05" : true, "MT-06" : true, | |
755 | "MT-07" : true, "MT-08" : true, "MT-09" : true, "MT-10" : true, "MT-11" : true, | |
756 | "MT-12" : true, "MT-13" : true, "MT-14" : true, "MT-15" : true, "MT-16" : true, | |
757 | "MT-17" : true, "MT-18" : true, "MT-19" : true, "MT-20" : true, "MT-21" : true, | |
758 | "MT-22" : true, "MT-23" : true, "MT-24" : true, "MT-25" : true, "MT-26" : true, | |
759 | "MT-27" : true, "MT-28" : true, "MT-29" : true, "MT-30" : true, "MT-31" : true, | |
760 | "MT-32" : true, "MT-33" : true, "MT-34" : true, "MT-35" : true, "MT-36" : true, | |
761 | "MT-37" : true, "MT-38" : true, "MT-39" : true, "MT-40" : true, "MT-41" : true, | |
762 | "MT-42" : true, "MT-43" : true, "MT-44" : true, "MT-45" : true, "MT-46" : true, | |
763 | "MT-47" : true, "MT-48" : true, "MT-49" : true, "MT-50" : true, "MT-51" : true, | |
764 | "MT-52" : true, "MT-53" : true, "MT-54" : true, "MT-55" : true, "MT-56" : true, | |
765 | "MT-57" : true, "MT-58" : true, "MT-59" : true, "MT-60" : true, "MT-61" : true, | |
766 | "MT-62" : true, "MT-63" : true, "MT-64" : true, "MT-65" : true, "MT-66" : true, | |
767 | "MT-67" : true, "MT-68" : true, "MU-AG" : true, "MU-BL" : true, "MU-BR" : true, | |
768 | "MU-CC" : true, "MU-CU" : true, "MU-FL" : true, "MU-GP" : true, "MU-MO" : true, | |
769 | "MU-PA" : true, "MU-PL" : true, "MU-PU" : true, "MU-PW" : true, "MU-QB" : true, | |
770 | "MU-RO" : true, "MU-RP" : true, "MU-SA" : true, "MU-VP" : true, "MV-00" : true, | |
771 | "MV-01" : true, "MV-02" : true, "MV-03" : true, "MV-04" : true, "MV-05" : true, | |
772 | "MV-07" : true, "MV-08" : true, "MV-12" : true, "MV-13" : true, "MV-14" : true, | |
773 | "MV-17" : true, "MV-20" : true, "MV-23" : true, "MV-24" : true, "MV-25" : true, | |
774 | "MV-26" : true, "MV-27" : true, "MV-28" : true, "MV-29" : true, "MV-CE" : true, | |
775 | "MV-MLE" : true, "MV-NC" : true, "MV-NO" : true, "MV-SC" : true, "MV-SU" : true, | |
776 | "MV-UN" : true, "MV-US" : true, "MW-BA" : true, "MW-BL" : true, "MW-C" : true, | |
777 | "MW-CK" : true, "MW-CR" : true, "MW-CT" : true, "MW-DE" : true, "MW-DO" : true, | |
778 | "MW-KR" : true, "MW-KS" : true, "MW-LI" : true, "MW-LK" : true, "MW-MC" : true, | |
779 | "MW-MG" : true, "MW-MH" : true, "MW-MU" : true, "MW-MW" : true, "MW-MZ" : true, | |
780 | "MW-N" : true, "MW-NB" : true, "MW-NE" : true, "MW-NI" : true, "MW-NK" : true, | |
781 | "MW-NS" : true, "MW-NU" : true, "MW-PH" : true, "MW-RU" : true, "MW-S" : true, | |
782 | "MW-SA" : true, "MW-TH" : true, "MW-ZO" : true, "MX-AGU" : true, "MX-BCN" : true, | |
783 | "MX-BCS" : true, "MX-CAM" : true, "MX-CHH" : true, "MX-CHP" : true, "MX-COA" : true, | |
784 | "MX-COL" : true, "MX-DIF" : true, "MX-DUR" : true, "MX-GRO" : true, "MX-GUA" : true, | |
785 | "MX-HID" : true, "MX-JAL" : true, "MX-MEX" : true, "MX-MIC" : true, "MX-MOR" : true, | |
786 | "MX-NAY" : true, "MX-NLE" : true, "MX-OAX" : true, "MX-PUE" : true, "MX-QUE" : true, | |
787 | "MX-ROO" : true, "MX-SIN" : true, "MX-SLP" : true, "MX-SON" : true, "MX-TAB" : true, | |
788 | "MX-TAM" : true, "MX-TLA" : true, "MX-VER" : true, "MX-YUC" : true, "MX-ZAC" : true, | |
789 | "MY-01" : true, "MY-02" : true, "MY-03" : true, "MY-04" : true, "MY-05" : true, | |
790 | "MY-06" : true, "MY-07" : true, "MY-08" : true, "MY-09" : true, "MY-10" : true, | |
791 | "MY-11" : true, "MY-12" : true, "MY-13" : true, "MY-14" : true, "MY-15" : true, | |
792 | "MY-16" : true, "MZ-A" : true, "MZ-B" : true, "MZ-G" : true, "MZ-I" : true, | |
793 | "MZ-L" : true, "MZ-MPM" : true, "MZ-N" : true, "MZ-P" : true, "MZ-Q" : true, | |
794 | "MZ-S" : true, "MZ-T" : true, "NA-CA" : true, "NA-ER" : true, "NA-HA" : true, | |
795 | "NA-KA" : true, "NA-KH" : true, "NA-KU" : true, "NA-OD" : true, "NA-OH" : true, | |
796 | "NA-OK" : true, "NA-ON" : true, "NA-OS" : true, "NA-OT" : true, "NA-OW" : true, | |
797 | "NE-1" : true, "NE-2" : true, "NE-3" : true, "NE-4" : true, "NE-5" : true, | |
798 | "NE-6" : true, "NE-7" : true, "NE-8" : true, "NG-AB" : true, "NG-AD" : true, | |
799 | "NG-AK" : true, "NG-AN" : true, "NG-BA" : true, "NG-BE" : true, "NG-BO" : true, | |
800 | "NG-BY" : true, "NG-CR" : true, "NG-DE" : true, "NG-EB" : true, "NG-ED" : true, | |
801 | "NG-EK" : true, "NG-EN" : true, "NG-FC" : true, "NG-GO" : true, "NG-IM" : true, | |
802 | "NG-JI" : true, "NG-KD" : true, "NG-KE" : true, "NG-KN" : true, "NG-KO" : true, | |
803 | "NG-KT" : true, "NG-KW" : true, "NG-LA" : true, "NG-NA" : true, "NG-NI" : true, | |
804 | "NG-OG" : true, "NG-ON" : true, "NG-OS" : true, "NG-OY" : true, "NG-PL" : true, | |
805 | "NG-RI" : true, "NG-SO" : true, "NG-TA" : true, "NG-YO" : true, "NG-ZA" : true, | |
806 | "NI-AN" : true, "NI-AS" : true, "NI-BO" : true, "NI-CA" : true, "NI-CI" : true, | |
807 | "NI-CO" : true, "NI-ES" : true, "NI-GR" : true, "NI-JI" : true, "NI-LE" : true, | |
808 | "NI-MD" : true, "NI-MN" : true, "NI-MS" : true, "NI-MT" : true, "NI-NS" : true, | |
809 | "NI-RI" : true, "NI-SJ" : true, "NL-AW" : true, "NL-BQ1" : true, "NL-BQ2" : true, | |
810 | "NL-BQ3" : true, "NL-CW" : true, "NL-DR" : true, "NL-FL" : true, "NL-FR" : true, | |
811 | "NL-GE" : true, "NL-GR" : true, "NL-LI" : true, "NL-NB" : true, "NL-NH" : true, | |
812 | "NL-OV" : true, "NL-SX" : true, "NL-UT" : true, "NL-ZE" : true, "NL-ZH" : true, | |
813 | "NO-01" : true, "NO-02" : true, "NO-03" : true, "NO-04" : true, "NO-05" : true, | |
814 | "NO-06" : true, "NO-07" : true, "NO-08" : true, "NO-09" : true, "NO-10" : true, | |
815 | "NO-11" : true, "NO-12" : true, "NO-14" : true, "NO-15" : true, "NO-16" : true, | |
816 | "NO-17" : true, "NO-18" : true, "NO-19" : true, "NO-20" : true, "NO-21" : true, | |
817 | "NO-22" : true, "NP-1" : true, "NP-2" : true, "NP-3" : true, "NP-4" : true, | |
818 | "NP-5" : true, "NP-BA" : true, "NP-BH" : true, "NP-DH" : true, "NP-GA" : true, | |
819 | "NP-JA" : true, "NP-KA" : true, "NP-KO" : true, "NP-LU" : true, "NP-MA" : true, | |
820 | "NP-ME" : true, "NP-NA" : true, "NP-RA" : true, "NP-SA" : true, "NP-SE" : true, | |
821 | "NR-01" : true, "NR-02" : true, "NR-03" : true, "NR-04" : true, "NR-05" : true, | |
822 | "NR-06" : true, "NR-07" : true, "NR-08" : true, "NR-09" : true, "NR-10" : true, | |
823 | "NR-11" : true, "NR-12" : true, "NR-13" : true, "NR-14" : true, "NZ-AUK" : true, | |
824 | "NZ-BOP" : true, "NZ-CAN" : true, "NZ-CIT" : true, "NZ-GIS" : true, "NZ-HKB" : true, | |
825 | "NZ-MBH" : true, "NZ-MWT" : true, "NZ-N" : true, "NZ-NSN" : true, "NZ-NTL" : true, | |
826 | "NZ-OTA" : true, "NZ-S" : true, "NZ-STL" : true, "NZ-TAS" : true, "NZ-TKI" : true, | |
827 | "NZ-WGN" : true, "NZ-WKO" : true, "NZ-WTC" : true, "OM-BA" : true, "OM-BU" : true, | |
828 | "OM-DA" : true, "OM-MA" : true, "OM-MU" : true, "OM-SH" : true, "OM-WU" : true, | |
829 | "OM-ZA" : true, "OM-ZU" : true, "PA-1" : true, "PA-2" : true, "PA-3" : true, | |
830 | "PA-4" : true, "PA-5" : true, "PA-6" : true, "PA-7" : true, "PA-8" : true, | |
831 | "PA-9" : true, "PA-EM" : true, "PA-KY" : true, "PA-NB" : true, "PE-AMA" : true, | |
832 | "PE-ANC" : true, "PE-APU" : true, "PE-ARE" : true, "PE-AYA" : true, "PE-CAJ" : true, | |
833 | "PE-CAL" : true, "PE-CUS" : true, "PE-HUC" : true, "PE-HUV" : true, "PE-ICA" : true, | |
834 | "PE-JUN" : true, "PE-LAL" : true, "PE-LAM" : true, "PE-LIM" : true, "PE-LMA" : true, | |
835 | "PE-LOR" : true, "PE-MDD" : true, "PE-MOQ" : true, "PE-PAS" : true, "PE-PIU" : true, | |
836 | "PE-PUN" : true, "PE-SAM" : true, "PE-TAC" : true, "PE-TUM" : true, "PE-UCA" : true, | |
837 | "PG-CPK" : true, "PG-CPM" : true, "PG-EBR" : true, "PG-EHG" : true, "PG-EPW" : true, | |
838 | "PG-ESW" : true, "PG-GPK" : true, "PG-MBA" : true, "PG-MPL" : true, "PG-MPM" : true, | |
839 | "PG-MRL" : true, "PG-NCD" : true, "PG-NIK" : true, "PG-NPP" : true, "PG-NSB" : true, | |
840 | "PG-SAN" : true, "PG-SHM" : true, "PG-WBK" : true, "PG-WHM" : true, "PG-WPD" : true, | |
841 | "PH-00" : true, "PH-01" : true, "PH-02" : true, "PH-03" : true, "PH-05" : true, | |
842 | "PH-06" : true, "PH-07" : true, "PH-08" : true, "PH-09" : true, "PH-10" : true, | |
843 | "PH-11" : true, "PH-12" : true, "PH-13" : true, "PH-14" : true, "PH-15" : true, | |
844 | "PH-40" : true, "PH-41" : true, "PH-ABR" : true, "PH-AGN" : true, "PH-AGS" : true, | |
845 | "PH-AKL" : true, "PH-ALB" : true, "PH-ANT" : true, "PH-APA" : true, "PH-AUR" : true, | |
846 | "PH-BAN" : true, "PH-BAS" : true, "PH-BEN" : true, "PH-BIL" : true, "PH-BOH" : true, | |
847 | "PH-BTG" : true, "PH-BTN" : true, "PH-BUK" : true, "PH-BUL" : true, "PH-CAG" : true, | |
848 | "PH-CAM" : true, "PH-CAN" : true, "PH-CAP" : true, "PH-CAS" : true, "PH-CAT" : true, | |
849 | "PH-CAV" : true, "PH-CEB" : true, "PH-COM" : true, "PH-DAO" : true, "PH-DAS" : true, | |
850 | "PH-DAV" : true, "PH-DIN" : true, "PH-EAS" : true, "PH-GUI" : true, "PH-IFU" : true, | |
851 | "PH-ILI" : true, "PH-ILN" : true, "PH-ILS" : true, "PH-ISA" : true, "PH-KAL" : true, | |
852 | "PH-LAG" : true, "PH-LAN" : true, "PH-LAS" : true, "PH-LEY" : true, "PH-LUN" : true, | |
853 | "PH-MAD" : true, "PH-MAG" : true, "PH-MAS" : true, "PH-MDC" : true, "PH-MDR" : true, | |
854 | "PH-MOU" : true, "PH-MSC" : true, "PH-MSR" : true, "PH-NCO" : true, "PH-NEC" : true, | |
855 | "PH-NER" : true, "PH-NSA" : true, "PH-NUE" : true, "PH-NUV" : true, "PH-PAM" : true, | |
856 | "PH-PAN" : true, "PH-PLW" : true, "PH-QUE" : true, "PH-QUI" : true, "PH-RIZ" : true, | |
857 | "PH-ROM" : true, "PH-SAR" : true, "PH-SCO" : true, "PH-SIG" : true, "PH-SLE" : true, | |
858 | "PH-SLU" : true, "PH-SOR" : true, "PH-SUK" : true, "PH-SUN" : true, "PH-SUR" : true, | |
859 | "PH-TAR" : true, "PH-TAW" : true, "PH-WSA" : true, "PH-ZAN" : true, "PH-ZAS" : true, | |
860 | "PH-ZMB" : true, "PH-ZSI" : true, "PK-BA" : true, "PK-GB" : true, "PK-IS" : true, | |
861 | "PK-JK" : true, "PK-KP" : true, "PK-PB" : true, "PK-SD" : true, "PK-TA" : true, | |
862 | "PL-DS" : true, "PL-KP" : true, "PL-LB" : true, "PL-LD" : true, "PL-LU" : true, | |
863 | "PL-MA" : true, "PL-MZ" : true, "PL-OP" : true, "PL-PD" : true, "PL-PK" : true, | |
864 | "PL-PM" : true, "PL-SK" : true, "PL-SL" : true, "PL-WN" : true, "PL-WP" : true, | |
865 | "PL-ZP" : true, "PS-BTH" : true, "PS-DEB" : true, "PS-GZA" : true, "PS-HBN" : true, | |
866 | "PS-JEM" : true, "PS-JEN" : true, "PS-JRH" : true, "PS-KYS" : true, "PS-NBS" : true, | |
867 | "PS-NGZ" : true, "PS-QQA" : true, "PS-RBH" : true, "PS-RFH" : true, "PS-SLT" : true, | |
868 | "PS-TBS" : true, "PS-TKM" : true, "PT-01" : true, "PT-02" : true, "PT-03" : true, | |
869 | "PT-04" : true, "PT-05" : true, "PT-06" : true, "PT-07" : true, "PT-08" : true, | |
870 | "PT-09" : true, "PT-10" : true, "PT-11" : true, "PT-12" : true, "PT-13" : true, | |
871 | "PT-14" : true, "PT-15" : true, "PT-16" : true, "PT-17" : true, "PT-18" : true, | |
872 | "PT-20" : true, "PT-30" : true, "PW-002" : true, "PW-004" : true, "PW-010" : true, | |
873 | "PW-050" : true, "PW-100" : true, "PW-150" : true, "PW-212" : true, "PW-214" : true, | |
874 | "PW-218" : true, "PW-222" : true, "PW-224" : true, "PW-226" : true, "PW-227" : true, | |
875 | "PW-228" : true, "PW-350" : true, "PW-370" : true, "PY-1" : true, "PY-10" : true, | |
876 | "PY-11" : true, "PY-12" : true, "PY-13" : true, "PY-14" : true, "PY-15" : true, | |
877 | "PY-16" : true, "PY-19" : true, "PY-2" : true, "PY-3" : true, "PY-4" : true, | |
878 | "PY-5" : true, "PY-6" : true, "PY-7" : true, "PY-8" : true, "PY-9" : true, | |
879 | "PY-ASU" : true, "QA-DA" : true, "QA-KH" : true, "QA-MS" : true, "QA-RA" : true, | |
880 | "QA-US" : true, "QA-WA" : true, "QA-ZA" : true, "RO-AB" : true, "RO-AG" : true, | |
881 | "RO-AR" : true, "RO-B" : true, "RO-BC" : true, "RO-BH" : true, "RO-BN" : true, | |
882 | "RO-BR" : true, "RO-BT" : true, "RO-BV" : true, "RO-BZ" : true, "RO-CJ" : true, | |
883 | "RO-CL" : true, "RO-CS" : true, "RO-CT" : true, "RO-CV" : true, "RO-DB" : true, | |
884 | "RO-DJ" : true, "RO-GJ" : true, "RO-GL" : true, "RO-GR" : true, "RO-HD" : true, | |
885 | "RO-HR" : true, "RO-IF" : true, "RO-IL" : true, "RO-IS" : true, "RO-MH" : true, | |
886 | "RO-MM" : true, "RO-MS" : true, "RO-NT" : true, "RO-OT" : true, "RO-PH" : true, | |
887 | "RO-SB" : true, "RO-SJ" : true, "RO-SM" : true, "RO-SV" : true, "RO-TL" : true, | |
888 | "RO-TM" : true, "RO-TR" : true, "RO-VL" : true, "RO-VN" : true, "RO-VS" : true, | |
889 | "RS-00" : true, "RS-01" : true, "RS-02" : true, "RS-03" : true, "RS-04" : true, | |
890 | "RS-05" : true, "RS-06" : true, "RS-07" : true, "RS-08" : true, "RS-09" : true, | |
891 | "RS-10" : true, "RS-11" : true, "RS-12" : true, "RS-13" : true, "RS-14" : true, | |
892 | "RS-15" : true, "RS-16" : true, "RS-17" : true, "RS-18" : true, "RS-19" : true, | |
893 | "RS-20" : true, "RS-21" : true, "RS-22" : true, "RS-23" : true, "RS-24" : true, | |
894 | "RS-25" : true, "RS-26" : true, "RS-27" : true, "RS-28" : true, "RS-29" : true, | |
895 | "RS-KM" : true, "RS-VO" : true, "RU-AD" : true, "RU-AL" : true, "RU-ALT" : true, | |
896 | "RU-AMU" : true, "RU-ARK" : true, "RU-AST" : true, "RU-BA" : true, "RU-BEL" : true, | |
897 | "RU-BRY" : true, "RU-BU" : true, "RU-CE" : true, "RU-CHE" : true, "RU-CHU" : true, | |
898 | "RU-CU" : true, "RU-DA" : true, "RU-IN" : true, "RU-IRK" : true, "RU-IVA" : true, | |
899 | "RU-KAM" : true, "RU-KB" : true, "RU-KC" : true, "RU-KDA" : true, "RU-KEM" : true, | |
900 | "RU-KGD" : true, "RU-KGN" : true, "RU-KHA" : true, "RU-KHM" : true, "RU-KIR" : true, | |
901 | "RU-KK" : true, "RU-KL" : true, "RU-KLU" : true, "RU-KO" : true, "RU-KOS" : true, | |
902 | "RU-KR" : true, "RU-KRS" : true, "RU-KYA" : true, "RU-LEN" : true, "RU-LIP" : true, | |
903 | "RU-MAG" : true, "RU-ME" : true, "RU-MO" : true, "RU-MOS" : true, "RU-MOW" : true, | |
904 | "RU-MUR" : true, "RU-NEN" : true, "RU-NGR" : true, "RU-NIZ" : true, "RU-NVS" : true, | |
905 | "RU-OMS" : true, "RU-ORE" : true, "RU-ORL" : true, "RU-PER" : true, "RU-PNZ" : true, | |
906 | "RU-PRI" : true, "RU-PSK" : true, "RU-ROS" : true, "RU-RYA" : true, "RU-SA" : true, | |
907 | "RU-SAK" : true, "RU-SAM" : true, "RU-SAR" : true, "RU-SE" : true, "RU-SMO" : true, | |
908 | "RU-SPE" : true, "RU-STA" : true, "RU-SVE" : true, "RU-TA" : true, "RU-TAM" : true, | |
909 | "RU-TOM" : true, "RU-TUL" : true, "RU-TVE" : true, "RU-TY" : true, "RU-TYU" : true, | |
910 | "RU-UD" : true, "RU-ULY" : true, "RU-VGG" : true, "RU-VLA" : true, "RU-VLG" : true, | |
911 | "RU-VOR" : true, "RU-YAN" : true, "RU-YAR" : true, "RU-YEV" : true, "RU-ZAB" : true, | |
912 | "RW-01" : true, "RW-02" : true, "RW-03" : true, "RW-04" : true, "RW-05" : true, | |
913 | "SA-01" : true, "SA-02" : true, "SA-03" : true, "SA-04" : true, "SA-05" : true, | |
914 | "SA-06" : true, "SA-07" : true, "SA-08" : true, "SA-09" : true, "SA-10" : true, | |
915 | "SA-11" : true, "SA-12" : true, "SA-14" : true, "SB-CE" : true, "SB-CH" : true, | |
916 | "SB-CT" : true, "SB-GU" : true, "SB-IS" : true, "SB-MK" : true, "SB-ML" : true, | |
917 | "SB-RB" : true, "SB-TE" : true, "SB-WE" : true, "SC-01" : true, "SC-02" : true, | |
918 | "SC-03" : true, "SC-04" : true, "SC-05" : true, "SC-06" : true, "SC-07" : true, | |
919 | "SC-08" : true, "SC-09" : true, "SC-10" : true, "SC-11" : true, "SC-12" : true, | |
920 | "SC-13" : true, "SC-14" : true, "SC-15" : true, "SC-16" : true, "SC-17" : true, | |
921 | "SC-18" : true, "SC-19" : true, "SC-20" : true, "SC-21" : true, "SC-22" : true, | |
922 | "SC-23" : true, "SC-24" : true, "SC-25" : true, "SD-DC" : true, "SD-DE" : true, | |
923 | "SD-DN" : true, "SD-DS" : true, "SD-DW" : true, "SD-GD" : true, "SD-GZ" : true, | |
924 | "SD-KA" : true, "SD-KH" : true, "SD-KN" : true, "SD-KS" : true, "SD-NB" : true, | |
925 | "SD-NO" : true, "SD-NR" : true, "SD-NW" : true, "SD-RS" : true, "SD-SI" : true, | |
926 | "SE-AB" : true, "SE-AC" : true, "SE-BD" : true, "SE-C" : true, "SE-D" : true, | |
927 | "SE-E" : true, "SE-F" : true, "SE-G" : true, "SE-H" : true, "SE-I" : true, | |
928 | "SE-K" : true, "SE-M" : true, "SE-N" : true, "SE-O" : true, "SE-S" : true, | |
929 | "SE-T" : true, "SE-U" : true, "SE-W" : true, "SE-X" : true, "SE-Y" : true, | |
930 | "SE-Z" : true, "SG-01" : true, "SG-02" : true, "SG-03" : true, "SG-04" : true, | |
931 | "SG-05" : true, "SH-AC" : true, "SH-HL" : true, "SH-TA" : true, "SI-001" : true, | |
932 | "SI-002" : true, "SI-003" : true, "SI-004" : true, "SI-005" : true, "SI-006" : true, | |
933 | "SI-007" : true, "SI-008" : true, "SI-009" : true, "SI-010" : true, "SI-011" : true, | |
934 | "SI-012" : true, "SI-013" : true, "SI-014" : true, "SI-015" : true, "SI-016" : true, | |
935 | "SI-017" : true, "SI-018" : true, "SI-019" : true, "SI-020" : true, "SI-021" : true, | |
936 | "SI-022" : true, "SI-023" : true, "SI-024" : true, "SI-025" : true, "SI-026" : true, | |
937 | "SI-027" : true, "SI-028" : true, "SI-029" : true, "SI-030" : true, "SI-031" : true, | |
938 | "SI-032" : true, "SI-033" : true, "SI-034" : true, "SI-035" : true, "SI-036" : true, | |
939 | "SI-037" : true, "SI-038" : true, "SI-039" : true, "SI-040" : true, "SI-041" : true, | |
940 | "SI-042" : true, "SI-043" : true, "SI-044" : true, "SI-045" : true, "SI-046" : true, | |
941 | "SI-047" : true, "SI-048" : true, "SI-049" : true, "SI-050" : true, "SI-051" : true, | |
942 | "SI-052" : true, "SI-053" : true, "SI-054" : true, "SI-055" : true, "SI-056" : true, | |
943 | "SI-057" : true, "SI-058" : true, "SI-059" : true, "SI-060" : true, "SI-061" : true, | |
944 | "SI-062" : true, "SI-063" : true, "SI-064" : true, "SI-065" : true, "SI-066" : true, | |
945 | "SI-067" : true, "SI-068" : true, "SI-069" : true, "SI-070" : true, "SI-071" : true, | |
946 | "SI-072" : true, "SI-073" : true, "SI-074" : true, "SI-075" : true, "SI-076" : true, | |
947 | "SI-077" : true, "SI-078" : true, "SI-079" : true, "SI-080" : true, "SI-081" : true, | |
948 | "SI-082" : true, "SI-083" : true, "SI-084" : true, "SI-085" : true, "SI-086" : true, | |
949 | "SI-087" : true, "SI-088" : true, "SI-089" : true, "SI-090" : true, "SI-091" : true, | |
950 | "SI-092" : true, "SI-093" : true, "SI-094" : true, "SI-095" : true, "SI-096" : true, | |
951 | "SI-097" : true, "SI-098" : true, "SI-099" : true, "SI-100" : true, "SI-101" : true, | |
952 | "SI-102" : true, "SI-103" : true, "SI-104" : true, "SI-105" : true, "SI-106" : true, | |
953 | "SI-107" : true, "SI-108" : true, "SI-109" : true, "SI-110" : true, "SI-111" : true, | |
954 | "SI-112" : true, "SI-113" : true, "SI-114" : true, "SI-115" : true, "SI-116" : true, | |
955 | "SI-117" : true, "SI-118" : true, "SI-119" : true, "SI-120" : true, "SI-121" : true, | |
956 | "SI-122" : true, "SI-123" : true, "SI-124" : true, "SI-125" : true, "SI-126" : true, | |
957 | "SI-127" : true, "SI-128" : true, "SI-129" : true, "SI-130" : true, "SI-131" : true, | |
958 | "SI-132" : true, "SI-133" : true, "SI-134" : true, "SI-135" : true, "SI-136" : true, | |
959 | "SI-137" : true, "SI-138" : true, "SI-139" : true, "SI-140" : true, "SI-141" : true, | |
960 | "SI-142" : true, "SI-143" : true, "SI-144" : true, "SI-146" : true, "SI-147" : true, | |
961 | "SI-148" : true, "SI-149" : true, "SI-150" : true, "SI-151" : true, "SI-152" : true, | |
962 | "SI-153" : true, "SI-154" : true, "SI-155" : true, "SI-156" : true, "SI-157" : true, | |
963 | "SI-158" : true, "SI-159" : true, "SI-160" : true, "SI-161" : true, "SI-162" : true, | |
964 | "SI-163" : true, "SI-164" : true, "SI-165" : true, "SI-166" : true, "SI-167" : true, | |
965 | "SI-168" : true, "SI-169" : true, "SI-170" : true, "SI-171" : true, "SI-172" : true, | |
966 | "SI-173" : true, "SI-174" : true, "SI-175" : true, "SI-176" : true, "SI-177" : true, | |
967 | "SI-178" : true, "SI-179" : true, "SI-180" : true, "SI-181" : true, "SI-182" : true, | |
968 | "SI-183" : true, "SI-184" : true, "SI-185" : true, "SI-186" : true, "SI-187" : true, | |
969 | "SI-188" : true, "SI-189" : true, "SI-190" : true, "SI-191" : true, "SI-192" : true, | |
970 | "SI-193" : true, "SI-194" : true, "SI-195" : true, "SI-196" : true, "SI-197" : true, | |
971 | "SI-198" : true, "SI-199" : true, "SI-200" : true, "SI-201" : true, "SI-202" : true, | |
972 | "SI-203" : true, "SI-204" : true, "SI-205" : true, "SI-206" : true, "SI-207" : true, | |
973 | "SI-208" : true, "SI-209" : true, "SI-210" : true, "SI-211" : true, "SK-BC" : true, | |
974 | "SK-BL" : true, "SK-KI" : true, "SK-NI" : true, "SK-PV" : true, "SK-TA" : true, | |
975 | "SK-TC" : true, "SK-ZI" : true, "SL-E" : true, "SL-N" : true, "SL-S" : true, | |
976 | "SL-W" : true, "SM-01" : true, "SM-02" : true, "SM-03" : true, "SM-04" : true, | |
977 | "SM-05" : true, "SM-06" : true, "SM-07" : true, "SM-08" : true, "SM-09" : true, | |
978 | "SN-DB" : true, "SN-DK" : true, "SN-FK" : true, "SN-KA" : true, "SN-KD" : true, | |
979 | "SN-KE" : true, "SN-KL" : true, "SN-LG" : true, "SN-MT" : true, "SN-SE" : true, | |
980 | "SN-SL" : true, "SN-TC" : true, "SN-TH" : true, "SN-ZG" : true, "SO-AW" : true, | |
981 | "SO-BK" : true, "SO-BN" : true, "SO-BR" : true, "SO-BY" : true, "SO-GA" : true, | |
982 | "SO-GE" : true, "SO-HI" : true, "SO-JD" : true, "SO-JH" : true, "SO-MU" : true, | |
983 | "SO-NU" : true, "SO-SA" : true, "SO-SD" : true, "SO-SH" : true, "SO-SO" : true, | |
984 | "SO-TO" : true, "SO-WO" : true, "SR-BR" : true, "SR-CM" : true, "SR-CR" : true, | |
985 | "SR-MA" : true, "SR-NI" : true, "SR-PM" : true, "SR-PR" : true, "SR-SA" : true, | |
986 | "SR-SI" : true, "SR-WA" : true, "SS-BN" : true, "SS-BW" : true, "SS-EC" : true, | |
987 | "SS-EE8" : true, "SS-EW" : true, "SS-JG" : true, "SS-LK" : true, "SS-NU" : true, | |
988 | "SS-UY" : true, "SS-WR" : true, "ST-P" : true, "ST-S" : true, "SV-AH" : true, | |
989 | "SV-CA" : true, "SV-CH" : true, "SV-CU" : true, "SV-LI" : true, "SV-MO" : true, | |
990 | "SV-PA" : true, "SV-SA" : true, "SV-SM" : true, "SV-SO" : true, "SV-SS" : true, | |
991 | "SV-SV" : true, "SV-UN" : true, "SV-US" : true, "SY-DI" : true, "SY-DR" : true, | |
992 | "SY-DY" : true, "SY-HA" : true, "SY-HI" : true, "SY-HL" : true, "SY-HM" : true, | |
993 | "SY-ID" : true, "SY-LA" : true, "SY-QU" : true, "SY-RA" : true, "SY-RD" : true, | |
994 | "SY-SU" : true, "SY-TA" : true, "SZ-HH" : true, "SZ-LU" : true, "SZ-MA" : true, | |
995 | "SZ-SH" : true, "TD-BA" : true, "TD-BG" : true, "TD-BO" : true, "TD-CB" : true, | |
996 | "TD-EN" : true, "TD-GR" : true, "TD-HL" : true, "TD-KA" : true, "TD-LC" : true, | |
997 | "TD-LO" : true, "TD-LR" : true, "TD-MA" : true, "TD-MC" : true, "TD-ME" : true, | |
998 | "TD-MO" : true, "TD-ND" : true, "TD-OD" : true, "TD-SA" : true, "TD-SI" : true, | |
999 | "TD-TA" : true, "TD-TI" : true, "TD-WF" : true, "TG-C" : true, "TG-K" : true, | |
1000 | "TG-M" : true, "TG-P" : true, "TG-S" : true, "TH-10" : true, "TH-11" : true, | |
1001 | "TH-12" : true, "TH-13" : true, "TH-14" : true, "TH-15" : true, "TH-16" : true, | |
1002 | "TH-17" : true, "TH-18" : true, "TH-19" : true, "TH-20" : true, "TH-21" : true, | |
1003 | "TH-22" : true, "TH-23" : true, "TH-24" : true, "TH-25" : true, "TH-26" : true, | |
1004 | "TH-27" : true, "TH-30" : true, "TH-31" : true, "TH-32" : true, "TH-33" : true, | |
1005 | "TH-34" : true, "TH-35" : true, "TH-36" : true, "TH-37" : true, "TH-39" : true, | |
1006 | "TH-40" : true, "TH-41" : true, "TH-42" : true, "TH-43" : true, "TH-44" : true, | |
1007 | "TH-45" : true, "TH-46" : true, "TH-47" : true, "TH-48" : true, "TH-49" : true, | |
1008 | "TH-50" : true, "TH-51" : true, "TH-52" : true, "TH-53" : true, "TH-54" : true, | |
1009 | "TH-55" : true, "TH-56" : true, "TH-57" : true, "TH-58" : true, "TH-60" : true, | |
1010 | "TH-61" : true, "TH-62" : true, "TH-63" : true, "TH-64" : true, "TH-65" : true, | |
1011 | "TH-66" : true, "TH-67" : true, "TH-70" : true, "TH-71" : true, "TH-72" : true, | |
1012 | "TH-73" : true, "TH-74" : true, "TH-75" : true, "TH-76" : true, "TH-77" : true, | |
1013 | "TH-80" : true, "TH-81" : true, "TH-82" : true, "TH-83" : true, "TH-84" : true, | |
1014 | "TH-85" : true, "TH-86" : true, "TH-90" : true, "TH-91" : true, "TH-92" : true, | |
1015 | "TH-93" : true, "TH-94" : true, "TH-95" : true, "TH-96" : true, "TH-S" : true, | |
1016 | "TJ-GB" : true, "TJ-KT" : true, "TJ-SU" : true, "TL-AL" : true, "TL-AN" : true, | |
1017 | "TL-BA" : true, "TL-BO" : true, "TL-CO" : true, "TL-DI" : true, "TL-ER" : true, | |
1018 | "TL-LA" : true, "TL-LI" : true, "TL-MF" : true, "TL-MT" : true, "TL-OE" : true, | |
1019 | "TL-VI" : true, "TM-A" : true, "TM-B" : true, "TM-D" : true, "TM-L" : true, | |
1020 | "TM-M" : true, "TM-S" : true, "TN-11" : true, "TN-12" : true, "TN-13" : true, | |
1021 | "TN-14" : true, "TN-21" : true, "TN-22" : true, "TN-23" : true, "TN-31" : true, | |
1022 | "TN-32" : true, "TN-33" : true, "TN-34" : true, "TN-41" : true, "TN-42" : true, | |
1023 | "TN-43" : true, "TN-51" : true, "TN-52" : true, "TN-53" : true, "TN-61" : true, | |
1024 | "TN-71" : true, "TN-72" : true, "TN-73" : true, "TN-81" : true, "TN-82" : true, | |
1025 | "TN-83" : true, "TO-01" : true, "TO-02" : true, "TO-03" : true, "TO-04" : true, | |
1026 | "TO-05" : true, "TR-01" : true, "TR-02" : true, "TR-03" : true, "TR-04" : true, | |
1027 | "TR-05" : true, "TR-06" : true, "TR-07" : true, "TR-08" : true, "TR-09" : true, | |
1028 | "TR-10" : true, "TR-11" : true, "TR-12" : true, "TR-13" : true, "TR-14" : true, | |
1029 | "TR-15" : true, "TR-16" : true, "TR-17" : true, "TR-18" : true, "TR-19" : true, | |
1030 | "TR-20" : true, "TR-21" : true, "TR-22" : true, "TR-23" : true, "TR-24" : true, | |
1031 | "TR-25" : true, "TR-26" : true, "TR-27" : true, "TR-28" : true, "TR-29" : true, | |
1032 | "TR-30" : true, "TR-31" : true, "TR-32" : true, "TR-33" : true, "TR-34" : true, | |
1033 | "TR-35" : true, "TR-36" : true, "TR-37" : true, "TR-38" : true, "TR-39" : true, | |
1034 | "TR-40" : true, "TR-41" : true, "TR-42" : true, "TR-43" : true, "TR-44" : true, | |
1035 | "TR-45" : true, "TR-46" : true, "TR-47" : true, "TR-48" : true, "TR-49" : true, | |
1036 | "TR-50" : true, "TR-51" : true, "TR-52" : true, "TR-53" : true, "TR-54" : true, | |
1037 | "TR-55" : true, "TR-56" : true, "TR-57" : true, "TR-58" : true, "TR-59" : true, | |
1038 | "TR-60" : true, "TR-61" : true, "TR-62" : true, "TR-63" : true, "TR-64" : true, | |
1039 | "TR-65" : true, "TR-66" : true, "TR-67" : true, "TR-68" : true, "TR-69" : true, | |
1040 | "TR-70" : true, "TR-71" : true, "TR-72" : true, "TR-73" : true, "TR-74" : true, | |
1041 | "TR-75" : true, "TR-76" : true, "TR-77" : true, "TR-78" : true, "TR-79" : true, | |
1042 | "TR-80" : true, "TR-81" : true, "TT-ARI" : true, "TT-CHA" : true, "TT-CTT" : true, | |
1043 | "TT-DMN" : true, "TT-ETO" : true, "TT-PED" : true, "TT-POS" : true, "TT-PRT" : true, | |
1044 | "TT-PTF" : true, "TT-RCM" : true, "TT-SFO" : true, "TT-SGE" : true, "TT-SIP" : true, | |
1045 | "TT-SJL" : true, "TT-TUP" : true, "TT-WTO" : true, "TV-FUN" : true, "TV-NIT" : true, | |
1046 | "TV-NKF" : true, "TV-NKL" : true, "TV-NMA" : true, "TV-NMG" : true, "TV-NUI" : true, | |
1047 | "TV-VAI" : true, "TW-CHA" : true, "TW-CYI" : true, "TW-CYQ" : true, "TW-HSQ" : true, | |
1048 | "TW-HSZ" : true, "TW-HUA" : true, "TW-ILA" : true, "TW-KEE" : true, "TW-KHH" : true, | |
1049 | "TW-KHQ" : true, "TW-MIA" : true, "TW-NAN" : true, "TW-PEN" : true, "TW-PIF" : true, | |
1050 | "TW-TAO" : true, "TW-TNN" : true, "TW-TNQ" : true, "TW-TPE" : true, "TW-TPQ" : true, | |
1051 | "TW-TTT" : true, "TW-TXG" : true, "TW-TXQ" : true, "TW-YUN" : true, "TZ-01" : true, | |
1052 | "TZ-02" : true, "TZ-03" : true, "TZ-04" : true, "TZ-05" : true, "TZ-06" : true, | |
1053 | "TZ-07" : true, "TZ-08" : true, "TZ-09" : true, "TZ-10" : true, "TZ-11" : true, | |
1054 | "TZ-12" : true, "TZ-13" : true, "TZ-14" : true, "TZ-15" : true, "TZ-16" : true, | |
1055 | "TZ-17" : true, "TZ-18" : true, "TZ-19" : true, "TZ-20" : true, "TZ-21" : true, | |
1056 | "TZ-22" : true, "TZ-23" : true, "TZ-24" : true, "TZ-25" : true, "TZ-26" : true, | |
1057 | "UA-05" : true, "UA-07" : true, "UA-09" : true, "UA-12" : true, "UA-14" : true, | |
1058 | "UA-18" : true, "UA-21" : true, "UA-23" : true, "UA-26" : true, "UA-30" : true, | |
1059 | "UA-32" : true, "UA-35" : true, "UA-40" : true, "UA-43" : true, "UA-46" : true, | |
1060 | "UA-48" : true, "UA-51" : true, "UA-53" : true, "UA-56" : true, "UA-59" : true, | |
1061 | "UA-61" : true, "UA-63" : true, "UA-65" : true, "UA-68" : true, "UA-71" : true, | |
1062 | "UA-74" : true, "UA-77" : true, "UG-101" : true, "UG-102" : true, "UG-103" : true, | |
1063 | "UG-104" : true, "UG-105" : true, "UG-106" : true, "UG-107" : true, "UG-108" : true, | |
1064 | "UG-109" : true, "UG-110" : true, "UG-111" : true, "UG-112" : true, "UG-113" : true, | |
1065 | "UG-114" : true, "UG-115" : true, "UG-116" : true, "UG-201" : true, "UG-202" : true, | |
1066 | "UG-203" : true, "UG-204" : true, "UG-205" : true, "UG-206" : true, "UG-207" : true, | |
1067 | "UG-208" : true, "UG-209" : true, "UG-210" : true, "UG-211" : true, "UG-212" : true, | |
1068 | "UG-213" : true, "UG-214" : true, "UG-215" : true, "UG-216" : true, "UG-217" : true, | |
1069 | "UG-218" : true, "UG-219" : true, "UG-220" : true, "UG-221" : true, "UG-222" : true, | |
1070 | "UG-223" : true, "UG-224" : true, "UG-301" : true, "UG-302" : true, "UG-303" : true, | |
1071 | "UG-304" : true, "UG-305" : true, "UG-306" : true, "UG-307" : true, "UG-308" : true, | |
1072 | "UG-309" : true, "UG-310" : true, "UG-311" : true, "UG-312" : true, "UG-313" : true, | |
1073 | "UG-314" : true, "UG-315" : true, "UG-316" : true, "UG-317" : true, "UG-318" : true, | |
1074 | "UG-319" : true, "UG-320" : true, "UG-321" : true, "UG-401" : true, "UG-402" : true, | |
1075 | "UG-403" : true, "UG-404" : true, "UG-405" : true, "UG-406" : true, "UG-407" : true, | |
1076 | "UG-408" : true, "UG-409" : true, "UG-410" : true, "UG-411" : true, "UG-412" : true, | |
1077 | "UG-413" : true, "UG-414" : true, "UG-415" : true, "UG-416" : true, "UG-417" : true, | |
1078 | "UG-418" : true, "UG-419" : true, "UG-C" : true, "UG-E" : true, "UG-N" : true, | |
1079 | "UG-W" : true, "UM-67" : true, "UM-71" : true, "UM-76" : true, "UM-79" : true, | |
1080 | "UM-81" : true, "UM-84" : true, "UM-86" : true, "UM-89" : true, "UM-95" : true, | |
1081 | "US-AK" : true, "US-AL" : true, "US-AR" : true, "US-AS" : true, "US-AZ" : true, | |
1082 | "US-CA" : true, "US-CO" : true, "US-CT" : true, "US-DC" : true, "US-DE" : true, | |
1083 | "US-FL" : true, "US-GA" : true, "US-GU" : true, "US-HI" : true, "US-IA" : true, | |
1084 | "US-ID" : true, "US-IL" : true, "US-IN" : true, "US-KS" : true, "US-KY" : true, | |
1085 | "US-LA" : true, "US-MA" : true, "US-MD" : true, "US-ME" : true, "US-MI" : true, | |
1086 | "US-MN" : true, "US-MO" : true, "US-MP" : true, "US-MS" : true, "US-MT" : true, | |
1087 | "US-NC" : true, "US-ND" : true, "US-NE" : true, "US-NH" : true, "US-NJ" : true, | |
1088 | "US-NM" : true, "US-NV" : true, "US-NY" : true, "US-OH" : true, "US-OK" : true, | |
1089 | "US-OR" : true, "US-PA" : true, "US-PR" : true, "US-RI" : true, "US-SC" : true, | |
1090 | "US-SD" : true, "US-TN" : true, "US-TX" : true, "US-UM" : true, "US-UT" : true, | |
1091 | "US-VA" : true, "US-VI" : true, "US-VT" : true, "US-WA" : true, "US-WI" : true, | |
1092 | "US-WV" : true, "US-WY" : true, "UY-AR" : true, "UY-CA" : true, "UY-CL" : true, | |
1093 | "UY-CO" : true, "UY-DU" : true, "UY-FD" : true, "UY-FS" : true, "UY-LA" : true, | |
1094 | "UY-MA" : true, "UY-MO" : true, "UY-PA" : true, "UY-RN" : true, "UY-RO" : true, | |
1095 | "UY-RV" : true, "UY-SA" : true, "UY-SJ" : true, "UY-SO" : true, "UY-TA" : true, | |
1096 | "UY-TT" : true, "UZ-AN" : true, "UZ-BU" : true, "UZ-FA" : true, "UZ-JI" : true, | |
1097 | "UZ-NG" : true, "UZ-NW" : true, "UZ-QA" : true, "UZ-QR" : true, "UZ-SA" : true, | |
1098 | "UZ-SI" : true, "UZ-SU" : true, "UZ-TK" : true, "UZ-TO" : true, "UZ-XO" : true, | |
1099 | "VC-01" : true, "VC-02" : true, "VC-03" : true, "VC-04" : true, "VC-05" : true, | |
1100 | "VC-06" : true, "VE-A" : true, "VE-B" : true, "VE-C" : true, "VE-D" : true, | |
1101 | "VE-E" : true, "VE-F" : true, "VE-G" : true, "VE-H" : true, "VE-I" : true, | |
1102 | "VE-J" : true, "VE-K" : true, "VE-L" : true, "VE-M" : true, "VE-N" : true, | |
1103 | "VE-O" : true, "VE-P" : true, "VE-R" : true, "VE-S" : true, "VE-T" : true, | |
1104 | "VE-U" : true, "VE-V" : true, "VE-W" : true, "VE-X" : true, "VE-Y" : true, | |
1105 | "VE-Z" : true, "VN-01" : true, "VN-02" : true, "VN-03" : true, "VN-04" : true, | |
1106 | "VN-05" : true, "VN-06" : true, "VN-07" : true, "VN-09" : true, "VN-13" : true, | |
1107 | "VN-14" : true, "VN-15" : true, "VN-18" : true, "VN-20" : true, "VN-21" : true, | |
1108 | "VN-22" : true, "VN-23" : true, "VN-24" : true, "VN-25" : true, "VN-26" : true, | |
1109 | "VN-27" : true, "VN-28" : true, "VN-29" : true, "VN-30" : true, "VN-31" : true, | |
1110 | "VN-32" : true, "VN-33" : true, "VN-34" : true, "VN-35" : true, "VN-36" : true, | |
1111 | "VN-37" : true, "VN-39" : true, "VN-40" : true, "VN-41" : true, "VN-43" : true, | |
1112 | "VN-44" : true, "VN-45" : true, "VN-46" : true, "VN-47" : true, "VN-49" : true, | |
1113 | "VN-50" : true, "VN-51" : true, "VN-52" : true, "VN-53" : true, "VN-54" : true, | |
1114 | "VN-55" : true, "VN-56" : true, "VN-57" : true, "VN-58" : true, "VN-59" : true, | |
1115 | "VN-61" : true, "VN-63" : true, "VN-66" : true, "VN-67" : true, "VN-68" : true, | |
1116 | "VN-69" : true, "VN-70" : true, "VN-71" : true, "VN-72" : true, "VN-73" : true, | |
1117 | "VN-CT" : true, "VN-DN" : true, "VN-HN" : true, "VN-HP" : true, "VN-SG" : true, | |
1118 | "VU-MAP" : true, "VU-PAM" : true, "VU-SAM" : true, "VU-SEE" : true, "VU-TAE" : true, | |
1119 | "VU-TOB" : true, "WS-AA" : true, "WS-AL" : true, "WS-AT" : true, "WS-FA" : true, | |
1120 | "WS-GE" : true, "WS-GI" : true, "WS-PA" : true, "WS-SA" : true, "WS-TU" : true, | |
1121 | "WS-VF" : true, "WS-VS" : true, "YE-AB" : true, "YE-AD" : true, "YE-AM" : true, | |
1122 | "YE-BA" : true, "YE-DA" : true, "YE-DH" : true, "YE-HD" : true, "YE-HJ" : true, | |
1123 | "YE-IB" : true, "YE-JA" : true, "YE-LA" : true, "YE-MA" : true, "YE-MR" : true, | |
1124 | "YE-MU" : true, "YE-MW" : true, "YE-RA" : true, "YE-SD" : true, "YE-SH" : true, | |
1125 | "YE-SN" : true, "YE-TA" : true, "ZA-EC" : true, "ZA-FS" : true, "ZA-GP" : true, | |
1126 | "ZA-LP" : true, "ZA-MP" : true, "ZA-NC" : true, "ZA-NW" : true, "ZA-WC" : true, | |
1127 | "ZA-ZN" : true, "ZM-01" : true, "ZM-02" : true, "ZM-03" : true, "ZM-04" : true, | |
1128 | "ZM-05" : true, "ZM-06" : true, "ZM-07" : true, "ZM-08" : true, "ZM-09" : true, | |
1129 | "ZW-BU" : true, "ZW-HA" : true, "ZW-MA" : true, "ZW-MC" : true, "ZW-ME" : true, | |
1130 | "ZW-MI" : true, "ZW-MN" : true, "ZW-MS" : true, "ZW-MV" : true, "ZW-MW" : true, | |
1131 | } |
810 | 810 | |
811 | 811 | Usage: json |
812 | 812 | |
813 | JWT String | |
814 | ||
815 | This validates that a string value is a valid JWT | |
816 | ||
817 | Usage: jwt | |
818 | ||
813 | 819 | File path |
814 | 820 | |
815 | 821 | This validates that a string value contains a valid file path and that |
1220 | 1226 | |
1221 | 1227 | Usage: iso3166_1_alpha3 |
1222 | 1228 | |
1229 | BCP 47 Language Tag | |
1230 | ||
1231 | This validates that a string value is a valid BCP 47 language tag, as parsed by language.Parse. | |
1232 | More information on https://pkg.go.dev/golang.org/x/text/language | |
1233 | ||
1234 | Usage: bcp47_language_tag | |
1235 | ||
1236 | BIC (SWIFT code) | |
1237 | ||
1238 | This validates that a string value is a valid Business Identifier Code (SWIFT code), defined in ISO 9362. | |
1239 | More information on https://www.iso.org/standard/60390.html | |
1240 | ||
1241 | Usage: bic | |
1242 | ||
1223 | 1243 | TimeZone |
1224 | 1244 | |
1225 | 1245 | This validates that a string value is a valid time zone based on the time zone database present on the system. |
1227 | 1247 | More information on https://golang.org/pkg/time/#LoadLocation |
1228 | 1248 | |
1229 | 1249 | Usage: timezone |
1230 | ||
1250 | ||
1231 | 1251 | |
1232 | 1252 | Alias Validators and Tags |
1233 | 1253 |
81 | 81 | // FieldError contains all functions to get error details |
82 | 82 | type FieldError interface { |
83 | 83 | |
84 | // returns the validation tag that failed. if the | |
84 | // Tag returns the validation tag that failed. if the | |
85 | 85 | // validation was an alias, this will return the |
86 | 86 | // alias name and not the underlying tag that failed. |
87 | 87 | // |
89 | 89 | // will return "iscolor" |
90 | 90 | Tag() string |
91 | 91 | |
92 | // returns the validation tag that failed, even if an | |
92 | // ActualTag returns the validation tag that failed, even if an | |
93 | 93 | // alias the actual tag within the alias will be returned. |
94 | 94 | // If an 'or' validation fails the entire or will be returned. |
95 | 95 | // |
97 | 97 | // will return "hexcolor|rgb|rgba|hsl|hsla" |
98 | 98 | ActualTag() string |
99 | 99 | |
100 | // returns the namespace for the field error, with the tag | |
100 | // Namespace returns the namespace for the field error, with the tag | |
101 | 101 | // name taking precedence over the field's actual name. |
102 | 102 | // |
103 | 103 | // eg. JSON name "User.fname" |
108 | 108 | // using validate.Field(...) as there is no way to extract it's name |
109 | 109 | Namespace() string |
110 | 110 | |
111 | // returns the namespace for the field error, with the field's | |
111 | // StructNamespace returns the namespace for the field error, with the field's | |
112 | 112 | // actual name. |
113 | 113 | // |
114 | 114 | // eq. "User.FirstName" see Namespace for comparison |
117 | 117 | // using validate.Field(...) as there is no way to extract its name |
118 | 118 | StructNamespace() string |
119 | 119 | |
120 | // returns the fields name with the tag name taking precedence over the | |
120 | // Field returns the fields name with the tag name taking precedence over the | |
121 | 121 | // field's actual name. |
122 | 122 | // |
123 | 123 | // eq. JSON name "fname" |
124 | 124 | // see StructField for comparison |
125 | 125 | Field() string |
126 | 126 | |
127 | // returns the field's actual name from the struct, when able to determine. | |
127 | // StructField returns the field's actual name from the struct, when able to determine. | |
128 | 128 | // |
129 | 129 | // eq. "FirstName" |
130 | 130 | // see Field for comparison |
131 | 131 | StructField() string |
132 | 132 | |
133 | // returns the actual field's value in case needed for creating the error | |
133 | // Value returns the actual field's value in case needed for creating the error | |
134 | 134 | // message |
135 | 135 | Value() interface{} |
136 | 136 | |
137 | // returns the param value, in string form for comparison; this will also | |
137 | // Param returns the param value, in string form for comparison; this will also | |
138 | 138 | // help with generating an error message |
139 | 139 | Param() string |
140 | 140 | |
145 | 145 | |
146 | 146 | // Type returns the Field's reflect Type |
147 | 147 | // |
148 | // // eg. time.Time's type is time.Time | |
148 | // eg. time.Time's type is time.Time | |
149 | 149 | Type() reflect.Type |
150 | 150 | |
151 | // returns the FieldError's translated error | |
151 | // Translate returns the FieldError's translated error | |
152 | 152 | // from the provided 'ut.Translator' and registered 'TranslationFunc' |
153 | 153 | // |
154 | 154 | // NOTE: if no registered translator can be found it returns the same as |
220 | 220 | // return fld |
221 | 221 | } |
222 | 222 | |
223 | // returns the field's actual name from the struct, when able to determine. | |
223 | // StructField returns the field's actual name from the struct, when able to determine. | |
224 | 224 | func (fe *fieldError) StructField() string { |
225 | 225 | // return fe.structField |
226 | 226 | return fe.structNs[len(fe.structNs)-int(fe.structfieldLen):] |
4 | 4 | // FieldLevel contains all the information and helper functions |
5 | 5 | // to validate a field |
6 | 6 | type FieldLevel interface { |
7 | // returns the top level struct, if any | |
7 | ||
8 | // Top returns the top level struct, if any | |
8 | 9 | Top() reflect.Value |
9 | 10 | |
10 | // returns the current fields parent struct, if any or | |
11 | // Parent returns the current fields parent struct, if any or | |
11 | 12 | // the comparison value if called 'VarWithValue' |
12 | 13 | Parent() reflect.Value |
13 | 14 | |
14 | // returns current field for validation | |
15 | // Field returns current field for validation | |
15 | 16 | Field() reflect.Value |
16 | 17 | |
17 | // returns the field's name with the tag | |
18 | // FieldName returns the field's name with the tag | |
18 | 19 | // name taking precedence over the fields actual name. |
19 | 20 | FieldName() string |
20 | 21 | |
21 | // returns the struct field's name | |
22 | // StructFieldName returns the struct field's name | |
22 | 23 | StructFieldName() string |
23 | 24 | |
24 | // returns param for validation against current field | |
25 | // Param returns param for validation against current field | |
25 | 26 | Param() string |
26 | 27 | |
27 | 28 | // GetTag returns the current validations tag name |
32 | 33 | // underlying value and it's kind. |
33 | 34 | ExtractType(field reflect.Value) (value reflect.Value, kind reflect.Kind, nullable bool) |
34 | 35 | |
35 | // traverses the parent struct to retrieve a specific field denoted by the provided namespace | |
36 | // GetStructFieldOK traverses the parent struct to retrieve a specific field denoted by the provided namespace | |
36 | 37 | // in the param and returns the field, field kind and whether is was successful in retrieving |
37 | 38 | // the field at all. |
38 | 39 | // |
48 | 49 | // Deprecated: Use GetStructFieldOKAdvanced2() instead which also return if the value is nullable. |
49 | 50 | GetStructFieldOKAdvanced(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool) |
50 | 51 | |
51 | // traverses the parent struct to retrieve a specific field denoted by the provided namespace | |
52 | // GetStructFieldOK2 traverses the parent struct to retrieve a specific field denoted by the provided namespace | |
52 | 53 | // in the param and returns the field, field kind, if it's a nullable type and whether is was successful in retrieving |
53 | 54 | // the field at all. |
54 | 55 | // |
56 | 57 | // could not be retrieved because it didn't exist. |
57 | 58 | GetStructFieldOK2() (reflect.Value, reflect.Kind, bool, bool) |
58 | 59 | |
59 | // GetStructFieldOKAdvanced is the same as GetStructFieldOK except that it accepts the parent struct to start looking for | |
60 | // GetStructFieldOKAdvanced2 is the same as GetStructFieldOK except that it accepts the parent struct to start looking for | |
60 | 61 | // the field and namespace allowing more extensibility for validators. |
61 | 62 | GetStructFieldOKAdvanced2(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool, bool) |
62 | 63 | } |
106 | 107 | return current, kind, found |
107 | 108 | } |
108 | 109 | |
109 | // GetStructFieldOK returns Param returns param for validation against current field | |
110 | // GetStructFieldOK2 returns Param returns param for validation against current field | |
110 | 111 | func (v *validate) GetStructFieldOK2() (reflect.Value, reflect.Kind, bool, bool) { |
111 | 112 | return v.getStructFieldOKInternal(v.slflParent, v.ct.param) |
112 | 113 | } |
113 | 114 | |
114 | // GetStructFieldOKAdvanced is the same as GetStructFieldOK except that it accepts the parent struct to start looking for | |
115 | // GetStructFieldOKAdvanced2 is the same as GetStructFieldOK except that it accepts the parent struct to start looking for | |
115 | 116 | // the field and namespace allowing more extensibility for validators. |
116 | 117 | func (v *validate) GetStructFieldOKAdvanced2(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool, bool) { |
117 | 118 | return v.getStructFieldOKInternal(val, namespace) |
5 | 5 | github.com/go-playground/assert/v2 v2.0.1 |
6 | 6 | github.com/go-playground/locales v0.13.0 |
7 | 7 | github.com/go-playground/universal-translator v0.17.0 |
8 | github.com/leodido/go-urn v1.2.0 | |
9 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 | |
8 | github.com/leodido/go-urn v1.2.1 | |
9 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 | |
10 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect | |
11 | golang.org/x/text v0.3.6 | |
10 | 12 | ) |
5 | 5 | github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= |
6 | 6 | github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= |
7 | 7 | github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= |
8 | github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= | |
9 | github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= | |
8 | github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= | |
9 | github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= | |
10 | 10 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= |
11 | 11 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= |
12 | 12 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= |
13 | github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= | |
14 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | |
15 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | |
16 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= | |
17 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | |
18 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | |
19 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | |
20 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |
21 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | |
13 | github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= | |
14 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | |
15 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= | |
16 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | |
17 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= | |
18 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |
19 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | |
20 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= | |
21 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | |
22 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | |
22 | 23 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= |
24 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | |
25 | golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= | |
26 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | |
23 | 27 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= |
24 | 28 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= |
25 | 29 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
26 | gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= | |
27 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | |
30 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= | |
31 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
0 | package validator | |
1 | ||
2 | import "regexp" | |
3 | ||
4 | var postCodePatternDict = map[string]string{ | |
5 | "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}$`, | |
6 | "JE": `^JE\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}$`, | |
7 | "GG": `^GY\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}$`, | |
8 | "IM": `^IM\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}$`, | |
9 | "US": `^\d{5}([ \-]\d{4})?$`, | |
10 | "CA": `^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ ]?\d[ABCEGHJ-NPRSTV-Z]\d$`, | |
11 | "DE": `^\d{5}$`, | |
12 | "JP": `^\d{3}-\d{4}$`, | |
13 | "FR": `^\d{2}[ ]?\d{3}$`, | |
14 | "AU": `^\d{4}$`, | |
15 | "IT": `^\d{5}$`, | |
16 | "CH": `^\d{4}$`, | |
17 | "AT": `^\d{4}$`, | |
18 | "ES": `^\d{5}$`, | |
19 | "NL": `^\d{4}[ ]?[A-Z]{2}$`, | |
20 | "BE": `^\d{4}$`, | |
21 | "DK": `^\d{4}$`, | |
22 | "SE": `^\d{3}[ ]?\d{2}$`, | |
23 | "NO": `^\d{4}$`, | |
24 | "BR": `^\d{5}[\-]?\d{3}$`, | |
25 | "PT": `^\d{4}([\-]\d{3})?$`, | |
26 | "FI": `^\d{5}$`, | |
27 | "AX": `^22\d{3}$`, | |
28 | "KR": `^\d{3}[\-]\d{3}$`, | |
29 | "CN": `^\d{6}$`, | |
30 | "TW": `^\d{3}(\d{2})?$`, | |
31 | "SG": `^\d{6}$`, | |
32 | "DZ": `^\d{5}$`, | |
33 | "AD": `^AD\d{3}$`, | |
34 | "AR": `^([A-HJ-NP-Z])?\d{4}([A-Z]{3})?$`, | |
35 | "AM": `^(37)?\d{4}$`, | |
36 | "AZ": `^\d{4}$`, | |
37 | "BH": `^((1[0-2]|[2-9])\d{2})?$`, | |
38 | "BD": `^\d{4}$`, | |
39 | "BB": `^(BB\d{5})?$`, | |
40 | "BY": `^\d{6}$`, | |
41 | "BM": `^[A-Z]{2}[ ]?[A-Z0-9]{2}$`, | |
42 | "BA": `^\d{5}$`, | |
43 | "IO": `^BBND 1ZZ$`, | |
44 | "BN": `^[A-Z]{2}[ ]?\d{4}$`, | |
45 | "BG": `^\d{4}$`, | |
46 | "KH": `^\d{5}$`, | |
47 | "CV": `^\d{4}$`, | |
48 | "CL": `^\d{7}$`, | |
49 | "CR": `^\d{4,5}|\d{3}-\d{4}$`, | |
50 | "HR": `^\d{5}$`, | |
51 | "CY": `^\d{4}$`, | |
52 | "CZ": `^\d{3}[ ]?\d{2}$`, | |
53 | "DO": `^\d{5}$`, | |
54 | "EC": `^([A-Z]\d{4}[A-Z]|(?:[A-Z]{2})?\d{6})?$`, | |
55 | "EG": `^\d{5}$`, | |
56 | "EE": `^\d{5}$`, | |
57 | "FO": `^\d{3}$`, | |
58 | "GE": `^\d{4}$`, | |
59 | "GR": `^\d{3}[ ]?\d{2}$`, | |
60 | "GL": `^39\d{2}$`, | |
61 | "GT": `^\d{5}$`, | |
62 | "HT": `^\d{4}$`, | |
63 | "HN": `^(?:\d{5})?$`, | |
64 | "HU": `^\d{4}$`, | |
65 | "IS": `^\d{3}$`, | |
66 | "IN": `^\d{6}$`, | |
67 | "ID": `^\d{5}$`, | |
68 | "IL": `^\d{5}$`, | |
69 | "JO": `^\d{5}$`, | |
70 | "KZ": `^\d{6}$`, | |
71 | "KE": `^\d{5}$`, | |
72 | "KW": `^\d{5}$`, | |
73 | "LA": `^\d{5}$`, | |
74 | "LV": `^\d{4}$`, | |
75 | "LB": `^(\d{4}([ ]?\d{4})?)?$`, | |
76 | "LI": `^(948[5-9])|(949[0-7])$`, | |
77 | "LT": `^\d{5}$`, | |
78 | "LU": `^\d{4}$`, | |
79 | "MK": `^\d{4}$`, | |
80 | "MY": `^\d{5}$`, | |
81 | "MV": `^\d{5}$`, | |
82 | "MT": `^[A-Z]{3}[ ]?\d{2,4}$`, | |
83 | "MU": `^(\d{3}[A-Z]{2}\d{3})?$`, | |
84 | "MX": `^\d{5}$`, | |
85 | "MD": `^\d{4}$`, | |
86 | "MC": `^980\d{2}$`, | |
87 | "MA": `^\d{5}$`, | |
88 | "NP": `^\d{5}$`, | |
89 | "NZ": `^\d{4}$`, | |
90 | "NI": `^((\d{4}-)?\d{3}-\d{3}(-\d{1})?)?$`, | |
91 | "NG": `^(\d{6})?$`, | |
92 | "OM": `^(PC )?\d{3}$`, | |
93 | "PK": `^\d{5}$`, | |
94 | "PY": `^\d{4}$`, | |
95 | "PH": `^\d{4}$`, | |
96 | "PL": `^\d{2}-\d{3}$`, | |
97 | "PR": `^00[679]\d{2}([ \-]\d{4})?$`, | |
98 | "RO": `^\d{6}$`, | |
99 | "RU": `^\d{6}$`, | |
100 | "SM": `^4789\d$`, | |
101 | "SA": `^\d{5}$`, | |
102 | "SN": `^\d{5}$`, | |
103 | "SK": `^\d{3}[ ]?\d{2}$`, | |
104 | "SI": `^\d{4}$`, | |
105 | "ZA": `^\d{4}$`, | |
106 | "LK": `^\d{5}$`, | |
107 | "TJ": `^\d{6}$`, | |
108 | "TH": `^\d{5}$`, | |
109 | "TN": `^\d{4}$`, | |
110 | "TR": `^\d{5}$`, | |
111 | "TM": `^\d{6}$`, | |
112 | "UA": `^\d{5}$`, | |
113 | "UY": `^\d{5}$`, | |
114 | "UZ": `^\d{6}$`, | |
115 | "VA": `^00120$`, | |
116 | "VE": `^\d{4}$`, | |
117 | "ZM": `^\d{5}$`, | |
118 | "AS": `^96799$`, | |
119 | "CC": `^6799$`, | |
120 | "CK": `^\d{4}$`, | |
121 | "RS": `^\d{6}$`, | |
122 | "ME": `^8\d{4}$`, | |
123 | "CS": `^\d{5}$`, | |
124 | "YU": `^\d{5}$`, | |
125 | "CX": `^6798$`, | |
126 | "ET": `^\d{4}$`, | |
127 | "FK": `^FIQQ 1ZZ$`, | |
128 | "NF": `^2899$`, | |
129 | "FM": `^(9694[1-4])([ \-]\d{4})?$`, | |
130 | "GF": `^9[78]3\d{2}$`, | |
131 | "GN": `^\d{3}$`, | |
132 | "GP": `^9[78][01]\d{2}$`, | |
133 | "GS": `^SIQQ 1ZZ$`, | |
134 | "GU": `^969[123]\d([ \-]\d{4})?$`, | |
135 | "GW": `^\d{4}$`, | |
136 | "HM": `^\d{4}$`, | |
137 | "IQ": `^\d{5}$`, | |
138 | "KG": `^\d{6}$`, | |
139 | "LR": `^\d{4}$`, | |
140 | "LS": `^\d{3}$`, | |
141 | "MG": `^\d{3}$`, | |
142 | "MH": `^969[67]\d([ \-]\d{4})?$`, | |
143 | "MN": `^\d{6}$`, | |
144 | "MP": `^9695[012]([ \-]\d{4})?$`, | |
145 | "MQ": `^9[78]2\d{2}$`, | |
146 | "NC": `^988\d{2}$`, | |
147 | "NE": `^\d{4}$`, | |
148 | "VI": `^008(([0-4]\d)|(5[01]))([ \-]\d{4})?$`, | |
149 | "VN": `^[0-9]{1,6}$`, | |
150 | "PF": `^987\d{2}$`, | |
151 | "PG": `^\d{3}$`, | |
152 | "PM": `^9[78]5\d{2}$`, | |
153 | "PN": `^PCRN 1ZZ$`, | |
154 | "PW": `^96940$`, | |
155 | "RE": `^9[78]4\d{2}$`, | |
156 | "SH": `^(ASCN|STHL) 1ZZ$`, | |
157 | "SJ": `^\d{4}$`, | |
158 | "SO": `^\d{5}$`, | |
159 | "SZ": `^[HLMS]\d{3}$`, | |
160 | "TC": `^TKCA 1ZZ$`, | |
161 | "WF": `^986\d{2}$`, | |
162 | "XK": `^\d{5}$`, | |
163 | "YT": `^976\d{2}$`, | |
164 | } | |
165 | ||
166 | var postCodeRegexDict = map[string]*regexp.Regexp{} | |
167 | ||
168 | func init() { | |
169 | for countryCode, pattern := range postCodePatternDict { | |
170 | postCodeRegexDict[countryCode] = regexp.MustCompile(pattern) | |
171 | } | |
172 | } |
9 | 9 | numericRegexString = "^[-+]?[0-9]+(?:\\.[0-9]+)?$" |
10 | 10 | numberRegexString = "^[0-9]+$" |
11 | 11 | hexadecimalRegexString = "^(0[xX])?[0-9a-fA-F]+$" |
12 | hexcolorRegexString = "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$" | |
12 | hexColorRegexString = "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$" | |
13 | 13 | 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*\\)$" |
14 | 14 | 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*\\)$" |
15 | 15 | 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*\\)$" |
44 | 44 | ethAddressRegexString = `^0x[0-9a-fA-F]{40}$` |
45 | 45 | ethAddressUpperRegexString = `^0x[0-9A-F]{40}$` |
46 | 46 | ethAddressLowerRegexString = `^0x[0-9a-f]{40}$` |
47 | uRLEncodedRegexString = `(%[A-Fa-f0-9]{2})` | |
47 | uRLEncodedRegexString = `^(?:[^%]|%[0-9A-Fa-f]{2})*$` | |
48 | 48 | hTMLEncodedRegexString = `&#[x]?([0-9a-fA-F]{2})|(>)|(<)|(")|(&)+[;]?` |
49 | 49 | hTMLRegexString = `<[/]?([a-zA-Z]+).*?>` |
50 | jWTRegexString = "^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$" | |
50 | 51 | splitParamsRegexString = `'[^']*'|\S+` |
52 | bicRegexString = `^[A-Za-z]{6}[A-Za-z0-9]{2}([A-Za-z0-9]{3})?$` | |
51 | 53 | ) |
52 | 54 | |
53 | 55 | var ( |
58 | 60 | numericRegex = regexp.MustCompile(numericRegexString) |
59 | 61 | numberRegex = regexp.MustCompile(numberRegexString) |
60 | 62 | hexadecimalRegex = regexp.MustCompile(hexadecimalRegexString) |
61 | hexcolorRegex = regexp.MustCompile(hexcolorRegexString) | |
63 | hexColorRegex = regexp.MustCompile(hexColorRegexString) | |
62 | 64 | rgbRegex = regexp.MustCompile(rgbRegexString) |
63 | 65 | rgbaRegex = regexp.MustCompile(rgbaRegexString) |
64 | 66 | hslRegex = regexp.MustCompile(hslRegexString) |
91 | 93 | btcUpperAddressRegexBech32 = regexp.MustCompile(btcAddressUpperRegexStringBech32) |
92 | 94 | btcLowerAddressRegexBech32 = regexp.MustCompile(btcAddressLowerRegexStringBech32) |
93 | 95 | ethAddressRegex = regexp.MustCompile(ethAddressRegexString) |
94 | ethaddressRegexUpper = regexp.MustCompile(ethAddressUpperRegexString) | |
96 | ethAddressRegexUpper = regexp.MustCompile(ethAddressUpperRegexString) | |
95 | 97 | ethAddressRegexLower = regexp.MustCompile(ethAddressLowerRegexString) |
96 | 98 | uRLEncodedRegex = regexp.MustCompile(uRLEncodedRegexString) |
97 | 99 | hTMLEncodedRegex = regexp.MustCompile(hTMLEncodedRegexString) |
98 | 100 | hTMLRegex = regexp.MustCompile(hTMLRegexString) |
101 | jWTRegex = regexp.MustCompile(jWTRegexString) | |
99 | 102 | splitParamsRegex = regexp.MustCompile(splitParamsRegexString) |
103 | bicRegex = regexp.MustCompile(bicRegexString) | |
100 | 104 | ) |
22 | 22 | // to validate a struct |
23 | 23 | type StructLevel interface { |
24 | 24 | |
25 | // returns the main validation object, in case one wants to call validations internally. | |
25 | // Validator returns the main validation object, in case one wants to call validations internally. | |
26 | 26 | // this is so you don't have to use anonymous functions to get access to the validate |
27 | 27 | // instance. |
28 | 28 | Validator() *Validate |
29 | 29 | |
30 | // returns the top level struct, if any | |
30 | // Top returns the top level struct, if any | |
31 | 31 | Top() reflect.Value |
32 | 32 | |
33 | // returns the current fields parent struct, if any | |
33 | // Parent returns the current fields parent struct, if any | |
34 | 34 | Parent() reflect.Value |
35 | 35 | |
36 | // returns the current struct. | |
36 | // Current returns the current struct. | |
37 | 37 | Current() reflect.Value |
38 | 38 | |
39 | 39 | // ExtractType gets the actual underlying type of field value. |
41 | 41 | // underlying value and its kind. |
42 | 42 | ExtractType(field reflect.Value) (value reflect.Value, kind reflect.Kind, nullable bool) |
43 | 43 | |
44 | // reports an error just by passing the field and tag information | |
44 | // ReportError reports an error just by passing the field and tag information | |
45 | 45 | // |
46 | 46 | // NOTES: |
47 | 47 | // |
53 | 53 | // and process on the flip side it's up to you. |
54 | 54 | ReportError(field interface{}, fieldName, structFieldName string, tag, param string) |
55 | 55 | |
56 | // reports an error just by passing ValidationErrors | |
56 | // ReportValidationErrors reports an error just by passing ValidationErrors | |
57 | 57 | // |
58 | 58 | // NOTES: |
59 | 59 | // |
15 | 15 | // RegisterDefaultTranslations registers a set of default translations |
16 | 16 | // for all built in tag's in validator; you may add your own as desired. |
17 | 17 | func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (err error) { |
18 | ||
19 | 18 | translations := []struct { |
20 | 19 | tag string |
21 | 20 | translation string |
31 | 30 | { |
32 | 31 | tag: "len", |
33 | 32 | customRegisFunc: func(ut ut.Translator) (err error) { |
34 | ||
35 | 33 | if err = ut.Add("len-string", "{0} must be {1} in length", false); err != nil { |
36 | 34 | return |
37 | 35 | } |
60 | 58 | } |
61 | 59 | |
62 | 60 | return |
63 | ||
64 | }, | |
65 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
66 | ||
61 | }, | |
62 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
67 | 63 | var err error |
68 | 64 | var t string |
69 | 65 | |
122 | 118 | { |
123 | 119 | tag: "min", |
124 | 120 | customRegisFunc: func(ut ut.Translator) (err error) { |
125 | ||
126 | 121 | if err = ut.Add("min-string", "{0} must be at least {1} in length", false); err != nil { |
127 | 122 | return |
128 | 123 | } |
151 | 146 | } |
152 | 147 | |
153 | 148 | return |
154 | ||
155 | }, | |
156 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
157 | ||
149 | }, | |
150 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
158 | 151 | var err error |
159 | 152 | var t string |
160 | 153 | |
213 | 206 | { |
214 | 207 | tag: "max", |
215 | 208 | customRegisFunc: func(ut ut.Translator) (err error) { |
216 | ||
217 | 209 | if err = ut.Add("max-string", "{0} must be a maximum of {1} in length", false); err != nil { |
218 | 210 | return |
219 | 211 | } |
242 | 234 | } |
243 | 235 | |
244 | 236 | return |
245 | ||
246 | }, | |
247 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
248 | ||
237 | }, | |
238 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
249 | 239 | var err error |
250 | 240 | var t string |
251 | 241 | |
306 | 296 | translation: "{0} is not equal to {1}", |
307 | 297 | override: false, |
308 | 298 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
309 | ||
310 | 299 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
311 | 300 | if err != nil { |
312 | 301 | fmt.Printf("warning: error translating FieldError: %#v", fe) |
321 | 310 | translation: "{0} should not be equal to {1}", |
322 | 311 | override: false, |
323 | 312 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
324 | ||
325 | 313 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
326 | 314 | if err != nil { |
327 | 315 | fmt.Printf("warning: error translating FieldError: %#v", fe) |
334 | 322 | { |
335 | 323 | tag: "lt", |
336 | 324 | customRegisFunc: func(ut ut.Translator) (err error) { |
337 | ||
338 | 325 | if err = ut.Add("lt-string", "{0} must be less than {1} in length", false); err != nil { |
339 | 326 | return |
340 | 327 | } |
368 | 355 | } |
369 | 356 | |
370 | 357 | return |
371 | ||
372 | }, | |
373 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
374 | ||
358 | }, | |
359 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
375 | 360 | var err error |
376 | 361 | var t string |
377 | 362 | var f64 float64 |
379 | 364 | var kind reflect.Kind |
380 | 365 | |
381 | 366 | fn := func() (err error) { |
382 | ||
383 | 367 | if idx := strings.Index(fe.Param(), "."); idx != -1 { |
384 | 368 | digits = uint64(len(fe.Param()[idx+1:])) |
385 | 369 | } |
455 | 439 | { |
456 | 440 | tag: "lte", |
457 | 441 | customRegisFunc: func(ut ut.Translator) (err error) { |
458 | ||
459 | 442 | if err = ut.Add("lte-string", "{0} must be at maximum {1} in length", false); err != nil { |
460 | 443 | return |
461 | 444 | } |
491 | 474 | return |
492 | 475 | }, |
493 | 476 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
494 | ||
495 | 477 | var err error |
496 | 478 | var t string |
497 | 479 | var f64 float64 |
499 | 481 | var kind reflect.Kind |
500 | 482 | |
501 | 483 | fn := func() (err error) { |
502 | ||
503 | 484 | if idx := strings.Index(fe.Param(), "."); idx != -1 { |
504 | 485 | digits = uint64(len(fe.Param()[idx+1:])) |
505 | 486 | } |
575 | 556 | { |
576 | 557 | tag: "gt", |
577 | 558 | customRegisFunc: func(ut ut.Translator) (err error) { |
578 | ||
579 | 559 | if err = ut.Add("gt-string", "{0} must be greater than {1} in length", false); err != nil { |
580 | 560 | return |
581 | 561 | } |
611 | 591 | return |
612 | 592 | }, |
613 | 593 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
614 | ||
615 | 594 | var err error |
616 | 595 | var t string |
617 | 596 | var f64 float64 |
619 | 598 | var kind reflect.Kind |
620 | 599 | |
621 | 600 | fn := func() (err error) { |
622 | ||
623 | 601 | if idx := strings.Index(fe.Param(), "."); idx != -1 { |
624 | 602 | digits = uint64(len(fe.Param()[idx+1:])) |
625 | 603 | } |
695 | 673 | { |
696 | 674 | tag: "gte", |
697 | 675 | customRegisFunc: func(ut ut.Translator) (err error) { |
698 | ||
699 | 676 | if err = ut.Add("gte-string", "{0} must be at least {1} in length", false); err != nil { |
700 | 677 | return |
701 | 678 | } |
731 | 708 | return |
732 | 709 | }, |
733 | 710 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
734 | ||
735 | 711 | var err error |
736 | 712 | var t string |
737 | 713 | var f64 float64 |
739 | 715 | var kind reflect.Kind |
740 | 716 | |
741 | 717 | fn := func() (err error) { |
742 | ||
743 | 718 | if idx := strings.Index(fe.Param(), "."); idx != -1 { |
744 | 719 | digits = uint64(len(fe.Param()[idx+1:])) |
745 | 720 | } |
817 | 792 | translation: "{0} must be equal to {1}", |
818 | 793 | override: false, |
819 | 794 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
820 | ||
821 | 795 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
822 | 796 | if err != nil { |
823 | 797 | log.Printf("warning: error translating FieldError: %#v", fe) |
832 | 806 | translation: "{0} must be equal to {1}", |
833 | 807 | override: false, |
834 | 808 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
835 | ||
836 | 809 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
837 | 810 | if err != nil { |
838 | 811 | log.Printf("warning: error translating FieldError: %#v", fe) |
847 | 820 | translation: "{0} cannot be equal to {1}", |
848 | 821 | override: false, |
849 | 822 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
850 | ||
851 | 823 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
852 | 824 | if err != nil { |
853 | 825 | log.Printf("warning: error translating FieldError: %#v", fe) |
862 | 834 | translation: "{0} must be greater than {1}", |
863 | 835 | override: false, |
864 | 836 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
865 | ||
866 | 837 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
867 | 838 | if err != nil { |
868 | 839 | log.Printf("warning: error translating FieldError: %#v", fe) |
877 | 848 | translation: "{0} must be greater than or equal to {1}", |
878 | 849 | override: false, |
879 | 850 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
880 | ||
881 | 851 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
882 | 852 | if err != nil { |
883 | 853 | log.Printf("warning: error translating FieldError: %#v", fe) |
892 | 862 | translation: "{0} must be less than {1}", |
893 | 863 | override: false, |
894 | 864 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
895 | ||
896 | 865 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
897 | 866 | if err != nil { |
898 | 867 | log.Printf("warning: error translating FieldError: %#v", fe) |
907 | 876 | translation: "{0} must be less than or equal to {1}", |
908 | 877 | override: false, |
909 | 878 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
910 | ||
911 | 879 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
912 | 880 | if err != nil { |
913 | 881 | log.Printf("warning: error translating FieldError: %#v", fe) |
922 | 890 | translation: "{0} cannot be equal to {1}", |
923 | 891 | override: false, |
924 | 892 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
925 | ||
926 | 893 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
927 | 894 | if err != nil { |
928 | 895 | log.Printf("warning: error translating FieldError: %#v", fe) |
937 | 904 | translation: "{0} must be greater than {1}", |
938 | 905 | override: false, |
939 | 906 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
940 | ||
941 | 907 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
942 | 908 | if err != nil { |
943 | 909 | log.Printf("warning: error translating FieldError: %#v", fe) |
952 | 918 | translation: "{0} must be greater than or equal to {1}", |
953 | 919 | override: false, |
954 | 920 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
955 | ||
956 | 921 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
957 | 922 | if err != nil { |
958 | 923 | log.Printf("warning: error translating FieldError: %#v", fe) |
967 | 932 | translation: "{0} must be less than {1}", |
968 | 933 | override: false, |
969 | 934 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
970 | ||
971 | 935 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
972 | 936 | if err != nil { |
973 | 937 | log.Printf("warning: error translating FieldError: %#v", fe) |
982 | 946 | translation: "{0} must be less than or equal to {1}", |
983 | 947 | override: false, |
984 | 948 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
985 | ||
986 | 949 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
987 | 950 | if err != nil { |
988 | 951 | log.Printf("warning: error translating FieldError: %#v", fe) |
1072 | 1035 | translation: "{0} must contain the text '{1}'", |
1073 | 1036 | override: false, |
1074 | 1037 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
1075 | ||
1076 | 1038 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
1077 | 1039 | if err != nil { |
1078 | 1040 | log.Printf("warning: error translating FieldError: %#v", fe) |
1087 | 1049 | translation: "{0} must contain at least one of the following characters '{1}'", |
1088 | 1050 | override: false, |
1089 | 1051 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
1090 | ||
1091 | 1052 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
1092 | 1053 | if err != nil { |
1093 | 1054 | log.Printf("warning: error translating FieldError: %#v", fe) |
1102 | 1063 | translation: "{0} cannot contain the text '{1}'", |
1103 | 1064 | override: false, |
1104 | 1065 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
1105 | ||
1106 | 1066 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
1107 | 1067 | if err != nil { |
1108 | 1068 | log.Printf("warning: error translating FieldError: %#v", fe) |
1117 | 1077 | translation: "{0} cannot contain any of the following characters '{1}'", |
1118 | 1078 | override: false, |
1119 | 1079 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
1120 | ||
1121 | 1080 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
1122 | 1081 | if err != nil { |
1123 | 1082 | log.Printf("warning: error translating FieldError: %#v", fe) |
1132 | 1091 | translation: "{0} cannot contain the following '{1}'", |
1133 | 1092 | override: false, |
1134 | 1093 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
1135 | ||
1136 | 1094 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
1137 | 1095 | if err != nil { |
1138 | 1096 | log.Printf("warning: error translating FieldError: %#v", fe) |
1324 | 1282 | tag: "json", |
1325 | 1283 | translation: "{0} must be a valid json string", |
1326 | 1284 | override: false, |
1327 | }, | |
1328 | { | |
1285 | }, | |
1286 | { | |
1287 | tag: "jwt", | |
1288 | translation: "{0} must be a valid jwt string", | |
1289 | override: false, | |
1290 | }, | |
1291 | { | |
1329 | 1292 | tag: "lowercase", |
1330 | 1293 | translation: "{0} must be a lowercase string", |
1331 | 1294 | override: false, |
1340 | 1303 | translation: "{0} does not match the {1} format", |
1341 | 1304 | override: false, |
1342 | 1305 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
1343 | ||
1306 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
1307 | if err != nil { | |
1308 | log.Printf("warning: error translating FieldError: %#v", fe) | |
1309 | return fe.(error).Error() | |
1310 | } | |
1311 | ||
1312 | return t | |
1313 | }, | |
1314 | }, | |
1315 | { | |
1316 | tag: "postcode_iso3166_alpha2", | |
1317 | translation: "{0} does not match postcode format of {1} country", | |
1318 | override: false, | |
1319 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
1320 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
1321 | if err != nil { | |
1322 | log.Printf("warning: error translating FieldError: %#v", fe) | |
1323 | return fe.(error).Error() | |
1324 | } | |
1325 | ||
1326 | return t | |
1327 | }, | |
1328 | }, | |
1329 | { | |
1330 | tag: "postcode_iso3166_alpha2_field", | |
1331 | translation: "{0} does not match postcode format of country in {1} field", | |
1332 | override: false, | |
1333 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
1344 | 1334 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
1345 | 1335 | if err != nil { |
1346 | 1336 | log.Printf("warning: error translating FieldError: %#v", fe) |
1355 | 1345 | for _, t := range translations { |
1356 | 1346 | |
1357 | 1347 | if t.customTransFunc != nil && t.customRegisFunc != nil { |
1358 | ||
1359 | 1348 | err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, t.customTransFunc) |
1360 | ||
1361 | 1349 | } else if t.customTransFunc != nil && t.customRegisFunc == nil { |
1362 | ||
1363 | 1350 | err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), t.customTransFunc) |
1364 | ||
1365 | 1351 | } else if t.customTransFunc == nil && t.customRegisFunc != nil { |
1366 | ||
1367 | 1352 | err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, translateFunc) |
1368 | ||
1369 | 1353 | } else { |
1370 | 1354 | err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), translateFunc) |
1371 | 1355 | } |
1379 | 1363 | } |
1380 | 1364 | |
1381 | 1365 | func registrationFunc(tag string, translation string, override bool) validator.RegisterTranslationsFunc { |
1382 | ||
1383 | 1366 | return func(ut ut.Translator) (err error) { |
1384 | ||
1385 | 1367 | if err = ut.Add(tag, translation, override); err != nil { |
1386 | 1368 | return |
1387 | 1369 | } |
1388 | 1370 | |
1389 | 1371 | return |
1390 | ||
1391 | 1372 | } |
1392 | ||
1393 | 1373 | } |
1394 | 1374 | |
1395 | 1375 | func translateFunc(ut ut.Translator, fe validator.FieldError) string { |
1396 | ||
1397 | 1376 | t, err := ut.T(fe.Tag(), fe.Field()) |
1398 | 1377 | if err != nil { |
1399 | 1378 | log.Printf("warning: error translating FieldError: %#v", fe) |
10 | 10 | ) |
11 | 11 | |
12 | 12 | func TestTranslations(t *testing.T) { |
13 | ||
14 | 13 | eng := english.New() |
15 | 14 | uni := ut.New(eng, eng) |
16 | 15 | trans, _ := uni.GetTranslator("en") |
141 | 140 | UniqueArray [3]string `validate:"unique"` |
142 | 141 | UniqueMap map[string]string `validate:"unique"` |
143 | 142 | JSONString string `validate:"json"` |
143 | JWTString string `validate:"jwt"` | |
144 | 144 | LowercaseString string `validate:"lowercase"` |
145 | 145 | UppercaseString string `validate:"uppercase"` |
146 | 146 | Datetime string `validate:"datetime=2006-01-02"` |
147 | PostCode string `validate:"postcode_iso3166_alpha2=SG"` | |
148 | PostCodeCountry string | |
149 | PostCodeByField string `validate:"postcode_iso3166_alpha2_field=PostCodeCountry"` | |
147 | 150 | } |
148 | 151 | |
149 | 152 | var test Test |
644 | 647 | expected: "JSONString must be a valid json string", |
645 | 648 | }, |
646 | 649 | { |
650 | ns: "Test.JWTString", | |
651 | expected: "JWTString must be a valid jwt string", | |
652 | }, | |
653 | { | |
647 | 654 | ns: "Test.LowercaseString", |
648 | 655 | expected: "LowercaseString must be a lowercase string", |
649 | 656 | }, |
654 | 661 | { |
655 | 662 | ns: "Test.Datetime", |
656 | 663 | expected: "Datetime does not match the 2006-01-02 format", |
664 | }, | |
665 | { | |
666 | ns: "Test.PostCode", | |
667 | expected: "PostCode does not match postcode format of SG country", | |
668 | }, | |
669 | { | |
670 | ns: "Test.PostCodeByField", | |
671 | expected: "PostCodeByField does not match postcode format of country in PostCodeCountry field", | |
657 | 672 | }, |
658 | 673 | } |
659 | 674 | |
671 | 686 | NotEqual(t, fe, nil) |
672 | 687 | Equal(t, tt.expected, fe.Translate(trans)) |
673 | 688 | } |
674 | ||
675 | 689 | } |
0 | package fa | |
1 | ||
2 | import ( | |
3 | "fmt" | |
4 | "log" | |
5 | "reflect" | |
6 | "strconv" | |
7 | "strings" | |
8 | "time" | |
9 | ||
10 | "github.com/go-playground/locales" | |
11 | ut "github.com/go-playground/universal-translator" | |
12 | "github.com/go-playground/validator/v10" | |
13 | ) | |
14 | ||
15 | // RegisterDefaultTranslations registers a set of default translations | |
16 | // for all built in tag's in validator; you may add your own as desired. | |
17 | func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (err error) { | |
18 | translations := []struct { | |
19 | tag string | |
20 | translation string | |
21 | override bool | |
22 | customRegisFunc validator.RegisterTranslationsFunc | |
23 | customTransFunc validator.TranslationFunc | |
24 | }{ | |
25 | { | |
26 | tag: "required", | |
27 | translation: "فیلد {0} اجباری میباشد", | |
28 | override: false, | |
29 | }, | |
30 | { | |
31 | tag: "len", | |
32 | customRegisFunc: func(ut ut.Translator) (err error) { | |
33 | if err = ut.Add("len-string", "طول {0} باید {1} باشد", false); err != nil { | |
34 | return | |
35 | } | |
36 | ||
37 | if err = ut.AddCardinal("len-string-character", "{0} کاراکتر", locales.PluralRuleOne, false); err != nil { | |
38 | return | |
39 | } | |
40 | ||
41 | if err = ut.AddCardinal("len-string-character", "{0} کاراکتر", locales.PluralRuleOther, false); err != nil { | |
42 | return | |
43 | } | |
44 | ||
45 | if err = ut.Add("len-number", "طول {0} باید برابر {1} باشد", false); err != nil { | |
46 | return | |
47 | } | |
48 | ||
49 | if err = ut.Add("len-items", "تعداد {0} باید برابر {1} باشد", false); err != nil { | |
50 | return | |
51 | } | |
52 | if err = ut.AddCardinal("len-items-item", "{0} آیتم", locales.PluralRuleOne, false); err != nil { | |
53 | return | |
54 | } | |
55 | ||
56 | if err = ut.AddCardinal("len-items-item", "{0} آیتم", locales.PluralRuleOther, false); err != nil { | |
57 | return | |
58 | } | |
59 | ||
60 | return | |
61 | }, | |
62 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
63 | var err error | |
64 | var t string | |
65 | ||
66 | var digits uint64 | |
67 | var kind reflect.Kind | |
68 | ||
69 | if idx := strings.Index(fe.Param(), "."); idx != -1 { | |
70 | digits = uint64(len(fe.Param()[idx+1:])) | |
71 | } | |
72 | ||
73 | f64, err := strconv.ParseFloat(fe.Param(), 64) | |
74 | if err != nil { | |
75 | goto END | |
76 | } | |
77 | ||
78 | kind = fe.Kind() | |
79 | if kind == reflect.Ptr { | |
80 | kind = fe.Type().Elem().Kind() | |
81 | } | |
82 | ||
83 | switch kind { | |
84 | case reflect.String: | |
85 | ||
86 | var c string | |
87 | ||
88 | c, err = ut.C("len-string-character", f64, digits, ut.FmtNumber(f64, digits)) | |
89 | if err != nil { | |
90 | goto END | |
91 | } | |
92 | ||
93 | t, err = ut.T("len-string", fe.Field(), c) | |
94 | ||
95 | case reflect.Slice, reflect.Map, reflect.Array: | |
96 | var c string | |
97 | ||
98 | c, err = ut.C("len-items-item", f64, digits, ut.FmtNumber(f64, digits)) | |
99 | if err != nil { | |
100 | goto END | |
101 | } | |
102 | ||
103 | t, err = ut.T("len-items", fe.Field(), c) | |
104 | ||
105 | default: | |
106 | t, err = ut.T("len-number", fe.Field(), ut.FmtNumber(f64, digits)) | |
107 | } | |
108 | ||
109 | END: | |
110 | if err != nil { | |
111 | fmt.Printf("warning: error translating FieldError: %s", err) | |
112 | return fe.(error).Error() | |
113 | } | |
114 | ||
115 | return t | |
116 | }, | |
117 | }, | |
118 | { | |
119 | tag: "min", | |
120 | customRegisFunc: func(ut ut.Translator) (err error) { | |
121 | if err = ut.Add("min-string", "طول {0} باید حداقل {1} باشد", false); err != nil { | |
122 | return | |
123 | } | |
124 | ||
125 | if err = ut.AddCardinal("min-string-character", "{0} کاراکتر", locales.PluralRuleOne, false); err != nil { | |
126 | return | |
127 | } | |
128 | ||
129 | if err = ut.AddCardinal("min-string-character", "{0} کاراکتر", locales.PluralRuleOther, false); err != nil { | |
130 | return | |
131 | } | |
132 | ||
133 | if err = ut.Add("min-number", "{0} باید بزرگتر یا برابر {1} باشد", false); err != nil { | |
134 | return | |
135 | } | |
136 | ||
137 | if err = ut.Add("min-items", "{0} باید شامل حداقل {1} باشد", false); err != nil { | |
138 | return | |
139 | } | |
140 | if err = ut.AddCardinal("min-items-item", "{0} آیتم", locales.PluralRuleOne, false); err != nil { | |
141 | return | |
142 | } | |
143 | ||
144 | if err = ut.AddCardinal("min-items-item", "{0} آیتم", locales.PluralRuleOther, false); err != nil { | |
145 | return | |
146 | } | |
147 | ||
148 | return | |
149 | }, | |
150 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
151 | var err error | |
152 | var t string | |
153 | ||
154 | var digits uint64 | |
155 | var kind reflect.Kind | |
156 | ||
157 | if idx := strings.Index(fe.Param(), "."); idx != -1 { | |
158 | digits = uint64(len(fe.Param()[idx+1:])) | |
159 | } | |
160 | ||
161 | f64, err := strconv.ParseFloat(fe.Param(), 64) | |
162 | if err != nil { | |
163 | goto END | |
164 | } | |
165 | ||
166 | kind = fe.Kind() | |
167 | if kind == reflect.Ptr { | |
168 | kind = fe.Type().Elem().Kind() | |
169 | } | |
170 | ||
171 | switch kind { | |
172 | case reflect.String: | |
173 | ||
174 | var c string | |
175 | ||
176 | c, err = ut.C("min-string-character", f64, digits, ut.FmtNumber(f64, digits)) | |
177 | if err != nil { | |
178 | goto END | |
179 | } | |
180 | ||
181 | t, err = ut.T("min-string", fe.Field(), c) | |
182 | ||
183 | case reflect.Slice, reflect.Map, reflect.Array: | |
184 | var c string | |
185 | ||
186 | c, err = ut.C("min-items-item", f64, digits, ut.FmtNumber(f64, digits)) | |
187 | if err != nil { | |
188 | goto END | |
189 | } | |
190 | ||
191 | t, err = ut.T("min-items", fe.Field(), c) | |
192 | ||
193 | default: | |
194 | t, err = ut.T("min-number", fe.Field(), ut.FmtNumber(f64, digits)) | |
195 | } | |
196 | ||
197 | END: | |
198 | if err != nil { | |
199 | fmt.Printf("warning: error translating FieldError: %s", err) | |
200 | return fe.(error).Error() | |
201 | } | |
202 | ||
203 | return t | |
204 | }, | |
205 | }, | |
206 | { | |
207 | tag: "max", | |
208 | customRegisFunc: func(ut ut.Translator) (err error) { | |
209 | if err = ut.Add("max-string", "طول {0} باید حداکثر {1} باشد", false); err != nil { | |
210 | return | |
211 | } | |
212 | ||
213 | if err = ut.AddCardinal("max-string-character", "{0} کاراکتر", locales.PluralRuleOne, false); err != nil { | |
214 | return | |
215 | } | |
216 | ||
217 | if err = ut.AddCardinal("max-string-character", "{0} کاراکتر", locales.PluralRuleOther, false); err != nil { | |
218 | return | |
219 | } | |
220 | ||
221 | if err = ut.Add("max-number", "{0} باید کمتر یا برابر {1} باشد", false); err != nil { | |
222 | return | |
223 | } | |
224 | ||
225 | if err = ut.Add("max-items", "{0} باید شامل حداکثر {1} باشد", false); err != nil { | |
226 | return | |
227 | } | |
228 | if err = ut.AddCardinal("max-items-item", "{0} آیتم", locales.PluralRuleOne, false); err != nil { | |
229 | return | |
230 | } | |
231 | ||
232 | if err = ut.AddCardinal("max-items-item", "{0} آیتم", locales.PluralRuleOther, false); err != nil { | |
233 | return | |
234 | } | |
235 | ||
236 | return | |
237 | }, | |
238 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
239 | var err error | |
240 | var t string | |
241 | ||
242 | var digits uint64 | |
243 | var kind reflect.Kind | |
244 | ||
245 | if idx := strings.Index(fe.Param(), "."); idx != -1 { | |
246 | digits = uint64(len(fe.Param()[idx+1:])) | |
247 | } | |
248 | ||
249 | f64, err := strconv.ParseFloat(fe.Param(), 64) | |
250 | if err != nil { | |
251 | goto END | |
252 | } | |
253 | ||
254 | kind = fe.Kind() | |
255 | if kind == reflect.Ptr { | |
256 | kind = fe.Type().Elem().Kind() | |
257 | } | |
258 | ||
259 | switch kind { | |
260 | case reflect.String: | |
261 | ||
262 | var c string | |
263 | ||
264 | c, err = ut.C("max-string-character", f64, digits, ut.FmtNumber(f64, digits)) | |
265 | if err != nil { | |
266 | goto END | |
267 | } | |
268 | ||
269 | t, err = ut.T("max-string", fe.Field(), c) | |
270 | ||
271 | case reflect.Slice, reflect.Map, reflect.Array: | |
272 | var c string | |
273 | ||
274 | c, err = ut.C("max-items-item", f64, digits, ut.FmtNumber(f64, digits)) | |
275 | if err != nil { | |
276 | goto END | |
277 | } | |
278 | ||
279 | t, err = ut.T("max-items", fe.Field(), c) | |
280 | ||
281 | default: | |
282 | t, err = ut.T("max-number", fe.Field(), ut.FmtNumber(f64, digits)) | |
283 | } | |
284 | ||
285 | END: | |
286 | if err != nil { | |
287 | fmt.Printf("warning: error translating FieldError: %s", err) | |
288 | return fe.(error).Error() | |
289 | } | |
290 | ||
291 | return t | |
292 | }, | |
293 | }, | |
294 | { | |
295 | tag: "eq", | |
296 | translation: "{0} برابر {1} نمیباشد", | |
297 | override: false, | |
298 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
299 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
300 | if err != nil { | |
301 | fmt.Printf("warning: error translating FieldError: %#v", fe) | |
302 | return fe.(error).Error() | |
303 | } | |
304 | ||
305 | return t | |
306 | }, | |
307 | }, | |
308 | { | |
309 | tag: "ne", | |
310 | translation: "{0} نباید برابر {1} باشد", | |
311 | override: false, | |
312 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
313 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
314 | if err != nil { | |
315 | fmt.Printf("warning: error translating FieldError: %#v", fe) | |
316 | return fe.(error).Error() | |
317 | } | |
318 | ||
319 | return t | |
320 | }, | |
321 | }, | |
322 | { | |
323 | tag: "lt", | |
324 | customRegisFunc: func(ut ut.Translator) (err error) { | |
325 | if err = ut.Add("lt-string", "طول {0} باید کمتر از {1} باشد", false); err != nil { | |
326 | return | |
327 | } | |
328 | ||
329 | if err = ut.AddCardinal("lt-string-character", "{0} کاراکتر", locales.PluralRuleOne, false); err != nil { | |
330 | return | |
331 | } | |
332 | ||
333 | if err = ut.AddCardinal("lt-string-character", "{0} کاراکتر", locales.PluralRuleOther, false); err != nil { | |
334 | return | |
335 | } | |
336 | ||
337 | if err = ut.Add("lt-number", "{0} باید کمتر از {1} باشد", false); err != nil { | |
338 | return | |
339 | } | |
340 | ||
341 | if err = ut.Add("lt-items", "{0} باید دارای کمتر از {1} باشد", false); err != nil { | |
342 | return | |
343 | } | |
344 | ||
345 | if err = ut.AddCardinal("lt-items-item", "{0} آیتم", locales.PluralRuleOne, false); err != nil { | |
346 | return | |
347 | } | |
348 | ||
349 | if err = ut.AddCardinal("lt-items-item", "{0} آیتم", locales.PluralRuleOther, false); err != nil { | |
350 | return | |
351 | } | |
352 | ||
353 | if err = ut.Add("lt-datetime", "{0} باید قبل از تاریخ و زمان کنونی باشد", false); err != nil { | |
354 | return | |
355 | } | |
356 | ||
357 | return | |
358 | }, | |
359 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
360 | var err error | |
361 | var t string | |
362 | var f64 float64 | |
363 | var digits uint64 | |
364 | var kind reflect.Kind | |
365 | ||
366 | fn := func() (err error) { | |
367 | if idx := strings.Index(fe.Param(), "."); idx != -1 { | |
368 | digits = uint64(len(fe.Param()[idx+1:])) | |
369 | } | |
370 | ||
371 | f64, err = strconv.ParseFloat(fe.Param(), 64) | |
372 | ||
373 | return | |
374 | } | |
375 | ||
376 | kind = fe.Kind() | |
377 | if kind == reflect.Ptr { | |
378 | kind = fe.Type().Elem().Kind() | |
379 | } | |
380 | ||
381 | switch kind { | |
382 | case reflect.String: | |
383 | ||
384 | var c string | |
385 | ||
386 | err = fn() | |
387 | if err != nil { | |
388 | goto END | |
389 | } | |
390 | ||
391 | c, err = ut.C("lt-string-character", f64, digits, ut.FmtNumber(f64, digits)) | |
392 | if err != nil { | |
393 | goto END | |
394 | } | |
395 | ||
396 | t, err = ut.T("lt-string", fe.Field(), c) | |
397 | ||
398 | case reflect.Slice, reflect.Map, reflect.Array: | |
399 | var c string | |
400 | ||
401 | err = fn() | |
402 | if err != nil { | |
403 | goto END | |
404 | } | |
405 | ||
406 | c, err = ut.C("lt-items-item", f64, digits, ut.FmtNumber(f64, digits)) | |
407 | if err != nil { | |
408 | goto END | |
409 | } | |
410 | ||
411 | t, err = ut.T("lt-items", fe.Field(), c) | |
412 | ||
413 | case reflect.Struct: | |
414 | if fe.Type() != reflect.TypeOf(time.Time{}) { | |
415 | err = fmt.Errorf("tag '%s' cannot be used on a struct type", fe.Tag()) | |
416 | goto END | |
417 | } | |
418 | ||
419 | t, err = ut.T("lt-datetime", fe.Field()) | |
420 | ||
421 | default: | |
422 | err = fn() | |
423 | if err != nil { | |
424 | goto END | |
425 | } | |
426 | ||
427 | t, err = ut.T("lt-number", fe.Field(), ut.FmtNumber(f64, digits)) | |
428 | } | |
429 | ||
430 | END: | |
431 | if err != nil { | |
432 | fmt.Printf("warning: error translating FieldError: %s", err) | |
433 | return fe.(error).Error() | |
434 | } | |
435 | ||
436 | return t | |
437 | }, | |
438 | }, | |
439 | { | |
440 | tag: "lte", | |
441 | customRegisFunc: func(ut ut.Translator) (err error) { | |
442 | if err = ut.Add("lte-string", "طول {0} باید حداکثر {1} باشد", false); err != nil { | |
443 | return | |
444 | } | |
445 | ||
446 | if err = ut.AddCardinal("lte-string-character", "{0} کاراکتر", locales.PluralRuleOne, false); err != nil { | |
447 | return | |
448 | } | |
449 | ||
450 | if err = ut.AddCardinal("lte-string-character", "{0} کاراکتر", locales.PluralRuleOther, false); err != nil { | |
451 | return | |
452 | } | |
453 | ||
454 | if err = ut.Add("lte-number", "{0} باید کمتر یا برابر {1} باشد", false); err != nil { | |
455 | return | |
456 | } | |
457 | ||
458 | if err = ut.Add("lte-items", "{0} باید حداکثر شامل {1} باشد", false); err != nil { | |
459 | return | |
460 | } | |
461 | ||
462 | if err = ut.AddCardinal("lte-items-item", "{0} آیتم", locales.PluralRuleOne, false); err != nil { | |
463 | return | |
464 | } | |
465 | ||
466 | if err = ut.AddCardinal("lte-items-item", "{0} آیتم", locales.PluralRuleOther, false); err != nil { | |
467 | return | |
468 | } | |
469 | ||
470 | if err = ut.Add("lte-datetime", "{0} باید قبل یا برابر تاریخ و زمان کنونی باشد", false); err != nil { | |
471 | return | |
472 | } | |
473 | ||
474 | return | |
475 | }, | |
476 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
477 | var err error | |
478 | var t string | |
479 | var f64 float64 | |
480 | var digits uint64 | |
481 | var kind reflect.Kind | |
482 | ||
483 | fn := func() (err error) { | |
484 | if idx := strings.Index(fe.Param(), "."); idx != -1 { | |
485 | digits = uint64(len(fe.Param()[idx+1:])) | |
486 | } | |
487 | ||
488 | f64, err = strconv.ParseFloat(fe.Param(), 64) | |
489 | ||
490 | return | |
491 | } | |
492 | ||
493 | kind = fe.Kind() | |
494 | if kind == reflect.Ptr { | |
495 | kind = fe.Type().Elem().Kind() | |
496 | } | |
497 | ||
498 | switch kind { | |
499 | case reflect.String: | |
500 | ||
501 | var c string | |
502 | ||
503 | err = fn() | |
504 | if err != nil { | |
505 | goto END | |
506 | } | |
507 | ||
508 | c, err = ut.C("lte-string-character", f64, digits, ut.FmtNumber(f64, digits)) | |
509 | if err != nil { | |
510 | goto END | |
511 | } | |
512 | ||
513 | t, err = ut.T("lte-string", fe.Field(), c) | |
514 | ||
515 | case reflect.Slice, reflect.Map, reflect.Array: | |
516 | var c string | |
517 | ||
518 | err = fn() | |
519 | if err != nil { | |
520 | goto END | |
521 | } | |
522 | ||
523 | c, err = ut.C("lte-items-item", f64, digits, ut.FmtNumber(f64, digits)) | |
524 | if err != nil { | |
525 | goto END | |
526 | } | |
527 | ||
528 | t, err = ut.T("lte-items", fe.Field(), c) | |
529 | ||
530 | case reflect.Struct: | |
531 | if fe.Type() != reflect.TypeOf(time.Time{}) { | |
532 | err = fmt.Errorf("tag '%s' cannot be used on a struct type", fe.Tag()) | |
533 | goto END | |
534 | } | |
535 | ||
536 | t, err = ut.T("lte-datetime", fe.Field()) | |
537 | ||
538 | default: | |
539 | err = fn() | |
540 | if err != nil { | |
541 | goto END | |
542 | } | |
543 | ||
544 | t, err = ut.T("lte-number", fe.Field(), ut.FmtNumber(f64, digits)) | |
545 | } | |
546 | ||
547 | END: | |
548 | if err != nil { | |
549 | fmt.Printf("warning: error translating FieldError: %s", err) | |
550 | return fe.(error).Error() | |
551 | } | |
552 | ||
553 | return t | |
554 | }, | |
555 | }, | |
556 | { | |
557 | tag: "gt", | |
558 | customRegisFunc: func(ut ut.Translator) (err error) { | |
559 | if err = ut.Add("gt-string", "طول {0} باید بیشتر از {1} باشد", false); err != nil { | |
560 | return | |
561 | } | |
562 | ||
563 | if err = ut.AddCardinal("gt-string-character", "{0} کاراکتر", locales.PluralRuleOne, false); err != nil { | |
564 | return | |
565 | } | |
566 | ||
567 | if err = ut.AddCardinal("gt-string-character", "{0} کاراکتر", locales.PluralRuleOther, false); err != nil { | |
568 | return | |
569 | } | |
570 | ||
571 | if err = ut.Add("gt-number", "{0} باید بیشتر از {1} باشد", false); err != nil { | |
572 | return | |
573 | } | |
574 | ||
575 | if err = ut.Add("gt-items", "{0} باید دارای بیشتر از {1} باشد", false); err != nil { | |
576 | return | |
577 | } | |
578 | ||
579 | if err = ut.AddCardinal("gt-items-item", "{0} آیتم", locales.PluralRuleOne, false); err != nil { | |
580 | return | |
581 | } | |
582 | ||
583 | if err = ut.AddCardinal("gt-items-item", "{0} آیتم", locales.PluralRuleOther, false); err != nil { | |
584 | return | |
585 | } | |
586 | ||
587 | if err = ut.Add("gt-datetime", "{0} باید بعد از تاریخ و زمان کنونی باشد", false); err != nil { | |
588 | return | |
589 | } | |
590 | ||
591 | return | |
592 | }, | |
593 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
594 | var err error | |
595 | var t string | |
596 | var f64 float64 | |
597 | var digits uint64 | |
598 | var kind reflect.Kind | |
599 | ||
600 | fn := func() (err error) { | |
601 | if idx := strings.Index(fe.Param(), "."); idx != -1 { | |
602 | digits = uint64(len(fe.Param()[idx+1:])) | |
603 | } | |
604 | ||
605 | f64, err = strconv.ParseFloat(fe.Param(), 64) | |
606 | ||
607 | return | |
608 | } | |
609 | ||
610 | kind = fe.Kind() | |
611 | if kind == reflect.Ptr { | |
612 | kind = fe.Type().Elem().Kind() | |
613 | } | |
614 | ||
615 | switch kind { | |
616 | case reflect.String: | |
617 | ||
618 | var c string | |
619 | ||
620 | err = fn() | |
621 | if err != nil { | |
622 | goto END | |
623 | } | |
624 | ||
625 | c, err = ut.C("gt-string-character", f64, digits, ut.FmtNumber(f64, digits)) | |
626 | if err != nil { | |
627 | goto END | |
628 | } | |
629 | ||
630 | t, err = ut.T("gt-string", fe.Field(), c) | |
631 | ||
632 | case reflect.Slice, reflect.Map, reflect.Array: | |
633 | var c string | |
634 | ||
635 | err = fn() | |
636 | if err != nil { | |
637 | goto END | |
638 | } | |
639 | ||
640 | c, err = ut.C("gt-items-item", f64, digits, ut.FmtNumber(f64, digits)) | |
641 | if err != nil { | |
642 | goto END | |
643 | } | |
644 | ||
645 | t, err = ut.T("gt-items", fe.Field(), c) | |
646 | ||
647 | case reflect.Struct: | |
648 | if fe.Type() != reflect.TypeOf(time.Time{}) { | |
649 | err = fmt.Errorf("tag '%s' cannot be used on a struct type", fe.Tag()) | |
650 | goto END | |
651 | } | |
652 | ||
653 | t, err = ut.T("gt-datetime", fe.Field()) | |
654 | ||
655 | default: | |
656 | err = fn() | |
657 | if err != nil { | |
658 | goto END | |
659 | } | |
660 | ||
661 | t, err = ut.T("gt-number", fe.Field(), ut.FmtNumber(f64, digits)) | |
662 | } | |
663 | ||
664 | END: | |
665 | if err != nil { | |
666 | fmt.Printf("warning: error translating FieldError: %s", err) | |
667 | return fe.(error).Error() | |
668 | } | |
669 | ||
670 | return t | |
671 | }, | |
672 | }, | |
673 | { | |
674 | tag: "gte", | |
675 | customRegisFunc: func(ut ut.Translator) (err error) { | |
676 | if err = ut.Add("gte-string", "طول {0} باید حداقل {1} باشد", false); err != nil { | |
677 | return | |
678 | } | |
679 | ||
680 | if err = ut.AddCardinal("gte-string-character", "{0} کاراکتر", locales.PluralRuleOne, false); err != nil { | |
681 | return | |
682 | } | |
683 | ||
684 | if err = ut.AddCardinal("gte-string-character", "{0} کاراکتر", locales.PluralRuleOther, false); err != nil { | |
685 | return | |
686 | } | |
687 | ||
688 | if err = ut.Add("gte-number", "{0} باید بیشتر یا برابر {1} باشد", false); err != nil { | |
689 | return | |
690 | } | |
691 | ||
692 | if err = ut.Add("gte-items", "{0} باید شامل حداقل {1} باشد", false); err != nil { | |
693 | return | |
694 | } | |
695 | ||
696 | if err = ut.AddCardinal("gte-items-item", "{0} آیتم", locales.PluralRuleOne, false); err != nil { | |
697 | return | |
698 | } | |
699 | ||
700 | if err = ut.AddCardinal("gte-items-item", "{0} آیتم", locales.PluralRuleOther, false); err != nil { | |
701 | return | |
702 | } | |
703 | ||
704 | if err = ut.Add("gte-datetime", "{0} باید بعد یا برابر تاریخ و زمان کنونی باشد", false); err != nil { | |
705 | return | |
706 | } | |
707 | ||
708 | return | |
709 | }, | |
710 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
711 | var err error | |
712 | var t string | |
713 | var f64 float64 | |
714 | var digits uint64 | |
715 | var kind reflect.Kind | |
716 | ||
717 | fn := func() (err error) { | |
718 | if idx := strings.Index(fe.Param(), "."); idx != -1 { | |
719 | digits = uint64(len(fe.Param()[idx+1:])) | |
720 | } | |
721 | ||
722 | f64, err = strconv.ParseFloat(fe.Param(), 64) | |
723 | ||
724 | return | |
725 | } | |
726 | ||
727 | kind = fe.Kind() | |
728 | if kind == reflect.Ptr { | |
729 | kind = fe.Type().Elem().Kind() | |
730 | } | |
731 | ||
732 | switch kind { | |
733 | case reflect.String: | |
734 | ||
735 | var c string | |
736 | ||
737 | err = fn() | |
738 | if err != nil { | |
739 | goto END | |
740 | } | |
741 | ||
742 | c, err = ut.C("gte-string-character", f64, digits, ut.FmtNumber(f64, digits)) | |
743 | if err != nil { | |
744 | goto END | |
745 | } | |
746 | ||
747 | t, err = ut.T("gte-string", fe.Field(), c) | |
748 | ||
749 | case reflect.Slice, reflect.Map, reflect.Array: | |
750 | var c string | |
751 | ||
752 | err = fn() | |
753 | if err != nil { | |
754 | goto END | |
755 | } | |
756 | ||
757 | c, err = ut.C("gte-items-item", f64, digits, ut.FmtNumber(f64, digits)) | |
758 | if err != nil { | |
759 | goto END | |
760 | } | |
761 | ||
762 | t, err = ut.T("gte-items", fe.Field(), c) | |
763 | ||
764 | case reflect.Struct: | |
765 | if fe.Type() != reflect.TypeOf(time.Time{}) { | |
766 | err = fmt.Errorf("tag '%s' cannot be used on a struct type", fe.Tag()) | |
767 | goto END | |
768 | } | |
769 | ||
770 | t, err = ut.T("gte-datetime", fe.Field()) | |
771 | ||
772 | default: | |
773 | err = fn() | |
774 | if err != nil { | |
775 | goto END | |
776 | } | |
777 | ||
778 | t, err = ut.T("gte-number", fe.Field(), ut.FmtNumber(f64, digits)) | |
779 | } | |
780 | ||
781 | END: | |
782 | if err != nil { | |
783 | fmt.Printf("warning: error translating FieldError: %s", err) | |
784 | return fe.(error).Error() | |
785 | } | |
786 | ||
787 | return t | |
788 | }, | |
789 | }, | |
790 | { | |
791 | tag: "eqfield", | |
792 | translation: "{0} باید برابر {1} باشد", | |
793 | override: false, | |
794 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
795 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
796 | if err != nil { | |
797 | log.Printf("warning: error translating FieldError: %#v", fe) | |
798 | return fe.(error).Error() | |
799 | } | |
800 | ||
801 | return t | |
802 | }, | |
803 | }, | |
804 | { | |
805 | tag: "eqcsfield", | |
806 | translation: "{0} باید برابر {1} باشد", | |
807 | override: false, | |
808 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
809 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
810 | if err != nil { | |
811 | log.Printf("warning: error translating FieldError: %#v", fe) | |
812 | return fe.(error).Error() | |
813 | } | |
814 | ||
815 | return t | |
816 | }, | |
817 | }, | |
818 | { | |
819 | tag: "necsfield", | |
820 | translation: "{0} نمیتواند برابر {1} باشد", | |
821 | override: false, | |
822 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
823 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
824 | if err != nil { | |
825 | log.Printf("warning: error translating FieldError: %#v", fe) | |
826 | return fe.(error).Error() | |
827 | } | |
828 | ||
829 | return t | |
830 | }, | |
831 | }, | |
832 | { | |
833 | tag: "gtcsfield", | |
834 | translation: "طول {0} باید بیشتر از {1} باشد", | |
835 | override: false, | |
836 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
837 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
838 | if err != nil { | |
839 | log.Printf("warning: error translating FieldError: %#v", fe) | |
840 | return fe.(error).Error() | |
841 | } | |
842 | ||
843 | return t | |
844 | }, | |
845 | }, | |
846 | { | |
847 | tag: "gtecsfield", | |
848 | translation: "طول {0} باید بیشتر یا برابر {1} باشد", | |
849 | override: false, | |
850 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
851 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
852 | if err != nil { | |
853 | log.Printf("warning: error translating FieldError: %#v", fe) | |
854 | return fe.(error).Error() | |
855 | } | |
856 | ||
857 | return t | |
858 | }, | |
859 | }, | |
860 | { | |
861 | tag: "ltcsfield", | |
862 | translation: "طول {0} باید کمتر از {1} باشد", | |
863 | override: false, | |
864 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
865 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
866 | if err != nil { | |
867 | log.Printf("warning: error translating FieldError: %#v", fe) | |
868 | return fe.(error).Error() | |
869 | } | |
870 | ||
871 | return t | |
872 | }, | |
873 | }, | |
874 | { | |
875 | tag: "ltecsfield", | |
876 | translation: "طول {0} باید کمتر یا برابر {1} باشد", | |
877 | override: false, | |
878 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
879 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
880 | if err != nil { | |
881 | log.Printf("warning: error translating FieldError: %#v", fe) | |
882 | return fe.(error).Error() | |
883 | } | |
884 | ||
885 | return t | |
886 | }, | |
887 | }, | |
888 | { | |
889 | tag: "nefield", | |
890 | translation: "{0} نمیتواند برابر {1} باشد", | |
891 | override: false, | |
892 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
893 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
894 | if err != nil { | |
895 | log.Printf("warning: error translating FieldError: %#v", fe) | |
896 | return fe.(error).Error() | |
897 | } | |
898 | ||
899 | return t | |
900 | }, | |
901 | }, | |
902 | { | |
903 | tag: "gtfield", | |
904 | translation: "طول {0} باید بیشتر از {1} باشد", | |
905 | override: false, | |
906 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
907 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
908 | if err != nil { | |
909 | log.Printf("warning: error translating FieldError: %#v", fe) | |
910 | return fe.(error).Error() | |
911 | } | |
912 | ||
913 | return t | |
914 | }, | |
915 | }, | |
916 | { | |
917 | tag: "gtefield", | |
918 | translation: "طول {0} باید بیشتر یا برابر {1} باشد", | |
919 | override: false, | |
920 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
921 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
922 | if err != nil { | |
923 | log.Printf("warning: error translating FieldError: %#v", fe) | |
924 | return fe.(error).Error() | |
925 | } | |
926 | ||
927 | return t | |
928 | }, | |
929 | }, | |
930 | { | |
931 | tag: "ltfield", | |
932 | translation: "طول {0} باید کمتر از {1} باشد", | |
933 | override: false, | |
934 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
935 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
936 | if err != nil { | |
937 | log.Printf("warning: error translating FieldError: %#v", fe) | |
938 | return fe.(error).Error() | |
939 | } | |
940 | ||
941 | return t | |
942 | }, | |
943 | }, | |
944 | { | |
945 | tag: "ltefield", | |
946 | translation: "طول {0} باید کمتر یا برابر {1} باشد", | |
947 | override: false, | |
948 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
949 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
950 | if err != nil { | |
951 | log.Printf("warning: error translating FieldError: %#v", fe) | |
952 | return fe.(error).Error() | |
953 | } | |
954 | ||
955 | return t | |
956 | }, | |
957 | }, | |
958 | { | |
959 | tag: "alpha", | |
960 | translation: "{0} میتواند فقط شامل حروف باشد", | |
961 | override: false, | |
962 | }, | |
963 | { | |
964 | tag: "alphanum", | |
965 | translation: "{0} میتواند فقط شامل حروف و اعداد باشد", | |
966 | override: false, | |
967 | }, | |
968 | { | |
969 | tag: "numeric", | |
970 | translation: "{0} باید یک عدد معتبر باشد", | |
971 | override: false, | |
972 | }, | |
973 | { | |
974 | tag: "number", | |
975 | translation: "{0} باید یک عدد معتبر باشد", | |
976 | override: false, | |
977 | }, | |
978 | { | |
979 | tag: "hexadecimal", | |
980 | translation: "{0} باید یک عدد درمبنای16 باشد", | |
981 | override: false, | |
982 | }, | |
983 | { | |
984 | tag: "hexcolor", | |
985 | translation: "{0} باید یک کد رنگ HEX باشد", | |
986 | override: false, | |
987 | }, | |
988 | { | |
989 | tag: "rgb", | |
990 | translation: "{0} باید یک کد رنگ RGB باشد", | |
991 | override: false, | |
992 | }, | |
993 | { | |
994 | tag: "rgba", | |
995 | translation: "{0} باید یک کد رنگ RGBA باشد", | |
996 | override: false, | |
997 | }, | |
998 | { | |
999 | tag: "hsl", | |
1000 | translation: "{0} باید یک کد رنگ HSL باشد", | |
1001 | override: false, | |
1002 | }, | |
1003 | { | |
1004 | tag: "hsla", | |
1005 | translation: "{0} باید یک کد رنگ HSLA باشد", | |
1006 | override: false, | |
1007 | }, | |
1008 | { | |
1009 | tag: "e164", | |
1010 | translation: "{0} باید یک شمارهتلفن معتبر با فرمت E.164 باشد", | |
1011 | override: false, | |
1012 | }, | |
1013 | { | |
1014 | tag: "email", | |
1015 | translation: "{0} باید یک ایمیل معتبر باشد", | |
1016 | override: false, | |
1017 | }, | |
1018 | { | |
1019 | tag: "url", | |
1020 | translation: "{0} باید یک آدرس اینترنتی معتبر باشد", | |
1021 | override: false, | |
1022 | }, | |
1023 | { | |
1024 | tag: "uri", | |
1025 | translation: "{0} باید یک URI معتبر باشد", | |
1026 | override: false, | |
1027 | }, | |
1028 | { | |
1029 | tag: "base64", | |
1030 | translation: "{0} باید یک متن درمبنای64 معتبر باشد", | |
1031 | override: false, | |
1032 | }, | |
1033 | { | |
1034 | tag: "contains", | |
1035 | translation: "{0} باید شامل '{1}' باشد", | |
1036 | override: false, | |
1037 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
1038 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
1039 | if err != nil { | |
1040 | log.Printf("warning: error translating FieldError: %#v", fe) | |
1041 | return fe.(error).Error() | |
1042 | } | |
1043 | ||
1044 | return t | |
1045 | }, | |
1046 | }, | |
1047 | { | |
1048 | tag: "containsany", | |
1049 | translation: "{0} باید شامل کاراکترهای '{1}' باشد", | |
1050 | override: false, | |
1051 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
1052 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
1053 | if err != nil { | |
1054 | log.Printf("warning: error translating FieldError: %#v", fe) | |
1055 | return fe.(error).Error() | |
1056 | } | |
1057 | ||
1058 | return t | |
1059 | }, | |
1060 | }, | |
1061 | { | |
1062 | tag: "excludes", | |
1063 | translation: "{0} نمیتواند شامل '{1}' باشد", | |
1064 | override: false, | |
1065 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
1066 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
1067 | if err != nil { | |
1068 | log.Printf("warning: error translating FieldError: %#v", fe) | |
1069 | return fe.(error).Error() | |
1070 | } | |
1071 | ||
1072 | return t | |
1073 | }, | |
1074 | }, | |
1075 | { | |
1076 | tag: "excludesall", | |
1077 | translation: "{0} نمیتواند شامل کاراکترهای '{1}' باشد", | |
1078 | override: false, | |
1079 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
1080 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
1081 | if err != nil { | |
1082 | log.Printf("warning: error translating FieldError: %#v", fe) | |
1083 | return fe.(error).Error() | |
1084 | } | |
1085 | ||
1086 | return t | |
1087 | }, | |
1088 | }, | |
1089 | { | |
1090 | tag: "excludesrune", | |
1091 | translation: "{0} نمیتواند شامل '{1}' باشد", | |
1092 | override: false, | |
1093 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
1094 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
1095 | if err != nil { | |
1096 | log.Printf("warning: error translating FieldError: %#v", fe) | |
1097 | return fe.(error).Error() | |
1098 | } | |
1099 | ||
1100 | return t | |
1101 | }, | |
1102 | }, | |
1103 | { | |
1104 | tag: "isbn", | |
1105 | translation: "{0} باید یک شابک معتبر باشد", | |
1106 | override: false, | |
1107 | }, | |
1108 | { | |
1109 | tag: "isbn10", | |
1110 | translation: "{0} باید یک شابک(ISBN-10) معتبر باشد", | |
1111 | override: false, | |
1112 | }, | |
1113 | { | |
1114 | tag: "isbn13", | |
1115 | translation: "{0} باید یک شابک(ISBN-13) معتبر باشد", | |
1116 | override: false, | |
1117 | }, | |
1118 | { | |
1119 | tag: "uuid", | |
1120 | translation: "{0} باید یک UUID معتبر باشد", | |
1121 | override: false, | |
1122 | }, | |
1123 | { | |
1124 | tag: "uuid3", | |
1125 | translation: "{0} باید یک UUID نسخه 3 معتبر باشد", | |
1126 | override: false, | |
1127 | }, | |
1128 | { | |
1129 | tag: "uuid4", | |
1130 | translation: "{0} باید یک UUID نسخه 4 معتبر باشد", | |
1131 | override: false, | |
1132 | }, | |
1133 | { | |
1134 | tag: "uuid5", | |
1135 | translation: "{0} باید یک UUID نسخه 5 معتبر باشد", | |
1136 | override: false, | |
1137 | }, | |
1138 | { | |
1139 | tag: "ascii", | |
1140 | translation: "{0} باید فقط شامل کاراکترهای اسکی باشد", | |
1141 | override: false, | |
1142 | }, | |
1143 | { | |
1144 | tag: "printascii", | |
1145 | translation: "{0} باید فقط شامل کاراکترهای اسکی قابل چاپ باشد", | |
1146 | override: false, | |
1147 | }, | |
1148 | { | |
1149 | tag: "multibyte", | |
1150 | translation: "{0} باید شامل کاراکترهای چندبایته باشد", | |
1151 | override: false, | |
1152 | }, | |
1153 | { | |
1154 | tag: "datauri", | |
1155 | translation: "{0} باید یک Data URI معتبر باشد", | |
1156 | override: false, | |
1157 | }, | |
1158 | { | |
1159 | tag: "latitude", | |
1160 | translation: "{0} باید یک عرض جغرافیایی معتبر باشد", | |
1161 | override: false, | |
1162 | }, | |
1163 | { | |
1164 | tag: "longitude", | |
1165 | translation: "{0} باید یک طول جغرافیایی معتبر باشد", | |
1166 | override: false, | |
1167 | }, | |
1168 | { | |
1169 | tag: "ssn", | |
1170 | translation: "{0} باید یک شماره SSN معتبر باشد", | |
1171 | override: false, | |
1172 | }, | |
1173 | { | |
1174 | tag: "ipv4", | |
1175 | translation: "{0} باید یک آدرس آیپی IPv4 معتبر باشد", | |
1176 | override: false, | |
1177 | }, | |
1178 | { | |
1179 | tag: "ipv6", | |
1180 | translation: "{0} باید یک آدرس آیپی IPv6 معتبر باشد", | |
1181 | override: false, | |
1182 | }, | |
1183 | { | |
1184 | tag: "ip", | |
1185 | translation: "{0} باید یک آدرس آیپی معتبر باشد", | |
1186 | override: false, | |
1187 | }, | |
1188 | { | |
1189 | tag: "cidr", | |
1190 | translation: "{0} باید یک نشانهگذاری CIDR معتبر باشد", | |
1191 | override: false, | |
1192 | }, | |
1193 | { | |
1194 | tag: "cidrv4", | |
1195 | translation: "{0} باید یک نشانهگذاری CIDR معتبر برای آدرس آیپی IPv4 باشد", | |
1196 | override: false, | |
1197 | }, | |
1198 | { | |
1199 | tag: "cidrv6", | |
1200 | translation: "{0} باید یک نشانهگذاری CIDR معتبر برای آدرس آیپی IPv6 باشد", | |
1201 | override: false, | |
1202 | }, | |
1203 | { | |
1204 | tag: "tcp_addr", | |
1205 | translation: "{0} باید یک آدرس TCP معتبر باشد", | |
1206 | override: false, | |
1207 | }, | |
1208 | { | |
1209 | tag: "tcp4_addr", | |
1210 | translation: "{0} باید یک آدرس TCP IPv4 معتبر باشد", | |
1211 | override: false, | |
1212 | }, | |
1213 | { | |
1214 | tag: "tcp6_addr", | |
1215 | translation: "{0} باید یک آدرس TCP IPv6 معتبر باشد", | |
1216 | override: false, | |
1217 | }, | |
1218 | { | |
1219 | tag: "udp_addr", | |
1220 | translation: "{0} باید یک آدرس UDP معتبر باشد", | |
1221 | override: false, | |
1222 | }, | |
1223 | { | |
1224 | tag: "udp4_addr", | |
1225 | translation: "{0} باید یک آدرس UDP IPv4 معتبر باشد", | |
1226 | override: false, | |
1227 | }, | |
1228 | { | |
1229 | tag: "udp6_addr", | |
1230 | translation: "{0} باید یک آدرس UDP IPv6 معتبر باشد", | |
1231 | override: false, | |
1232 | }, | |
1233 | { | |
1234 | tag: "ip_addr", | |
1235 | translation: "{0} باید یک آدرس آیپی قابل دسترس باشد", | |
1236 | override: false, | |
1237 | }, | |
1238 | { | |
1239 | tag: "ip4_addr", | |
1240 | translation: "{0} باید یک آدرس آیپی IPv4 قابل دسترس باشد", | |
1241 | override: false, | |
1242 | }, | |
1243 | { | |
1244 | tag: "ip6_addr", | |
1245 | translation: "{0} باید یک آدرس آیپی IPv6 قابل دسترس باشد", | |
1246 | override: false, | |
1247 | }, | |
1248 | { | |
1249 | tag: "unix_addr", | |
1250 | translation: "{0} باید یک آدرس UNIX معتبر باشد", | |
1251 | override: false, | |
1252 | }, | |
1253 | { | |
1254 | tag: "mac", | |
1255 | translation: "{0} باید یک مکآدرس معتبر باشد", | |
1256 | override: false, | |
1257 | }, | |
1258 | { | |
1259 | tag: "unique", | |
1260 | translation: "{0} باید شامل مقادیر منحصربفرد باشد", | |
1261 | override: false, | |
1262 | }, | |
1263 | { | |
1264 | tag: "iscolor", | |
1265 | translation: "{0} باید یک رنگ معتبر باشد", | |
1266 | override: false, | |
1267 | }, | |
1268 | { | |
1269 | tag: "oneof", | |
1270 | translation: "{0} باید یکی از مقادیر [{1}] باشد", | |
1271 | override: false, | |
1272 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
1273 | s, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
1274 | if err != nil { | |
1275 | log.Printf("warning: error translating FieldError: %#v", fe) | |
1276 | return fe.(error).Error() | |
1277 | } | |
1278 | return s | |
1279 | }, | |
1280 | }, | |
1281 | { | |
1282 | tag: "json", | |
1283 | translation: "{0} باید یک json معتبر باشد", | |
1284 | override: false, | |
1285 | }, | |
1286 | { | |
1287 | tag: "lowercase", | |
1288 | translation: "{0} باید یک متن با حروف کوچک باشد", | |
1289 | override: false, | |
1290 | }, | |
1291 | { | |
1292 | tag: "uppercase", | |
1293 | translation: "{0} باید یک متن با حروف بزرگ باشد", | |
1294 | override: false, | |
1295 | }, | |
1296 | { | |
1297 | tag: "datetime", | |
1298 | translation: "فرمت {0} با {1} سازگار نیست", | |
1299 | override: false, | |
1300 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
1301 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
1302 | if err != nil { | |
1303 | log.Printf("warning: error translating FieldError: %#v", fe) | |
1304 | return fe.(error).Error() | |
1305 | } | |
1306 | ||
1307 | return t | |
1308 | }, | |
1309 | }, | |
1310 | { | |
1311 | tag: "postcode_iso3166_alpha2", | |
1312 | translation: "{0} یک کدپستی معتبر کشور {1} نیست", | |
1313 | override: false, | |
1314 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
1315 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
1316 | if err != nil { | |
1317 | log.Printf("warning: error translating FieldError: %#v", fe) | |
1318 | return fe.(error).Error() | |
1319 | } | |
1320 | ||
1321 | return t | |
1322 | }, | |
1323 | }, | |
1324 | { | |
1325 | tag: "postcode_iso3166_alpha2_field", | |
1326 | translation: "{0} یک کدپستی معتبر کشور فیلد {1} نیست", | |
1327 | override: false, | |
1328 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
1329 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
1330 | if err != nil { | |
1331 | log.Printf("warning: error translating FieldError: %#v", fe) | |
1332 | return fe.(error).Error() | |
1333 | } | |
1334 | ||
1335 | return t | |
1336 | }, | |
1337 | }, | |
1338 | } | |
1339 | ||
1340 | for _, t := range translations { | |
1341 | ||
1342 | if t.customTransFunc != nil && t.customRegisFunc != nil { | |
1343 | err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, t.customTransFunc) | |
1344 | } else if t.customTransFunc != nil && t.customRegisFunc == nil { | |
1345 | err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), t.customTransFunc) | |
1346 | } else if t.customTransFunc == nil && t.customRegisFunc != nil { | |
1347 | err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, translateFunc) | |
1348 | } else { | |
1349 | err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), translateFunc) | |
1350 | } | |
1351 | ||
1352 | if err != nil { | |
1353 | return | |
1354 | } | |
1355 | } | |
1356 | ||
1357 | return | |
1358 | } | |
1359 | ||
1360 | func registrationFunc(tag string, translation string, override bool) validator.RegisterTranslationsFunc { | |
1361 | return func(ut ut.Translator) (err error) { | |
1362 | if err = ut.Add(tag, translation, override); err != nil { | |
1363 | return | |
1364 | } | |
1365 | ||
1366 | return | |
1367 | } | |
1368 | } | |
1369 | ||
1370 | func translateFunc(ut ut.Translator, fe validator.FieldError) string { | |
1371 | t, err := ut.T(fe.Tag(), fe.Field()) | |
1372 | if err != nil { | |
1373 | log.Printf("warning: error translating FieldError: %#v", fe) | |
1374 | return fe.(error).Error() | |
1375 | } | |
1376 | ||
1377 | return t | |
1378 | } |
0 | package fa | |
1 | ||
2 | import ( | |
3 | "testing" | |
4 | "time" | |
5 | ||
6 | . "github.com/go-playground/assert/v2" | |
7 | english "github.com/go-playground/locales/en" | |
8 | ut "github.com/go-playground/universal-translator" | |
9 | "github.com/go-playground/validator/v10" | |
10 | ) | |
11 | ||
12 | func TestTranslations(t *testing.T) { | |
13 | eng := english.New() | |
14 | uni := ut.New(eng, eng) | |
15 | trans, _ := uni.GetTranslator("en") | |
16 | ||
17 | validate := validator.New() | |
18 | ||
19 | err := RegisterDefaultTranslations(validate, trans) | |
20 | Equal(t, err, nil) | |
21 | ||
22 | type Inner struct { | |
23 | EqCSFieldString string | |
24 | NeCSFieldString string | |
25 | GtCSFieldString string | |
26 | GteCSFieldString string | |
27 | LtCSFieldString string | |
28 | LteCSFieldString string | |
29 | } | |
30 | ||
31 | type Test struct { | |
32 | Inner Inner | |
33 | RequiredString string `validate:"required"` | |
34 | RequiredNumber int `validate:"required"` | |
35 | RequiredMultiple []string `validate:"required"` | |
36 | LenString string `validate:"len=1"` | |
37 | LenNumber float64 `validate:"len=1113.00"` | |
38 | LenMultiple []string `validate:"len=7"` | |
39 | MinString string `validate:"min=1"` | |
40 | MinNumber float64 `validate:"min=1113.00"` | |
41 | MinMultiple []string `validate:"min=7"` | |
42 | MaxString string `validate:"max=3"` | |
43 | MaxNumber float64 `validate:"max=1113.00"` | |
44 | MaxMultiple []string `validate:"max=7"` | |
45 | EqString string `validate:"eq=3"` | |
46 | EqNumber float64 `validate:"eq=2.33"` | |
47 | EqMultiple []string `validate:"eq=7"` | |
48 | NeString string `validate:"ne="` | |
49 | NeNumber float64 `validate:"ne=0.00"` | |
50 | NeMultiple []string `validate:"ne=0"` | |
51 | LtString string `validate:"lt=3"` | |
52 | LtNumber float64 `validate:"lt=5.56"` | |
53 | LtMultiple []string `validate:"lt=2"` | |
54 | LtTime time.Time `validate:"lt"` | |
55 | LteString string `validate:"lte=3"` | |
56 | LteNumber float64 `validate:"lte=5.56"` | |
57 | LteMultiple []string `validate:"lte=2"` | |
58 | LteTime time.Time `validate:"lte"` | |
59 | GtString string `validate:"gt=3"` | |
60 | GtNumber float64 `validate:"gt=5.56"` | |
61 | GtMultiple []string `validate:"gt=2"` | |
62 | GtTime time.Time `validate:"gt"` | |
63 | GteString string `validate:"gte=3"` | |
64 | GteNumber float64 `validate:"gte=5.56"` | |
65 | GteMultiple []string `validate:"gte=2"` | |
66 | GteTime time.Time `validate:"gte"` | |
67 | EqFieldString string `validate:"eqfield=MaxString"` | |
68 | EqCSFieldString string `validate:"eqcsfield=Inner.EqCSFieldString"` | |
69 | NeCSFieldString string `validate:"necsfield=Inner.NeCSFieldString"` | |
70 | GtCSFieldString string `validate:"gtcsfield=Inner.GtCSFieldString"` | |
71 | GteCSFieldString string `validate:"gtecsfield=Inner.GteCSFieldString"` | |
72 | LtCSFieldString string `validate:"ltcsfield=Inner.LtCSFieldString"` | |
73 | LteCSFieldString string `validate:"ltecsfield=Inner.LteCSFieldString"` | |
74 | NeFieldString string `validate:"nefield=EqFieldString"` | |
75 | GtFieldString string `validate:"gtfield=MaxString"` | |
76 | GteFieldString string `validate:"gtefield=MaxString"` | |
77 | LtFieldString string `validate:"ltfield=MaxString"` | |
78 | LteFieldString string `validate:"ltefield=MaxString"` | |
79 | AlphaString string `validate:"alpha"` | |
80 | AlphanumString string `validate:"alphanum"` | |
81 | NumericString string `validate:"numeric"` | |
82 | NumberString string `validate:"number"` | |
83 | HexadecimalString string `validate:"hexadecimal"` | |
84 | HexColorString string `validate:"hexcolor"` | |
85 | RGBColorString string `validate:"rgb"` | |
86 | RGBAColorString string `validate:"rgba"` | |
87 | HSLColorString string `validate:"hsl"` | |
88 | HSLAColorString string `validate:"hsla"` | |
89 | Email string `validate:"email"` | |
90 | URL string `validate:"url"` | |
91 | URI string `validate:"uri"` | |
92 | Base64 string `validate:"base64"` | |
93 | Contains string `validate:"contains=purpose"` | |
94 | ContainsAny string `validate:"containsany=!@#$"` | |
95 | Excludes string `validate:"excludes=text"` | |
96 | ExcludesAll string `validate:"excludesall=!@#$"` | |
97 | ExcludesRune string `validate:"excludesrune=☻"` | |
98 | ISBN string `validate:"isbn"` | |
99 | ISBN10 string `validate:"isbn10"` | |
100 | ISBN13 string `validate:"isbn13"` | |
101 | UUID string `validate:"uuid"` | |
102 | UUID3 string `validate:"uuid3"` | |
103 | UUID4 string `validate:"uuid4"` | |
104 | UUID5 string `validate:"uuid5"` | |
105 | ASCII string `validate:"ascii"` | |
106 | PrintableASCII string `validate:"printascii"` | |
107 | MultiByte string `validate:"multibyte"` | |
108 | DataURI string `validate:"datauri"` | |
109 | Latitude string `validate:"latitude"` | |
110 | Longitude string `validate:"longitude"` | |
111 | SSN string `validate:"ssn"` | |
112 | IP string `validate:"ip"` | |
113 | IPv4 string `validate:"ipv4"` | |
114 | IPv6 string `validate:"ipv6"` | |
115 | CIDR string `validate:"cidr"` | |
116 | CIDRv4 string `validate:"cidrv4"` | |
117 | CIDRv6 string `validate:"cidrv6"` | |
118 | TCPAddr string `validate:"tcp_addr"` | |
119 | TCPAddrv4 string `validate:"tcp4_addr"` | |
120 | TCPAddrv6 string `validate:"tcp6_addr"` | |
121 | UDPAddr string `validate:"udp_addr"` | |
122 | UDPAddrv4 string `validate:"udp4_addr"` | |
123 | UDPAddrv6 string `validate:"udp6_addr"` | |
124 | IPAddr string `validate:"ip_addr"` | |
125 | IPAddrv4 string `validate:"ip4_addr"` | |
126 | IPAddrv6 string `validate:"ip6_addr"` | |
127 | UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future | |
128 | MAC string `validate:"mac"` | |
129 | IsColor string `validate:"iscolor"` | |
130 | StrPtrMinLen *string `validate:"min=10"` | |
131 | StrPtrMaxLen *string `validate:"max=1"` | |
132 | StrPtrLen *string `validate:"len=2"` | |
133 | StrPtrLt *string `validate:"lt=1"` | |
134 | StrPtrLte *string `validate:"lte=1"` | |
135 | StrPtrGt *string `validate:"gt=10"` | |
136 | StrPtrGte *string `validate:"gte=10"` | |
137 | OneOfString string `validate:"oneof=red green"` | |
138 | OneOfInt int `validate:"oneof=5 63"` | |
139 | UniqueSlice []string `validate:"unique"` | |
140 | UniqueArray [3]string `validate:"unique"` | |
141 | UniqueMap map[string]string `validate:"unique"` | |
142 | JSONString string `validate:"json"` | |
143 | LowercaseString string `validate:"lowercase"` | |
144 | UppercaseString string `validate:"uppercase"` | |
145 | Datetime string `validate:"datetime=2006-01-02"` | |
146 | PostCode string `validate:"postcode_iso3166_alpha2=SG"` | |
147 | PostCodeCountry string | |
148 | PostCodeByField string `validate:"postcode_iso3166_alpha2_field=PostCodeCountry"` | |
149 | } | |
150 | ||
151 | var test Test | |
152 | ||
153 | test.Inner.EqCSFieldString = "1234" | |
154 | test.Inner.GtCSFieldString = "1234" | |
155 | test.Inner.GteCSFieldString = "1234" | |
156 | ||
157 | test.MaxString = "1234" | |
158 | test.MaxNumber = 2000 | |
159 | test.MaxMultiple = make([]string, 9) | |
160 | ||
161 | test.LtString = "1234" | |
162 | test.LtNumber = 6 | |
163 | test.LtMultiple = make([]string, 3) | |
164 | test.LtTime = time.Now().Add(time.Hour * 24) | |
165 | ||
166 | test.LteString = "1234" | |
167 | test.LteNumber = 6 | |
168 | test.LteMultiple = make([]string, 3) | |
169 | test.LteTime = time.Now().Add(time.Hour * 24) | |
170 | ||
171 | test.LtFieldString = "12345" | |
172 | test.LteFieldString = "12345" | |
173 | ||
174 | test.LtCSFieldString = "1234" | |
175 | test.LteCSFieldString = "1234" | |
176 | ||
177 | test.AlphaString = "abc3" | |
178 | test.AlphanumString = "abc3!" | |
179 | test.NumericString = "12E.00" | |
180 | test.NumberString = "12E" | |
181 | ||
182 | test.Excludes = "this is some test text" | |
183 | test.ExcludesAll = "This is Great!" | |
184 | test.ExcludesRune = "Love it ☻" | |
185 | ||
186 | test.ASCII = "カタカナ" | |
187 | test.PrintableASCII = "カタカナ" | |
188 | ||
189 | test.MultiByte = "1234feerf" | |
190 | ||
191 | test.LowercaseString = "ABCDEFG" | |
192 | test.UppercaseString = "abcdefg" | |
193 | ||
194 | s := "toolong" | |
195 | test.StrPtrMaxLen = &s | |
196 | test.StrPtrLen = &s | |
197 | ||
198 | test.UniqueSlice = []string{"1234", "1234"} | |
199 | test.UniqueMap = map[string]string{"key1": "1234", "key2": "1234"} | |
200 | test.Datetime = "2008-Feb-01" | |
201 | ||
202 | err = validate.Struct(test) | |
203 | NotEqual(t, err, nil) | |
204 | ||
205 | errs, ok := err.(validator.ValidationErrors) | |
206 | Equal(t, ok, true) | |
207 | ||
208 | tests := []struct { | |
209 | ns string | |
210 | expected string | |
211 | }{ | |
212 | { | |
213 | ns: "Test.IsColor", | |
214 | expected: "IsColor باید یک رنگ معتبر باشد", | |
215 | }, | |
216 | { | |
217 | ns: "Test.MAC", | |
218 | expected: "MAC باید یک مکآدرس معتبر باشد", | |
219 | }, | |
220 | { | |
221 | ns: "Test.IPAddr", | |
222 | expected: "IPAddr باید یک آدرس آیپی قابل دسترس باشد", | |
223 | }, | |
224 | { | |
225 | ns: "Test.IPAddrv4", | |
226 | expected: "IPAddrv4 باید یک آدرس آیپی IPv4 قابل دسترس باشد", | |
227 | }, | |
228 | { | |
229 | ns: "Test.IPAddrv6", | |
230 | expected: "IPAddrv6 باید یک آدرس آیپی IPv6 قابل دسترس باشد", | |
231 | }, | |
232 | { | |
233 | ns: "Test.UDPAddr", | |
234 | expected: "UDPAddr باید یک آدرس UDP معتبر باشد", | |
235 | }, | |
236 | { | |
237 | ns: "Test.UDPAddrv4", | |
238 | expected: "UDPAddrv4 باید یک آدرس UDP IPv4 معتبر باشد", | |
239 | }, | |
240 | { | |
241 | ns: "Test.UDPAddrv6", | |
242 | expected: "UDPAddrv6 باید یک آدرس UDP IPv6 معتبر باشد", | |
243 | }, | |
244 | { | |
245 | ns: "Test.TCPAddr", | |
246 | expected: "TCPAddr باید یک آدرس TCP معتبر باشد", | |
247 | }, | |
248 | { | |
249 | ns: "Test.TCPAddrv4", | |
250 | expected: "TCPAddrv4 باید یک آدرس TCP IPv4 معتبر باشد", | |
251 | }, | |
252 | { | |
253 | ns: "Test.TCPAddrv6", | |
254 | expected: "TCPAddrv6 باید یک آدرس TCP IPv6 معتبر باشد", | |
255 | }, | |
256 | { | |
257 | ns: "Test.CIDR", | |
258 | expected: "CIDR باید یک نشانهگذاری CIDR معتبر باشد", | |
259 | }, | |
260 | { | |
261 | ns: "Test.CIDRv4", | |
262 | expected: "CIDRv4 باید یک نشانهگذاری CIDR معتبر برای آدرس آیپی IPv4 باشد", | |
263 | }, | |
264 | { | |
265 | ns: "Test.CIDRv6", | |
266 | expected: "CIDRv6 باید یک نشانهگذاری CIDR معتبر برای آدرس آیپی IPv6 باشد", | |
267 | }, | |
268 | { | |
269 | ns: "Test.SSN", | |
270 | expected: "SSN باید یک شماره SSN معتبر باشد", | |
271 | }, | |
272 | { | |
273 | ns: "Test.IP", | |
274 | expected: "IP باید یک آدرس آیپی معتبر باشد", | |
275 | }, | |
276 | { | |
277 | ns: "Test.IPv4", | |
278 | expected: "IPv4 باید یک آدرس آیپی IPv4 معتبر باشد", | |
279 | }, | |
280 | { | |
281 | ns: "Test.IPv6", | |
282 | expected: "IPv6 باید یک آدرس آیپی IPv6 معتبر باشد", | |
283 | }, | |
284 | { | |
285 | ns: "Test.DataURI", | |
286 | expected: "DataURI باید یک Data URI معتبر باشد", | |
287 | }, | |
288 | { | |
289 | ns: "Test.Latitude", | |
290 | expected: "Latitude باید یک عرض جغرافیایی معتبر باشد", | |
291 | }, | |
292 | { | |
293 | ns: "Test.Longitude", | |
294 | expected: "Longitude باید یک طول جغرافیایی معتبر باشد", | |
295 | }, | |
296 | { | |
297 | ns: "Test.MultiByte", | |
298 | expected: "MultiByte باید شامل کاراکترهای چندبایته باشد", | |
299 | }, | |
300 | { | |
301 | ns: "Test.ASCII", | |
302 | expected: "ASCII باید فقط شامل کاراکترهای اسکی باشد", | |
303 | }, | |
304 | { | |
305 | ns: "Test.PrintableASCII", | |
306 | expected: "PrintableASCII باید فقط شامل کاراکترهای اسکی قابل چاپ باشد", | |
307 | }, | |
308 | { | |
309 | ns: "Test.UUID", | |
310 | expected: "UUID باید یک UUID معتبر باشد", | |
311 | }, | |
312 | { | |
313 | ns: "Test.UUID3", | |
314 | expected: "UUID3 باید یک UUID نسخه 3 معتبر باشد", | |
315 | }, | |
316 | { | |
317 | ns: "Test.UUID4", | |
318 | expected: "UUID4 باید یک UUID نسخه 4 معتبر باشد", | |
319 | }, | |
320 | { | |
321 | ns: "Test.UUID5", | |
322 | expected: "UUID5 باید یک UUID نسخه 5 معتبر باشد", | |
323 | }, | |
324 | { | |
325 | ns: "Test.ISBN", | |
326 | expected: "ISBN باید یک شابک معتبر باشد", | |
327 | }, | |
328 | { | |
329 | ns: "Test.ISBN10", | |
330 | expected: "ISBN10 باید یک شابک(ISBN-10) معتبر باشد", | |
331 | }, | |
332 | { | |
333 | ns: "Test.ISBN13", | |
334 | expected: "ISBN13 باید یک شابک(ISBN-13) معتبر باشد", | |
335 | }, | |
336 | { | |
337 | ns: "Test.Excludes", | |
338 | expected: "Excludes نمیتواند شامل 'text' باشد", | |
339 | }, | |
340 | { | |
341 | ns: "Test.ExcludesAll", | |
342 | expected: "ExcludesAll نمیتواند شامل کاراکترهای '!@#$' باشد", | |
343 | }, | |
344 | { | |
345 | ns: "Test.ExcludesRune", | |
346 | expected: "ExcludesRune نمیتواند شامل '☻' باشد", | |
347 | }, | |
348 | { | |
349 | ns: "Test.ContainsAny", | |
350 | expected: "ContainsAny باید شامل کاراکترهای '!@#$' باشد", | |
351 | }, | |
352 | { | |
353 | ns: "Test.Contains", | |
354 | expected: "Contains باید شامل 'purpose' باشد", | |
355 | }, | |
356 | { | |
357 | ns: "Test.Base64", | |
358 | expected: "Base64 باید یک متن درمبنای64 معتبر باشد", | |
359 | }, | |
360 | { | |
361 | ns: "Test.Email", | |
362 | expected: "Email باید یک ایمیل معتبر باشد", | |
363 | }, | |
364 | { | |
365 | ns: "Test.URL", | |
366 | expected: "URL باید یک آدرس اینترنتی معتبر باشد", | |
367 | }, | |
368 | { | |
369 | ns: "Test.URI", | |
370 | expected: "URI باید یک URI معتبر باشد", | |
371 | }, | |
372 | { | |
373 | ns: "Test.RGBColorString", | |
374 | expected: "RGBColorString باید یک کد رنگ RGB باشد", | |
375 | }, | |
376 | { | |
377 | ns: "Test.RGBAColorString", | |
378 | expected: "RGBAColorString باید یک کد رنگ RGBA باشد", | |
379 | }, | |
380 | { | |
381 | ns: "Test.HSLColorString", | |
382 | expected: "HSLColorString باید یک کد رنگ HSL باشد", | |
383 | }, | |
384 | { | |
385 | ns: "Test.HSLAColorString", | |
386 | expected: "HSLAColorString باید یک کد رنگ HSLA باشد", | |
387 | }, | |
388 | { | |
389 | ns: "Test.HexadecimalString", | |
390 | expected: "HexadecimalString باید یک عدد درمبنای16 باشد", | |
391 | }, | |
392 | { | |
393 | ns: "Test.HexColorString", | |
394 | expected: "HexColorString باید یک کد رنگ HEX باشد", | |
395 | }, | |
396 | { | |
397 | ns: "Test.NumberString", | |
398 | expected: "NumberString باید یک عدد معتبر باشد", | |
399 | }, | |
400 | { | |
401 | ns: "Test.NumericString", | |
402 | expected: "NumericString باید یک عدد معتبر باشد", | |
403 | }, | |
404 | { | |
405 | ns: "Test.AlphanumString", | |
406 | expected: "AlphanumString میتواند فقط شامل حروف و اعداد باشد", | |
407 | }, | |
408 | { | |
409 | ns: "Test.AlphaString", | |
410 | expected: "AlphaString میتواند فقط شامل حروف باشد", | |
411 | }, | |
412 | { | |
413 | ns: "Test.LtFieldString", | |
414 | expected: "طول LtFieldString باید کمتر از MaxString باشد", | |
415 | }, | |
416 | { | |
417 | ns: "Test.LteFieldString", | |
418 | expected: "طول LteFieldString باید کمتر یا برابر MaxString باشد", | |
419 | }, | |
420 | { | |
421 | ns: "Test.GtFieldString", | |
422 | expected: "طول GtFieldString باید بیشتر از MaxString باشد", | |
423 | }, | |
424 | { | |
425 | ns: "Test.GteFieldString", | |
426 | expected: "طول GteFieldString باید بیشتر یا برابر MaxString باشد", | |
427 | }, | |
428 | { | |
429 | ns: "Test.NeFieldString", | |
430 | expected: "NeFieldString نمیتواند برابر EqFieldString باشد", | |
431 | }, | |
432 | { | |
433 | ns: "Test.LtCSFieldString", | |
434 | expected: "طول LtCSFieldString باید کمتر از Inner.LtCSFieldString باشد", | |
435 | }, | |
436 | { | |
437 | ns: "Test.LteCSFieldString", | |
438 | expected: "طول LteCSFieldString باید کمتر یا برابر Inner.LteCSFieldString باشد", | |
439 | }, | |
440 | { | |
441 | ns: "Test.GtCSFieldString", | |
442 | expected: "طول GtCSFieldString باید بیشتر از Inner.GtCSFieldString باشد", | |
443 | }, | |
444 | { | |
445 | ns: "Test.GteCSFieldString", | |
446 | expected: "طول GteCSFieldString باید بیشتر یا برابر Inner.GteCSFieldString باشد", | |
447 | }, | |
448 | { | |
449 | ns: "Test.NeCSFieldString", | |
450 | expected: "NeCSFieldString نمیتواند برابر Inner.NeCSFieldString باشد", | |
451 | }, | |
452 | { | |
453 | ns: "Test.EqCSFieldString", | |
454 | expected: "EqCSFieldString باید برابر Inner.EqCSFieldString باشد", | |
455 | }, | |
456 | { | |
457 | ns: "Test.EqFieldString", | |
458 | expected: "EqFieldString باید برابر MaxString باشد", | |
459 | }, | |
460 | { | |
461 | ns: "Test.GteString", | |
462 | expected: "طول GteString باید حداقل 3 کاراکتر باشد", | |
463 | }, | |
464 | { | |
465 | ns: "Test.GteNumber", | |
466 | expected: "GteNumber باید بیشتر یا برابر 5.56 باشد", | |
467 | }, | |
468 | { | |
469 | ns: "Test.GteMultiple", | |
470 | expected: "GteMultiple باید شامل حداقل 2 آیتم باشد", | |
471 | }, | |
472 | { | |
473 | ns: "Test.GteTime", | |
474 | expected: "GteTime باید بعد یا برابر تاریخ و زمان کنونی باشد", | |
475 | }, | |
476 | { | |
477 | ns: "Test.GtString", | |
478 | expected: "طول GtString باید بیشتر از 3 کاراکتر باشد", | |
479 | }, | |
480 | { | |
481 | ns: "Test.GtNumber", | |
482 | expected: "GtNumber باید بیشتر از 5.56 باشد", | |
483 | }, | |
484 | { | |
485 | ns: "Test.GtMultiple", | |
486 | expected: "GtMultiple باید دارای بیشتر از 2 آیتم باشد", | |
487 | }, | |
488 | { | |
489 | ns: "Test.GtTime", | |
490 | expected: "GtTime باید بعد از تاریخ و زمان کنونی باشد", | |
491 | }, | |
492 | { | |
493 | ns: "Test.LteString", | |
494 | expected: "طول LteString باید حداکثر 3 کاراکتر باشد", | |
495 | }, | |
496 | { | |
497 | ns: "Test.LteNumber", | |
498 | expected: "LteNumber باید کمتر یا برابر 5.56 باشد", | |
499 | }, | |
500 | { | |
501 | ns: "Test.LteMultiple", | |
502 | expected: "LteMultiple باید حداکثر شامل 2 آیتم باشد", | |
503 | }, | |
504 | { | |
505 | ns: "Test.LteTime", | |
506 | expected: "LteTime باید قبل یا برابر تاریخ و زمان کنونی باشد", | |
507 | }, | |
508 | { | |
509 | ns: "Test.LtString", | |
510 | expected: "طول LtString باید کمتر از 3 کاراکتر باشد", | |
511 | }, | |
512 | { | |
513 | ns: "Test.LtNumber", | |
514 | expected: "LtNumber باید کمتر از 5.56 باشد", | |
515 | }, | |
516 | { | |
517 | ns: "Test.LtMultiple", | |
518 | expected: "LtMultiple باید دارای کمتر از 2 آیتم باشد", | |
519 | }, | |
520 | { | |
521 | ns: "Test.LtTime", | |
522 | expected: "LtTime باید قبل از تاریخ و زمان کنونی باشد", | |
523 | }, | |
524 | { | |
525 | ns: "Test.NeString", | |
526 | expected: "NeString نباید برابر باشد", | |
527 | }, | |
528 | { | |
529 | ns: "Test.NeNumber", | |
530 | expected: "NeNumber نباید برابر 0.00 باشد", | |
531 | }, | |
532 | { | |
533 | ns: "Test.NeMultiple", | |
534 | expected: "NeMultiple نباید برابر 0 باشد", | |
535 | }, | |
536 | { | |
537 | ns: "Test.EqString", | |
538 | expected: "EqString برابر 3 نمیباشد", | |
539 | }, | |
540 | { | |
541 | ns: "Test.EqNumber", | |
542 | expected: "EqNumber برابر 2.33 نمیباشد", | |
543 | }, | |
544 | { | |
545 | ns: "Test.EqMultiple", | |
546 | expected: "EqMultiple برابر 7 نمیباشد", | |
547 | }, | |
548 | { | |
549 | ns: "Test.MaxString", | |
550 | expected: "طول MaxString باید حداکثر 3 کاراکتر باشد", | |
551 | }, | |
552 | { | |
553 | ns: "Test.MaxNumber", | |
554 | expected: "MaxNumber باید کمتر یا برابر 1,113.00 باشد", | |
555 | }, | |
556 | { | |
557 | ns: "Test.MaxMultiple", | |
558 | expected: "MaxMultiple باید شامل حداکثر 7 آیتم باشد", | |
559 | }, | |
560 | { | |
561 | ns: "Test.MinString", | |
562 | expected: "طول MinString باید حداقل 1 کاراکتر باشد", | |
563 | }, | |
564 | { | |
565 | ns: "Test.MinNumber", | |
566 | expected: "MinNumber باید بزرگتر یا برابر 1,113.00 باشد", | |
567 | }, | |
568 | { | |
569 | ns: "Test.MinMultiple", | |
570 | expected: "MinMultiple باید شامل حداقل 7 آیتم باشد", | |
571 | }, | |
572 | { | |
573 | ns: "Test.LenString", | |
574 | expected: "طول LenString باید 1 کاراکتر باشد", | |
575 | }, | |
576 | { | |
577 | ns: "Test.LenNumber", | |
578 | expected: "طول LenNumber باید برابر 1,113.00 باشد", | |
579 | }, | |
580 | { | |
581 | ns: "Test.LenMultiple", | |
582 | expected: "تعداد LenMultiple باید برابر 7 آیتم باشد", | |
583 | }, | |
584 | { | |
585 | ns: "Test.RequiredString", | |
586 | expected: "فیلد RequiredString اجباری میباشد", | |
587 | }, | |
588 | { | |
589 | ns: "Test.RequiredNumber", | |
590 | expected: "فیلد RequiredNumber اجباری میباشد", | |
591 | }, | |
592 | { | |
593 | ns: "Test.RequiredMultiple", | |
594 | expected: "فیلد RequiredMultiple اجباری میباشد", | |
595 | }, | |
596 | { | |
597 | ns: "Test.StrPtrMinLen", | |
598 | expected: "طول StrPtrMinLen باید حداقل 10 کاراکتر باشد", | |
599 | }, | |
600 | { | |
601 | ns: "Test.StrPtrMaxLen", | |
602 | expected: "طول StrPtrMaxLen باید حداکثر 1 کاراکتر باشد", | |
603 | }, | |
604 | { | |
605 | ns: "Test.StrPtrLen", | |
606 | expected: "طول StrPtrLen باید 2 کاراکتر باشد", | |
607 | }, | |
608 | { | |
609 | ns: "Test.StrPtrLt", | |
610 | expected: "طول StrPtrLt باید کمتر از 1 کاراکتر باشد", | |
611 | }, | |
612 | { | |
613 | ns: "Test.StrPtrLte", | |
614 | expected: "طول StrPtrLte باید حداکثر 1 کاراکتر باشد", | |
615 | }, | |
616 | { | |
617 | ns: "Test.StrPtrGt", | |
618 | expected: "طول StrPtrGt باید بیشتر از 10 کاراکتر باشد", | |
619 | }, | |
620 | { | |
621 | ns: "Test.StrPtrGte", | |
622 | expected: "طول StrPtrGte باید حداقل 10 کاراکتر باشد", | |
623 | }, | |
624 | { | |
625 | ns: "Test.OneOfString", | |
626 | expected: "OneOfString باید یکی از مقادیر [red green] باشد", | |
627 | }, | |
628 | { | |
629 | ns: "Test.OneOfInt", | |
630 | expected: "OneOfInt باید یکی از مقادیر [5 63] باشد", | |
631 | }, | |
632 | { | |
633 | ns: "Test.UniqueSlice", | |
634 | expected: "UniqueSlice باید شامل مقادیر منحصربفرد باشد", | |
635 | }, | |
636 | { | |
637 | ns: "Test.UniqueArray", | |
638 | expected: "UniqueArray باید شامل مقادیر منحصربفرد باشد", | |
639 | }, | |
640 | { | |
641 | ns: "Test.UniqueMap", | |
642 | expected: "UniqueMap باید شامل مقادیر منحصربفرد باشد", | |
643 | }, | |
644 | { | |
645 | ns: "Test.JSONString", | |
646 | expected: "JSONString باید یک json معتبر باشد", | |
647 | }, | |
648 | { | |
649 | ns: "Test.LowercaseString", | |
650 | expected: "LowercaseString باید یک متن با حروف کوچک باشد", | |
651 | }, | |
652 | { | |
653 | ns: "Test.UppercaseString", | |
654 | expected: "UppercaseString باید یک متن با حروف بزرگ باشد", | |
655 | }, | |
656 | { | |
657 | ns: "Test.Datetime", | |
658 | expected: "فرمت Datetime با 2006-01-02 سازگار نیست", | |
659 | }, | |
660 | { | |
661 | ns: "Test.PostCode", | |
662 | expected: "PostCode یک کدپستی معتبر کشور SG نیست", | |
663 | }, | |
664 | { | |
665 | ns: "Test.PostCodeByField", | |
666 | expected: "PostCodeByField یک کدپستی معتبر کشور فیلد PostCodeCountry نیست", | |
667 | }, | |
668 | } | |
669 | ||
670 | for _, tt := range tests { | |
671 | ||
672 | var fe validator.FieldError | |
673 | ||
674 | for _, e := range errs { | |
675 | if tt.ns == e.Namespace() { | |
676 | fe = e | |
677 | break | |
678 | } | |
679 | } | |
680 | ||
681 | NotEqual(t, fe, nil) | |
682 | Equal(t, tt.expected, fe.Translate(trans)) | |
683 | } | |
684 | } |
1225 | 1225 | }, |
1226 | 1226 | { |
1227 | 1227 | tag: "uuid5", |
1228 | translation: "{0}はバージョンが4の正しいUUIDでなければなりません", | |
1228 | translation: "{0}はバージョンが5の正しいUUIDでなければなりません", | |
1229 | 1229 | override: false, |
1230 | 1230 | }, |
1231 | 1231 | { |
303 | 303 | }, |
304 | 304 | { |
305 | 305 | ns: "Test.UUID5", |
306 | expected: "UUID5はバージョンが4の正しいUUIDでなければなりません", | |
306 | expected: "UUID5はバージョンが5の正しいUUIDでなければなりません", | |
307 | 307 | }, |
308 | 308 | { |
309 | 309 | ns: "Test.ISBN", |
1000 | 1000 | override: false, |
1001 | 1001 | }, |
1002 | 1002 | { |
1003 | tag: "alphanumunicode", | |
1004 | translation: "{0}只能包含字母数字和Unicode字符", | |
1005 | override: false, | |
1006 | }, | |
1007 | { | |
1008 | tag: "alphaunicode", | |
1009 | translation: "{0}只能包含字母和Unicode字符", | |
1010 | override: false, | |
1011 | }, | |
1012 | { | |
1003 | 1013 | tag: "numeric", |
1004 | 1014 | translation: "{0}必须是一个有效的数值", |
1005 | 1015 | override: false, |
1090 | 1100 | }, |
1091 | 1101 | }, |
1092 | 1102 | { |
1103 | tag: "containsrune", | |
1104 | translation: "{0}必须包含字符'{1}'", | |
1105 | override: false, | |
1106 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
1107 | ||
1108 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
1109 | if err != nil { | |
1110 | log.Printf("警告: 翻译字段错误: %#v", fe) | |
1111 | return fe.(error).Error() | |
1112 | } | |
1113 | ||
1114 | return t | |
1115 | }, | |
1116 | }, | |
1117 | { | |
1093 | 1118 | tag: "excludes", |
1094 | 1119 | translation: "{0}不能包含文本'{1}'", |
1095 | 1120 | override: false, |
1122 | 1147 | { |
1123 | 1148 | tag: "excludesrune", |
1124 | 1149 | translation: "{0}不能包含'{1}'", |
1150 | override: false, | |
1151 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
1152 | ||
1153 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
1154 | if err != nil { | |
1155 | log.Printf("警告: 翻译字段错误: %#v", fe) | |
1156 | return fe.(error).Error() | |
1157 | } | |
1158 | ||
1159 | return t | |
1160 | }, | |
1161 | }, | |
1162 | { | |
1163 | tag: "endswith", | |
1164 | translation: "{0}必须以文本'{1}'结尾", | |
1165 | override: false, | |
1166 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
1167 | ||
1168 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
1169 | if err != nil { | |
1170 | log.Printf("警告: 翻译字段错误: %#v", fe) | |
1171 | return fe.(error).Error() | |
1172 | } | |
1173 | ||
1174 | return t | |
1175 | }, | |
1176 | }, | |
1177 | { | |
1178 | tag: "startswith", | |
1179 | translation: "{0}必须以文本'{1}'开头", | |
1125 | 1180 | override: false, |
1126 | 1181 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
1127 | 1182 |
30 | 30 | } |
31 | 31 | |
32 | 32 | type Test struct { |
33 | Inner Inner | |
34 | RequiredString string `validate:"required"` | |
35 | RequiredNumber int `validate:"required"` | |
36 | RequiredMultiple []string `validate:"required"` | |
37 | LenString string `validate:"len=1"` | |
38 | LenNumber float64 `validate:"len=1113.00"` | |
39 | LenMultiple []string `validate:"len=7"` | |
40 | MinString string `validate:"min=1"` | |
41 | MinNumber float64 `validate:"min=1113.00"` | |
42 | MinMultiple []string `validate:"min=7"` | |
43 | MaxString string `validate:"max=3"` | |
44 | MaxNumber float64 `validate:"max=1113.00"` | |
45 | MaxMultiple []string `validate:"max=7"` | |
46 | EqString string `validate:"eq=3"` | |
47 | EqNumber float64 `validate:"eq=2.33"` | |
48 | EqMultiple []string `validate:"eq=7"` | |
49 | NeString string `validate:"ne="` | |
50 | NeNumber float64 `validate:"ne=0.00"` | |
51 | NeMultiple []string `validate:"ne=0"` | |
52 | LtString string `validate:"lt=3"` | |
53 | LtNumber float64 `validate:"lt=5.56"` | |
54 | LtMultiple []string `validate:"lt=2"` | |
55 | LtTime time.Time `validate:"lt"` | |
56 | LteString string `validate:"lte=3"` | |
57 | LteNumber float64 `validate:"lte=5.56"` | |
58 | LteMultiple []string `validate:"lte=2"` | |
59 | LteTime time.Time `validate:"lte"` | |
60 | GtString string `validate:"gt=3"` | |
61 | GtNumber float64 `validate:"gt=5.56"` | |
62 | GtMultiple []string `validate:"gt=2"` | |
63 | GtTime time.Time `validate:"gt"` | |
64 | GteString string `validate:"gte=3"` | |
65 | GteNumber float64 `validate:"gte=5.56"` | |
66 | GteMultiple []string `validate:"gte=2"` | |
67 | GteTime time.Time `validate:"gte"` | |
68 | EqFieldString string `validate:"eqfield=MaxString"` | |
69 | EqCSFieldString string `validate:"eqcsfield=Inner.EqCSFieldString"` | |
70 | NeCSFieldString string `validate:"necsfield=Inner.NeCSFieldString"` | |
71 | GtCSFieldString string `validate:"gtcsfield=Inner.GtCSFieldString"` | |
72 | GteCSFieldString string `validate:"gtecsfield=Inner.GteCSFieldString"` | |
73 | LtCSFieldString string `validate:"ltcsfield=Inner.LtCSFieldString"` | |
74 | LteCSFieldString string `validate:"ltecsfield=Inner.LteCSFieldString"` | |
75 | NeFieldString string `validate:"nefield=EqFieldString"` | |
76 | GtFieldString string `validate:"gtfield=MaxString"` | |
77 | GteFieldString string `validate:"gtefield=MaxString"` | |
78 | LtFieldString string `validate:"ltfield=MaxString"` | |
79 | LteFieldString string `validate:"ltefield=MaxString"` | |
80 | AlphaString string `validate:"alpha"` | |
81 | AlphanumString string `validate:"alphanum"` | |
82 | NumericString string `validate:"numeric"` | |
83 | NumberString string `validate:"number"` | |
84 | HexadecimalString string `validate:"hexadecimal"` | |
85 | HexColorString string `validate:"hexcolor"` | |
86 | RGBColorString string `validate:"rgb"` | |
87 | RGBAColorString string `validate:"rgba"` | |
88 | HSLColorString string `validate:"hsl"` | |
89 | HSLAColorString string `validate:"hsla"` | |
90 | Email string `validate:"email"` | |
91 | URL string `validate:"url"` | |
92 | URI string `validate:"uri"` | |
93 | Base64 string `validate:"base64"` | |
94 | Contains string `validate:"contains=purpose"` | |
95 | ContainsAny string `validate:"containsany=!@#$"` | |
96 | Excludes string `validate:"excludes=text"` | |
97 | ExcludesAll string `validate:"excludesall=!@#$"` | |
98 | ExcludesRune string `validate:"excludesrune=☻"` | |
99 | ISBN string `validate:"isbn"` | |
100 | ISBN10 string `validate:"isbn10"` | |
101 | ISBN13 string `validate:"isbn13"` | |
102 | UUID string `validate:"uuid"` | |
103 | UUID3 string `validate:"uuid3"` | |
104 | UUID4 string `validate:"uuid4"` | |
105 | UUID5 string `validate:"uuid5"` | |
106 | ASCII string `validate:"ascii"` | |
107 | PrintableASCII string `validate:"printascii"` | |
108 | MultiByte string `validate:"multibyte"` | |
109 | DataURI string `validate:"datauri"` | |
110 | Latitude string `validate:"latitude"` | |
111 | Longitude string `validate:"longitude"` | |
112 | SSN string `validate:"ssn"` | |
113 | IP string `validate:"ip"` | |
114 | IPv4 string `validate:"ipv4"` | |
115 | IPv6 string `validate:"ipv6"` | |
116 | CIDR string `validate:"cidr"` | |
117 | CIDRv4 string `validate:"cidrv4"` | |
118 | CIDRv6 string `validate:"cidrv6"` | |
119 | TCPAddr string `validate:"tcp_addr"` | |
120 | TCPAddrv4 string `validate:"tcp4_addr"` | |
121 | TCPAddrv6 string `validate:"tcp6_addr"` | |
122 | UDPAddr string `validate:"udp_addr"` | |
123 | UDPAddrv4 string `validate:"udp4_addr"` | |
124 | UDPAddrv6 string `validate:"udp6_addr"` | |
125 | IPAddr string `validate:"ip_addr"` | |
126 | IPAddrv4 string `validate:"ip4_addr"` | |
127 | IPAddrv6 string `validate:"ip6_addr"` | |
128 | UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future | |
129 | MAC string `validate:"mac"` | |
130 | IsColor string `validate:"iscolor"` | |
131 | StrPtrMinLen *string `validate:"min=10"` | |
132 | StrPtrMaxLen *string `validate:"max=1"` | |
133 | StrPtrLen *string `validate:"len=2"` | |
134 | StrPtrLt *string `validate:"lt=1"` | |
135 | StrPtrLte *string `validate:"lte=1"` | |
136 | StrPtrGt *string `validate:"gt=10"` | |
137 | StrPtrGte *string `validate:"gte=10"` | |
138 | OneOfString string `validate:"oneof=red green"` | |
139 | OneOfInt int `validate:"oneof=5 63"` | |
140 | JsonString string `validate:"json"` | |
141 | LowercaseString string `validate:"lowercase"` | |
142 | UppercaseString string `validate:"uppercase"` | |
143 | Datetime string `validate:"datetime=2006-01-02"` | |
33 | Inner Inner | |
34 | RequiredString string `validate:"required"` | |
35 | RequiredNumber int `validate:"required"` | |
36 | RequiredMultiple []string `validate:"required"` | |
37 | LenString string `validate:"len=1"` | |
38 | LenNumber float64 `validate:"len=1113.00"` | |
39 | LenMultiple []string `validate:"len=7"` | |
40 | MinString string `validate:"min=1"` | |
41 | MinNumber float64 `validate:"min=1113.00"` | |
42 | MinMultiple []string `validate:"min=7"` | |
43 | MaxString string `validate:"max=3"` | |
44 | MaxNumber float64 `validate:"max=1113.00"` | |
45 | MaxMultiple []string `validate:"max=7"` | |
46 | EqString string `validate:"eq=3"` | |
47 | EqNumber float64 `validate:"eq=2.33"` | |
48 | EqMultiple []string `validate:"eq=7"` | |
49 | NeString string `validate:"ne="` | |
50 | NeNumber float64 `validate:"ne=0.00"` | |
51 | NeMultiple []string `validate:"ne=0"` | |
52 | LtString string `validate:"lt=3"` | |
53 | LtNumber float64 `validate:"lt=5.56"` | |
54 | LtMultiple []string `validate:"lt=2"` | |
55 | LtTime time.Time `validate:"lt"` | |
56 | LteString string `validate:"lte=3"` | |
57 | LteNumber float64 `validate:"lte=5.56"` | |
58 | LteMultiple []string `validate:"lte=2"` | |
59 | LteTime time.Time `validate:"lte"` | |
60 | GtString string `validate:"gt=3"` | |
61 | GtNumber float64 `validate:"gt=5.56"` | |
62 | GtMultiple []string `validate:"gt=2"` | |
63 | GtTime time.Time `validate:"gt"` | |
64 | GteString string `validate:"gte=3"` | |
65 | GteNumber float64 `validate:"gte=5.56"` | |
66 | GteMultiple []string `validate:"gte=2"` | |
67 | GteTime time.Time `validate:"gte"` | |
68 | EqFieldString string `validate:"eqfield=MaxString"` | |
69 | EqCSFieldString string `validate:"eqcsfield=Inner.EqCSFieldString"` | |
70 | NeCSFieldString string `validate:"necsfield=Inner.NeCSFieldString"` | |
71 | GtCSFieldString string `validate:"gtcsfield=Inner.GtCSFieldString"` | |
72 | GteCSFieldString string `validate:"gtecsfield=Inner.GteCSFieldString"` | |
73 | LtCSFieldString string `validate:"ltcsfield=Inner.LtCSFieldString"` | |
74 | LteCSFieldString string `validate:"ltecsfield=Inner.LteCSFieldString"` | |
75 | NeFieldString string `validate:"nefield=EqFieldString"` | |
76 | GtFieldString string `validate:"gtfield=MaxString"` | |
77 | GteFieldString string `validate:"gtefield=MaxString"` | |
78 | LtFieldString string `validate:"ltfield=MaxString"` | |
79 | LteFieldString string `validate:"ltefield=MaxString"` | |
80 | AlphaString string `validate:"alpha"` | |
81 | AlphanumString string `validate:"alphanum"` | |
82 | AlphanumUnicodeString string `validate:"alphanumunicode"` | |
83 | AlphaUnicodeString string `validate:"alphaunicode"` | |
84 | NumericString string `validate:"numeric"` | |
85 | NumberString string `validate:"number"` | |
86 | HexadecimalString string `validate:"hexadecimal"` | |
87 | HexColorString string `validate:"hexcolor"` | |
88 | RGBColorString string `validate:"rgb"` | |
89 | RGBAColorString string `validate:"rgba"` | |
90 | HSLColorString string `validate:"hsl"` | |
91 | HSLAColorString string `validate:"hsla"` | |
92 | Email string `validate:"email"` | |
93 | URL string `validate:"url"` | |
94 | URI string `validate:"uri"` | |
95 | Base64 string `validate:"base64"` | |
96 | Contains string `validate:"contains=purpose"` | |
97 | ContainsAny string `validate:"containsany=!@#$"` | |
98 | ContainsRune string `validate:"containsrune=☻"` | |
99 | Excludes string `validate:"excludes=text"` | |
100 | ExcludesAll string `validate:"excludesall=!@#$"` | |
101 | ExcludesRune string `validate:"excludesrune=☻"` | |
102 | EndsWith string `validate:"endswith=end"` | |
103 | StartsWith string `validate:"startswith=start"` | |
104 | ISBN string `validate:"isbn"` | |
105 | ISBN10 string `validate:"isbn10"` | |
106 | ISBN13 string `validate:"isbn13"` | |
107 | UUID string `validate:"uuid"` | |
108 | UUID3 string `validate:"uuid3"` | |
109 | UUID4 string `validate:"uuid4"` | |
110 | UUID5 string `validate:"uuid5"` | |
111 | ASCII string `validate:"ascii"` | |
112 | PrintableASCII string `validate:"printascii"` | |
113 | MultiByte string `validate:"multibyte"` | |
114 | DataURI string `validate:"datauri"` | |
115 | Latitude string `validate:"latitude"` | |
116 | Longitude string `validate:"longitude"` | |
117 | SSN string `validate:"ssn"` | |
118 | IP string `validate:"ip"` | |
119 | IPv4 string `validate:"ipv4"` | |
120 | IPv6 string `validate:"ipv6"` | |
121 | CIDR string `validate:"cidr"` | |
122 | CIDRv4 string `validate:"cidrv4"` | |
123 | CIDRv6 string `validate:"cidrv6"` | |
124 | TCPAddr string `validate:"tcp_addr"` | |
125 | TCPAddrv4 string `validate:"tcp4_addr"` | |
126 | TCPAddrv6 string `validate:"tcp6_addr"` | |
127 | UDPAddr string `validate:"udp_addr"` | |
128 | UDPAddrv4 string `validate:"udp4_addr"` | |
129 | UDPAddrv6 string `validate:"udp6_addr"` | |
130 | IPAddr string `validate:"ip_addr"` | |
131 | IPAddrv4 string `validate:"ip4_addr"` | |
132 | IPAddrv6 string `validate:"ip6_addr"` | |
133 | UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future | |
134 | MAC string `validate:"mac"` | |
135 | IsColor string `validate:"iscolor"` | |
136 | StrPtrMinLen *string `validate:"min=10"` | |
137 | StrPtrMaxLen *string `validate:"max=1"` | |
138 | StrPtrLen *string `validate:"len=2"` | |
139 | StrPtrLt *string `validate:"lt=1"` | |
140 | StrPtrLte *string `validate:"lte=1"` | |
141 | StrPtrGt *string `validate:"gt=10"` | |
142 | StrPtrGte *string `validate:"gte=10"` | |
143 | OneOfString string `validate:"oneof=red green"` | |
144 | OneOfInt int `validate:"oneof=5 63"` | |
145 | JsonString string `validate:"json"` | |
146 | LowercaseString string `validate:"lowercase"` | |
147 | UppercaseString string `validate:"uppercase"` | |
148 | Datetime string `validate:"datetime=2006-01-02"` | |
144 | 149 | } |
145 | 150 | |
146 | 151 | var test Test |
171 | 176 | |
172 | 177 | test.AlphaString = "abc3" |
173 | 178 | test.AlphanumString = "abc3!" |
179 | test.AlphanumUnicodeString = "abc3啊!" | |
180 | test.AlphaUnicodeString = "abc3啊" | |
174 | 181 | test.NumericString = "12E.00" |
175 | 182 | test.NumberString = "12E" |
176 | 183 | |
177 | 184 | test.Excludes = "this is some test text" |
178 | 185 | test.ExcludesAll = "This is Great!" |
179 | 186 | test.ExcludesRune = "Love it ☻" |
187 | ||
188 | test.EndsWith = "this is some test text" | |
189 | test.StartsWith = "this is some test text" | |
180 | 190 | |
181 | 191 | test.ASCII = "カタカナ" |
182 | 192 | test.PrintableASCII = "カタカナ" |
329 | 339 | expected: "ISBN13必须是一个有效的ISBN-13编号", |
330 | 340 | }, |
331 | 341 | { |
342 | ns: "Test.EndsWith", | |
343 | expected: "EndsWith必须以文本'end'结尾", | |
344 | }, | |
345 | { | |
346 | ns: "Test.StartsWith", | |
347 | expected: "StartsWith必须以文本'start'开头", | |
348 | }, | |
349 | { | |
332 | 350 | ns: "Test.Excludes", |
333 | 351 | expected: "Excludes不能包含文本'text'", |
334 | 352 | }, |
341 | 359 | expected: "ExcludesRune不能包含'☻'", |
342 | 360 | }, |
343 | 361 | { |
362 | ns: "Test.ContainsRune", | |
363 | expected: "ContainsRune必须包含字符'☻'", | |
364 | }, | |
365 | { | |
344 | 366 | ns: "Test.ContainsAny", |
345 | 367 | expected: "ContainsAny必须包含至少一个以下字符'!@#$'", |
346 | 368 | }, |
395 | 417 | { |
396 | 418 | ns: "Test.NumericString", |
397 | 419 | expected: "NumericString必须是一个有效的数值", |
420 | }, | |
421 | { | |
422 | ns: "Test.AlphaUnicodeString", | |
423 | expected: "AlphaUnicodeString只能包含字母和Unicode字符", | |
424 | }, | |
425 | { | |
426 | ns: "Test.AlphanumUnicodeString", | |
427 | expected: "AlphanumUnicodeString只能包含字母数字和Unicode字符", | |
398 | 428 | }, |
399 | 429 | { |
400 | 430 | ns: "Test.AlphanumString", |
73 | 73 | } |
74 | 74 | } |
75 | 75 | |
76 | v.traverseField(ctx, parent, current.Field(f.idx), ns, structNs, f, f.cTags) | |
76 | v.traverseField(ctx, current, current.Field(f.idx), ns, structNs, f, f.cTags) | |
77 | 77 | } |
78 | 78 | } |
79 | 79 | |
221 | 221 | structNs = append(append(structNs, cf.name...), '.') |
222 | 222 | } |
223 | 223 | |
224 | v.validateStruct(ctx, current, current, typ, ns, structNs, ct) | |
225 | return | |
226 | } | |
227 | } | |
228 | ||
229 | if !ct.hasTag { | |
224 | v.validateStruct(ctx, parent, current, typ, ns, structNs, ct) | |
225 | return | |
226 | } | |
227 | } | |
228 | ||
229 | if ct == nil || !ct.hasTag { | |
230 | 230 | return |
231 | 231 | } |
232 | 232 |
28 | 28 | requiredWithAllTag = "required_with_all" |
29 | 29 | requiredIfTag = "required_if" |
30 | 30 | requiredUnlessTag = "required_unless" |
31 | excludedWithoutAllTag = "excluded_without_all" | |
32 | excludedWithoutTag = "excluded_without" | |
33 | excludedWithTag = "excluded_with" | |
34 | excludedWithAllTag = "excluded_with_all" | |
31 | 35 | skipValidationTag = "-" |
32 | 36 | diveTag = "dive" |
33 | 37 | keysTag = "keys" |
110 | 114 | |
111 | 115 | switch k { |
112 | 116 | // these require that even if the value is nil that the validation should run, omitempty still overrides this behaviour |
113 | case requiredIfTag, requiredUnlessTag, requiredWithTag, requiredWithAllTag, requiredWithoutTag, requiredWithoutAllTag: | |
117 | case requiredIfTag, requiredUnlessTag, requiredWithTag, requiredWithAllTag, requiredWithoutTag, requiredWithoutAllTag, | |
118 | excludedWithTag, excludedWithAllTag, excludedWithoutTag, excludedWithoutAllTag: | |
114 | 119 | _ = v.registerValidation(k, wrapFunc(val), true, true) |
115 | 120 | default: |
116 | 121 | // no need to error check here, baked in will always be valid |
135 | 140 | // SetTagName allows for changing of the default tag name of 'validate' |
136 | 141 | func (v *Validate) SetTagName(name string) { |
137 | 142 | v.tagName = name |
143 | } | |
144 | ||
145 | // ValidateMapCtx validates a map using a map of validation rules and allows passing of contextual | |
146 | // validation validation information via context.Context. | |
147 | func (v Validate) ValidateMapCtx(ctx context.Context, data map[string]interface{}, rules map[string]interface{}) map[string]interface{} { | |
148 | errs := make(map[string]interface{}) | |
149 | for field, rule := range rules { | |
150 | if reflect.ValueOf(rule).Kind() == reflect.Map && reflect.ValueOf(data[field]).Kind() == reflect.Map { | |
151 | err := v.ValidateMapCtx(ctx, data[field].(map[string]interface{}), rule.(map[string]interface{})) | |
152 | if len(err) > 0 { | |
153 | errs[field] = err | |
154 | } | |
155 | } else if reflect.ValueOf(rule).Kind() == reflect.Map { | |
156 | errs[field] = errors.New("The field: '" + field + "' is not a map to dive") | |
157 | } else { | |
158 | err := v.VarCtx(ctx, data[field], rule.(string)) | |
159 | if err != nil { | |
160 | errs[field] = err | |
161 | } | |
162 | } | |
163 | } | |
164 | return errs | |
165 | } | |
166 | ||
167 | // ValidateMap validates map data form a map of tags | |
168 | func (v *Validate) ValidateMap(data map[string]interface{}, rules map[string]interface{}) map[string]interface{} { | |
169 | return v.ValidateMapCtx(context.Background(), data, rules) | |
138 | 170 | } |
139 | 171 | |
140 | 172 | // RegisterTagNameFunc registers a function to get alternate names for StructFields. |
174 | 206 | |
175 | 207 | func (v *Validate) registerValidation(tag string, fn FuncCtx, bakedIn bool, nilCheckable bool) error { |
176 | 208 | if len(tag) == 0 { |
177 | return errors.New("Function Key cannot be empty") | |
209 | return errors.New("function Key cannot be empty") | |
178 | 210 | } |
179 | 211 | |
180 | 212 | if fn == nil { |
181 | return errors.New("Function cannot be empty") | |
213 | return errors.New("function cannot be empty") | |
182 | 214 | } |
183 | 215 | |
184 | 216 | _, ok := restrictedTags[tag] |
408 | 440 | if len(flds) > 0 { |
409 | 441 | |
410 | 442 | vd.misc = append(vd.misc[0:0], name...) |
411 | vd.misc = append(vd.misc, '.') | |
443 | // Don't append empty name for unnamed structs | |
444 | if len(vd.misc) != 0 { | |
445 | vd.misc = append(vd.misc, '.') | |
446 | } | |
412 | 447 | |
413 | 448 | for _, s := range flds { |
414 | 449 |
107 | 107 | } |
108 | 108 | |
109 | 109 | func AssertError(t *testing.T, err error, nsKey, structNsKey, field, structField, expectedTag string) { |
110 | ||
111 | 110 | errs := err.(ValidationErrors) |
112 | 111 | |
113 | 112 | found := false |
149 | 148 | } |
150 | 149 | |
151 | 150 | func getError(err error, nsKey, structNsKey string) FieldError { |
152 | ||
153 | 151 | errs := err.(ValidationErrors) |
154 | 152 | |
155 | 153 | var fe FieldError |
169 | 167 | } |
170 | 168 | |
171 | 169 | func (v valuer) Value() (driver.Value, error) { |
172 | ||
173 | 170 | if v.Name == "errorme" { |
174 | 171 | panic("SQL Driver Valuer error: some kind of error") |
175 | 172 | // return nil, errors.New("some kind of error") |
188 | 185 | } |
189 | 186 | |
190 | 187 | func ValidateCustomType(field reflect.Value) interface{} { |
191 | ||
192 | 188 | if cust, ok := field.Interface().(MadeUpCustomType); ok { |
193 | 189 | |
194 | 190 | if len(cust.FirstName) == 0 || len(cust.LastName) == 0 { |
202 | 198 | } |
203 | 199 | |
204 | 200 | func OverrideIntTypeForSomeReason(field reflect.Value) interface{} { |
205 | ||
206 | 201 | if i, ok := field.Interface().(int); ok { |
207 | 202 | if i == 1 { |
208 | 203 | return "1" |
222 | 217 | } |
223 | 218 | |
224 | 219 | func ValidateValuerType(field reflect.Value) interface{} { |
225 | ||
226 | 220 | if valuer, ok := field.Interface().(driver.Valuer); ok { |
227 | 221 | |
228 | 222 | val, err := valuer.Value() |
260 | 254 | } |
261 | 255 | |
262 | 256 | func StructValidationTestStructSuccess(sl StructLevel) { |
263 | ||
264 | 257 | st := sl.Current().Interface().(TestStruct) |
265 | 258 | |
266 | 259 | if st.String != "good value" { |
269 | 262 | } |
270 | 263 | |
271 | 264 | func StructValidationTestStruct(sl StructLevel) { |
272 | ||
273 | 265 | st := sl.Current().Interface().(TestStruct) |
274 | 266 | |
275 | 267 | if st.String != "bad value" { |
278 | 270 | } |
279 | 271 | |
280 | 272 | func StructValidationNoTestStructCustomName(sl StructLevel) { |
281 | ||
282 | 273 | st := sl.Current().Interface().(TestStruct) |
283 | 274 | |
284 | 275 | if st.String != "bad value" { |
287 | 278 | } |
288 | 279 | |
289 | 280 | func StructValidationTestStructInvalid(sl StructLevel) { |
290 | ||
291 | 281 | st := sl.Current().Interface().(TestStruct) |
292 | 282 | |
293 | 283 | if st.String != "bad value" { |
296 | 286 | } |
297 | 287 | |
298 | 288 | func StructValidationTestStructReturnValidationErrors(sl StructLevel) { |
299 | ||
300 | 289 | s := sl.Current().Interface().(TestStructReturnValidationErrors) |
301 | 290 | |
302 | 291 | errs := sl.Validator().Struct(s.Inner1.Inner2) |
308 | 297 | } |
309 | 298 | |
310 | 299 | func StructValidationTestStructReturnValidationErrors2(sl StructLevel) { |
311 | ||
312 | 300 | s := sl.Current().Interface().(TestStructReturnValidationErrors) |
313 | 301 | |
314 | 302 | errs := sl.Validator().Struct(s.Inner1.Inner2) |
336 | 324 | } |
337 | 325 | |
338 | 326 | func StructLevelInvalidError(sl StructLevel) { |
339 | ||
340 | 327 | top := sl.Top().Interface().(StructLevelInvalidErr) |
341 | 328 | s := sl.Current().Interface().(StructLevelInvalidErr) |
342 | 329 | |
358 | 345 | } |
359 | 346 | |
360 | 347 | func TestStructLevelInvalidError(t *testing.T) { |
361 | ||
362 | 348 | validate := New() |
363 | 349 | validate.RegisterStructValidation(StructLevelInvalidError, StructLevelInvalidErr{}) |
364 | 350 | |
382 | 368 | } |
383 | 369 | |
384 | 370 | func TestNameNamespace(t *testing.T) { |
385 | ||
386 | 371 | type Inner2Namespace struct { |
387 | 372 | String []string `validate:"dive,required" json:"JSONString"` |
388 | 373 | } |
431 | 416 | } |
432 | 417 | |
433 | 418 | func TestAnonymous(t *testing.T) { |
434 | ||
435 | 419 | validate := New() |
436 | 420 | validate.RegisterTagNameFunc(func(fld reflect.StructField) string { |
437 | 421 | name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] |
499 | 483 | } |
500 | 484 | |
501 | 485 | func TestAnonymousSameStructDifferentTags(t *testing.T) { |
502 | ||
503 | 486 | validate := New() |
504 | 487 | validate.RegisterTagNameFunc(func(fld reflect.StructField) string { |
505 | 488 | name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] |
544 | 527 | } |
545 | 528 | |
546 | 529 | func TestStructLevelReturnValidationErrors(t *testing.T) { |
547 | ||
548 | 530 | validate := New() |
549 | 531 | validate.RegisterStructValidation(StructValidationTestStructReturnValidationErrors, TestStructReturnValidationErrors{}) |
550 | 532 | |
574 | 556 | } |
575 | 557 | |
576 | 558 | func TestStructLevelReturnValidationErrorsWithJSON(t *testing.T) { |
577 | ||
578 | 559 | validate := New() |
579 | 560 | validate.RegisterTagNameFunc(func(fld reflect.StructField) string { |
580 | 561 | name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] |
631 | 612 | } |
632 | 613 | |
633 | 614 | func TestStructLevelValidations(t *testing.T) { |
634 | ||
635 | 615 | v1 := New() |
636 | 616 | v1.RegisterStructValidation(StructValidationTestStruct, TestStruct{}) |
637 | 617 | |
665 | 645 | } |
666 | 646 | |
667 | 647 | func TestAliasTags(t *testing.T) { |
668 | ||
669 | 648 | validate := New() |
670 | 649 | validate.RegisterAlias("iscoloralias", "hexcolor|rgb|rgba|hsl|hsla") |
671 | 650 | |
713 | 692 | } |
714 | 693 | |
715 | 694 | func TestNilValidator(t *testing.T) { |
716 | ||
717 | 695 | type TestStruct struct { |
718 | 696 | Test string `validate:"required"` |
719 | 697 | } |
723 | 701 | var val *Validate |
724 | 702 | |
725 | 703 | fn := func(fl FieldLevel) bool { |
726 | ||
727 | 704 | return fl.Parent().String() == fl.Field().String() |
728 | 705 | } |
729 | 706 | |
948 | 925 | NotEqual(t, errs, nil) |
949 | 926 | AssertError(t, errs, "TestPartial.Anonymous.SubAnonStruct[0].Test", "TestPartial.Anonymous.SubAnonStruct[0].Test", "Test", "Test", "required") |
950 | 927 | |
928 | // Test for unnamed struct | |
929 | testStruct := &TestStruct{ | |
930 | String: "test", | |
931 | } | |
932 | unnamedStruct := struct { | |
933 | String string `validate:"required" json:"StringVal"` | |
934 | }{String: "test"} | |
935 | composedUnnamedStruct := struct{ *TestStruct }{&TestStruct{String: "test"}} | |
936 | ||
937 | errs = validate.StructPartial(testStruct, "String") | |
938 | Equal(t, errs, nil) | |
939 | ||
940 | errs = validate.StructPartial(unnamedStruct, "String") | |
941 | Equal(t, errs, nil) | |
942 | ||
943 | errs = validate.StructPartial(composedUnnamedStruct, "TestStruct.String") | |
944 | Equal(t, errs, nil) | |
945 | ||
946 | testStruct.String = "" | |
947 | errs = validate.StructPartial(testStruct, "String") | |
948 | NotEqual(t, errs, nil) | |
949 | AssertError(t, errs, "TestStruct.String", "TestStruct.String", "String", "String", "required") | |
950 | ||
951 | unnamedStruct.String = "" | |
952 | errs = validate.StructPartial(unnamedStruct, "String") | |
953 | NotEqual(t, errs, nil) | |
954 | AssertError(t, errs, "String", "String", "String", "String", "required") | |
955 | ||
956 | composedUnnamedStruct.String = "" | |
957 | errs = validate.StructPartial(composedUnnamedStruct, "TestStruct.String") | |
958 | NotEqual(t, errs, nil) | |
959 | AssertError(t, errs, "TestStruct.String", "TestStruct.String", "String", "String", "required") | |
951 | 960 | } |
952 | 961 | |
953 | 962 | func TestCrossStructLteFieldValidation(t *testing.T) { |
1637 | 1646 | i := 1 |
1638 | 1647 | j = 1 |
1639 | 1648 | k = 1.543 |
1649 | b := true | |
1640 | 1650 | arr := []string{"test"} |
1641 | 1651 | |
1642 | 1652 | s2 := "abcd" |
1643 | 1653 | i2 := 1 |
1644 | 1654 | j2 = 1 |
1645 | 1655 | k2 = 1.543 |
1656 | b2 := true | |
1646 | 1657 | arr2 := []string{"test"} |
1647 | 1658 | arr3 := []string{"test", "test2"} |
1648 | 1659 | now2 := now |
1663 | 1674 | NotEqual(t, errs, nil) |
1664 | 1675 | AssertError(t, errs, "", "", "", "", "necsfield") |
1665 | 1676 | |
1677 | errs = validate.VarWithValue(b2, b, "necsfield") | |
1678 | NotEqual(t, errs, nil) | |
1679 | AssertError(t, errs, "", "", "", "", "necsfield") | |
1680 | ||
1666 | 1681 | errs = validate.VarWithValue(arr2, arr, "necsfield") |
1667 | 1682 | NotEqual(t, errs, nil) |
1668 | 1683 | AssertError(t, errs, "", "", "", "", "necsfield") |
1788 | 1803 | errs = validate.Struct(test) |
1789 | 1804 | Equal(t, errs, nil) |
1790 | 1805 | |
1791 | newTime := time.Now().UTC() | |
1806 | newTime := time.Now().Add(time.Hour).UTC() | |
1792 | 1807 | test.CreatedAt = &newTime |
1793 | 1808 | |
1794 | 1809 | errs = validate.Struct(test) |
1801 | 1816 | i := 1 |
1802 | 1817 | j = 1 |
1803 | 1818 | k = 1.543 |
1819 | b := true | |
1804 | 1820 | arr := []string{"test"} |
1805 | 1821 | |
1806 | 1822 | var j2 uint64 |
1809 | 1825 | i2 := 1 |
1810 | 1826 | j2 = 1 |
1811 | 1827 | k2 = 1.543 |
1828 | b2 := true | |
1812 | 1829 | arr2 := []string{"test"} |
1813 | 1830 | arr3 := []string{"test", "test2"} |
1814 | 1831 | now2 := now |
1825 | 1842 | errs = validate.VarWithValue(k2, k, "eqcsfield") |
1826 | 1843 | Equal(t, errs, nil) |
1827 | 1844 | |
1845 | errs = validate.VarWithValue(b2, b, "eqcsfield") | |
1846 | Equal(t, errs, nil) | |
1847 | ||
1828 | 1848 | errs = validate.VarWithValue(arr2, arr, "eqcsfield") |
1829 | 1849 | Equal(t, errs, nil) |
1830 | 1850 | |
1927 | 1947 | } |
1928 | 1948 | |
1929 | 1949 | func TestCrossNamespaceFieldValidation(t *testing.T) { |
1930 | ||
1931 | 1950 | type SliceStruct struct { |
1932 | 1951 | Name string |
1933 | 1952 | } |
2165 | 2184 | } |
2166 | 2185 | |
2167 | 2186 | func TestExistsValidation(t *testing.T) { |
2168 | ||
2169 | 2187 | jsonText := "{ \"truthiness2\": true }" |
2170 | 2188 | |
2171 | 2189 | type Thing struct { |
2196 | 2214 | } |
2197 | 2215 | |
2198 | 2216 | func TestSQLValue2Validation(t *testing.T) { |
2199 | ||
2200 | 2217 | validate := New() |
2201 | 2218 | validate.RegisterCustomTypeFunc(ValidateValuerType, valuer{}, (*driver.Valuer)(nil), sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{}) |
2202 | 2219 | validate.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{}) |
2247 | 2264 | } |
2248 | 2265 | |
2249 | 2266 | func TestSQLValueValidation(t *testing.T) { |
2250 | ||
2251 | 2267 | validate := New() |
2252 | 2268 | validate.RegisterCustomTypeFunc(ValidateValuerType, (*driver.Valuer)(nil), valuer{}) |
2253 | 2269 | validate.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{}) |
2925 | 2941 | } |
2926 | 2942 | |
2927 | 2943 | func TestSliceMapArrayChanFuncPtrInterfaceRequiredValidation(t *testing.T) { |
2928 | ||
2929 | 2944 | validate := New() |
2930 | 2945 | |
2931 | 2946 | var m map[string]string |
3003 | 3018 | } |
3004 | 3019 | |
3005 | 3020 | func TestDatePtrValidationIssueValidation(t *testing.T) { |
3006 | ||
3007 | 3021 | type Test struct { |
3008 | 3022 | LastViewed *time.Time |
3009 | 3023 | Reminder *time.Time |
3055 | 3069 | } |
3056 | 3070 | |
3057 | 3071 | func TestInterfaceErrValidation(t *testing.T) { |
3058 | ||
3059 | 3072 | var v2 interface{} = 1 |
3060 | 3073 | var v1 interface{} = v2 |
3061 | 3074 | |
3229 | 3242 | } |
3230 | 3243 | |
3231 | 3244 | func TestMapDiveValidation(t *testing.T) { |
3232 | ||
3233 | 3245 | validate := New() |
3234 | 3246 | |
3235 | 3247 | n := map[int]interface{}{0: nil} |
3270 | 3282 | // for full test coverage |
3271 | 3283 | s := fmt.Sprint(errs.Error()) |
3272 | 3284 | NotEqual(t, s, "") |
3285 | ||
3286 | type TestMapInterface struct { | |
3287 | Errs map[int]interface{} `validate:"dive"` | |
3288 | } | |
3289 | ||
3290 | mit := map[int]interface{}{0: Inner{"ok"}, 1: Inner{""}, 3: nil, 5: "string", 6: 33} | |
3291 | ||
3292 | msi := &TestMapInterface{ | |
3293 | Errs: mit, | |
3294 | } | |
3295 | ||
3296 | errs = validate.Struct(msi) | |
3297 | NotEqual(t, errs, nil) | |
3298 | Equal(t, len(errs.(ValidationErrors)), 1) | |
3299 | AssertError(t, errs, "TestMapInterface.Errs[1].Name", "TestMapInterface.Errs[1].Name", "Name", "Name", "required") | |
3273 | 3300 | |
3274 | 3301 | type TestMapTimeStruct struct { |
3275 | 3302 | Errs map[int]*time.Time `validate:"gt=0,dive,required"` |
3352 | 3379 | } |
3353 | 3380 | |
3354 | 3381 | func TestArrayDiveValidation(t *testing.T) { |
3355 | ||
3356 | 3382 | validate := New() |
3357 | 3383 | |
3358 | 3384 | arr := []string{"ok", "", "ok"} |
4361 | 4387 | } |
4362 | 4388 | |
4363 | 4389 | func TestExcludesRuneValidation(t *testing.T) { |
4364 | ||
4365 | 4390 | tests := []struct { |
4366 | 4391 | Value string `validate:"excludesrune=☻"` |
4367 | 4392 | Tag string |
4389 | 4414 | } |
4390 | 4415 | |
4391 | 4416 | func TestExcludesAllValidation(t *testing.T) { |
4392 | ||
4393 | 4417 | tests := []struct { |
4394 | 4418 | Value string `validate:"excludesall=@!{}[]"` |
4395 | 4419 | Tag string |
4435 | 4459 | } |
4436 | 4460 | |
4437 | 4461 | func TestExcludesValidation(t *testing.T) { |
4438 | ||
4439 | 4462 | tests := []struct { |
4440 | 4463 | Value string `validate:"excludes=@"` |
4441 | 4464 | Tag string |
4463 | 4486 | } |
4464 | 4487 | |
4465 | 4488 | func TestContainsRuneValidation(t *testing.T) { |
4466 | ||
4467 | 4489 | tests := []struct { |
4468 | 4490 | Value string `validate:"containsrune=☻"` |
4469 | 4491 | Tag string |
4491 | 4513 | } |
4492 | 4514 | |
4493 | 4515 | func TestContainsAnyValidation(t *testing.T) { |
4494 | ||
4495 | 4516 | tests := []struct { |
4496 | 4517 | Value string `validate:"containsany=@!{}[]"` |
4497 | 4518 | Tag string |
4519 | 4540 | } |
4520 | 4541 | |
4521 | 4542 | func TestContainsValidation(t *testing.T) { |
4522 | ||
4523 | 4543 | tests := []struct { |
4524 | 4544 | Value string `validate:"contains=@"` |
4525 | 4545 | Tag string |
4556 | 4576 | i := 1 |
4557 | 4577 | j = 1 |
4558 | 4578 | k = 1.543 |
4579 | b := true | |
4559 | 4580 | arr := []string{"test"} |
4560 | 4581 | now := time.Now().UTC() |
4561 | 4582 | |
4565 | 4586 | i2 := 3 |
4566 | 4587 | j2 = 2 |
4567 | 4588 | k2 = 1.5434456 |
4589 | b2 := false | |
4568 | 4590 | arr2 := []string{"test", "test2"} |
4569 | 4591 | arr3 := []string{"test"} |
4570 | 4592 | now2 := now |
4581 | 4603 | errs = validate.VarWithValue(k2, k, "nefield") |
4582 | 4604 | Equal(t, errs, nil) |
4583 | 4605 | |
4606 | errs = validate.VarWithValue(b2, b, "nefield") | |
4607 | Equal(t, errs, nil) | |
4608 | ||
4584 | 4609 | errs = validate.VarWithValue(arr2, arr, "nefield") |
4585 | 4610 | Equal(t, errs, nil) |
4586 | 4611 | |
4606 | 4631 | NotEqual(t, errs, nil) |
4607 | 4632 | AssertError(t, errs, "Test.Start", "Test.Start", "Start", "Start", "nefield") |
4608 | 4633 | |
4609 | now3 := time.Now().UTC() | |
4634 | now3 := time.Now().Add(time.Hour).UTC() | |
4610 | 4635 | |
4611 | 4636 | sv = &Test{ |
4612 | 4637 | Start: &now, |
4791 | 4816 | i := 1 |
4792 | 4817 | j = 1 |
4793 | 4818 | k = 1.543 |
4819 | b := true | |
4794 | 4820 | arr := []string{"test"} |
4795 | 4821 | now := time.Now().UTC() |
4796 | 4822 | |
4800 | 4826 | i2 := 1 |
4801 | 4827 | j2 = 1 |
4802 | 4828 | k2 = 1.543 |
4829 | b2 := true | |
4803 | 4830 | arr2 := []string{"test"} |
4804 | 4831 | arr3 := []string{"test", "test2"} |
4805 | 4832 | now2 := now |
4816 | 4843 | errs = validate.VarWithValue(k2, k, "eqfield") |
4817 | 4844 | Equal(t, errs, nil) |
4818 | 4845 | |
4846 | errs = validate.VarWithValue(b2, b, "eqfield") | |
4847 | Equal(t, errs, nil) | |
4848 | ||
4819 | 4849 | errs = validate.VarWithValue(arr2, arr, "eqfield") |
4820 | 4850 | Equal(t, errs, nil) |
4821 | 4851 | |
4839 | 4869 | errs = validate.Struct(sv) |
4840 | 4870 | Equal(t, errs, nil) |
4841 | 4871 | |
4842 | now3 := time.Now().UTC() | |
4872 | now3 := time.Now().Add(time.Hour).UTC() | |
4843 | 4873 | |
4844 | 4874 | sv = &Test{ |
4845 | 4875 | Start: &now, |
5095 | 5125 | } |
5096 | 5126 | |
5097 | 5127 | func TestBase64Validation(t *testing.T) { |
5098 | ||
5099 | 5128 | validate := New() |
5100 | 5129 | |
5101 | 5130 | s := "dW5pY29ybg==" |
5199 | 5228 | } |
5200 | 5229 | |
5201 | 5230 | func TestEthereumAddressValidation(t *testing.T) { |
5202 | ||
5203 | 5231 | validate := New() |
5204 | 5232 | |
5205 | 5233 | tests := []struct { |
5253 | 5281 | } |
5254 | 5282 | |
5255 | 5283 | func TestBitcoinAddressValidation(t *testing.T) { |
5256 | ||
5257 | 5284 | validate := New() |
5258 | 5285 | |
5259 | 5286 | tests := []struct { |
5363 | 5390 | } |
5364 | 5391 | |
5365 | 5392 | func TestBitcoinBech32AddressValidation(t *testing.T) { |
5366 | ||
5367 | 5393 | validate := New() |
5368 | 5394 | |
5369 | 5395 | tests := []struct { |
5414 | 5440 | } |
5415 | 5441 | |
5416 | 5442 | func TestNoStructLevelValidation(t *testing.T) { |
5417 | ||
5418 | 5443 | type Inner struct { |
5419 | 5444 | Test string `validate:"len=5"` |
5420 | 5445 | } |
5446 | 5471 | } |
5447 | 5472 | |
5448 | 5473 | func TestStructOnlyValidation(t *testing.T) { |
5449 | ||
5450 | 5474 | type Inner struct { |
5451 | 5475 | Test string `validate:"len=5"` |
5452 | 5476 | } |
6512 | 6536 | Equal(t, errs, nil) |
6513 | 6537 | |
6514 | 6538 | fn := func(fl FieldLevel) bool { |
6515 | ||
6516 | 6539 | return fl.Parent().String() == fl.Field().String() |
6517 | 6540 | } |
6518 | 6541 | |
6530 | 6553 | } |
6531 | 6554 | |
6532 | 6555 | func TestAddFunctions(t *testing.T) { |
6533 | ||
6534 | 6556 | fn := func(fl FieldLevel) bool { |
6535 | ||
6536 | 6557 | return true |
6537 | 6558 | } |
6538 | 6559 | |
6561 | 6582 | } |
6562 | 6583 | |
6563 | 6584 | func TestChangeTag(t *testing.T) { |
6564 | ||
6565 | 6585 | validate := New() |
6566 | 6586 | validate.SetTagName("val") |
6567 | 6587 | |
7208 | 7228 | } |
7209 | 7229 | |
7210 | 7230 | func TestUrnRFC2141(t *testing.T) { |
7211 | ||
7212 | var tests = []struct { | |
7231 | tests := []struct { | |
7213 | 7232 | param string |
7214 | 7233 | expected bool |
7215 | 7234 | }{ |
7285 | 7304 | } |
7286 | 7305 | |
7287 | 7306 | func TestUrl(t *testing.T) { |
7288 | ||
7289 | var tests = []struct { | |
7307 | tests := []struct { | |
7290 | 7308 | param string |
7291 | 7309 | expected bool |
7292 | 7310 | }{ |
7353 | 7371 | } |
7354 | 7372 | |
7355 | 7373 | func TestUri(t *testing.T) { |
7356 | ||
7357 | var tests = []struct { | |
7374 | tests := []struct { | |
7358 | 7375 | param string |
7359 | 7376 | expected bool |
7360 | 7377 | }{ |
7420 | 7437 | } |
7421 | 7438 | |
7422 | 7439 | func TestOrTag(t *testing.T) { |
7423 | ||
7424 | 7440 | validate := New() |
7425 | 7441 | |
7426 | 7442 | s := "rgba(0,31,255,0.5)" |
7450 | 7466 | Equal(t, errs, nil) |
7451 | 7467 | |
7452 | 7468 | s = "green" |
7453 | errs = validate.Var(s, "eq=|eq=blue,rgb|rgba") //should fail on first validation block | |
7469 | errs = validate.Var(s, "eq=|eq=blue,rgb|rgba") // should fail on first validation block | |
7454 | 7470 | NotEqual(t, errs, nil) |
7455 | 7471 | ve := errs.(ValidationErrors) |
7456 | 7472 | Equal(t, len(ve), 1) |
7463 | 7479 | |
7464 | 7480 | v2 := New() |
7465 | 7481 | v2.RegisterTagNameFunc(func(fld reflect.StructField) string { |
7466 | ||
7467 | 7482 | name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] |
7468 | 7483 | |
7469 | 7484 | if name == "-" { |
7488 | 7503 | } |
7489 | 7504 | |
7490 | 7505 | func TestHsla(t *testing.T) { |
7491 | ||
7492 | 7506 | validate := New() |
7493 | 7507 | |
7494 | 7508 | s := "hsla(360,100%,100%,1)" |
7535 | 7549 | } |
7536 | 7550 | |
7537 | 7551 | func TestHsl(t *testing.T) { |
7538 | ||
7539 | 7552 | validate := New() |
7540 | 7553 | |
7541 | 7554 | s := "hsl(360,100%,50%)" |
7573 | 7586 | } |
7574 | 7587 | |
7575 | 7588 | func TestRgba(t *testing.T) { |
7576 | ||
7577 | 7589 | validate := New() |
7578 | 7590 | |
7579 | 7591 | s := "rgba(0,31,255,0.5)" |
7619 | 7631 | } |
7620 | 7632 | |
7621 | 7633 | func TestRgb(t *testing.T) { |
7622 | ||
7623 | 7634 | validate := New() |
7624 | 7635 | |
7625 | 7636 | s := "rgb(0,31,255)" |
7661 | 7672 | } |
7662 | 7673 | |
7663 | 7674 | func TestEmail(t *testing.T) { |
7664 | ||
7665 | 7675 | validate := New() |
7666 | 7676 | |
7667 | 7677 | s := "test@mail.com" |
7729 | 7739 | } |
7730 | 7740 | |
7731 | 7741 | func TestHexColor(t *testing.T) { |
7732 | ||
7733 | 7742 | validate := New() |
7734 | 7743 | |
7735 | 7744 | s := "#fff" |
7757 | 7766 | } |
7758 | 7767 | |
7759 | 7768 | func TestHexadecimal(t *testing.T) { |
7760 | ||
7761 | 7769 | validate := New() |
7762 | 7770 | |
7763 | 7771 | s := "ff0044" |
7784 | 7792 | } |
7785 | 7793 | |
7786 | 7794 | func TestNumber(t *testing.T) { |
7787 | ||
7788 | 7795 | validate := New() |
7789 | 7796 | |
7790 | 7797 | s := "1" |
7832 | 7839 | } |
7833 | 7840 | |
7834 | 7841 | func TestNumeric(t *testing.T) { |
7835 | ||
7836 | 7842 | validate := New() |
7837 | 7843 | |
7838 | 7844 | s := "1" |
7875 | 7881 | } |
7876 | 7882 | |
7877 | 7883 | func TestAlphaNumeric(t *testing.T) { |
7878 | ||
7879 | 7884 | validate := New() |
7880 | 7885 | |
7881 | 7886 | s := "abcd123" |
7893 | 7898 | } |
7894 | 7899 | |
7895 | 7900 | func TestAlpha(t *testing.T) { |
7896 | ||
7897 | 7901 | validate := New() |
7898 | 7902 | |
7899 | 7903 | s := "abcd" |
7923 | 7927 | errs = validate.Var(1, "alpha") |
7924 | 7928 | NotEqual(t, errs, nil) |
7925 | 7929 | AssertError(t, errs, "", "", "", "", "alpha") |
7926 | ||
7927 | 7930 | } |
7928 | 7931 | |
7929 | 7932 | func TestStructStringValidation(t *testing.T) { |
7930 | ||
7931 | 7933 | validate := New() |
7932 | 7934 | |
7933 | 7935 | tSuccess := &TestString{ |
8009 | 8011 | } |
8010 | 8012 | |
8011 | 8013 | func TestStructInt32Validation(t *testing.T) { |
8012 | ||
8013 | 8014 | type TestInt32 struct { |
8014 | 8015 | Required int `validate:"required"` |
8015 | 8016 | Len int `validate:"len=10"` |
8073 | 8074 | } |
8074 | 8075 | |
8075 | 8076 | func TestStructUint64Validation(t *testing.T) { |
8076 | ||
8077 | 8077 | validate := New() |
8078 | 8078 | |
8079 | 8079 | tSuccess := &TestUint64{ |
8113 | 8113 | } |
8114 | 8114 | |
8115 | 8115 | func TestStructFloat64Validation(t *testing.T) { |
8116 | ||
8117 | 8116 | validate := New() |
8118 | 8117 | |
8119 | 8118 | tSuccess := &TestFloat64{ |
8153 | 8152 | } |
8154 | 8153 | |
8155 | 8154 | func TestStructSliceValidation(t *testing.T) { |
8156 | ||
8157 | 8155 | validate := New() |
8158 | 8156 | |
8159 | 8157 | tSuccess := &TestSlice{ |
8203 | 8201 | |
8204 | 8202 | _, ok := fe.Value().([]int) |
8205 | 8203 | Equal(t, ok, true) |
8206 | ||
8207 | 8204 | } |
8208 | 8205 | |
8209 | 8206 | func TestInvalidStruct(t *testing.T) { |
8210 | ||
8211 | 8207 | validate := New() |
8212 | 8208 | |
8213 | 8209 | s := &SubTest{ |
8232 | 8228 | } |
8233 | 8229 | |
8234 | 8230 | func TestInvalidValidatorFunction(t *testing.T) { |
8235 | ||
8236 | 8231 | validate := New() |
8237 | 8232 | |
8238 | 8233 | s := &SubTest{ |
8243 | 8238 | } |
8244 | 8239 | |
8245 | 8240 | func TestCustomFieldName(t *testing.T) { |
8246 | ||
8247 | 8241 | validate := New() |
8248 | 8242 | validate.RegisterTagNameFunc(func(fld reflect.StructField) string { |
8249 | 8243 | name := strings.SplitN(fld.Tag.Get("schema"), ",", 2)[0] |
8287 | 8281 | } |
8288 | 8282 | |
8289 | 8283 | func TestMutipleRecursiveExtractStructCache(t *testing.T) { |
8290 | ||
8291 | 8284 | validate := New() |
8292 | 8285 | |
8293 | 8286 | type Recursive struct { |
8304 | 8297 | ptr := fmt.Sprintf("%p", sc) |
8305 | 8298 | |
8306 | 8299 | for i := 0; i < 100; i++ { |
8307 | ||
8308 | 8300 | go func() { |
8309 | 8301 | <-proceed |
8310 | 8302 | sc := validate.extractStructCache(current, name) |
8317 | 8309 | |
8318 | 8310 | // Thanks @robbrockbank, see https://github.com/go-playground/validator/issues/249 |
8319 | 8311 | func TestPointerAndOmitEmpty(t *testing.T) { |
8320 | ||
8321 | 8312 | validate := New() |
8322 | 8313 | |
8323 | 8314 | type Test struct { |
8363 | 8354 | } |
8364 | 8355 | |
8365 | 8356 | func TestRequired(t *testing.T) { |
8366 | ||
8367 | 8357 | validate := New() |
8368 | 8358 | validate.RegisterTagNameFunc(func(fld reflect.StructField) string { |
8369 | 8359 | name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] |
8387 | 8377 | } |
8388 | 8378 | |
8389 | 8379 | func TestBoolEqual(t *testing.T) { |
8390 | ||
8391 | 8380 | validate := New() |
8392 | 8381 | |
8393 | 8382 | type Test struct { |
8415 | 8404 | validate := New() |
8416 | 8405 | err := validate.RegisterTranslation("required", trans, |
8417 | 8406 | func(ut ut.Translator) (err error) { |
8418 | ||
8419 | 8407 | // using this stype because multiple translation may have to be added for the full translation |
8420 | 8408 | if err = ut.Add("required", "{0} is a required field", false); err != nil { |
8421 | 8409 | return |
8422 | 8410 | } |
8423 | 8411 | |
8424 | 8412 | return |
8425 | ||
8426 | 8413 | }, func(ut ut.Translator, fe FieldError) string { |
8427 | ||
8428 | 8414 | t, err := ut.T(fe.Tag(), fe.Field()) |
8429 | 8415 | if err != nil { |
8430 | 8416 | fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError)) |
8437 | 8423 | |
8438 | 8424 | err = validate.RegisterTranslation("required", fr, |
8439 | 8425 | func(ut ut.Translator) (err error) { |
8440 | ||
8441 | 8426 | // using this stype because multiple translation may have to be added for the full translation |
8442 | 8427 | if err = ut.Add("required", "{0} est un champ obligatoire", false); err != nil { |
8443 | 8428 | return |
8444 | 8429 | } |
8445 | 8430 | |
8446 | 8431 | return |
8447 | ||
8448 | 8432 | }, func(ut ut.Translator, fe FieldError) string { |
8449 | ||
8450 | 8433 | t, transErr := ut.T(fe.Tag(), fe.Field()) |
8451 | 8434 | if transErr != nil { |
8452 | 8435 | fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError)) |
8524 | 8507 | validate := New() |
8525 | 8508 | err = validate.RegisterTranslation("required", trans, |
8526 | 8509 | func(ut ut.Translator) (err error) { |
8527 | ||
8528 | 8510 | // using this stype because multiple translation may have to be added for the full translation |
8529 | 8511 | if err = ut.Add("required", "{0} is a required field", false); err != nil { |
8530 | 8512 | return |
8531 | 8513 | } |
8532 | 8514 | |
8533 | 8515 | return |
8534 | ||
8535 | 8516 | }, func(ut ut.Translator, fe FieldError) string { |
8536 | ||
8537 | 8517 | t, err := ut.T(fe.Tag(), fe.Field()) |
8538 | 8518 | if err != nil { |
8539 | 8519 | fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError)) |
8548 | 8528 | } |
8549 | 8529 | |
8550 | 8530 | func TestStructFiltered(t *testing.T) { |
8551 | ||
8552 | 8531 | p1 := func(ns []byte) bool { |
8553 | 8532 | if bytes.HasSuffix(ns, []byte("NoTag")) || bytes.HasSuffix(ns, []byte("Required")) { |
8554 | 8533 | return false |
8714 | 8693 | } |
8715 | 8694 | |
8716 | 8695 | func TestRequiredPtr(t *testing.T) { |
8717 | ||
8718 | 8696 | type Test struct { |
8719 | 8697 | Bool *bool `validate:"required"` |
8720 | 8698 | } |
8848 | 8826 | } |
8849 | 8827 | |
8850 | 8828 | func TestAlphanumericUnicodeValidation(t *testing.T) { |
8851 | ||
8852 | 8829 | tests := []struct { |
8853 | 8830 | param string |
8854 | 8831 | expected bool |
8891 | 8868 | } |
8892 | 8869 | |
8893 | 8870 | func TestArrayStructNamespace(t *testing.T) { |
8894 | ||
8895 | 8871 | validate := New() |
8896 | 8872 | validate.RegisterTagNameFunc(func(fld reflect.StructField) string { |
8897 | 8873 | name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] |
8920 | 8896 | } |
8921 | 8897 | |
8922 | 8898 | func TestMapStructNamespace(t *testing.T) { |
8923 | ||
8924 | 8899 | validate := New() |
8925 | 8900 | validate.RegisterTagNameFunc(func(fld reflect.StructField) string { |
8926 | 8901 | name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] |
9575 | 9550 | {"a%b", false}, |
9576 | 9551 | {"1%2", false}, |
9577 | 9552 | {"%%a%%", false}, |
9553 | {"hello", true}, | |
9554 | {"", true}, | |
9555 | {"+", true}, | |
9578 | 9556 | } |
9579 | 9557 | |
9580 | 9558 | validate := New() |
9601 | 9579 | } |
9602 | 9580 | |
9603 | 9581 | func TestKeys(t *testing.T) { |
9604 | ||
9605 | 9582 | type Test struct { |
9606 | 9583 | Test1 map[string]string `validate:"gt=0,dive,keys,eq=testkey,endkeys,eq=testval" json:"test1"` |
9607 | 9584 | Test2 map[int]int `validate:"gt=0,dive,keys,eq=3,endkeys,eq=4" json:"test2"` |
9660 | 9637 | AssertError(t, err.(ValidationErrors), "Test2.NestedKeys", "Test2.NestedKeys", "NestedKeys", "NestedKeys", "gt") |
9661 | 9638 | |
9662 | 9639 | tst2.NestedKeys = map[[1]string]string{ |
9663 | [1]string{"innertestkey"}: "outertestval", | |
9640 | {"innertestkey"}: "outertestval", | |
9664 | 9641 | } |
9665 | 9642 | |
9666 | 9643 | err = validate.Struct(tst2) |
9770 | 9747 | } |
9771 | 9748 | |
9772 | 9749 | func TestKeyOrs(t *testing.T) { |
9773 | ||
9774 | 9750 | type Test struct { |
9775 | 9751 | Test1 map[string]string `validate:"gt=0,dive,keys,eq=testkey|eq=testkeyok,endkeys,eq=testval" json:"test1"` |
9776 | 9752 | } |
10027 | 10003 | Field6 uint `validate:"required_unless=Field5 2" json:"field_6"` |
10028 | 10004 | Field7 float32 `validate:"required_unless=Field6 0" json:"field_7"` |
10029 | 10005 | Field8 float64 `validate:"required_unless=Field7 0.0" json:"field_8"` |
10006 | Field9 bool `validate:"omitempty" json:"field_9"` | |
10007 | Field10 string `validate:"required_unless=Field9 true" json:"field_10"` | |
10030 | 10008 | }{ |
10031 | 10009 | FieldE: "test", |
10032 | 10010 | Field2: &fieldVal, |
10033 | 10011 | Field3: map[string]string{"key": "val"}, |
10034 | 10012 | Field4: "test", |
10035 | 10013 | Field5: 2, |
10014 | Field9: true, | |
10036 | 10015 | } |
10037 | 10016 | |
10038 | 10017 | validate := New() |
10052 | 10031 | Field5 string `validate:"required_unless=Field3 0" json:"field_5"` |
10053 | 10032 | Field6 string `validate:"required_unless=Inner.Field test" json:"field_6"` |
10054 | 10033 | Field7 string `validate:"required_unless=Inner2.Field test" json:"field_7"` |
10034 | Field8 bool `validate:"omitempty" json:"field_8"` | |
10035 | Field9 string `validate:"required_unless=Field8 true" json:"field_9"` | |
10055 | 10036 | }{ |
10056 | 10037 | Inner: &Inner{Field: &fieldVal}, |
10057 | 10038 | FieldE: "test", |
10062 | 10043 | NotEqual(t, errs, nil) |
10063 | 10044 | |
10064 | 10045 | ve := errs.(ValidationErrors) |
10065 | Equal(t, len(ve), 3) | |
10046 | Equal(t, len(ve), 4) | |
10066 | 10047 | AssertError(t, errs, "Field3", "Field3", "Field3", "Field3", "required_unless") |
10067 | 10048 | AssertError(t, errs, "Field4", "Field4", "Field4", "Field4", "required_unless") |
10068 | 10049 | AssertError(t, errs, "Field7", "Field7", "Field7", "Field7", "required_unless") |
10050 | AssertError(t, errs, "Field9", "Field9", "Field9", "Field9", "required_unless") | |
10069 | 10051 | |
10070 | 10052 | defer func() { |
10071 | 10053 | if r := recover(); r == nil { |
10201 | 10183 | name := fmt.Sprintf("Field%d", i) |
10202 | 10184 | AssertError(t, errs, name, name, name, name, "excluded_with") |
10203 | 10185 | } |
10186 | ||
10187 | test3 := struct { | |
10188 | Inner *Inner | |
10189 | Inner2 *Inner | |
10190 | Field string `validate:"omitempty" json:"field"` | |
10191 | FieldE string `validate:"omitempty" json:"field_e"` | |
10192 | Field1 string `validate:"excluded_with=FieldE" json:"field_1"` | |
10193 | Field2 *string `validate:"excluded_with=FieldE" json:"field_2"` | |
10194 | Field3 map[string]string `validate:"excluded_with=FieldE" json:"field_3"` | |
10195 | Field4 interface{} `validate:"excluded_with=FieldE" json:"field_4"` | |
10196 | Field5 string `validate:"excluded_with=Inner.FieldE" json:"field_5"` | |
10197 | Field6 string `validate:"excluded_with=Inner2.FieldE" json:"field_6"` | |
10198 | }{ | |
10199 | Inner: &Inner{FieldE: "populated"}, | |
10200 | Inner2: &Inner{FieldE: "populated"}, | |
10201 | FieldE: "populated", | |
10202 | } | |
10203 | ||
10204 | validate = New() | |
10205 | ||
10206 | errs = validate.Struct(test3) | |
10207 | Equal(t, errs, nil) | |
10204 | 10208 | } |
10205 | 10209 | |
10206 | 10210 | func TestExcludedWithout(t *testing.T) { |
10265 | 10269 | name := fmt.Sprintf("Field%d", i) |
10266 | 10270 | AssertError(t, errs, name, name, name, name, "excluded_without") |
10267 | 10271 | } |
10272 | ||
10273 | test3 := struct { | |
10274 | Inner *Inner | |
10275 | Inner2 *Inner | |
10276 | Field string `validate:"omitempty" json:"field"` | |
10277 | FieldE string `validate:"omitempty" json:"field_e"` | |
10278 | Field1 string `validate:"excluded_without=Field" json:"field_1"` | |
10279 | Field2 *string `validate:"excluded_without=Field" json:"field_2"` | |
10280 | Field3 map[string]string `validate:"excluded_without=Field" json:"field_3"` | |
10281 | Field4 interface{} `validate:"excluded_without=Field" json:"field_4"` | |
10282 | Field5 string `validate:"excluded_without=Inner.Field" json:"field_5"` | |
10283 | }{ | |
10284 | Inner: &Inner{Field: &fieldVal}, | |
10285 | Field: "populated", | |
10286 | } | |
10287 | ||
10288 | validate = New() | |
10289 | ||
10290 | errs = validate.Struct(test3) | |
10291 | Equal(t, errs, nil) | |
10268 | 10292 | } |
10269 | 10293 | |
10270 | 10294 | func TestExcludedWithAll(t *testing.T) { |
10333 | 10357 | name := fmt.Sprintf("Field%d", i) |
10334 | 10358 | AssertError(t, errs, name, name, name, name, "excluded_with_all") |
10335 | 10359 | } |
10360 | ||
10361 | test3 := struct { | |
10362 | Inner *Inner | |
10363 | Inner2 *Inner | |
10364 | Field string `validate:"omitempty" json:"field"` | |
10365 | FieldE string `validate:"omitempty" json:"field_e"` | |
10366 | Field1 string `validate:"excluded_with_all=FieldE Field" json:"field_1"` | |
10367 | Field2 *string `validate:"excluded_with_all=FieldE Field" json:"field_2"` | |
10368 | Field3 map[string]string `validate:"excluded_with_all=FieldE Field" json:"field_3"` | |
10369 | Field4 interface{} `validate:"excluded_with_all=FieldE Field" json:"field_4"` | |
10370 | Field5 string `validate:"excluded_with_all=Inner.FieldE" json:"field_5"` | |
10371 | Field6 string `validate:"excluded_with_all=Inner2.FieldE" json:"field_6"` | |
10372 | }{ | |
10373 | Inner: &Inner{FieldE: "populated"}, | |
10374 | Inner2: &Inner{FieldE: "populated"}, | |
10375 | Field: "populated", | |
10376 | FieldE: "populated", | |
10377 | } | |
10378 | ||
10379 | validate = New() | |
10380 | ||
10381 | errs = validate.Struct(test3) | |
10382 | Equal(t, errs, nil) | |
10336 | 10383 | } |
10337 | 10384 | |
10338 | 10385 | func TestExcludedWithoutAll(t *testing.T) { |
10351 | 10398 | Field2 *string `validate:"excluded_without_all=Field FieldE" json:"field_2"` |
10352 | 10399 | Field3 map[string]string `validate:"excluded_without_all=Field FieldE" json:"field_3"` |
10353 | 10400 | Field4 interface{} `validate:"excluded_without_all=Field FieldE" json:"field_4"` |
10354 | Field5 string `validate:"excluded_without_all=Inner.Field Inner.Field2" json:"field_5"` | |
10401 | Field5 string `validate:"excluded_without_all=Inner.Field Inner2.Field" json:"field_5"` | |
10355 | 10402 | }{ |
10356 | 10403 | Inner: &Inner{Field: &fieldVal}, |
10404 | Inner2: &Inner{Field: &fieldVal}, | |
10357 | 10405 | Field: "populated", |
10358 | 10406 | Field1: fieldVal, |
10359 | 10407 | Field2: &fieldVal, |
10397 | 10445 | name := fmt.Sprintf("Field%d", i) |
10398 | 10446 | AssertError(t, errs, name, name, name, name, "excluded_without_all") |
10399 | 10447 | } |
10448 | ||
10449 | test3 := struct { | |
10450 | Inner *Inner | |
10451 | Inner2 *Inner | |
10452 | Field string `validate:"omitempty" json:"field"` | |
10453 | FieldE string `validate:"omitempty" json:"field_e"` | |
10454 | Field1 string `validate:"excluded_without_all=Field FieldE" json:"field_1"` | |
10455 | Field2 *string `validate:"excluded_without_all=Field FieldE" json:"field_2"` | |
10456 | Field3 map[string]string `validate:"excluded_without_all=Field FieldE" json:"field_3"` | |
10457 | Field4 interface{} `validate:"excluded_without_all=Field FieldE" json:"field_4"` | |
10458 | Field5 string `validate:"excluded_without_all=Inner.Field Inner2.Field" json:"field_5"` | |
10459 | }{ | |
10460 | Inner: &Inner{Field: &fieldVal}, | |
10461 | Inner2: &Inner{Field: &fieldVal}, | |
10462 | Field: "populated", | |
10463 | FieldE: "populated", | |
10464 | } | |
10465 | ||
10466 | validate = New() | |
10467 | ||
10468 | errs = validate.Struct(test3) | |
10469 | Equal(t, errs, nil) | |
10400 | 10470 | } |
10401 | 10471 | |
10402 | 10472 | func TestRequiredWithAll(t *testing.T) { |
10454 | 10524 | } |
10455 | 10525 | |
10456 | 10526 | func TestRequiredWithout(t *testing.T) { |
10457 | ||
10458 | 10527 | type Inner struct { |
10459 | 10528 | Field *string |
10460 | 10529 | } |
10520 | 10589 | } |
10521 | 10590 | |
10522 | 10591 | func TestRequiredWithoutAll(t *testing.T) { |
10523 | ||
10524 | 10592 | fieldVal := "test" |
10525 | 10593 | test := struct { |
10526 | 10594 | Field1 string `validate:"omitempty" json:"field_1"` |
10577 | 10645 | } |
10578 | 10646 | |
10579 | 10647 | func TestAbilityToValidateNils(t *testing.T) { |
10580 | ||
10581 | 10648 | type TestStruct struct { |
10582 | 10649 | Test *string `validate:"nil"` |
10583 | 10650 | } |
10718 | 10785 | }, "Bad field type int") |
10719 | 10786 | } |
10720 | 10787 | |
10788 | func TestJWTValidation(t *testing.T) { | |
10789 | tests := []struct { | |
10790 | param string | |
10791 | expected bool | |
10792 | }{ | |
10793 | {"eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiZ29waGVyIn0.O_bROM_szPq9qBql-XDHMranHwP48ODdoLICWzqBr_U", true}, | |
10794 | {"acb123-_.def456-_.ghi789-_", true}, | |
10795 | {"eyJhbGciOiJOT05FIn0.e30.", true}, | |
10796 | {"eyJhbGciOiJOT05FIn0.e30.\n", false}, | |
10797 | {"\x00.\x00.\x00", false}, | |
10798 | {"", false}, | |
10799 | } | |
10800 | ||
10801 | validate := New() | |
10802 | ||
10803 | for i, test := range tests { | |
10804 | ||
10805 | errs := validate.Var(test.param, "jwt") | |
10806 | ||
10807 | if test.expected { | |
10808 | if !IsEqual(errs, nil) { | |
10809 | t.Fatalf("Index: %d jwt failed Error: %s", i, errs) | |
10810 | } | |
10811 | } else { | |
10812 | if IsEqual(errs, nil) { | |
10813 | t.Fatalf("Index: %d jwt failed Error: %s", i, errs) | |
10814 | } else { | |
10815 | val := getError(errs, "", "") | |
10816 | if val.Tag() != "jwt" { | |
10817 | t.Fatalf("Index: %d jwt failed Error: %s", i, errs) | |
10818 | } | |
10819 | } | |
10820 | } | |
10821 | } | |
10822 | } | |
10823 | ||
10721 | 10824 | func Test_hostnameport_validator(t *testing.T) { |
10722 | ||
10723 | 10825 | type Host struct { |
10724 | 10826 | Addr string `validate:"hostname_port"` |
10725 | 10827 | } |
10821 | 10923 | PanicMatches(t, func() { |
10822 | 10924 | _ = validate.Var(2, "uppercase") |
10823 | 10925 | }, "Bad field type int") |
10824 | ||
10825 | 10926 | } |
10826 | 10927 | |
10827 | 10928 | func TestDatetimeValidation(t *testing.T) { |
10884 | 10985 | } else { |
10885 | 10986 | if IsEqual(errs, nil) { |
10886 | 10987 | t.Fatalf("Index: %d iso3166_1_alpha2 failed Error: %s", i, errs) |
10988 | } | |
10989 | } | |
10990 | } | |
10991 | } | |
10992 | ||
10993 | func TestIsIso31662Validation(t *testing.T) { | |
10994 | tests := []struct { | |
10995 | value string `validate:"iso3166_2"` | |
10996 | expected bool | |
10997 | }{ | |
10998 | {"US-FL", true}, | |
10999 | {"US-F", false}, | |
11000 | {"US", false}, | |
11001 | } | |
11002 | ||
11003 | validate := New() | |
11004 | ||
11005 | for i, test := range tests { | |
11006 | ||
11007 | errs := validate.Var(test.value, "iso3166_2") | |
11008 | ||
11009 | if test.expected { | |
11010 | if !IsEqual(errs, nil) { | |
11011 | t.Fatalf("Index: %d iso3166_2 failed Error: %s", i, errs) | |
11012 | } | |
11013 | } else { | |
11014 | if IsEqual(errs, nil) { | |
11015 | t.Fatalf("Index: %d iso3166_2 failed Error: %s", i, errs) | |
10887 | 11016 | } |
10888 | 11017 | } |
10889 | 11018 | } |
11032 | 11161 | }) |
11033 | 11162 | } |
11034 | 11163 | } |
11164 | ||
11165 | func TestBCP47LanguageTagValidation(t *testing.T) { | |
11166 | tests := []struct { | |
11167 | value string `validate:"bcp47_language_tag"` | |
11168 | tag string | |
11169 | expected bool | |
11170 | }{ | |
11171 | {"en-US", "bcp47_language_tag", true}, | |
11172 | {"en_GB", "bcp47_language_tag", true}, | |
11173 | {"es", "bcp47_language_tag", true}, | |
11174 | {"English", "bcp47_language_tag", false}, | |
11175 | {"ESES", "bcp47_language_tag", false}, | |
11176 | {"az-Cyrl-AZ", "bcp47_language_tag", true}, | |
11177 | {"en-029", "bcp47_language_tag", true}, | |
11178 | {"xog", "bcp47_language_tag", true}, | |
11179 | } | |
11180 | ||
11181 | validate := New() | |
11182 | ||
11183 | for i, test := range tests { | |
11184 | ||
11185 | errs := validate.Var(test.value, test.tag) | |
11186 | ||
11187 | if test.expected { | |
11188 | if !IsEqual(errs, nil) { | |
11189 | t.Fatalf("Index: %d locale failed Error: %s", i, errs) | |
11190 | } | |
11191 | } else { | |
11192 | if IsEqual(errs, nil) { | |
11193 | t.Fatalf("Index: %d locale failed Error: %s", i, errs) | |
11194 | } else { | |
11195 | val := getError(errs, "", "") | |
11196 | if val.Tag() != "bcp47_language_tag" { | |
11197 | t.Fatalf("Index: %d locale failed Error: %s", i, errs) | |
11198 | } | |
11199 | } | |
11200 | } | |
11201 | } | |
11202 | ||
11203 | PanicMatches(t, func() { | |
11204 | _ = validate.Var(2, "bcp47_language_tag") | |
11205 | }, "Bad field type int") | |
11206 | } | |
11207 | ||
11208 | func TestBicIsoFormatValidation(t *testing.T) { | |
11209 | tests := []struct { | |
11210 | value string `validate:"bic"` | |
11211 | tag string | |
11212 | expected bool | |
11213 | }{ | |
11214 | {"SBICKEN1345", "bic", true}, | |
11215 | {"SBICKEN1", "bic", true}, | |
11216 | {"SBICKENY", "bic", true}, | |
11217 | {"SBICKEN1YYP", "bic", true}, | |
11218 | {"SBIC23NXXX", "bic", false}, | |
11219 | {"S23CKENXXXX", "bic", false}, | |
11220 | {"SBICKENXX", "bic", false}, | |
11221 | {"SBICKENXX9", "bic", false}, | |
11222 | {"SBICKEN13458", "bic", false}, | |
11223 | {"SBICKEN", "bic", false}, | |
11224 | } | |
11225 | ||
11226 | validate := New() | |
11227 | ||
11228 | for i, test := range tests { | |
11229 | ||
11230 | errs := validate.Var(test.value, test.tag) | |
11231 | ||
11232 | if test.expected { | |
11233 | if !IsEqual(errs, nil) { | |
11234 | t.Fatalf("Index: %d bic failed Error: %s", i, errs) | |
11235 | } | |
11236 | } else { | |
11237 | if IsEqual(errs, nil) { | |
11238 | t.Fatalf("Index: %d bic failed Error: %s", i, errs) | |
11239 | } else { | |
11240 | val := getError(errs, "", "") | |
11241 | if val.Tag() != "bic" { | |
11242 | t.Fatalf("Index: %d bic failed Error: %s", i, errs) | |
11243 | } | |
11244 | } | |
11245 | } | |
11246 | } | |
11247 | } | |
11248 | ||
11249 | func TestPostCodeByIso3166Alpha2(t *testing.T) { | |
11250 | tests := map[string][]struct { | |
11251 | value string | |
11252 | expected bool | |
11253 | }{ | |
11254 | "VN": { | |
11255 | {"ABC", false}, | |
11256 | {"700000", true}, | |
11257 | {"A1", false}, | |
11258 | }, | |
11259 | "GB": { | |
11260 | {"EC1A 1BB", true}, | |
11261 | {"CF10 1B1H", false}, | |
11262 | }, | |
11263 | "VI": { | |
11264 | {"00803", true}, | |
11265 | {"1234567", false}, | |
11266 | }, | |
11267 | "LC": { // not support regexp for post code | |
11268 | {"123456", false}, | |
11269 | }, | |
11270 | "XX": { // not support country | |
11271 | {"123456", false}, | |
11272 | }, | |
11273 | } | |
11274 | ||
11275 | validate := New() | |
11276 | ||
11277 | for cc, ccTests := range tests { | |
11278 | for i, test := range ccTests { | |
11279 | errs := validate.Var(test.value, fmt.Sprintf("postcode_iso3166_alpha2=%s", cc)) | |
11280 | ||
11281 | if test.expected { | |
11282 | if !IsEqual(errs, nil) { | |
11283 | t.Fatalf("Index: %d postcode_iso3166_alpha2=%s failed Error: %s", i, cc, errs) | |
11284 | } | |
11285 | } else { | |
11286 | if IsEqual(errs, nil) { | |
11287 | t.Fatalf("Index: %d postcode_iso3166_alpha2=%s failed Error: %s", i, cc, errs) | |
11288 | } | |
11289 | } | |
11290 | } | |
11291 | } | |
11292 | } | |
11293 | ||
11294 | func TestPostCodeByIso3166Alpha2Field(t *testing.T) { | |
11295 | tests := []struct { | |
11296 | Value string `validate:"postcode_iso3166_alpha2_field=CountryCode"` | |
11297 | CountryCode interface{} | |
11298 | expected bool | |
11299 | }{ | |
11300 | {"ABC", "VN", false}, | |
11301 | {"700000", "VN", true}, | |
11302 | {"A1", "VN", false}, | |
11303 | {"EC1A 1BB", "GB", true}, | |
11304 | {"CF10 1B1H", "GB", false}, | |
11305 | {"00803", "VI", true}, | |
11306 | {"1234567", "VI", false}, | |
11307 | {"123456", "LC", false}, // not support regexp for post code | |
11308 | {"123456", "XX", false}, // not support country | |
11309 | } | |
11310 | ||
11311 | validate := New() | |
11312 | ||
11313 | for i, test := range tests { | |
11314 | errs := validate.Struct(test) | |
11315 | if test.expected { | |
11316 | if !IsEqual(errs, nil) { | |
11317 | t.Fatalf("Index: %d postcode_iso3166_alpha2_field=CountryCode failed Error: %s", i, errs) | |
11318 | } | |
11319 | } else { | |
11320 | if IsEqual(errs, nil) { | |
11321 | t.Fatalf("Index: %d postcode_iso3166_alpha2_field=CountryCode failed Error: %s", i, errs) | |
11322 | } | |
11323 | } | |
11324 | } | |
11325 | } | |
11326 | ||
11327 | func TestPostCodeByIso3166Alpha2Field_WrongField(t *testing.T) { | |
11328 | type test struct { | |
11329 | Value string `validate:"postcode_iso3166_alpha2_field=CountryCode"` | |
11330 | CountryCode1 interface{} | |
11331 | expected bool | |
11332 | } | |
11333 | ||
11334 | errs := New().Struct(test{"ABC", "VN", false}) | |
11335 | NotEqual(t, nil, errs) | |
11336 | } | |
11337 | ||
11338 | func TestPostCodeByIso3166Alpha2Field_MissingParam(t *testing.T) { | |
11339 | type test struct { | |
11340 | Value string `validate:"postcode_iso3166_alpha2_field="` | |
11341 | CountryCode1 interface{} | |
11342 | expected bool | |
11343 | } | |
11344 | ||
11345 | errs := New().Struct(test{"ABC", "VN", false}) | |
11346 | NotEqual(t, nil, errs) | |
11347 | } | |
11348 | ||
11349 | func TestPostCodeByIso3166Alpha2Field_InvalidKind(t *testing.T) { | |
11350 | type test struct { | |
11351 | Value string `validate:"postcode_iso3166_alpha2_field=CountryCode"` | |
11352 | CountryCode interface{} | |
11353 | expected bool | |
11354 | } | |
11355 | defer func() { _ = recover() }() | |
11356 | ||
11357 | _ = New().Struct(test{"ABC", 123, false}) | |
11358 | t.Errorf("Didn't panic as expected") | |
11359 | } |