Import upstream version 10.10.1
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.41.1 |
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.41.1; \ | |
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.10.1-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 | |
125 | 125 | | alphanumunicode | Alphanumeric Unicode | |
126 | 126 | | alphaunicode | Alpha Unicode | |
127 | 127 | | ascii | ASCII | |
128 | | boolean | Boolean | | |
128 | 129 | | contains | Contains | |
129 | 130 | | containsany | Contains Any | |
130 | 131 | | containsrune | Contains Rune | |
132 | | endsnotwith | Ends With | | |
131 | 133 | | endswith | Ends With | |
134 | | excludes | Excludes | | |
135 | | excludesall | Excludes All | | |
136 | | excludesrune | Excludes Rune | | |
132 | 137 | | lowercase | Lowercase | |
133 | 138 | | multibyte | Multi-Byte Characters | |
134 | 139 | | number | NOT DOCUMENTED IN doc.go | |
135 | 140 | | numeric | Numeric | |
136 | 141 | | printascii | Printable ASCII | |
142 | | startsnotwith | Starts Not With | | |
137 | 143 | | startswith | Starts With | |
138 | 144 | | uppercase | Uppercase | |
139 | 145 | |
142 | 148 | | - | - | |
143 | 149 | | base64 | Base64 String | |
144 | 150 | | base64url | Base64URL String | |
151 | | bic | Business Identifier Code (ISO 9362) | | |
152 | | bcp47_language_tag | Language tag (BCP 47) | | |
145 | 153 | | btc_addr | Bitcoin Address | |
146 | 154 | | btc_addr_bech32 | Bitcoin Bech32 Address (segwit) | |
147 | 155 | | datetime | Datetime | |
157 | 165 | | isbn | International Standard Book Number | |
158 | 166 | | isbn10 | International Standard Book Number 10 | |
159 | 167 | | isbn13 | International Standard Book Number 13 | |
168 | | iso3166_1_alpha2 | Two-letter country code (ISO 3166-1 alpha-2) | | |
169 | | iso3166_1_alpha3 | Three-letter country code (ISO 3166-1 alpha-3) | | |
170 | | iso3166_1_alpha_numeric | Numeric country code (ISO 3166-1 numeric) | | |
171 | | iso3166_2 | Country subdivision code (ISO 3166-2) | | |
172 | | iso4217 | Currency code (ISO 4217) | | |
160 | 173 | | json | JSON | |
174 | | jwt | JSON Web Token (JWT) | | |
161 | 175 | | latitude | Latitude | |
162 | 176 | | longitude | Longitude | |
177 | | postcode_iso3166_alpha2 | Postcode | | |
178 | | postcode_iso3166_alpha2_field | Postcode | | |
163 | 179 | | rgb | RGB String | |
164 | 180 | | rgba | RGBA String | |
165 | 181 | | ssn | Social Security Number SSN | |
182 | | timezone | Timezone | | |
166 | 183 | | uuid | Universally Unique Identifier UUID | |
167 | 184 | | uuid3 | Universally Unique Identifier UUID v3 | |
168 | 185 | | uuid3_rfc4122 | Universally Unique Identifier UUID v3 RFC4122 | |
171 | 188 | | uuid5 | Universally Unique Identifier UUID v5 | |
172 | 189 | | uuid5_rfc4122 | Universally Unique Identifier UUID v5 RFC4122 | |
173 | 190 | | uuid_rfc4122 | Universally Unique Identifier UUID RFC4122 | |
191 | | semver | Semantic Versioning 2.0.0 | | |
192 | | ulid | Universally Unique Lexicographically Sortable Identifier ULID | | |
174 | 193 | |
175 | 194 | ### Comparisons: |
176 | 195 | | Tag | Description | |
177 | 196 | | - | - | |
178 | 197 | | eq | Equals | |
179 | 198 | | gt | Greater than| |
180 | | gte |Greater than or equal | | |
199 | | gte | Greater than or equal | | |
181 | 200 | | lt | Less Than | |
182 | 201 | | lte | Less Than or Equal | |
183 | 202 | | ne | Not Equal | |
186 | 205 | | Tag | Description | |
187 | 206 | | - | - | |
188 | 207 | | dir | Directory | |
189 | | endswith | Ends With | | |
190 | | excludes | Excludes | | |
191 | | excludesall | Excludes All | | |
192 | | excludesrune | Excludes Rune | | |
193 | 208 | | file | File path | |
194 | 209 | | isdefault | Is Default | |
195 | 210 | | len | Length | |
208 | 223 | | excluded_without | Excluded Without | |
209 | 224 | | excluded_without_all | Excluded Without All | |
210 | 225 | | unique | Unique | |
226 | ||
227 | #### Aliases: | |
228 | | Tag | Description | | |
229 | | - | - | | |
230 | | iscolor | hexcolor\|rgb\|rgba\|hsl\|hsla | | |
231 | | country_code | iso3166_1_alpha2\|iso3166_1_alpha3\|iso3166_1_alpha_numeric | | |
211 | 232 | |
212 | 233 | Benchmarks |
213 | 234 | ------ |
294 | 315 | Make a pull request... |
295 | 316 | |
296 | 317 | License |
297 | ------ | |
318 | ------- | |
298 | 319 | Distributed under MIT License, please see license file within the code for more details. |
320 | ||
321 | Maintainers | |
322 | ----------- | |
323 | This project has grown large enough that more than one person is required to properly support the community. | |
324 | 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 | "boolean": isBoolean, | |
110 | "numeric": isNumeric, | |
111 | "number": isNumber, | |
112 | "hexadecimal": isHexadecimal, | |
113 | "hexcolor": isHEXColor, | |
114 | "rgb": isRGB, | |
115 | "rgba": isRGBA, | |
116 | "hsl": isHSL, | |
117 | "hsla": isHSLA, | |
118 | "e164": isE164, | |
119 | "email": isEmail, | |
120 | "url": isURL, | |
121 | "uri": isURI, | |
122 | "urn_rfc2141": isUrnRFC2141, // RFC 2141 | |
123 | "file": isFile, | |
124 | "base64": isBase64, | |
125 | "base64url": isBase64URL, | |
126 | "contains": contains, | |
127 | "containsany": containsAny, | |
128 | "containsrune": containsRune, | |
129 | "excludes": excludes, | |
130 | "excludesall": excludesAll, | |
131 | "excludesrune": excludesRune, | |
132 | "startswith": startsWith, | |
133 | "endswith": endsWith, | |
134 | "startsnotwith": startsNotWith, | |
135 | "endsnotwith": endsNotWith, | |
136 | "isbn": isISBN, | |
137 | "isbn10": isISBN10, | |
138 | "isbn13": isISBN13, | |
139 | "eth_addr": isEthereumAddress, | |
140 | "btc_addr": isBitcoinAddress, | |
141 | "btc_addr_bech32": isBitcoinBech32Address, | |
142 | "uuid": isUUID, | |
143 | "uuid3": isUUID3, | |
144 | "uuid4": isUUID4, | |
145 | "uuid5": isUUID5, | |
146 | "uuid_rfc4122": isUUIDRFC4122, | |
147 | "uuid3_rfc4122": isUUID3RFC4122, | |
148 | "uuid4_rfc4122": isUUID4RFC4122, | |
149 | "uuid5_rfc4122": isUUID5RFC4122, | |
150 | "ulid": isULID, | |
151 | "ascii": isASCII, | |
152 | "printascii": isPrintableASCII, | |
153 | "multibyte": hasMultiByteCharacter, | |
154 | "datauri": isDataURI, | |
155 | "latitude": isLatitude, | |
156 | "longitude": isLongitude, | |
157 | "ssn": isSSN, | |
158 | "ipv4": isIPv4, | |
159 | "ipv6": isIPv6, | |
160 | "ip": isIP, | |
161 | "cidrv4": isCIDRv4, | |
162 | "cidrv6": isCIDRv6, | |
163 | "cidr": isCIDR, | |
164 | "tcp4_addr": isTCP4AddrResolvable, | |
165 | "tcp6_addr": isTCP6AddrResolvable, | |
166 | "tcp_addr": isTCPAddrResolvable, | |
167 | "udp4_addr": isUDP4AddrResolvable, | |
168 | "udp6_addr": isUDP6AddrResolvable, | |
169 | "udp_addr": isUDPAddrResolvable, | |
170 | "ip4_addr": isIP4AddrResolvable, | |
171 | "ip6_addr": isIP6AddrResolvable, | |
172 | "ip_addr": isIPAddrResolvable, | |
173 | "unix_addr": isUnixAddrResolvable, | |
174 | "mac": isMAC, | |
175 | "hostname": isHostnameRFC952, // RFC 952 | |
176 | "hostname_rfc1123": isHostnameRFC1123, // RFC 1123 | |
177 | "fqdn": isFQDN, | |
178 | "unique": isUnique, | |
179 | "oneof": isOneOf, | |
180 | "html": isHTML, | |
181 | "html_encoded": isHTMLEncoded, | |
182 | "url_encoded": isURLEncoded, | |
183 | "dir": isDir, | |
184 | "json": isJSON, | |
185 | "jwt": isJWT, | |
186 | "hostname_port": isHostnamePort, | |
187 | "lowercase": isLowercase, | |
188 | "uppercase": isUppercase, | |
189 | "datetime": isDatetime, | |
190 | "timezone": isTimeZone, | |
191 | "iso3166_1_alpha2": isIso3166Alpha2, | |
192 | "iso3166_1_alpha3": isIso3166Alpha3, | |
193 | "iso3166_1_alpha_numeric": isIso3166AlphaNumeric, | |
194 | "iso3166_2": isIso31662, | |
195 | "iso4217": isIso4217, | |
196 | "iso4217_numeric": isIso4217Numeric, | |
197 | "bcp47_language_tag": isBCP47LanguageTag, | |
198 | "postcode_iso3166_alpha2": isPostcodeByIso3166Alpha2, | |
199 | "postcode_iso3166_alpha2_field": isPostcodeByIso3166Alpha2Field, | |
200 | "bic": isIsoBicFormat, | |
201 | "semver": isSemverFormat, | |
202 | "dns_rfc1035_label": isDnsRFC1035LabelFormat, | |
190 | 203 | } |
191 | 204 | ) |
192 | 205 | |
295 | 308 | } |
296 | 309 | } |
297 | 310 | |
298 | // IsMAC is the validation function for validating if the field's value is a valid MAC address. | |
311 | // isMAC is the validation function for validating if the field's value is a valid MAC address. | |
299 | 312 | func isMAC(fl FieldLevel) bool { |
300 | 313 | |
301 | 314 | _, err := net.ParseMAC(fl.Field().String()) |
303 | 316 | return err == nil |
304 | 317 | } |
305 | 318 | |
306 | // IsCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address. | |
319 | // isCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address. | |
307 | 320 | func isCIDRv4(fl FieldLevel) bool { |
308 | 321 | |
309 | 322 | ip, _, err := net.ParseCIDR(fl.Field().String()) |
311 | 324 | return err == nil && ip.To4() != nil |
312 | 325 | } |
313 | 326 | |
314 | // IsCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address. | |
327 | // isCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address. | |
315 | 328 | func isCIDRv6(fl FieldLevel) bool { |
316 | 329 | |
317 | 330 | ip, _, err := net.ParseCIDR(fl.Field().String()) |
319 | 332 | return err == nil && ip.To4() == nil |
320 | 333 | } |
321 | 334 | |
322 | // IsCIDR is the validation function for validating if the field's value is a valid v4 or v6 CIDR address. | |
335 | // isCIDR is the validation function for validating if the field's value is a valid v4 or v6 CIDR address. | |
323 | 336 | func isCIDR(fl FieldLevel) bool { |
324 | 337 | |
325 | 338 | _, _, err := net.ParseCIDR(fl.Field().String()) |
327 | 340 | return err == nil |
328 | 341 | } |
329 | 342 | |
330 | // IsIPv4 is the validation function for validating if a value is a valid v4 IP address. | |
343 | // isIPv4 is the validation function for validating if a value is a valid v4 IP address. | |
331 | 344 | func isIPv4(fl FieldLevel) bool { |
332 | 345 | |
333 | 346 | ip := net.ParseIP(fl.Field().String()) |
335 | 348 | return ip != nil && ip.To4() != nil |
336 | 349 | } |
337 | 350 | |
338 | // IsIPv6 is the validation function for validating if the field's value is a valid v6 IP address. | |
351 | // isIPv6 is the validation function for validating if the field's value is a valid v6 IP address. | |
339 | 352 | func isIPv6(fl FieldLevel) bool { |
340 | 353 | |
341 | 354 | ip := net.ParseIP(fl.Field().String()) |
343 | 356 | return ip != nil && ip.To4() == nil |
344 | 357 | } |
345 | 358 | |
346 | // IsIP is the validation function for validating if the field's value is a valid v4 or v6 IP address. | |
359 | // isIP is the validation function for validating if the field's value is a valid v4 or v6 IP address. | |
347 | 360 | func isIP(fl FieldLevel) bool { |
348 | 361 | |
349 | 362 | ip := net.ParseIP(fl.Field().String()) |
351 | 364 | return ip != nil |
352 | 365 | } |
353 | 366 | |
354 | // IsSSN is the validation function for validating if the field's value is a valid SSN. | |
367 | // isSSN is the validation function for validating if the field's value is a valid SSN. | |
355 | 368 | func isSSN(fl FieldLevel) bool { |
356 | 369 | |
357 | 370 | field := fl.Field() |
363 | 376 | return sSNRegex.MatchString(field.String()) |
364 | 377 | } |
365 | 378 | |
366 | // IsLongitude is the validation function for validating if the field's value is a valid longitude coordinate. | |
379 | // isLongitude is the validation function for validating if the field's value is a valid longitude coordinate. | |
367 | 380 | func isLongitude(fl FieldLevel) bool { |
368 | 381 | field := fl.Field() |
369 | 382 | |
386 | 399 | return longitudeRegex.MatchString(v) |
387 | 400 | } |
388 | 401 | |
389 | // IsLatitude is the validation function for validating if the field's value is a valid latitude coordinate. | |
402 | // isLatitude is the validation function for validating if the field's value is a valid latitude coordinate. | |
390 | 403 | func isLatitude(fl FieldLevel) bool { |
391 | 404 | field := fl.Field() |
392 | 405 | |
409 | 422 | return latitudeRegex.MatchString(v) |
410 | 423 | } |
411 | 424 | |
412 | // IsDataURI is the validation function for validating if the field's value is a valid data URI. | |
425 | // isDataURI is the validation function for validating if the field's value is a valid data URI. | |
413 | 426 | func isDataURI(fl FieldLevel) bool { |
414 | 427 | |
415 | 428 | uri := strings.SplitN(fl.Field().String(), ",", 2) |
425 | 438 | return base64Regex.MatchString(uri[1]) |
426 | 439 | } |
427 | 440 | |
428 | // HasMultiByteCharacter is the validation function for validating if the field's value has a multi byte character. | |
441 | // hasMultiByteCharacter is the validation function for validating if the field's value has a multi byte character. | |
429 | 442 | func hasMultiByteCharacter(fl FieldLevel) bool { |
430 | 443 | |
431 | 444 | field := fl.Field() |
437 | 450 | return multibyteRegex.MatchString(field.String()) |
438 | 451 | } |
439 | 452 | |
440 | // IsPrintableASCII is the validation function for validating if the field's value is a valid printable ASCII character. | |
453 | // isPrintableASCII is the validation function for validating if the field's value is a valid printable ASCII character. | |
441 | 454 | func isPrintableASCII(fl FieldLevel) bool { |
442 | 455 | return printableASCIIRegex.MatchString(fl.Field().String()) |
443 | 456 | } |
444 | 457 | |
445 | // IsASCII is the validation function for validating if the field's value is a valid ASCII character. | |
458 | // isASCII is the validation function for validating if the field's value is a valid ASCII character. | |
446 | 459 | func isASCII(fl FieldLevel) bool { |
447 | 460 | return aSCIIRegex.MatchString(fl.Field().String()) |
448 | 461 | } |
449 | 462 | |
450 | // IsUUID5 is the validation function for validating if the field's value is a valid v5 UUID. | |
463 | // isUUID5 is the validation function for validating if the field's value is a valid v5 UUID. | |
451 | 464 | func isUUID5(fl FieldLevel) bool { |
452 | 465 | return uUID5Regex.MatchString(fl.Field().String()) |
453 | 466 | } |
454 | 467 | |
455 | // IsUUID4 is the validation function for validating if the field's value is a valid v4 UUID. | |
468 | // isUUID4 is the validation function for validating if the field's value is a valid v4 UUID. | |
456 | 469 | func isUUID4(fl FieldLevel) bool { |
457 | 470 | return uUID4Regex.MatchString(fl.Field().String()) |
458 | 471 | } |
459 | 472 | |
460 | // IsUUID3 is the validation function for validating if the field's value is a valid v3 UUID. | |
473 | // isUUID3 is the validation function for validating if the field's value is a valid v3 UUID. | |
461 | 474 | func isUUID3(fl FieldLevel) bool { |
462 | 475 | return uUID3Regex.MatchString(fl.Field().String()) |
463 | 476 | } |
464 | 477 | |
465 | // IsUUID is the validation function for validating if the field's value is a valid UUID of any version. | |
478 | // isUUID is the validation function for validating if the field's value is a valid UUID of any version. | |
466 | 479 | func isUUID(fl FieldLevel) bool { |
467 | 480 | return uUIDRegex.MatchString(fl.Field().String()) |
468 | 481 | } |
469 | 482 | |
470 | // IsUUID5RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v5 UUID. | |
483 | // isUUID5RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v5 UUID. | |
471 | 484 | func isUUID5RFC4122(fl FieldLevel) bool { |
472 | 485 | return uUID5RFC4122Regex.MatchString(fl.Field().String()) |
473 | 486 | } |
474 | 487 | |
475 | // IsUUID4RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v4 UUID. | |
488 | // isUUID4RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v4 UUID. | |
476 | 489 | func isUUID4RFC4122(fl FieldLevel) bool { |
477 | 490 | return uUID4RFC4122Regex.MatchString(fl.Field().String()) |
478 | 491 | } |
479 | 492 | |
480 | // IsUUID3RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v3 UUID. | |
493 | // isUUID3RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v3 UUID. | |
481 | 494 | func isUUID3RFC4122(fl FieldLevel) bool { |
482 | 495 | return uUID3RFC4122Regex.MatchString(fl.Field().String()) |
483 | 496 | } |
484 | 497 | |
485 | // IsUUIDRFC4122 is the validation function for validating if the field's value is a valid RFC4122 UUID of any version. | |
498 | // isUUIDRFC4122 is the validation function for validating if the field's value is a valid RFC4122 UUID of any version. | |
486 | 499 | func isUUIDRFC4122(fl FieldLevel) bool { |
487 | 500 | return uUIDRFC4122Regex.MatchString(fl.Field().String()) |
488 | 501 | } |
489 | 502 | |
490 | // IsISBN is the validation function for validating if the field's value is a valid v10 or v13 ISBN. | |
503 | // isULID is the validation function for validating if the field's value is a valid ULID. | |
504 | func isULID(fl FieldLevel) bool { | |
505 | return uLIDRegex.MatchString(fl.Field().String()) | |
506 | } | |
507 | ||
508 | // isISBN is the validation function for validating if the field's value is a valid v10 or v13 ISBN. | |
491 | 509 | func isISBN(fl FieldLevel) bool { |
492 | 510 | return isISBN10(fl) || isISBN13(fl) |
493 | 511 | } |
494 | 512 | |
495 | // IsISBN13 is the validation function for validating if the field's value is a valid v13 ISBN. | |
513 | // isISBN13 is the validation function for validating if the field's value is a valid v13 ISBN. | |
496 | 514 | func isISBN13(fl FieldLevel) bool { |
497 | 515 | |
498 | 516 | s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 4), " ", "", 4) |
513 | 531 | return (int32(s[12]-'0'))-((10-(checksum%10))%10) == 0 |
514 | 532 | } |
515 | 533 | |
516 | // IsISBN10 is the validation function for validating if the field's value is a valid v10 ISBN. | |
534 | // isISBN10 is the validation function for validating if the field's value is a valid v10 ISBN. | |
517 | 535 | func isISBN10(fl FieldLevel) bool { |
518 | 536 | |
519 | 537 | s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 3), " ", "", 3) |
538 | 556 | return checksum%11 == 0 |
539 | 557 | } |
540 | 558 | |
541 | // IsEthereumAddress is the validation function for validating if the field's value is a valid Ethereum address. | |
559 | // isEthereumAddress is the validation function for validating if the field's value is a valid Ethereum address. | |
542 | 560 | func isEthereumAddress(fl FieldLevel) bool { |
543 | 561 | address := fl.Field().String() |
544 | 562 | |
546 | 564 | return false |
547 | 565 | } |
548 | 566 | |
549 | if ethaddressRegexUpper.MatchString(address) || ethAddressRegexLower.MatchString(address) { | |
567 | if ethAddressRegexUpper.MatchString(address) || ethAddressRegexLower.MatchString(address) { | |
550 | 568 | return true |
551 | 569 | } |
552 | 570 | |
569 | 587 | return true |
570 | 588 | } |
571 | 589 | |
572 | // IsBitcoinAddress is the validation function for validating if the field's value is a valid btc address | |
590 | // isBitcoinAddress is the validation function for validating if the field's value is a valid btc address | |
573 | 591 | func isBitcoinAddress(fl FieldLevel) bool { |
574 | 592 | address := fl.Field().String() |
575 | 593 | |
606 | 624 | return validchecksum == computedchecksum |
607 | 625 | } |
608 | 626 | |
609 | // IsBitcoinBech32Address is the validation function for validating if the field's value is a valid bech32 btc address | |
627 | // isBitcoinBech32Address is the validation function for validating if the field's value is a valid bech32 btc address | |
610 | 628 | func isBitcoinBech32Address(fl FieldLevel) bool { |
611 | 629 | address := fl.Field().String() |
612 | 630 | |
686 | 704 | return true |
687 | 705 | } |
688 | 706 | |
689 | // ExcludesRune is the validation function for validating that the field's value does not contain the rune specified within the param. | |
707 | // excludesRune is the validation function for validating that the field's value does not contain the rune specified within the param. | |
690 | 708 | func excludesRune(fl FieldLevel) bool { |
691 | 709 | return !containsRune(fl) |
692 | 710 | } |
693 | 711 | |
694 | // ExcludesAll is the validation function for validating that the field's value does not contain any of the characters specified within the param. | |
712 | // excludesAll is the validation function for validating that the field's value does not contain any of the characters specified within the param. | |
695 | 713 | func excludesAll(fl FieldLevel) bool { |
696 | 714 | return !containsAny(fl) |
697 | 715 | } |
698 | 716 | |
699 | // Excludes is the validation function for validating that the field's value does not contain the text specified within the param. | |
717 | // excludes is the validation function for validating that the field's value does not contain the text specified within the param. | |
700 | 718 | func excludes(fl FieldLevel) bool { |
701 | 719 | return !contains(fl) |
702 | 720 | } |
703 | 721 | |
704 | // ContainsRune is the validation function for validating that the field's value contains the rune specified within the param. | |
722 | // containsRune is the validation function for validating that the field's value contains the rune specified within the param. | |
705 | 723 | func containsRune(fl FieldLevel) bool { |
706 | 724 | |
707 | 725 | r, _ := utf8.DecodeRuneInString(fl.Param()) |
709 | 727 | return strings.ContainsRune(fl.Field().String(), r) |
710 | 728 | } |
711 | 729 | |
712 | // ContainsAny is the validation function for validating that the field's value contains any of the characters specified within the param. | |
730 | // containsAny is the validation function for validating that the field's value contains any of the characters specified within the param. | |
713 | 731 | func containsAny(fl FieldLevel) bool { |
714 | 732 | return strings.ContainsAny(fl.Field().String(), fl.Param()) |
715 | 733 | } |
716 | 734 | |
717 | // Contains is the validation function for validating that the field's value contains the text specified within the param. | |
735 | // contains is the validation function for validating that the field's value contains the text specified within the param. | |
718 | 736 | func contains(fl FieldLevel) bool { |
719 | 737 | return strings.Contains(fl.Field().String(), fl.Param()) |
720 | 738 | } |
721 | 739 | |
722 | // StartsWith is the validation function for validating that the field's value starts with the text specified within the param. | |
740 | // startsWith is the validation function for validating that the field's value starts with the text specified within the param. | |
723 | 741 | func startsWith(fl FieldLevel) bool { |
724 | 742 | return strings.HasPrefix(fl.Field().String(), fl.Param()) |
725 | 743 | } |
726 | 744 | |
727 | // EndsWith is the validation function for validating that the field's value ends with the text specified within the param. | |
745 | // endsWith is the validation function for validating that the field's value ends with the text specified within the param. | |
728 | 746 | func endsWith(fl FieldLevel) bool { |
729 | 747 | return strings.HasSuffix(fl.Field().String(), fl.Param()) |
730 | 748 | } |
731 | 749 | |
732 | // StartsNotWith is the validation function for validating that the field's value does not start with the text specified within the param. | |
750 | // startsNotWith is the validation function for validating that the field's value does not start with the text specified within the param. | |
733 | 751 | func startsNotWith(fl FieldLevel) bool { |
734 | 752 | return !startsWith(fl) |
735 | 753 | } |
736 | 754 | |
737 | // EndsNotWith is the validation function for validating that the field's value does not end with the text specified within the param. | |
755 | // endsNotWith is the validation function for validating that the field's value does not end with the text specified within the param. | |
738 | 756 | func endsNotWith(fl FieldLevel) bool { |
739 | 757 | return !endsWith(fl) |
740 | 758 | } |
741 | 759 | |
742 | // FieldContains is the validation function for validating if the current field's value contains the field specified by the param's value. | |
760 | // fieldContains is the validation function for validating if the current field's value contains the field specified by the param's value. | |
743 | 761 | func fieldContains(fl FieldLevel) bool { |
744 | 762 | field := fl.Field() |
745 | 763 | |
752 | 770 | return strings.Contains(field.String(), currentField.String()) |
753 | 771 | } |
754 | 772 | |
755 | // FieldExcludes is the validation function for validating if the current field's value excludes the field specified by the param's value. | |
773 | // fieldExcludes is the validation function for validating if the current field's value excludes the field specified by the param's value. | |
756 | 774 | func fieldExcludes(fl FieldLevel) bool { |
757 | 775 | field := fl.Field() |
758 | 776 | |
764 | 782 | return !strings.Contains(field.String(), currentField.String()) |
765 | 783 | } |
766 | 784 | |
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. | |
785 | // 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 | 786 | func isNeField(fl FieldLevel) bool { |
769 | 787 | |
770 | 788 | field := fl.Field() |
789 | 807 | |
790 | 808 | case reflect.Slice, reflect.Map, reflect.Array: |
791 | 809 | return int64(field.Len()) != int64(currentField.Len()) |
810 | ||
811 | case reflect.Bool: | |
812 | return field.Bool() != currentField.Bool() | |
792 | 813 | |
793 | 814 | case reflect.Struct: |
794 | 815 | |
813 | 834 | return field.String() != currentField.String() |
814 | 835 | } |
815 | 836 | |
816 | // IsNe is the validation function for validating that the field's value does not equal the provided param value. | |
837 | // isNe is the validation function for validating that the field's value does not equal the provided param value. | |
817 | 838 | func isNe(fl FieldLevel) bool { |
818 | 839 | return !isEq(fl) |
819 | 840 | } |
820 | 841 | |
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. | |
842 | // 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 | 843 | func isLteCrossStructField(fl FieldLevel) bool { |
823 | 844 | |
824 | 845 | field := fl.Field() |
865 | 886 | return field.String() <= topField.String() |
866 | 887 | } |
867 | 888 | |
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. | |
889 | // 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 | 890 | // NOTE: This is exposed for use within your own custom functions and not intended to be called directly. |
870 | 891 | func isLtCrossStructField(fl FieldLevel) bool { |
871 | 892 | |
913 | 934 | return field.String() < topField.String() |
914 | 935 | } |
915 | 936 | |
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. | |
937 | // 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 | 938 | func isGteCrossStructField(fl FieldLevel) bool { |
918 | 939 | |
919 | 940 | field := fl.Field() |
960 | 981 | return field.String() >= topField.String() |
961 | 982 | } |
962 | 983 | |
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. | |
984 | // 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 | 985 | func isGtCrossStructField(fl FieldLevel) bool { |
965 | 986 | |
966 | 987 | field := fl.Field() |
1007 | 1028 | return field.String() > topField.String() |
1008 | 1029 | } |
1009 | 1030 | |
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. | |
1031 | // 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 | 1032 | func isNeCrossStructField(fl FieldLevel) bool { |
1012 | 1033 | |
1013 | 1034 | field := fl.Field() |
1032 | 1053 | case reflect.Slice, reflect.Map, reflect.Array: |
1033 | 1054 | return int64(topField.Len()) != int64(field.Len()) |
1034 | 1055 | |
1056 | case reflect.Bool: | |
1057 | return topField.Bool() != field.Bool() | |
1058 | ||
1035 | 1059 | case reflect.Struct: |
1036 | 1060 | |
1037 | 1061 | fieldType := field.Type() |
1054 | 1078 | return topField.String() != field.String() |
1055 | 1079 | } |
1056 | 1080 | |
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. | |
1081 | // 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 | 1082 | func isEqCrossStructField(fl FieldLevel) bool { |
1059 | 1083 | |
1060 | 1084 | field := fl.Field() |
1078 | 1102 | |
1079 | 1103 | case reflect.Slice, reflect.Map, reflect.Array: |
1080 | 1104 | return int64(topField.Len()) == int64(field.Len()) |
1105 | ||
1106 | case reflect.Bool: | |
1107 | return topField.Bool() == field.Bool() | |
1081 | 1108 | |
1082 | 1109 | case reflect.Struct: |
1083 | 1110 | |
1101 | 1128 | return topField.String() == field.String() |
1102 | 1129 | } |
1103 | 1130 | |
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. | |
1131 | // 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 | 1132 | func isEqField(fl FieldLevel) bool { |
1106 | 1133 | |
1107 | 1134 | field := fl.Field() |
1125 | 1152 | |
1126 | 1153 | case reflect.Slice, reflect.Map, reflect.Array: |
1127 | 1154 | return int64(field.Len()) == int64(currentField.Len()) |
1155 | ||
1156 | case reflect.Bool: | |
1157 | return field.Bool() == currentField.Bool() | |
1128 | 1158 | |
1129 | 1159 | case reflect.Struct: |
1130 | 1160 | |
1149 | 1179 | return field.String() == currentField.String() |
1150 | 1180 | } |
1151 | 1181 | |
1152 | // IsEq is the validation function for validating if the current field's value is equal to the param's value. | |
1182 | // isEq is the validation function for validating if the current field's value is equal to the param's value. | |
1153 | 1183 | func isEq(fl FieldLevel) bool { |
1154 | 1184 | |
1155 | 1185 | field := fl.Field() |
1189 | 1219 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) |
1190 | 1220 | } |
1191 | 1221 | |
1192 | // IsBase64 is the validation function for validating if the current field's value is a valid base 64. | |
1222 | // isPostcodeByIso3166Alpha2 validates by value which is country code in iso 3166 alpha 2 | |
1223 | // example: `postcode_iso3166_alpha2=US` | |
1224 | func isPostcodeByIso3166Alpha2(fl FieldLevel) bool { | |
1225 | field := fl.Field() | |
1226 | param := fl.Param() | |
1227 | ||
1228 | reg, found := postCodeRegexDict[param] | |
1229 | if !found { | |
1230 | return false | |
1231 | } | |
1232 | ||
1233 | return reg.MatchString(field.String()) | |
1234 | } | |
1235 | ||
1236 | // isPostcodeByIso3166Alpha2 validates by field which represents for a value of country code in iso 3166 alpha 2 | |
1237 | // example: `postcode_iso3166_alpha2_field=CountryCode` | |
1238 | func isPostcodeByIso3166Alpha2Field(fl FieldLevel) bool { | |
1239 | field := fl.Field() | |
1240 | params := parseOneOfParam2(fl.Param()) | |
1241 | ||
1242 | if len(params) != 1 { | |
1243 | return false | |
1244 | } | |
1245 | ||
1246 | currentField, kind, _, found := fl.GetStructFieldOKAdvanced2(fl.Parent(), params[0]) | |
1247 | if !found { | |
1248 | return false | |
1249 | } | |
1250 | ||
1251 | if kind != reflect.String { | |
1252 | panic(fmt.Sprintf("Bad field type %T", currentField.Interface())) | |
1253 | } | |
1254 | ||
1255 | reg, found := postCodeRegexDict[currentField.String()] | |
1256 | if !found { | |
1257 | return false | |
1258 | } | |
1259 | ||
1260 | return reg.MatchString(field.String()) | |
1261 | } | |
1262 | ||
1263 | // isBase64 is the validation function for validating if the current field's value is a valid base 64. | |
1193 | 1264 | func isBase64(fl FieldLevel) bool { |
1194 | 1265 | return base64Regex.MatchString(fl.Field().String()) |
1195 | 1266 | } |
1196 | 1267 | |
1197 | // IsBase64URL is the validation function for validating if the current field's value is a valid base64 URL safe string. | |
1268 | // isBase64URL is the validation function for validating if the current field's value is a valid base64 URL safe string. | |
1198 | 1269 | func isBase64URL(fl FieldLevel) bool { |
1199 | 1270 | return base64URLRegex.MatchString(fl.Field().String()) |
1200 | 1271 | } |
1201 | 1272 | |
1202 | // IsURI is the validation function for validating if the current field's value is a valid URI. | |
1273 | // isURI is the validation function for validating if the current field's value is a valid URI. | |
1203 | 1274 | func isURI(fl FieldLevel) bool { |
1204 | 1275 | |
1205 | 1276 | field := fl.Field() |
1228 | 1299 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) |
1229 | 1300 | } |
1230 | 1301 | |
1231 | // IsURL is the validation function for validating if the current field's value is a valid URL. | |
1302 | // isURL is the validation function for validating if the current field's value is a valid URL. | |
1232 | 1303 | func isURL(fl FieldLevel) bool { |
1233 | 1304 | |
1234 | 1305 | field := fl.Field() |
1280 | 1351 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) |
1281 | 1352 | } |
1282 | 1353 | |
1283 | // IsFile is the validation function for validating if the current field's value is a valid file path. | |
1354 | // isFile is the validation function for validating if the current field's value is a valid file path. | |
1284 | 1355 | func isFile(fl FieldLevel) bool { |
1285 | 1356 | field := fl.Field() |
1286 | 1357 | |
1297 | 1368 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) |
1298 | 1369 | } |
1299 | 1370 | |
1300 | // IsE164 is the validation function for validating if the current field's value is a valid e.164 formatted phone number. | |
1371 | // isE164 is the validation function for validating if the current field's value is a valid e.164 formatted phone number. | |
1301 | 1372 | func isE164(fl FieldLevel) bool { |
1302 | 1373 | return e164Regex.MatchString(fl.Field().String()) |
1303 | 1374 | } |
1304 | 1375 | |
1305 | // IsEmail is the validation function for validating if the current field's value is a valid email address. | |
1376 | // isEmail is the validation function for validating if the current field's value is a valid email address. | |
1306 | 1377 | func isEmail(fl FieldLevel) bool { |
1307 | 1378 | return emailRegex.MatchString(fl.Field().String()) |
1308 | 1379 | } |
1309 | 1380 | |
1310 | // IsHSLA is the validation function for validating if the current field's value is a valid HSLA color. | |
1381 | // isHSLA is the validation function for validating if the current field's value is a valid HSLA color. | |
1311 | 1382 | func isHSLA(fl FieldLevel) bool { |
1312 | 1383 | return hslaRegex.MatchString(fl.Field().String()) |
1313 | 1384 | } |
1314 | 1385 | |
1315 | // IsHSL is the validation function for validating if the current field's value is a valid HSL color. | |
1386 | // isHSL is the validation function for validating if the current field's value is a valid HSL color. | |
1316 | 1387 | func isHSL(fl FieldLevel) bool { |
1317 | 1388 | return hslRegex.MatchString(fl.Field().String()) |
1318 | 1389 | } |
1319 | 1390 | |
1320 | // IsRGBA is the validation function for validating if the current field's value is a valid RGBA color. | |
1391 | // isRGBA is the validation function for validating if the current field's value is a valid RGBA color. | |
1321 | 1392 | func isRGBA(fl FieldLevel) bool { |
1322 | 1393 | return rgbaRegex.MatchString(fl.Field().String()) |
1323 | 1394 | } |
1324 | 1395 | |
1325 | // IsRGB is the validation function for validating if the current field's value is a valid RGB color. | |
1396 | // isRGB is the validation function for validating if the current field's value is a valid RGB color. | |
1326 | 1397 | func isRGB(fl FieldLevel) bool { |
1327 | 1398 | return rgbRegex.MatchString(fl.Field().String()) |
1328 | 1399 | } |
1329 | 1400 | |
1330 | // IsHEXColor is the validation function for validating if the current field's value is a valid HEX color. | |
1401 | // isHEXColor is the validation function for validating if the current field's value is a valid HEX color. | |
1331 | 1402 | 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. | |
1403 | return hexColorRegex.MatchString(fl.Field().String()) | |
1404 | } | |
1405 | ||
1406 | // isHexadecimal is the validation function for validating if the current field's value is a valid hexadecimal. | |
1336 | 1407 | func isHexadecimal(fl FieldLevel) bool { |
1337 | 1408 | return hexadecimalRegex.MatchString(fl.Field().String()) |
1338 | 1409 | } |
1339 | 1410 | |
1340 | // IsNumber is the validation function for validating if the current field's value is a valid number. | |
1411 | // isNumber is the validation function for validating if the current field's value is a valid number. | |
1341 | 1412 | func isNumber(fl FieldLevel) bool { |
1342 | 1413 | switch fl.Field().Kind() { |
1343 | 1414 | 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 | 1418 | } |
1348 | 1419 | } |
1349 | 1420 | |
1350 | // IsNumeric is the validation function for validating if the current field's value is a valid numeric value. | |
1421 | // isNumeric is the validation function for validating if the current field's value is a valid numeric value. | |
1351 | 1422 | func isNumeric(fl FieldLevel) bool { |
1352 | 1423 | switch fl.Field().Kind() { |
1353 | 1424 | 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 | 1428 | } |
1358 | 1429 | } |
1359 | 1430 | |
1360 | // IsAlphanum is the validation function for validating if the current field's value is a valid alphanumeric value. | |
1431 | // isAlphanum is the validation function for validating if the current field's value is a valid alphanumeric value. | |
1361 | 1432 | func isAlphanum(fl FieldLevel) bool { |
1362 | 1433 | return alphaNumericRegex.MatchString(fl.Field().String()) |
1363 | 1434 | } |
1364 | 1435 | |
1365 | // IsAlpha is the validation function for validating if the current field's value is a valid alpha value. | |
1436 | // isAlpha is the validation function for validating if the current field's value is a valid alpha value. | |
1366 | 1437 | func isAlpha(fl FieldLevel) bool { |
1367 | 1438 | return alphaRegex.MatchString(fl.Field().String()) |
1368 | 1439 | } |
1369 | 1440 | |
1370 | // IsAlphanumUnicode is the validation function for validating if the current field's value is a valid alphanumeric unicode value. | |
1441 | // isAlphanumUnicode is the validation function for validating if the current field's value is a valid alphanumeric unicode value. | |
1371 | 1442 | func isAlphanumUnicode(fl FieldLevel) bool { |
1372 | 1443 | return alphaUnicodeNumericRegex.MatchString(fl.Field().String()) |
1373 | 1444 | } |
1374 | 1445 | |
1375 | // IsAlphaUnicode is the validation function for validating if the current field's value is a valid alpha unicode value. | |
1446 | // isAlphaUnicode is the validation function for validating if the current field's value is a valid alpha unicode value. | |
1376 | 1447 | func isAlphaUnicode(fl FieldLevel) bool { |
1377 | 1448 | return alphaUnicodeRegex.MatchString(fl.Field().String()) |
1449 | } | |
1450 | ||
1451 | // isBoolean is the validation function for validating if the current field's value can be safely converted to a boolean. | |
1452 | func isBoolean(fl FieldLevel) bool { | |
1453 | _, err := strconv.ParseBool(fl.Field().String()) | |
1454 | return err == nil | |
1378 | 1455 | } |
1379 | 1456 | |
1380 | 1457 | // isDefault is the opposite of required aka hasValue |
1382 | 1459 | return !hasValue(fl) |
1383 | 1460 | } |
1384 | 1461 | |
1385 | // HasValue is the validation function for validating if the current field's value is not the default static value. | |
1462 | // hasValue is the validation function for validating if the current field's value is not the default static value. | |
1386 | 1463 | func hasValue(fl FieldLevel) bool { |
1387 | 1464 | field := fl.Field() |
1388 | 1465 | switch field.Kind() { |
1440 | 1517 | |
1441 | 1518 | case reflect.Slice, reflect.Map, reflect.Array: |
1442 | 1519 | return int64(field.Len()) == asInt(value) |
1520 | ||
1521 | case reflect.Bool: | |
1522 | return field.Bool() == asBool(value) | |
1443 | 1523 | } |
1444 | 1524 | |
1445 | 1525 | // default reflect.String: |
1477 | 1557 | return hasValue(fl) |
1478 | 1558 | } |
1479 | 1559 | |
1480 | // ExcludedWith is the validation function | |
1560 | // excludedWith is the validation function | |
1481 | 1561 | // The field under validation must not be present or is empty if any of the other specified fields are present. |
1482 | 1562 | func excludedWith(fl FieldLevel) bool { |
1483 | 1563 | params := parseOneOfParam2(fl.Param()) |
1489 | 1569 | return true |
1490 | 1570 | } |
1491 | 1571 | |
1492 | // RequiredWith is the validation function | |
1572 | // requiredWith is the validation function | |
1493 | 1573 | // The field under validation must be present and not empty only if any of the other specified fields are present. |
1494 | 1574 | func requiredWith(fl FieldLevel) bool { |
1495 | 1575 | params := parseOneOfParam2(fl.Param()) |
1501 | 1581 | return true |
1502 | 1582 | } |
1503 | 1583 | |
1504 | // ExcludedWithAll is the validation function | |
1584 | // excludedWithAll is the validation function | |
1505 | 1585 | // The field under validation must not be present or is empty if all of the other specified fields are present. |
1506 | 1586 | func excludedWithAll(fl FieldLevel) bool { |
1507 | 1587 | params := parseOneOfParam2(fl.Param()) |
1513 | 1593 | return !hasValue(fl) |
1514 | 1594 | } |
1515 | 1595 | |
1516 | // RequiredWithAll is the validation function | |
1596 | // requiredWithAll is the validation function | |
1517 | 1597 | // The field under validation must be present and not empty only if all of the other specified fields are present. |
1518 | 1598 | func requiredWithAll(fl FieldLevel) bool { |
1519 | 1599 | params := parseOneOfParam2(fl.Param()) |
1525 | 1605 | return hasValue(fl) |
1526 | 1606 | } |
1527 | 1607 | |
1528 | // ExcludedWithout is the validation function | |
1608 | // excludedWithout is the validation function | |
1529 | 1609 | // The field under validation must not be present or is empty when any of the other specified fields are not present. |
1530 | 1610 | func excludedWithout(fl FieldLevel) bool { |
1531 | 1611 | if requireCheckFieldKind(fl, strings.TrimSpace(fl.Param()), true) { |
1534 | 1614 | return true |
1535 | 1615 | } |
1536 | 1616 | |
1537 | // RequiredWithout is the validation function | |
1617 | // requiredWithout is the validation function | |
1538 | 1618 | // The field under validation must be present and not empty only when any of the other specified fields are not present. |
1539 | 1619 | func requiredWithout(fl FieldLevel) bool { |
1540 | 1620 | if requireCheckFieldKind(fl, strings.TrimSpace(fl.Param()), true) { |
1543 | 1623 | return true |
1544 | 1624 | } |
1545 | 1625 | |
1546 | // RequiredWithoutAll is the validation function | |
1626 | // excludedWithoutAll is the validation function | |
1547 | 1627 | // The field under validation must not be present or is empty when all of the other specified fields are not present. |
1548 | 1628 | func excludedWithoutAll(fl FieldLevel) bool { |
1549 | 1629 | params := parseOneOfParam2(fl.Param()) |
1555 | 1635 | return !hasValue(fl) |
1556 | 1636 | } |
1557 | 1637 | |
1558 | // RequiredWithoutAll is the validation function | |
1638 | // requiredWithoutAll is the validation function | |
1559 | 1639 | // The field under validation must be present and not empty only when all of the other specified fields are not present. |
1560 | 1640 | func requiredWithoutAll(fl FieldLevel) bool { |
1561 | 1641 | params := parseOneOfParam2(fl.Param()) |
1567 | 1647 | return hasValue(fl) |
1568 | 1648 | } |
1569 | 1649 | |
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. | |
1650 | // 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 | 1651 | func isGteField(fl FieldLevel) bool { |
1572 | 1652 | |
1573 | 1653 | field := fl.Field() |
1614 | 1694 | return len(field.String()) >= len(currentField.String()) |
1615 | 1695 | } |
1616 | 1696 | |
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. | |
1697 | // 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 | 1698 | func isGtField(fl FieldLevel) bool { |
1619 | 1699 | |
1620 | 1700 | field := fl.Field() |
1661 | 1741 | return len(field.String()) > len(currentField.String()) |
1662 | 1742 | } |
1663 | 1743 | |
1664 | // IsGte is the validation function for validating if the current field's value is greater than or equal to the param's value. | |
1744 | // isGte is the validation function for validating if the current field's value is greater than or equal to the param's value. | |
1665 | 1745 | func isGte(fl FieldLevel) bool { |
1666 | 1746 | |
1667 | 1747 | field := fl.Field() |
1708 | 1788 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) |
1709 | 1789 | } |
1710 | 1790 | |
1711 | // IsGt is the validation function for validating if the current field's value is greater than the param's value. | |
1791 | // isGt is the validation function for validating if the current field's value is greater than the param's value. | |
1712 | 1792 | func isGt(fl FieldLevel) bool { |
1713 | 1793 | |
1714 | 1794 | field := fl.Field() |
1751 | 1831 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) |
1752 | 1832 | } |
1753 | 1833 | |
1754 | // HasLengthOf is the validation function for validating if the current field's value is equal to the param's value. | |
1834 | // hasLengthOf is the validation function for validating if the current field's value is equal to the param's value. | |
1755 | 1835 | func hasLengthOf(fl FieldLevel) bool { |
1756 | 1836 | |
1757 | 1837 | field := fl.Field() |
1788 | 1868 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) |
1789 | 1869 | } |
1790 | 1870 | |
1791 | // HasMinOf is the validation function for validating if the current field's value is greater than or equal to the param's value. | |
1871 | // hasMinOf is the validation function for validating if the current field's value is greater than or equal to the param's value. | |
1792 | 1872 | func hasMinOf(fl FieldLevel) bool { |
1793 | 1873 | return isGte(fl) |
1794 | 1874 | } |
1795 | 1875 | |
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. | |
1876 | // 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 | 1877 | func isLteField(fl FieldLevel) bool { |
1798 | 1878 | |
1799 | 1879 | field := fl.Field() |
1840 | 1920 | return len(field.String()) <= len(currentField.String()) |
1841 | 1921 | } |
1842 | 1922 | |
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. | |
1923 | // 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 | 1924 | func isLtField(fl FieldLevel) bool { |
1845 | 1925 | |
1846 | 1926 | field := fl.Field() |
1887 | 1967 | return len(field.String()) < len(currentField.String()) |
1888 | 1968 | } |
1889 | 1969 | |
1890 | // IsLte is the validation function for validating if the current field's value is less than or equal to the param's value. | |
1970 | // isLte is the validation function for validating if the current field's value is less than or equal to the param's value. | |
1891 | 1971 | func isLte(fl FieldLevel) bool { |
1892 | 1972 | |
1893 | 1973 | field := fl.Field() |
1934 | 2014 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) |
1935 | 2015 | } |
1936 | 2016 | |
1937 | // IsLt is the validation function for validating if the current field's value is less than the param's value. | |
2017 | // isLt is the validation function for validating if the current field's value is less than the param's value. | |
1938 | 2018 | func isLt(fl FieldLevel) bool { |
1939 | 2019 | |
1940 | 2020 | field := fl.Field() |
1978 | 2058 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) |
1979 | 2059 | } |
1980 | 2060 | |
1981 | // HasMaxOf is the validation function for validating if the current field's value is less than or equal to the param's value. | |
2061 | // hasMaxOf is the validation function for validating if the current field's value is less than or equal to the param's value. | |
1982 | 2062 | func hasMaxOf(fl FieldLevel) bool { |
1983 | 2063 | return isLte(fl) |
1984 | 2064 | } |
1985 | 2065 | |
1986 | // IsTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address. | |
2066 | // isTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address. | |
1987 | 2067 | func isTCP4AddrResolvable(fl FieldLevel) bool { |
1988 | 2068 | |
1989 | 2069 | if !isIP4Addr(fl) { |
1994 | 2074 | return err == nil |
1995 | 2075 | } |
1996 | 2076 | |
1997 | // IsTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address. | |
2077 | // isTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address. | |
1998 | 2078 | func isTCP6AddrResolvable(fl FieldLevel) bool { |
1999 | 2079 | |
2000 | 2080 | if !isIP6Addr(fl) { |
2006 | 2086 | return err == nil |
2007 | 2087 | } |
2008 | 2088 | |
2009 | // IsTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address. | |
2089 | // isTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address. | |
2010 | 2090 | func isTCPAddrResolvable(fl FieldLevel) bool { |
2011 | 2091 | |
2012 | 2092 | if !isIP4Addr(fl) && !isIP6Addr(fl) { |
2018 | 2098 | return err == nil |
2019 | 2099 | } |
2020 | 2100 | |
2021 | // IsUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address. | |
2101 | // isUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address. | |
2022 | 2102 | func isUDP4AddrResolvable(fl FieldLevel) bool { |
2023 | 2103 | |
2024 | 2104 | if !isIP4Addr(fl) { |
2030 | 2110 | return err == nil |
2031 | 2111 | } |
2032 | 2112 | |
2033 | // IsUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address. | |
2113 | // isUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address. | |
2034 | 2114 | func isUDP6AddrResolvable(fl FieldLevel) bool { |
2035 | 2115 | |
2036 | 2116 | if !isIP6Addr(fl) { |
2042 | 2122 | return err == nil |
2043 | 2123 | } |
2044 | 2124 | |
2045 | // IsUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address. | |
2125 | // isUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address. | |
2046 | 2126 | func isUDPAddrResolvable(fl FieldLevel) bool { |
2047 | 2127 | |
2048 | 2128 | if !isIP4Addr(fl) && !isIP6Addr(fl) { |
2054 | 2134 | return err == nil |
2055 | 2135 | } |
2056 | 2136 | |
2057 | // IsIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address. | |
2137 | // isIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address. | |
2058 | 2138 | func isIP4AddrResolvable(fl FieldLevel) bool { |
2059 | 2139 | |
2060 | 2140 | if !isIPv4(fl) { |
2066 | 2146 | return err == nil |
2067 | 2147 | } |
2068 | 2148 | |
2069 | // IsIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address. | |
2149 | // isIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address. | |
2070 | 2150 | func isIP6AddrResolvable(fl FieldLevel) bool { |
2071 | 2151 | |
2072 | 2152 | if !isIPv6(fl) { |
2078 | 2158 | return err == nil |
2079 | 2159 | } |
2080 | 2160 | |
2081 | // IsIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address. | |
2161 | // isIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address. | |
2082 | 2162 | func isIPAddrResolvable(fl FieldLevel) bool { |
2083 | 2163 | |
2084 | 2164 | if !isIP(fl) { |
2090 | 2170 | return err == nil |
2091 | 2171 | } |
2092 | 2172 | |
2093 | // IsUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address. | |
2173 | // isUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address. | |
2094 | 2174 | func isUnixAddrResolvable(fl FieldLevel) bool { |
2095 | 2175 | |
2096 | 2176 | _, err := net.ResolveUnixAddr("unix", fl.Field().String()) |
2144 | 2224 | return fqdnRegexRFC1123.MatchString(val) |
2145 | 2225 | } |
2146 | 2226 | |
2147 | // IsDir is the validation function for validating if the current field's value is a valid directory. | |
2227 | // isDir is the validation function for validating if the current field's value is a valid directory. | |
2148 | 2228 | func isDir(fl FieldLevel) bool { |
2149 | 2229 | field := fl.Field() |
2150 | 2230 | |
2170 | 2250 | } |
2171 | 2251 | |
2172 | 2252 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) |
2253 | } | |
2254 | ||
2255 | // isJWT is the validation function for validating if the current field's value is a valid JWT string. | |
2256 | func isJWT(fl FieldLevel) bool { | |
2257 | return jWTRegex.MatchString(fl.Field().String()) | |
2173 | 2258 | } |
2174 | 2259 | |
2175 | 2260 | // isHostnamePort validates a <dns>:<port> combination for fields typically used for socket address. |
2273 | 2358 | |
2274 | 2359 | var code int |
2275 | 2360 | switch field.Kind() { |
2361 | case reflect.String: | |
2362 | i, err := strconv.Atoi(field.String()) | |
2363 | if err != nil { | |
2364 | return false | |
2365 | } | |
2366 | code = i % 1000 | |
2276 | 2367 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: |
2277 | 2368 | code = int(field.Int() % 1000) |
2278 | 2369 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: |
2282 | 2373 | } |
2283 | 2374 | return iso3166_1_alpha_numeric[code] |
2284 | 2375 | } |
2376 | ||
2377 | // isIso31662 is the validation function for validating if the current field's value is a valid iso3166-2 code. | |
2378 | func isIso31662(fl FieldLevel) bool { | |
2379 | val := fl.Field().String() | |
2380 | return iso3166_2[val] | |
2381 | } | |
2382 | ||
2383 | // isIso4217 is the validation function for validating if the current field's value is a valid iso4217 currency code. | |
2384 | func isIso4217(fl FieldLevel) bool { | |
2385 | val := fl.Field().String() | |
2386 | return iso4217[val] | |
2387 | } | |
2388 | ||
2389 | // isIso4217Numeric is the validation function for validating if the current field's value is a valid iso4217 numeric currency code. | |
2390 | func isIso4217Numeric(fl FieldLevel) bool { | |
2391 | field := fl.Field() | |
2392 | ||
2393 | var code int | |
2394 | switch field.Kind() { | |
2395 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | |
2396 | code = int(field.Int()) | |
2397 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | |
2398 | code = int(field.Uint()) | |
2399 | default: | |
2400 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) | |
2401 | } | |
2402 | return iso4217_numeric[code] | |
2403 | } | |
2404 | ||
2405 | // 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 | |
2406 | func isBCP47LanguageTag(fl FieldLevel) bool { | |
2407 | field := fl.Field() | |
2408 | ||
2409 | if field.Kind() == reflect.String { | |
2410 | _, err := language.Parse(field.String()) | |
2411 | return err == nil | |
2412 | } | |
2413 | ||
2414 | panic(fmt.Sprintf("Bad field type %T", field.Interface())) | |
2415 | } | |
2416 | ||
2417 | // 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 | |
2418 | func isIsoBicFormat(fl FieldLevel) bool { | |
2419 | bicString := fl.Field().String() | |
2420 | ||
2421 | return bicRegex.MatchString(bicString) | |
2422 | } | |
2423 | ||
2424 | // isSemverFormat is the validation function for validating if the current field's value is a valid semver version, defined in Semantic Versioning 2.0.0 | |
2425 | func isSemverFormat(fl FieldLevel) bool { | |
2426 | semverString := fl.Field().String() | |
2427 | ||
2428 | return semverRegex.MatchString(semverString) | |
2429 | } | |
2430 | ||
2431 | // isDnsRFC1035LabelFormat is the validation function | |
2432 | // for validating if the current field's value is | |
2433 | // a valid dns RFC 1035 label, defined in RFC 1035. | |
2434 | func isDnsRFC1035LabelFormat(fl FieldLevel) bool { | |
2435 | val := fl.Field().String() | |
2436 | return dnsRegexRFC1035Label.MatchString(val) | |
2437 | } |
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 | } |
0 | package validator | |
1 | ||
2 | var iso4217 = map[string]bool{ | |
3 | "AFN": true, "EUR": true, "ALL": true, "DZD": true, "USD": true, | |
4 | "AOA": true, "XCD": true, "ARS": true, "AMD": true, "AWG": true, | |
5 | "AUD": true, "AZN": true, "BSD": true, "BHD": true, "BDT": true, | |
6 | "BBD": true, "BYN": true, "BZD": true, "XOF": true, "BMD": true, | |
7 | "INR": true, "BTN": true, "BOB": true, "BOV": true, "BAM": true, | |
8 | "BWP": true, "NOK": true, "BRL": true, "BND": true, "BGN": true, | |
9 | "BIF": true, "CVE": true, "KHR": true, "XAF": true, "CAD": true, | |
10 | "KYD": true, "CLP": true, "CLF": true, "CNY": true, "COP": true, | |
11 | "COU": true, "KMF": true, "CDF": true, "NZD": true, "CRC": true, | |
12 | "HRK": true, "CUP": true, "CUC": true, "ANG": true, "CZK": true, | |
13 | "DKK": true, "DJF": true, "DOP": true, "EGP": true, "SVC": true, | |
14 | "ERN": true, "SZL": true, "ETB": true, "FKP": true, "FJD": true, | |
15 | "XPF": true, "GMD": true, "GEL": true, "GHS": true, "GIP": true, | |
16 | "GTQ": true, "GBP": true, "GNF": true, "GYD": true, "HTG": true, | |
17 | "HNL": true, "HKD": true, "HUF": true, "ISK": true, "IDR": true, | |
18 | "XDR": true, "IRR": true, "IQD": true, "ILS": true, "JMD": true, | |
19 | "JPY": true, "JOD": true, "KZT": true, "KES": true, "KPW": true, | |
20 | "KRW": true, "KWD": true, "KGS": true, "LAK": true, "LBP": true, | |
21 | "LSL": true, "ZAR": true, "LRD": true, "LYD": true, "CHF": true, | |
22 | "MOP": true, "MKD": true, "MGA": true, "MWK": true, "MYR": true, | |
23 | "MVR": true, "MRU": true, "MUR": true, "XUA": true, "MXN": true, | |
24 | "MXV": true, "MDL": true, "MNT": true, "MAD": true, "MZN": true, | |
25 | "MMK": true, "NAD": true, "NPR": true, "NIO": true, "NGN": true, | |
26 | "OMR": true, "PKR": true, "PAB": true, "PGK": true, "PYG": true, | |
27 | "PEN": true, "PHP": true, "PLN": true, "QAR": true, "RON": true, | |
28 | "RUB": true, "RWF": true, "SHP": true, "WST": true, "STN": true, | |
29 | "SAR": true, "RSD": true, "SCR": true, "SLL": true, "SGD": true, | |
30 | "XSU": true, "SBD": true, "SOS": true, "SSP": true, "LKR": true, | |
31 | "SDG": true, "SRD": true, "SEK": true, "CHE": true, "CHW": true, | |
32 | "SYP": true, "TWD": true, "TJS": true, "TZS": true, "THB": true, | |
33 | "TOP": true, "TTD": true, "TND": true, "TRY": true, "TMT": true, | |
34 | "UGX": true, "UAH": true, "AED": true, "USN": true, "UYU": true, | |
35 | "UYI": true, "UYW": true, "UZS": true, "VUV": true, "VES": true, | |
36 | "VND": true, "YER": true, "ZMW": true, "ZWL": true, "XBA": true, | |
37 | "XBB": true, "XBC": true, "XBD": true, "XTS": true, "XXX": true, | |
38 | "XAU": true, "XPD": true, "XPT": true, "XAG": true, | |
39 | } | |
40 | ||
41 | var iso4217_numeric = map[int]bool{ | |
42 | 8: true, 12: true, 32: true, 36: true, 44: true, | |
43 | 48: true, 50: true, 51: true, 52: true, 60: true, | |
44 | 64: true, 68: true, 72: true, 84: true, 90: true, | |
45 | 96: true, 104: true, 108: true, 116: true, 124: true, | |
46 | 132: true, 136: true, 144: true, 152: true, 156: true, | |
47 | 170: true, 174: true, 188: true, 191: true, 192: true, | |
48 | 203: true, 208: true, 214: true, 222: true, 230: true, | |
49 | 232: true, 238: true, 242: true, 262: true, 270: true, | |
50 | 292: true, 320: true, 324: true, 328: true, 332: true, | |
51 | 340: true, 344: true, 348: true, 352: true, 356: true, | |
52 | 360: true, 364: true, 368: true, 376: true, 388: true, | |
53 | 392: true, 398: true, 400: true, 404: true, 408: true, | |
54 | 410: true, 414: true, 417: true, 418: true, 422: true, | |
55 | 426: true, 430: true, 434: true, 446: true, 454: true, | |
56 | 458: true, 462: true, 480: true, 484: true, 496: true, | |
57 | 498: true, 504: true, 512: true, 516: true, 524: true, | |
58 | 532: true, 533: true, 548: true, 554: true, 558: true, | |
59 | 566: true, 578: true, 586: true, 590: true, 598: true, | |
60 | 600: true, 604: true, 608: true, 634: true, 643: true, | |
61 | 646: true, 654: true, 682: true, 690: true, 694: true, | |
62 | 702: true, 704: true, 706: true, 710: true, 728: true, | |
63 | 748: true, 752: true, 756: true, 760: true, 764: true, | |
64 | 776: true, 780: true, 784: true, 788: true, 800: true, | |
65 | 807: true, 818: true, 826: true, 834: true, 840: true, | |
66 | 858: true, 860: true, 882: true, 886: true, 901: true, | |
67 | 927: true, 928: true, 929: true, 930: true, 931: true, | |
68 | 932: true, 933: true, 934: true, 936: true, 938: true, | |
69 | 940: true, 941: true, 943: true, 944: true, 946: true, | |
70 | 947: true, 948: true, 949: true, 950: true, 951: true, | |
71 | 952: true, 953: true, 955: true, 956: true, 957: true, | |
72 | 958: true, 959: true, 960: true, 961: true, 962: true, | |
73 | 963: true, 964: true, 965: true, 967: true, 968: true, | |
74 | 969: true, 970: true, 971: true, 972: true, 973: true, | |
75 | 975: true, 976: true, 977: true, 978: true, 979: true, | |
76 | 980: true, 981: true, 984: true, 985: true, 986: true, | |
77 | 990: true, 994: true, 997: true, 999: true, | |
78 | } |
5 | 5 | and has the ability to dive into arrays and maps of any type. |
6 | 6 | |
7 | 7 | see more examples https://github.com/go-playground/validator/tree/master/_examples |
8 | ||
9 | Singleton | |
10 | ||
11 | Validator is designed to be thread-safe and used as a singleton instance. | |
12 | It caches information about your struct and validations, | |
13 | in essence only parsing your validation tags once per struct type. | |
14 | Using multiple instances neglects the benefit of caching. | |
15 | The not thread-safe functions are explicitly marked as such in the documentation. | |
8 | 16 | |
9 | 17 | Validation Functions Return Type error |
10 | 18 | |
725 | 733 | |
726 | 734 | Usage: alphanumunicode |
727 | 735 | |
736 | Boolean | |
737 | ||
738 | This validates that a string value can successfully be parsed into a boolean with strconv.ParseBool | |
739 | ||
740 | Usage: boolean | |
741 | ||
728 | 742 | Number |
729 | 743 | |
730 | 744 | This validates that a string value contains number values only. |
809 | 823 | This validates that a string value is valid JSON |
810 | 824 | |
811 | 825 | Usage: json |
826 | ||
827 | JWT String | |
828 | ||
829 | This validates that a string value is a valid JWT | |
830 | ||
831 | Usage: jwt | |
812 | 832 | |
813 | 833 | File path |
814 | 834 | |
986 | 1006 | |
987 | 1007 | Usage: uuid5 |
988 | 1008 | |
1009 | Universally Unique Lexicographically Sortable Identifier ULID | |
1010 | ||
1011 | This validates that a string value contains a valid ULID value. | |
1012 | ||
1013 | Usage: ulid | |
1014 | ||
989 | 1015 | ASCII |
990 | 1016 | |
991 | 1017 | This validates that a string value contains only ASCII characters. |
1220 | 1246 | |
1221 | 1247 | Usage: iso3166_1_alpha3 |
1222 | 1248 | |
1249 | BCP 47 Language Tag | |
1250 | ||
1251 | This validates that a string value is a valid BCP 47 language tag, as parsed by language.Parse. | |
1252 | More information on https://pkg.go.dev/golang.org/x/text/language | |
1253 | ||
1254 | Usage: bcp47_language_tag | |
1255 | ||
1256 | BIC (SWIFT code) | |
1257 | ||
1258 | This validates that a string value is a valid Business Identifier Code (SWIFT code), defined in ISO 9362. | |
1259 | More information on https://www.iso.org/standard/60390.html | |
1260 | ||
1261 | Usage: bic | |
1262 | ||
1263 | RFC 1035 label | |
1264 | ||
1265 | This validates that a string value is a valid dns RFC 1035 label, defined in RFC 1035. | |
1266 | More information on https://datatracker.ietf.org/doc/html/rfc1035 | |
1267 | ||
1268 | Usage: dns_rfc1035_label | |
1269 | ||
1223 | 1270 | TimeZone |
1224 | 1271 | |
1225 | 1272 | This validates that a string value is a valid time zone based on the time zone database present on the system. |
1227 | 1274 | More information on https://golang.org/pkg/time/#LoadLocation |
1228 | 1275 | |
1229 | 1276 | Usage: timezone |
1230 | ||
1277 | ||
1278 | Semantic Version | |
1279 | ||
1280 | This validates that a string value is a valid semver version, defined in Semantic Versioning 2.0.0. | |
1281 | More information on https://semver.org/ | |
1282 | ||
1283 | Usage: semver | |
1231 | 1284 | |
1232 | 1285 | Alias Validators and Tags |
1233 | 1286 |
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) |
2 | 2 | go 1.13 |
3 | 3 | |
4 | 4 | require ( |
5 | github.com/davecgh/go-spew v1.1.1 // indirect | |
5 | 6 | github.com/go-playground/assert/v2 v2.0.1 |
6 | github.com/go-playground/locales v0.13.0 | |
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 | |
7 | github.com/go-playground/locales v0.14.0 | |
8 | github.com/go-playground/universal-translator v0.18.0 | |
9 | github.com/kr/pretty v0.3.0 // indirect | |
10 | github.com/leodido/go-urn v1.2.1 | |
11 | github.com/rogpeppe/go-internal v1.8.0 // indirect | |
12 | github.com/stretchr/testify v1.7.0 // indirect | |
13 | golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 | |
14 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 // indirect | |
15 | golang.org/x/text v0.3.7 | |
16 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect | |
17 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect | |
10 | 18 | ) |
0 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= | |
0 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= | |
1 | 1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
2 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | |
3 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | |
2 | 4 | github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= |
3 | 5 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= |
4 | github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= | |
5 | github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= | |
6 | github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= | |
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= | |
6 | github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= | |
7 | github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= | |
8 | github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= | |
9 | github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= | |
10 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= | |
11 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= | |
12 | github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= | |
13 | github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= | |
14 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | |
15 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | |
16 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | |
17 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= | |
18 | github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= | |
19 | github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= | |
20 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= | |
10 | 21 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= |
11 | 22 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= |
23 | github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= | |
24 | github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= | |
25 | github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= | |
12 | 26 | 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= | |
22 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | |
27 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | |
28 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= | |
29 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | |
30 | golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M= | |
31 | golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= | |
32 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= | |
33 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |
34 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | |
35 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | |
36 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 h1:siQdpVirKtzPhKl3lZWozZraCFObP8S1v6PRp0bLrtU= | |
37 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | |
38 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | |
39 | golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= | |
40 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | |
41 | golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= | |
42 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= | |
23 | 43 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= |
24 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | |
25 | 44 | 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= | |
45 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | |
46 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= | |
47 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= | |
48 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= | |
49 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | |
50 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= | |
51 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$" | |
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*\\)$" |
28 | 28 | uUID4RFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" |
29 | 29 | uUID5RFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-5[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" |
30 | 30 | uUIDRFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" |
31 | uLIDRegexString = "^[A-HJKMNP-TV-Z0-9]{26}$" | |
31 | 32 | aSCIIRegexString = "^[\x00-\x7F]*$" |
32 | 33 | printableASCIIRegexString = "^[\x20-\x7E]*$" |
33 | 34 | multibyteRegexString = "[^\x00-\x7F]" |
44 | 45 | ethAddressRegexString = `^0x[0-9a-fA-F]{40}$` |
45 | 46 | ethAddressUpperRegexString = `^0x[0-9A-F]{40}$` |
46 | 47 | ethAddressLowerRegexString = `^0x[0-9a-f]{40}$` |
47 | uRLEncodedRegexString = `(%[A-Fa-f0-9]{2})` | |
48 | uRLEncodedRegexString = `^(?:[^%]|%[0-9A-Fa-f]{2})*$` | |
48 | 49 | hTMLEncodedRegexString = `&#[x]?([0-9a-fA-F]{2})|(>)|(<)|(")|(&)+[;]?` |
49 | 50 | hTMLRegexString = `<[/]?([a-zA-Z]+).*?>` |
51 | jWTRegexString = "^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$" | |
50 | 52 | splitParamsRegexString = `'[^']*'|\S+` |
53 | bicRegexString = `^[A-Za-z]{6}[A-Za-z0-9]{2}([A-Za-z0-9]{3})?$` | |
54 | semverRegexString = `^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$` // numbered capture groups https://semver.org/ | |
55 | dnsRegexStringRFC1035Label = "^[a-z]([-a-z0-9]*[a-z0-9]){0,62}$" | |
51 | 56 | ) |
52 | 57 | |
53 | 58 | var ( |
58 | 63 | numericRegex = regexp.MustCompile(numericRegexString) |
59 | 64 | numberRegex = regexp.MustCompile(numberRegexString) |
60 | 65 | hexadecimalRegex = regexp.MustCompile(hexadecimalRegexString) |
61 | hexcolorRegex = regexp.MustCompile(hexcolorRegexString) | |
66 | hexColorRegex = regexp.MustCompile(hexColorRegexString) | |
62 | 67 | rgbRegex = regexp.MustCompile(rgbRegexString) |
63 | 68 | rgbaRegex = regexp.MustCompile(rgbaRegexString) |
64 | 69 | hslRegex = regexp.MustCompile(hslRegexString) |
77 | 82 | uUID4RFC4122Regex = regexp.MustCompile(uUID4RFC4122RegexString) |
78 | 83 | uUID5RFC4122Regex = regexp.MustCompile(uUID5RFC4122RegexString) |
79 | 84 | uUIDRFC4122Regex = regexp.MustCompile(uUIDRFC4122RegexString) |
85 | uLIDRegex = regexp.MustCompile(uLIDRegexString) | |
80 | 86 | aSCIIRegex = regexp.MustCompile(aSCIIRegexString) |
81 | 87 | printableASCIIRegex = regexp.MustCompile(printableASCIIRegexString) |
82 | 88 | multibyteRegex = regexp.MustCompile(multibyteRegexString) |
91 | 97 | btcUpperAddressRegexBech32 = regexp.MustCompile(btcAddressUpperRegexStringBech32) |
92 | 98 | btcLowerAddressRegexBech32 = regexp.MustCompile(btcAddressLowerRegexStringBech32) |
93 | 99 | ethAddressRegex = regexp.MustCompile(ethAddressRegexString) |
94 | ethaddressRegexUpper = regexp.MustCompile(ethAddressUpperRegexString) | |
100 | ethAddressRegexUpper = regexp.MustCompile(ethAddressUpperRegexString) | |
95 | 101 | ethAddressRegexLower = regexp.MustCompile(ethAddressLowerRegexString) |
96 | 102 | uRLEncodedRegex = regexp.MustCompile(uRLEncodedRegexString) |
97 | 103 | hTMLEncodedRegex = regexp.MustCompile(hTMLEncodedRegexString) |
98 | 104 | hTMLRegex = regexp.MustCompile(hTMLRegexString) |
105 | jWTRegex = regexp.MustCompile(jWTRegexString) | |
99 | 106 | splitParamsRegex = regexp.MustCompile(splitParamsRegexString) |
107 | bicRegex = regexp.MustCompile(bicRegexString) | |
108 | semverRegex = regexp.MustCompile(semverRegexString) | |
109 | dnsRegexRFC1035Label = regexp.MustCompile(dnsRegexStringRFC1035Label) | |
100 | 110 | ) |
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) |
1178 | 1136 | override: false, |
1179 | 1137 | }, |
1180 | 1138 | { |
1139 | tag: "ulid", | |
1140 | translation: "{0} must be a valid ULID", | |
1141 | override: false, | |
1142 | }, | |
1143 | { | |
1181 | 1144 | tag: "ascii", |
1182 | 1145 | translation: "{0} must contain only ascii characters", |
1183 | 1146 | override: false, |
1324 | 1287 | tag: "json", |
1325 | 1288 | translation: "{0} must be a valid json string", |
1326 | 1289 | override: false, |
1327 | }, | |
1328 | { | |
1290 | }, | |
1291 | { | |
1292 | tag: "jwt", | |
1293 | translation: "{0} must be a valid jwt string", | |
1294 | override: false, | |
1295 | }, | |
1296 | { | |
1329 | 1297 | tag: "lowercase", |
1330 | 1298 | translation: "{0} must be a lowercase string", |
1331 | 1299 | override: false, |
1340 | 1308 | translation: "{0} does not match the {1} format", |
1341 | 1309 | override: false, |
1342 | 1310 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { |
1343 | ||
1311 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
1312 | if err != nil { | |
1313 | log.Printf("warning: error translating FieldError: %#v", fe) | |
1314 | return fe.(error).Error() | |
1315 | } | |
1316 | ||
1317 | return t | |
1318 | }, | |
1319 | }, | |
1320 | { | |
1321 | tag: "postcode_iso3166_alpha2", | |
1322 | translation: "{0} does not match postcode format of {1} country", | |
1323 | override: false, | |
1324 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
1325 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
1326 | if err != nil { | |
1327 | log.Printf("warning: error translating FieldError: %#v", fe) | |
1328 | return fe.(error).Error() | |
1329 | } | |
1330 | ||
1331 | return t | |
1332 | }, | |
1333 | }, | |
1334 | { | |
1335 | tag: "postcode_iso3166_alpha2_field", | |
1336 | translation: "{0} does not match postcode format of country in {1} field", | |
1337 | override: false, | |
1338 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
1344 | 1339 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) |
1345 | 1340 | if err != nil { |
1346 | 1341 | log.Printf("warning: error translating FieldError: %#v", fe) |
1355 | 1350 | for _, t := range translations { |
1356 | 1351 | |
1357 | 1352 | if t.customTransFunc != nil && t.customRegisFunc != nil { |
1358 | ||
1359 | 1353 | err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, t.customTransFunc) |
1360 | ||
1361 | 1354 | } else if t.customTransFunc != nil && t.customRegisFunc == nil { |
1362 | ||
1363 | 1355 | err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), t.customTransFunc) |
1364 | ||
1365 | 1356 | } else if t.customTransFunc == nil && t.customRegisFunc != nil { |
1366 | ||
1367 | 1357 | err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, translateFunc) |
1368 | ||
1369 | 1358 | } else { |
1370 | 1359 | err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), translateFunc) |
1371 | 1360 | } |
1379 | 1368 | } |
1380 | 1369 | |
1381 | 1370 | func registrationFunc(tag string, translation string, override bool) validator.RegisterTranslationsFunc { |
1382 | ||
1383 | 1371 | return func(ut ut.Translator) (err error) { |
1384 | ||
1385 | 1372 | if err = ut.Add(tag, translation, override); err != nil { |
1386 | 1373 | return |
1387 | 1374 | } |
1388 | 1375 | |
1389 | 1376 | return |
1390 | ||
1391 | 1377 | } |
1392 | ||
1393 | 1378 | } |
1394 | 1379 | |
1395 | 1380 | func translateFunc(ut ut.Translator, fe validator.FieldError) string { |
1396 | ||
1397 | 1381 | t, err := ut.T(fe.Tag(), fe.Field()) |
1398 | 1382 | if err != nil { |
1399 | 1383 | 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") |
103 | 102 | UUID3 string `validate:"uuid3"` |
104 | 103 | UUID4 string `validate:"uuid4"` |
105 | 104 | UUID5 string `validate:"uuid5"` |
105 | ULID string `validate:"ulid"` | |
106 | 106 | ASCII string `validate:"ascii"` |
107 | 107 | PrintableASCII string `validate:"printascii"` |
108 | 108 | MultiByte string `validate:"multibyte"` |
141 | 141 | UniqueArray [3]string `validate:"unique"` |
142 | 142 | UniqueMap map[string]string `validate:"unique"` |
143 | 143 | JSONString string `validate:"json"` |
144 | JWTString string `validate:"jwt"` | |
144 | 145 | LowercaseString string `validate:"lowercase"` |
145 | 146 | UppercaseString string `validate:"uppercase"` |
146 | 147 | Datetime string `validate:"datetime=2006-01-02"` |
148 | PostCode string `validate:"postcode_iso3166_alpha2=SG"` | |
149 | PostCodeCountry string | |
150 | PostCodeByField string `validate:"postcode_iso3166_alpha2_field=PostCodeCountry"` | |
147 | 151 | } |
148 | 152 | |
149 | 153 | var test Test |
320 | 324 | expected: "UUID5 must be a valid version 5 UUID", |
321 | 325 | }, |
322 | 326 | { |
327 | ns: "Test.ULID", | |
328 | expected: "ULID must be a valid ULID", | |
329 | }, | |
330 | { | |
323 | 331 | ns: "Test.ISBN", |
324 | 332 | expected: "ISBN must be a valid ISBN number", |
325 | 333 | }, |
644 | 652 | expected: "JSONString must be a valid json string", |
645 | 653 | }, |
646 | 654 | { |
655 | ns: "Test.JWTString", | |
656 | expected: "JWTString must be a valid jwt string", | |
657 | }, | |
658 | { | |
647 | 659 | ns: "Test.LowercaseString", |
648 | 660 | expected: "LowercaseString must be a lowercase string", |
649 | 661 | }, |
654 | 666 | { |
655 | 667 | ns: "Test.Datetime", |
656 | 668 | expected: "Datetime does not match the 2006-01-02 format", |
669 | }, | |
670 | { | |
671 | ns: "Test.PostCode", | |
672 | expected: "PostCode does not match postcode format of SG country", | |
673 | }, | |
674 | { | |
675 | ns: "Test.PostCodeByField", | |
676 | expected: "PostCodeByField does not match postcode format of country in PostCodeCountry field", | |
657 | 677 | }, |
658 | 678 | } |
659 | 679 | |
671 | 691 | NotEqual(t, fe, nil) |
672 | 692 | Equal(t, tt.expected, fe.Translate(trans)) |
673 | 693 | } |
674 | ||
675 | 694 | } |
1178 | 1178 | override: false, |
1179 | 1179 | }, |
1180 | 1180 | { |
1181 | tag: "ulid", | |
1182 | translation: "{0} debe ser un ULID válido", | |
1183 | override: false, | |
1184 | }, | |
1185 | { | |
1181 | 1186 | tag: "ascii", |
1182 | 1187 | translation: "{0} debe contener sólo caracteres ascii", |
1183 | 1188 | override: false, |
3 | 3 | "testing" |
4 | 4 | "time" |
5 | 5 | |
6 | . "github.com/go-playground/assert/v2" | |
6 | 7 | spanish "github.com/go-playground/locales/es" |
7 | 8 | ut "github.com/go-playground/universal-translator" |
8 | . "github.com/go-playground/assert/v2" | |
9 | 9 | "github.com/go-playground/validator/v10" |
10 | 10 | ) |
11 | 11 | |
103 | 103 | UUID3 string `validate:"uuid3"` |
104 | 104 | UUID4 string `validate:"uuid4"` |
105 | 105 | UUID5 string `validate:"uuid5"` |
106 | ULID string `validate:"ulid"` | |
106 | 107 | ASCII string `validate:"ascii"` |
107 | 108 | PrintableASCII string `validate:"printascii"` |
108 | 109 | MultiByte string `validate:"multibyte"` |
312 | 313 | expected: "UUID5 debe ser una versión válida 5 UUID", |
313 | 314 | }, |
314 | 315 | { |
316 | ns: "Test.ULID", | |
317 | expected: "ULID debe ser un ULID válido", | |
318 | }, | |
319 | { | |
315 | 320 | ns: "Test.ISBN", |
316 | 321 | expected: "ISBN debe ser un número ISBN válido", |
317 | 322 | }, |
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: "ulid", | |
1140 | translation: "{0} باید یک ULID معتبر باشد", | |
1141 | override: false, | |
1142 | }, | |
1143 | { | |
1144 | tag: "ascii", | |
1145 | translation: "{0} باید فقط شامل کاراکترهای اسکی باشد", | |
1146 | override: false, | |
1147 | }, | |
1148 | { | |
1149 | tag: "printascii", | |
1150 | translation: "{0} باید فقط شامل کاراکترهای اسکی قابل چاپ باشد", | |
1151 | override: false, | |
1152 | }, | |
1153 | { | |
1154 | tag: "multibyte", | |
1155 | translation: "{0} باید شامل کاراکترهای چندبایته باشد", | |
1156 | override: false, | |
1157 | }, | |
1158 | { | |
1159 | tag: "datauri", | |
1160 | translation: "{0} باید یک Data URI معتبر باشد", | |
1161 | override: false, | |
1162 | }, | |
1163 | { | |
1164 | tag: "latitude", | |
1165 | translation: "{0} باید یک عرض جغرافیایی معتبر باشد", | |
1166 | override: false, | |
1167 | }, | |
1168 | { | |
1169 | tag: "longitude", | |
1170 | translation: "{0} باید یک طول جغرافیایی معتبر باشد", | |
1171 | override: false, | |
1172 | }, | |
1173 | { | |
1174 | tag: "ssn", | |
1175 | translation: "{0} باید یک شماره SSN معتبر باشد", | |
1176 | override: false, | |
1177 | }, | |
1178 | { | |
1179 | tag: "ipv4", | |
1180 | translation: "{0} باید یک آدرس آیپی IPv4 معتبر باشد", | |
1181 | override: false, | |
1182 | }, | |
1183 | { | |
1184 | tag: "ipv6", | |
1185 | translation: "{0} باید یک آدرس آیپی IPv6 معتبر باشد", | |
1186 | override: false, | |
1187 | }, | |
1188 | { | |
1189 | tag: "ip", | |
1190 | translation: "{0} باید یک آدرس آیپی معتبر باشد", | |
1191 | override: false, | |
1192 | }, | |
1193 | { | |
1194 | tag: "cidr", | |
1195 | translation: "{0} باید یک نشانهگذاری CIDR معتبر باشد", | |
1196 | override: false, | |
1197 | }, | |
1198 | { | |
1199 | tag: "cidrv4", | |
1200 | translation: "{0} باید یک نشانهگذاری CIDR معتبر برای آدرس آیپی IPv4 باشد", | |
1201 | override: false, | |
1202 | }, | |
1203 | { | |
1204 | tag: "cidrv6", | |
1205 | translation: "{0} باید یک نشانهگذاری CIDR معتبر برای آدرس آیپی IPv6 باشد", | |
1206 | override: false, | |
1207 | }, | |
1208 | { | |
1209 | tag: "tcp_addr", | |
1210 | translation: "{0} باید یک آدرس TCP معتبر باشد", | |
1211 | override: false, | |
1212 | }, | |
1213 | { | |
1214 | tag: "tcp4_addr", | |
1215 | translation: "{0} باید یک آدرس TCP IPv4 معتبر باشد", | |
1216 | override: false, | |
1217 | }, | |
1218 | { | |
1219 | tag: "tcp6_addr", | |
1220 | translation: "{0} باید یک آدرس TCP IPv6 معتبر باشد", | |
1221 | override: false, | |
1222 | }, | |
1223 | { | |
1224 | tag: "udp_addr", | |
1225 | translation: "{0} باید یک آدرس UDP معتبر باشد", | |
1226 | override: false, | |
1227 | }, | |
1228 | { | |
1229 | tag: "udp4_addr", | |
1230 | translation: "{0} باید یک آدرس UDP IPv4 معتبر باشد", | |
1231 | override: false, | |
1232 | }, | |
1233 | { | |
1234 | tag: "udp6_addr", | |
1235 | translation: "{0} باید یک آدرس UDP IPv6 معتبر باشد", | |
1236 | override: false, | |
1237 | }, | |
1238 | { | |
1239 | tag: "ip_addr", | |
1240 | translation: "{0} باید یک آدرس آیپی قابل دسترس باشد", | |
1241 | override: false, | |
1242 | }, | |
1243 | { | |
1244 | tag: "ip4_addr", | |
1245 | translation: "{0} باید یک آدرس آیپی IPv4 قابل دسترس باشد", | |
1246 | override: false, | |
1247 | }, | |
1248 | { | |
1249 | tag: "ip6_addr", | |
1250 | translation: "{0} باید یک آدرس آیپی IPv6 قابل دسترس باشد", | |
1251 | override: false, | |
1252 | }, | |
1253 | { | |
1254 | tag: "unix_addr", | |
1255 | translation: "{0} باید یک آدرس UNIX معتبر باشد", | |
1256 | override: false, | |
1257 | }, | |
1258 | { | |
1259 | tag: "mac", | |
1260 | translation: "{0} باید یک مکآدرس معتبر باشد", | |
1261 | override: false, | |
1262 | }, | |
1263 | { | |
1264 | tag: "unique", | |
1265 | translation: "{0} باید شامل مقادیر منحصربفرد باشد", | |
1266 | override: false, | |
1267 | }, | |
1268 | { | |
1269 | tag: "iscolor", | |
1270 | translation: "{0} باید یک رنگ معتبر باشد", | |
1271 | override: false, | |
1272 | }, | |
1273 | { | |
1274 | tag: "oneof", | |
1275 | translation: "{0} باید یکی از مقادیر [{1}] باشد", | |
1276 | override: false, | |
1277 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
1278 | s, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
1279 | if err != nil { | |
1280 | log.Printf("warning: error translating FieldError: %#v", fe) | |
1281 | return fe.(error).Error() | |
1282 | } | |
1283 | return s | |
1284 | }, | |
1285 | }, | |
1286 | { | |
1287 | tag: "json", | |
1288 | translation: "{0} باید یک json معتبر باشد", | |
1289 | override: false, | |
1290 | }, | |
1291 | { | |
1292 | tag: "lowercase", | |
1293 | translation: "{0} باید یک متن با حروف کوچک باشد", | |
1294 | override: false, | |
1295 | }, | |
1296 | { | |
1297 | tag: "uppercase", | |
1298 | translation: "{0} باید یک متن با حروف بزرگ باشد", | |
1299 | override: false, | |
1300 | }, | |
1301 | { | |
1302 | tag: "datetime", | |
1303 | translation: "فرمت {0} با {1} سازگار نیست", | |
1304 | override: false, | |
1305 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
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} یک کدپستی معتبر کشور {1} نیست", | |
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} یک کدپستی معتبر کشور فیلد {1} نیست", | |
1332 | override: false, | |
1333 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
1334 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
1335 | if err != nil { | |
1336 | log.Printf("warning: error translating FieldError: %#v", fe) | |
1337 | return fe.(error).Error() | |
1338 | } | |
1339 | ||
1340 | return t | |
1341 | }, | |
1342 | }, | |
1343 | } | |
1344 | ||
1345 | for _, t := range translations { | |
1346 | ||
1347 | if t.customTransFunc != nil && t.customRegisFunc != nil { | |
1348 | err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, t.customTransFunc) | |
1349 | } else if t.customTransFunc != nil && t.customRegisFunc == nil { | |
1350 | err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), t.customTransFunc) | |
1351 | } else if t.customTransFunc == nil && t.customRegisFunc != nil { | |
1352 | err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, translateFunc) | |
1353 | } else { | |
1354 | err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), translateFunc) | |
1355 | } | |
1356 | ||
1357 | if err != nil { | |
1358 | return | |
1359 | } | |
1360 | } | |
1361 | ||
1362 | return | |
1363 | } | |
1364 | ||
1365 | func registrationFunc(tag string, translation string, override bool) validator.RegisterTranslationsFunc { | |
1366 | return func(ut ut.Translator) (err error) { | |
1367 | if err = ut.Add(tag, translation, override); err != nil { | |
1368 | return | |
1369 | } | |
1370 | ||
1371 | return | |
1372 | } | |
1373 | } | |
1374 | ||
1375 | func translateFunc(ut ut.Translator, fe validator.FieldError) string { | |
1376 | t, err := ut.T(fe.Tag(), fe.Field()) | |
1377 | if err != nil { | |
1378 | log.Printf("warning: error translating FieldError: %#v", fe) | |
1379 | return fe.(error).Error() | |
1380 | } | |
1381 | ||
1382 | return t | |
1383 | } |
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 | ULID string `validate:"ulid"` | |
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 | UniqueSlice []string `validate:"unique"` | |
141 | UniqueArray [3]string `validate:"unique"` | |
142 | UniqueMap map[string]string `validate:"unique"` | |
143 | JSONString string `validate:"json"` | |
144 | LowercaseString string `validate:"lowercase"` | |
145 | UppercaseString string `validate:"uppercase"` | |
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"` | |
150 | } | |
151 | ||
152 | var test Test | |
153 | ||
154 | test.Inner.EqCSFieldString = "1234" | |
155 | test.Inner.GtCSFieldString = "1234" | |
156 | test.Inner.GteCSFieldString = "1234" | |
157 | ||
158 | test.MaxString = "1234" | |
159 | test.MaxNumber = 2000 | |
160 | test.MaxMultiple = make([]string, 9) | |
161 | ||
162 | test.LtString = "1234" | |
163 | test.LtNumber = 6 | |
164 | test.LtMultiple = make([]string, 3) | |
165 | test.LtTime = time.Now().Add(time.Hour * 24) | |
166 | ||
167 | test.LteString = "1234" | |
168 | test.LteNumber = 6 | |
169 | test.LteMultiple = make([]string, 3) | |
170 | test.LteTime = time.Now().Add(time.Hour * 24) | |
171 | ||
172 | test.LtFieldString = "12345" | |
173 | test.LteFieldString = "12345" | |
174 | ||
175 | test.LtCSFieldString = "1234" | |
176 | test.LteCSFieldString = "1234" | |
177 | ||
178 | test.AlphaString = "abc3" | |
179 | test.AlphanumString = "abc3!" | |
180 | test.NumericString = "12E.00" | |
181 | test.NumberString = "12E" | |
182 | ||
183 | test.Excludes = "this is some test text" | |
184 | test.ExcludesAll = "This is Great!" | |
185 | test.ExcludesRune = "Love it ☻" | |
186 | ||
187 | test.ASCII = "カタカナ" | |
188 | test.PrintableASCII = "カタカナ" | |
189 | ||
190 | test.MultiByte = "1234feerf" | |
191 | ||
192 | test.LowercaseString = "ABCDEFG" | |
193 | test.UppercaseString = "abcdefg" | |
194 | ||
195 | s := "toolong" | |
196 | test.StrPtrMaxLen = &s | |
197 | test.StrPtrLen = &s | |
198 | ||
199 | test.UniqueSlice = []string{"1234", "1234"} | |
200 | test.UniqueMap = map[string]string{"key1": "1234", "key2": "1234"} | |
201 | test.Datetime = "2008-Feb-01" | |
202 | ||
203 | err = validate.Struct(test) | |
204 | NotEqual(t, err, nil) | |
205 | ||
206 | errs, ok := err.(validator.ValidationErrors) | |
207 | Equal(t, ok, true) | |
208 | ||
209 | tests := []struct { | |
210 | ns string | |
211 | expected string | |
212 | }{ | |
213 | { | |
214 | ns: "Test.IsColor", | |
215 | expected: "IsColor باید یک رنگ معتبر باشد", | |
216 | }, | |
217 | { | |
218 | ns: "Test.MAC", | |
219 | expected: "MAC باید یک مکآدرس معتبر باشد", | |
220 | }, | |
221 | { | |
222 | ns: "Test.IPAddr", | |
223 | expected: "IPAddr باید یک آدرس آیپی قابل دسترس باشد", | |
224 | }, | |
225 | { | |
226 | ns: "Test.IPAddrv4", | |
227 | expected: "IPAddrv4 باید یک آدرس آیپی IPv4 قابل دسترس باشد", | |
228 | }, | |
229 | { | |
230 | ns: "Test.IPAddrv6", | |
231 | expected: "IPAddrv6 باید یک آدرس آیپی IPv6 قابل دسترس باشد", | |
232 | }, | |
233 | { | |
234 | ns: "Test.UDPAddr", | |
235 | expected: "UDPAddr باید یک آدرس UDP معتبر باشد", | |
236 | }, | |
237 | { | |
238 | ns: "Test.UDPAddrv4", | |
239 | expected: "UDPAddrv4 باید یک آدرس UDP IPv4 معتبر باشد", | |
240 | }, | |
241 | { | |
242 | ns: "Test.UDPAddrv6", | |
243 | expected: "UDPAddrv6 باید یک آدرس UDP IPv6 معتبر باشد", | |
244 | }, | |
245 | { | |
246 | ns: "Test.TCPAddr", | |
247 | expected: "TCPAddr باید یک آدرس TCP معتبر باشد", | |
248 | }, | |
249 | { | |
250 | ns: "Test.TCPAddrv4", | |
251 | expected: "TCPAddrv4 باید یک آدرس TCP IPv4 معتبر باشد", | |
252 | }, | |
253 | { | |
254 | ns: "Test.TCPAddrv6", | |
255 | expected: "TCPAddrv6 باید یک آدرس TCP IPv6 معتبر باشد", | |
256 | }, | |
257 | { | |
258 | ns: "Test.CIDR", | |
259 | expected: "CIDR باید یک نشانهگذاری CIDR معتبر باشد", | |
260 | }, | |
261 | { | |
262 | ns: "Test.CIDRv4", | |
263 | expected: "CIDRv4 باید یک نشانهگذاری CIDR معتبر برای آدرس آیپی IPv4 باشد", | |
264 | }, | |
265 | { | |
266 | ns: "Test.CIDRv6", | |
267 | expected: "CIDRv6 باید یک نشانهگذاری CIDR معتبر برای آدرس آیپی IPv6 باشد", | |
268 | }, | |
269 | { | |
270 | ns: "Test.SSN", | |
271 | expected: "SSN باید یک شماره SSN معتبر باشد", | |
272 | }, | |
273 | { | |
274 | ns: "Test.IP", | |
275 | expected: "IP باید یک آدرس آیپی معتبر باشد", | |
276 | }, | |
277 | { | |
278 | ns: "Test.IPv4", | |
279 | expected: "IPv4 باید یک آدرس آیپی IPv4 معتبر باشد", | |
280 | }, | |
281 | { | |
282 | ns: "Test.IPv6", | |
283 | expected: "IPv6 باید یک آدرس آیپی IPv6 معتبر باشد", | |
284 | }, | |
285 | { | |
286 | ns: "Test.DataURI", | |
287 | expected: "DataURI باید یک Data URI معتبر باشد", | |
288 | }, | |
289 | { | |
290 | ns: "Test.Latitude", | |
291 | expected: "Latitude باید یک عرض جغرافیایی معتبر باشد", | |
292 | }, | |
293 | { | |
294 | ns: "Test.Longitude", | |
295 | expected: "Longitude باید یک طول جغرافیایی معتبر باشد", | |
296 | }, | |
297 | { | |
298 | ns: "Test.MultiByte", | |
299 | expected: "MultiByte باید شامل کاراکترهای چندبایته باشد", | |
300 | }, | |
301 | { | |
302 | ns: "Test.ASCII", | |
303 | expected: "ASCII باید فقط شامل کاراکترهای اسکی باشد", | |
304 | }, | |
305 | { | |
306 | ns: "Test.PrintableASCII", | |
307 | expected: "PrintableASCII باید فقط شامل کاراکترهای اسکی قابل چاپ باشد", | |
308 | }, | |
309 | { | |
310 | ns: "Test.UUID", | |
311 | expected: "UUID باید یک UUID معتبر باشد", | |
312 | }, | |
313 | { | |
314 | ns: "Test.UUID3", | |
315 | expected: "UUID3 باید یک UUID نسخه 3 معتبر باشد", | |
316 | }, | |
317 | { | |
318 | ns: "Test.UUID4", | |
319 | expected: "UUID4 باید یک UUID نسخه 4 معتبر باشد", | |
320 | }, | |
321 | { | |
322 | ns: "Test.UUID5", | |
323 | expected: "UUID5 باید یک UUID نسخه 5 معتبر باشد", | |
324 | }, | |
325 | { | |
326 | ns: "Test.ULID", | |
327 | expected: "ULID باید یک ULID معتبر باشد", | |
328 | }, | |
329 | { | |
330 | ns: "Test.ISBN", | |
331 | expected: "ISBN باید یک شابک معتبر باشد", | |
332 | }, | |
333 | { | |
334 | ns: "Test.ISBN10", | |
335 | expected: "ISBN10 باید یک شابک(ISBN-10) معتبر باشد", | |
336 | }, | |
337 | { | |
338 | ns: "Test.ISBN13", | |
339 | expected: "ISBN13 باید یک شابک(ISBN-13) معتبر باشد", | |
340 | }, | |
341 | { | |
342 | ns: "Test.Excludes", | |
343 | expected: "Excludes نمیتواند شامل 'text' باشد", | |
344 | }, | |
345 | { | |
346 | ns: "Test.ExcludesAll", | |
347 | expected: "ExcludesAll نمیتواند شامل کاراکترهای '!@#$' باشد", | |
348 | }, | |
349 | { | |
350 | ns: "Test.ExcludesRune", | |
351 | expected: "ExcludesRune نمیتواند شامل '☻' باشد", | |
352 | }, | |
353 | { | |
354 | ns: "Test.ContainsAny", | |
355 | expected: "ContainsAny باید شامل کاراکترهای '!@#$' باشد", | |
356 | }, | |
357 | { | |
358 | ns: "Test.Contains", | |
359 | expected: "Contains باید شامل 'purpose' باشد", | |
360 | }, | |
361 | { | |
362 | ns: "Test.Base64", | |
363 | expected: "Base64 باید یک متن درمبنای64 معتبر باشد", | |
364 | }, | |
365 | { | |
366 | ns: "Test.Email", | |
367 | expected: "Email باید یک ایمیل معتبر باشد", | |
368 | }, | |
369 | { | |
370 | ns: "Test.URL", | |
371 | expected: "URL باید یک آدرس اینترنتی معتبر باشد", | |
372 | }, | |
373 | { | |
374 | ns: "Test.URI", | |
375 | expected: "URI باید یک URI معتبر باشد", | |
376 | }, | |
377 | { | |
378 | ns: "Test.RGBColorString", | |
379 | expected: "RGBColorString باید یک کد رنگ RGB باشد", | |
380 | }, | |
381 | { | |
382 | ns: "Test.RGBAColorString", | |
383 | expected: "RGBAColorString باید یک کد رنگ RGBA باشد", | |
384 | }, | |
385 | { | |
386 | ns: "Test.HSLColorString", | |
387 | expected: "HSLColorString باید یک کد رنگ HSL باشد", | |
388 | }, | |
389 | { | |
390 | ns: "Test.HSLAColorString", | |
391 | expected: "HSLAColorString باید یک کد رنگ HSLA باشد", | |
392 | }, | |
393 | { | |
394 | ns: "Test.HexadecimalString", | |
395 | expected: "HexadecimalString باید یک عدد درمبنای16 باشد", | |
396 | }, | |
397 | { | |
398 | ns: "Test.HexColorString", | |
399 | expected: "HexColorString باید یک کد رنگ HEX باشد", | |
400 | }, | |
401 | { | |
402 | ns: "Test.NumberString", | |
403 | expected: "NumberString باید یک عدد معتبر باشد", | |
404 | }, | |
405 | { | |
406 | ns: "Test.NumericString", | |
407 | expected: "NumericString باید یک عدد معتبر باشد", | |
408 | }, | |
409 | { | |
410 | ns: "Test.AlphanumString", | |
411 | expected: "AlphanumString میتواند فقط شامل حروف و اعداد باشد", | |
412 | }, | |
413 | { | |
414 | ns: "Test.AlphaString", | |
415 | expected: "AlphaString میتواند فقط شامل حروف باشد", | |
416 | }, | |
417 | { | |
418 | ns: "Test.LtFieldString", | |
419 | expected: "طول LtFieldString باید کمتر از MaxString باشد", | |
420 | }, | |
421 | { | |
422 | ns: "Test.LteFieldString", | |
423 | expected: "طول LteFieldString باید کمتر یا برابر MaxString باشد", | |
424 | }, | |
425 | { | |
426 | ns: "Test.GtFieldString", | |
427 | expected: "طول GtFieldString باید بیشتر از MaxString باشد", | |
428 | }, | |
429 | { | |
430 | ns: "Test.GteFieldString", | |
431 | expected: "طول GteFieldString باید بیشتر یا برابر MaxString باشد", | |
432 | }, | |
433 | { | |
434 | ns: "Test.NeFieldString", | |
435 | expected: "NeFieldString نمیتواند برابر EqFieldString باشد", | |
436 | }, | |
437 | { | |
438 | ns: "Test.LtCSFieldString", | |
439 | expected: "طول LtCSFieldString باید کمتر از Inner.LtCSFieldString باشد", | |
440 | }, | |
441 | { | |
442 | ns: "Test.LteCSFieldString", | |
443 | expected: "طول LteCSFieldString باید کمتر یا برابر Inner.LteCSFieldString باشد", | |
444 | }, | |
445 | { | |
446 | ns: "Test.GtCSFieldString", | |
447 | expected: "طول GtCSFieldString باید بیشتر از Inner.GtCSFieldString باشد", | |
448 | }, | |
449 | { | |
450 | ns: "Test.GteCSFieldString", | |
451 | expected: "طول GteCSFieldString باید بیشتر یا برابر Inner.GteCSFieldString باشد", | |
452 | }, | |
453 | { | |
454 | ns: "Test.NeCSFieldString", | |
455 | expected: "NeCSFieldString نمیتواند برابر Inner.NeCSFieldString باشد", | |
456 | }, | |
457 | { | |
458 | ns: "Test.EqCSFieldString", | |
459 | expected: "EqCSFieldString باید برابر Inner.EqCSFieldString باشد", | |
460 | }, | |
461 | { | |
462 | ns: "Test.EqFieldString", | |
463 | expected: "EqFieldString باید برابر MaxString باشد", | |
464 | }, | |
465 | { | |
466 | ns: "Test.GteString", | |
467 | expected: "طول GteString باید حداقل 3 کاراکتر باشد", | |
468 | }, | |
469 | { | |
470 | ns: "Test.GteNumber", | |
471 | expected: "GteNumber باید بیشتر یا برابر 5.56 باشد", | |
472 | }, | |
473 | { | |
474 | ns: "Test.GteMultiple", | |
475 | expected: "GteMultiple باید شامل حداقل 2 آیتم باشد", | |
476 | }, | |
477 | { | |
478 | ns: "Test.GteTime", | |
479 | expected: "GteTime باید بعد یا برابر تاریخ و زمان کنونی باشد", | |
480 | }, | |
481 | { | |
482 | ns: "Test.GtString", | |
483 | expected: "طول GtString باید بیشتر از 3 کاراکتر باشد", | |
484 | }, | |
485 | { | |
486 | ns: "Test.GtNumber", | |
487 | expected: "GtNumber باید بیشتر از 5.56 باشد", | |
488 | }, | |
489 | { | |
490 | ns: "Test.GtMultiple", | |
491 | expected: "GtMultiple باید دارای بیشتر از 2 آیتم باشد", | |
492 | }, | |
493 | { | |
494 | ns: "Test.GtTime", | |
495 | expected: "GtTime باید بعد از تاریخ و زمان کنونی باشد", | |
496 | }, | |
497 | { | |
498 | ns: "Test.LteString", | |
499 | expected: "طول LteString باید حداکثر 3 کاراکتر باشد", | |
500 | }, | |
501 | { | |
502 | ns: "Test.LteNumber", | |
503 | expected: "LteNumber باید کمتر یا برابر 5.56 باشد", | |
504 | }, | |
505 | { | |
506 | ns: "Test.LteMultiple", | |
507 | expected: "LteMultiple باید حداکثر شامل 2 آیتم باشد", | |
508 | }, | |
509 | { | |
510 | ns: "Test.LteTime", | |
511 | expected: "LteTime باید قبل یا برابر تاریخ و زمان کنونی باشد", | |
512 | }, | |
513 | { | |
514 | ns: "Test.LtString", | |
515 | expected: "طول LtString باید کمتر از 3 کاراکتر باشد", | |
516 | }, | |
517 | { | |
518 | ns: "Test.LtNumber", | |
519 | expected: "LtNumber باید کمتر از 5.56 باشد", | |
520 | }, | |
521 | { | |
522 | ns: "Test.LtMultiple", | |
523 | expected: "LtMultiple باید دارای کمتر از 2 آیتم باشد", | |
524 | }, | |
525 | { | |
526 | ns: "Test.LtTime", | |
527 | expected: "LtTime باید قبل از تاریخ و زمان کنونی باشد", | |
528 | }, | |
529 | { | |
530 | ns: "Test.NeString", | |
531 | expected: "NeString نباید برابر باشد", | |
532 | }, | |
533 | { | |
534 | ns: "Test.NeNumber", | |
535 | expected: "NeNumber نباید برابر 0.00 باشد", | |
536 | }, | |
537 | { | |
538 | ns: "Test.NeMultiple", | |
539 | expected: "NeMultiple نباید برابر 0 باشد", | |
540 | }, | |
541 | { | |
542 | ns: "Test.EqString", | |
543 | expected: "EqString برابر 3 نمیباشد", | |
544 | }, | |
545 | { | |
546 | ns: "Test.EqNumber", | |
547 | expected: "EqNumber برابر 2.33 نمیباشد", | |
548 | }, | |
549 | { | |
550 | ns: "Test.EqMultiple", | |
551 | expected: "EqMultiple برابر 7 نمیباشد", | |
552 | }, | |
553 | { | |
554 | ns: "Test.MaxString", | |
555 | expected: "طول MaxString باید حداکثر 3 کاراکتر باشد", | |
556 | }, | |
557 | { | |
558 | ns: "Test.MaxNumber", | |
559 | expected: "MaxNumber باید کمتر یا برابر 1,113.00 باشد", | |
560 | }, | |
561 | { | |
562 | ns: "Test.MaxMultiple", | |
563 | expected: "MaxMultiple باید شامل حداکثر 7 آیتم باشد", | |
564 | }, | |
565 | { | |
566 | ns: "Test.MinString", | |
567 | expected: "طول MinString باید حداقل 1 کاراکتر باشد", | |
568 | }, | |
569 | { | |
570 | ns: "Test.MinNumber", | |
571 | expected: "MinNumber باید بزرگتر یا برابر 1,113.00 باشد", | |
572 | }, | |
573 | { | |
574 | ns: "Test.MinMultiple", | |
575 | expected: "MinMultiple باید شامل حداقل 7 آیتم باشد", | |
576 | }, | |
577 | { | |
578 | ns: "Test.LenString", | |
579 | expected: "طول LenString باید 1 کاراکتر باشد", | |
580 | }, | |
581 | { | |
582 | ns: "Test.LenNumber", | |
583 | expected: "طول LenNumber باید برابر 1,113.00 باشد", | |
584 | }, | |
585 | { | |
586 | ns: "Test.LenMultiple", | |
587 | expected: "تعداد LenMultiple باید برابر 7 آیتم باشد", | |
588 | }, | |
589 | { | |
590 | ns: "Test.RequiredString", | |
591 | expected: "فیلد RequiredString اجباری میباشد", | |
592 | }, | |
593 | { | |
594 | ns: "Test.RequiredNumber", | |
595 | expected: "فیلد RequiredNumber اجباری میباشد", | |
596 | }, | |
597 | { | |
598 | ns: "Test.RequiredMultiple", | |
599 | expected: "فیلد RequiredMultiple اجباری میباشد", | |
600 | }, | |
601 | { | |
602 | ns: "Test.StrPtrMinLen", | |
603 | expected: "طول StrPtrMinLen باید حداقل 10 کاراکتر باشد", | |
604 | }, | |
605 | { | |
606 | ns: "Test.StrPtrMaxLen", | |
607 | expected: "طول StrPtrMaxLen باید حداکثر 1 کاراکتر باشد", | |
608 | }, | |
609 | { | |
610 | ns: "Test.StrPtrLen", | |
611 | expected: "طول StrPtrLen باید 2 کاراکتر باشد", | |
612 | }, | |
613 | { | |
614 | ns: "Test.StrPtrLt", | |
615 | expected: "طول StrPtrLt باید کمتر از 1 کاراکتر باشد", | |
616 | }, | |
617 | { | |
618 | ns: "Test.StrPtrLte", | |
619 | expected: "طول StrPtrLte باید حداکثر 1 کاراکتر باشد", | |
620 | }, | |
621 | { | |
622 | ns: "Test.StrPtrGt", | |
623 | expected: "طول StrPtrGt باید بیشتر از 10 کاراکتر باشد", | |
624 | }, | |
625 | { | |
626 | ns: "Test.StrPtrGte", | |
627 | expected: "طول StrPtrGte باید حداقل 10 کاراکتر باشد", | |
628 | }, | |
629 | { | |
630 | ns: "Test.OneOfString", | |
631 | expected: "OneOfString باید یکی از مقادیر [red green] باشد", | |
632 | }, | |
633 | { | |
634 | ns: "Test.OneOfInt", | |
635 | expected: "OneOfInt باید یکی از مقادیر [5 63] باشد", | |
636 | }, | |
637 | { | |
638 | ns: "Test.UniqueSlice", | |
639 | expected: "UniqueSlice باید شامل مقادیر منحصربفرد باشد", | |
640 | }, | |
641 | { | |
642 | ns: "Test.UniqueArray", | |
643 | expected: "UniqueArray باید شامل مقادیر منحصربفرد باشد", | |
644 | }, | |
645 | { | |
646 | ns: "Test.UniqueMap", | |
647 | expected: "UniqueMap باید شامل مقادیر منحصربفرد باشد", | |
648 | }, | |
649 | { | |
650 | ns: "Test.JSONString", | |
651 | expected: "JSONString باید یک json معتبر باشد", | |
652 | }, | |
653 | { | |
654 | ns: "Test.LowercaseString", | |
655 | expected: "LowercaseString باید یک متن با حروف کوچک باشد", | |
656 | }, | |
657 | { | |
658 | ns: "Test.UppercaseString", | |
659 | expected: "UppercaseString باید یک متن با حروف بزرگ باشد", | |
660 | }, | |
661 | { | |
662 | ns: "Test.Datetime", | |
663 | expected: "فرمت Datetime با 2006-01-02 سازگار نیست", | |
664 | }, | |
665 | { | |
666 | ns: "Test.PostCode", | |
667 | expected: "PostCode یک کدپستی معتبر کشور SG نیست", | |
668 | }, | |
669 | { | |
670 | ns: "Test.PostCodeByField", | |
671 | expected: "PostCodeByField یک کدپستی معتبر کشور فیلد PostCodeCountry نیست", | |
672 | }, | |
673 | } | |
674 | ||
675 | for _, tt := range tests { | |
676 | ||
677 | var fe validator.FieldError | |
678 | ||
679 | for _, e := range errs { | |
680 | if tt.ns == e.Namespace() { | |
681 | fe = e | |
682 | break | |
683 | } | |
684 | } | |
685 | ||
686 | NotEqual(t, fe, nil) | |
687 | Equal(t, tt.expected, fe.Translate(trans)) | |
688 | } | |
689 | } |
1173 | 1173 | override: false, |
1174 | 1174 | }, |
1175 | 1175 | { |
1176 | tag: "ulid", | |
1177 | translation: "{0} doit être une ULID valide", | |
1178 | override: false, | |
1179 | }, | |
1180 | { | |
1176 | 1181 | tag: "ascii", |
1177 | 1182 | translation: "{0} ne doit contenir que des caractères ascii", |
1178 | 1183 | override: false, |
3 | 3 | "testing" |
4 | 4 | "time" |
5 | 5 | |
6 | . "github.com/go-playground/assert/v2" | |
6 | 7 | french "github.com/go-playground/locales/fr" |
7 | 8 | ut "github.com/go-playground/universal-translator" |
8 | . "github.com/go-playground/assert/v2" | |
9 | 9 | "github.com/go-playground/validator/v10" |
10 | 10 | ) |
11 | 11 | |
103 | 103 | UUID3 string `validate:"uuid3"` |
104 | 104 | UUID4 string `validate:"uuid4"` |
105 | 105 | UUID5 string `validate:"uuid5"` |
106 | ULID string `validate:"ulid"` | |
106 | 107 | ASCII string `validate:"ascii"` |
107 | 108 | PrintableASCII string `validate:"printascii"` |
108 | 109 | MultiByte string `validate:"multibyte"` |
306 | 307 | expected: "UUID5 doit être un UUID version 5 valid", |
307 | 308 | }, |
308 | 309 | { |
310 | ns: "Test.ULID", | |
311 | expected: "ULID doit être une ULID valide", | |
312 | }, | |
313 | { | |
309 | 314 | ns: "Test.ISBN", |
310 | 315 | expected: "ISBN doit être un numéro ISBN valid", |
311 | 316 | }, |
535 | 540 | }, |
536 | 541 | { |
537 | 542 | ns: "Test.MaxNumber", |
538 | expected: "MaxNumber doit être égal à 1 113,00 ou moins", | |
543 | expected: "MaxNumber doit être égal à 1 113,00 ou moins", | |
539 | 544 | }, |
540 | 545 | { |
541 | 546 | ns: "Test.MaxMultiple", |
547 | 552 | }, |
548 | 553 | { |
549 | 554 | ns: "Test.MinNumber", |
550 | expected: "MinNumber doit être égal à 1 113,00 ou plus", | |
555 | expected: "MinNumber doit être égal à 1 113,00 ou plus", | |
551 | 556 | }, |
552 | 557 | { |
553 | 558 | ns: "Test.MinMultiple", |
559 | 564 | }, |
560 | 565 | { |
561 | 566 | ns: "Test.LenNumber", |
562 | expected: "LenNumber doit être égal à 1 113,00", | |
567 | expected: "LenNumber doit être égal à 1 113,00", | |
563 | 568 | }, |
564 | 569 | { |
565 | 570 | ns: "Test.LenMultiple", |
1173 | 1173 | override: false, |
1174 | 1174 | }, |
1175 | 1175 | { |
1176 | tag: "ulid", | |
1177 | translation: "{0} harus berupa ULID yang valid", | |
1178 | override: false, | |
1179 | }, | |
1180 | { | |
1176 | 1181 | tag: "ascii", |
1177 | 1182 | translation: "{0} hanya boleh berisi karakter ascii", |
1178 | 1183 | override: false, |
3 | 3 | "testing" |
4 | 4 | "time" |
5 | 5 | |
6 | . "github.com/go-playground/assert/v2" | |
6 | 7 | indonesia "github.com/go-playground/locales/id" |
7 | 8 | ut "github.com/go-playground/universal-translator" |
8 | . "github.com/go-playground/assert/v2" | |
9 | 9 | "github.com/go-playground/validator/v10" |
10 | 10 | ) |
11 | 11 | |
103 | 103 | UUID3 string `validate:"uuid3"` |
104 | 104 | UUID4 string `validate:"uuid4"` |
105 | 105 | UUID5 string `validate:"uuid5"` |
106 | ULID string `validate:"ulid"` | |
106 | 107 | ASCII string `validate:"ascii"` |
107 | 108 | PrintableASCII string `validate:"printascii"` |
108 | 109 | MultiByte string `validate:"multibyte"` |
306 | 307 | expected: "UUID5 harus berupa UUID versi 5 yang valid", |
307 | 308 | }, |
308 | 309 | { |
310 | ns: "Test.ULID", | |
311 | expected: "ULID harus berupa ULID yang valid", | |
312 | }, | |
313 | { | |
309 | 314 | ns: "Test.ISBN", |
310 | 315 | expected: "ISBN harus berupa nomor ISBN yang valid", |
311 | 316 | }, |
1225 | 1225 | }, |
1226 | 1226 | { |
1227 | 1227 | tag: "uuid5", |
1228 | translation: "{0}はバージョンが4の正しいUUIDでなければなりません", | |
1228 | translation: "{0}はバージョンが5の正しいUUIDでなければなりません", | |
1229 | override: false, | |
1230 | }, | |
1231 | { | |
1232 | tag: "ulid", | |
1233 | translation: "{0}は正しいULIDでなければなりません", | |
1229 | 1234 | override: false, |
1230 | 1235 | }, |
1231 | 1236 | { |
3 | 3 | "testing" |
4 | 4 | "time" |
5 | 5 | |
6 | . "github.com/go-playground/assert/v2" | |
6 | 7 | ja_locale "github.com/go-playground/locales/ja" |
7 | 8 | ut "github.com/go-playground/universal-translator" |
8 | . "github.com/go-playground/assert/v2" | |
9 | 9 | "github.com/go-playground/validator/v10" |
10 | 10 | ) |
11 | 11 | |
103 | 103 | UUID3 string `validate:"uuid3"` |
104 | 104 | UUID4 string `validate:"uuid4"` |
105 | 105 | UUID5 string `validate:"uuid5"` |
106 | ULID string `validate:"ulid"` | |
106 | 107 | ASCII string `validate:"ascii"` |
107 | 108 | PrintableASCII string `validate:"printascii"` |
108 | 109 | MultiByte string `validate:"multibyte"` |
303 | 304 | }, |
304 | 305 | { |
305 | 306 | ns: "Test.UUID5", |
306 | expected: "UUID5はバージョンが4の正しいUUIDでなければなりません", | |
307 | expected: "UUID5はバージョンが5の正しいUUIDでなければなりません", | |
308 | }, | |
309 | { | |
310 | ns: "Test.ULID", | |
311 | expected: "ULIDは正しいULIDでなければなりません", | |
307 | 312 | }, |
308 | 313 | { |
309 | 314 | ns: "Test.ISBN", |
1173 | 1173 | override: false, |
1174 | 1174 | }, |
1175 | 1175 | { |
1176 | tag: "ulid", | |
1177 | translation: "{0} moet een geldige ULID zijn", | |
1178 | override: false, | |
1179 | }, | |
1180 | { | |
1176 | 1181 | tag: "ascii", |
1177 | 1182 | translation: "{0} mag alleen ascii karakters bevatten", |
1178 | 1183 | override: false, |
3 | 3 | "testing" |
4 | 4 | "time" |
5 | 5 | |
6 | . "github.com/go-playground/assert/v2" | |
6 | 7 | english "github.com/go-playground/locales/en" |
7 | 8 | ut "github.com/go-playground/universal-translator" |
8 | . "github.com/go-playground/assert/v2" | |
9 | 9 | "github.com/go-playground/validator/v10" |
10 | 10 | ) |
11 | 11 | |
103 | 103 | UUID3 string `validate:"uuid3"` |
104 | 104 | UUID4 string `validate:"uuid4"` |
105 | 105 | UUID5 string `validate:"uuid5"` |
106 | ULID string `validate:"ulid"` | |
106 | 107 | ASCII string `validate:"ascii"` |
107 | 108 | PrintableASCII string `validate:"printascii"` |
108 | 109 | MultiByte string `validate:"multibyte"` |
306 | 307 | expected: "UUID5 moet een geldige versie 5 UUID zijn", |
307 | 308 | }, |
308 | 309 | { |
310 | ns: "Test.ULID", | |
311 | expected: "ULID moet een geldige ULID zijn", | |
312 | }, | |
313 | { | |
309 | 314 | ns: "Test.ISBN", |
310 | 315 | expected: "ISBN moet een geldig ISBN nummer zijn", |
311 | 316 | }, |
1178 | 1178 | override: false, |
1179 | 1179 | }, |
1180 | 1180 | { |
1181 | tag: "ulid", | |
1182 | translation: "{0} deve ser um ULID válido", | |
1183 | override: false, | |
1184 | }, | |
1185 | { | |
1181 | 1186 | tag: "ascii", |
1182 | 1187 | translation: "{0} deve conter apenas caracteres ascii", |
1183 | 1188 | override: false, |
104 | 104 | UUID3 string `validate:"uuid3"` |
105 | 105 | UUID4 string `validate:"uuid4"` |
106 | 106 | UUID5 string `validate:"uuid5"` |
107 | ULID string `validate:"ulid"` | |
107 | 108 | ASCII string `validate:"ascii"` |
108 | 109 | PrintableASCII string `validate:"printascii"` |
109 | 110 | MultiByte string `validate:"multibyte"` |
321 | 322 | expected: "UUID5 deve ser um UUID versão 5 válido", |
322 | 323 | }, |
323 | 324 | { |
325 | ns: "Test.ULID", | |
326 | expected: "ULID deve ser um ULID válido", | |
327 | }, | |
328 | { | |
324 | 329 | ns: "Test.ISBN", |
325 | 330 | expected: "ISBN deve ser um número de ISBN válido", |
326 | 331 | }, |
1173 | 1173 | override: false, |
1174 | 1174 | }, |
1175 | 1175 | { |
1176 | tag: "ulid", | |
1177 | translation: "{0} deve ser uma ULID válida", | |
1178 | override: false, | |
1179 | }, | |
1180 | { | |
1176 | 1181 | tag: "ascii", |
1177 | 1182 | translation: "{0} deve conter apenas caracteres ascii", |
1178 | 1183 | override: false, |
3 | 3 | "testing" |
4 | 4 | "time" |
5 | 5 | |
6 | . "github.com/go-playground/assert/v2" | |
6 | 7 | brazilian_portuguese "github.com/go-playground/locales/pt_BR" |
7 | 8 | ut "github.com/go-playground/universal-translator" |
8 | 9 | "github.com/go-playground/validator/v10" |
9 | . "github.com/go-playground/assert/v2" | |
10 | 10 | ) |
11 | 11 | |
12 | 12 | func TestTranslations(t *testing.T) { |
103 | 103 | UUID3 string `validate:"uuid3"` |
104 | 104 | UUID4 string `validate:"uuid4"` |
105 | 105 | UUID5 string `validate:"uuid5"` |
106 | ULID string `validate:"ulid"` | |
106 | 107 | ASCII string `validate:"ascii"` |
107 | 108 | PrintableASCII string `validate:"printascii"` |
108 | 109 | MultiByte string `validate:"multibyte"` |
306 | 307 | expected: "UUID5 deve ser um UUID versão 5 válido", |
307 | 308 | }, |
308 | 309 | { |
310 | ns: "Test.ULID", | |
311 | expected: "ULID deve ser uma ULID válida", | |
312 | }, | |
313 | { | |
309 | 314 | ns: "Test.ISBN", |
310 | 315 | expected: "ISBN deve ser um número ISBN válido", |
311 | 316 | }, |
40 | 40 | return |
41 | 41 | } |
42 | 42 | |
43 | if err = ut.AddCardinal("len-string-character", "{0} символа", locales.PluralRuleFew, false); err != nil { | |
44 | return | |
45 | } | |
46 | ||
47 | if err = ut.AddCardinal("len-string-character", "{0} символов", locales.PluralRuleMany, false); err != nil { | |
48 | return | |
49 | } | |
50 | ||
43 | 51 | if err = ut.AddCardinal("len-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil { |
44 | 52 | return |
45 | 53 | } |
51 | 59 | if err = ut.Add("len-items", "{0} должен содержать {1}", false); err != nil { |
52 | 60 | return |
53 | 61 | } |
62 | ||
54 | 63 | if err = ut.AddCardinal("len-items-item", "{0} элемент", locales.PluralRuleOne, false); err != nil { |
64 | return | |
65 | } | |
66 | ||
67 | if err = ut.AddCardinal("len-items-item", "{0} элемента", locales.PluralRuleFew, false); err != nil { | |
68 | return | |
69 | } | |
70 | ||
71 | if err = ut.AddCardinal("len-items-item", "{0} элементов", locales.PluralRuleMany, false); err != nil { | |
55 | 72 | return |
56 | 73 | } |
57 | 74 | |
131 | 148 | return |
132 | 149 | } |
133 | 150 | |
151 | if err = ut.AddCardinal("min-string-character", "{0} символа", locales.PluralRuleFew, false); err != nil { | |
152 | return | |
153 | } | |
154 | ||
155 | if err = ut.AddCardinal("min-string-character", "{0} символов", locales.PluralRuleMany, false); err != nil { | |
156 | return | |
157 | } | |
158 | ||
134 | 159 | if err = ut.AddCardinal("min-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil { |
135 | 160 | return |
136 | 161 | } |
143 | 168 | return |
144 | 169 | } |
145 | 170 | if err = ut.AddCardinal("min-items-item", "{0} элемент", locales.PluralRuleOne, false); err != nil { |
171 | return | |
172 | } | |
173 | ||
174 | if err = ut.AddCardinal("min-items-item", "{0} элемента", locales.PluralRuleFew, false); err != nil { | |
175 | return | |
176 | } | |
177 | ||
178 | if err = ut.AddCardinal("min-items-item", "{0} элементов", locales.PluralRuleMany, false); err != nil { | |
146 | 179 | return |
147 | 180 | } |
148 | 181 | |
222 | 255 | return |
223 | 256 | } |
224 | 257 | |
258 | if err = ut.AddCardinal("max-string-character", "{0} символа", locales.PluralRuleFew, false); err != nil { | |
259 | return | |
260 | } | |
261 | ||
262 | if err = ut.AddCardinal("max-string-character", "{0} символов", locales.PluralRuleMany, false); err != nil { | |
263 | return | |
264 | } | |
265 | ||
225 | 266 | if err = ut.AddCardinal("max-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil { |
226 | 267 | return |
227 | 268 | } |
234 | 275 | return |
235 | 276 | } |
236 | 277 | if err = ut.AddCardinal("max-items-item", "{0} элемент", locales.PluralRuleOne, false); err != nil { |
278 | return | |
279 | } | |
280 | ||
281 | if err = ut.AddCardinal("max-items-item", "{0} элемента", locales.PluralRuleFew, false); err != nil { | |
282 | return | |
283 | } | |
284 | ||
285 | if err = ut.AddCardinal("max-items-item", "{0} элементов", locales.PluralRuleMany, false); err != nil { | |
237 | 286 | return |
238 | 287 | } |
239 | 288 | |
343 | 392 | return |
344 | 393 | } |
345 | 394 | |
395 | if err = ut.AddCardinal("lt-string-character", "{0} символов", locales.PluralRuleFew, false); err != nil { | |
396 | return | |
397 | } | |
398 | ||
399 | if err = ut.AddCardinal("lt-string-character", "{0} символов", locales.PluralRuleMany, false); err != nil { | |
400 | return | |
401 | } | |
402 | ||
346 | 403 | if err = ut.AddCardinal("lt-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil { |
347 | 404 | return |
348 | 405 | } |
356 | 413 | } |
357 | 414 | |
358 | 415 | if err = ut.AddCardinal("lt-items-item", "{0} элемент", locales.PluralRuleOne, false); err != nil { |
416 | return | |
417 | } | |
418 | ||
419 | if err = ut.AddCardinal("lt-items-item", "{0} элементов", locales.PluralRuleFew, false); err != nil { | |
420 | return | |
421 | } | |
422 | ||
423 | if err = ut.AddCardinal("lt-items-item", "{0} элементов", locales.PluralRuleMany, false); err != nil { | |
359 | 424 | return |
360 | 425 | } |
361 | 426 | |
464 | 529 | return |
465 | 530 | } |
466 | 531 | |
532 | if err = ut.AddCardinal("lte-string-character", "{0} символа", locales.PluralRuleFew, false); err != nil { | |
533 | return | |
534 | } | |
535 | ||
536 | if err = ut.AddCardinal("lte-string-character", "{0} символов", locales.PluralRuleMany, false); err != nil { | |
537 | return | |
538 | } | |
539 | ||
467 | 540 | if err = ut.AddCardinal("lte-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil { |
468 | 541 | return |
469 | 542 | } |
477 | 550 | } |
478 | 551 | |
479 | 552 | if err = ut.AddCardinal("lte-items-item", "{0} элемент", locales.PluralRuleOne, false); err != nil { |
553 | return | |
554 | } | |
555 | ||
556 | if err = ut.AddCardinal("lte-items-item", "{0} элемента", locales.PluralRuleFew, false); err != nil { | |
557 | return | |
558 | } | |
559 | ||
560 | if err = ut.AddCardinal("lte-items-item", "{0} элементов", locales.PluralRuleMany, false); err != nil { | |
480 | 561 | return |
481 | 562 | } |
482 | 563 | |
584 | 665 | return |
585 | 666 | } |
586 | 667 | |
668 | if err = ut.AddCardinal("gt-string-character", "{0} символов", locales.PluralRuleFew, false); err != nil { | |
669 | return | |
670 | } | |
671 | ||
672 | if err = ut.AddCardinal("gt-string-character", "{0} символов", locales.PluralRuleMany, false); err != nil { | |
673 | return | |
674 | } | |
675 | ||
587 | 676 | if err = ut.AddCardinal("gt-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil { |
588 | 677 | return |
589 | 678 | } |
597 | 686 | } |
598 | 687 | |
599 | 688 | if err = ut.AddCardinal("gt-items-item", "{0} элемент", locales.PluralRuleOne, false); err != nil { |
689 | return | |
690 | } | |
691 | ||
692 | if err = ut.AddCardinal("gt-items-item", "{0} элементов", locales.PluralRuleFew, false); err != nil { | |
693 | return | |
694 | } | |
695 | ||
696 | if err = ut.AddCardinal("gt-items-item", "{0} элементов", locales.PluralRuleMany, false); err != nil { | |
600 | 697 | return |
601 | 698 | } |
602 | 699 | |
704 | 801 | return |
705 | 802 | } |
706 | 803 | |
804 | if err = ut.AddCardinal("gte-string-character", "{0} символа", locales.PluralRuleFew, false); err != nil { | |
805 | return | |
806 | } | |
807 | ||
808 | if err = ut.AddCardinal("gte-string-character", "{0} символов", locales.PluralRuleMany, false); err != nil { | |
809 | return | |
810 | } | |
811 | ||
707 | 812 | if err = ut.AddCardinal("gte-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil { |
708 | 813 | return |
709 | 814 | } |
717 | 822 | } |
718 | 823 | |
719 | 824 | if err = ut.AddCardinal("gte-items-item", "{0} элемент", locales.PluralRuleOne, false); err != nil { |
825 | return | |
826 | } | |
827 | ||
828 | if err = ut.AddCardinal("gte-items-item", "{0} элемента", locales.PluralRuleFew, false); err != nil { | |
829 | return | |
830 | } | |
831 | ||
832 | if err = ut.AddCardinal("gte-items-item", "{0} элементов", locales.PluralRuleMany, false); err != nil { | |
720 | 833 | return |
721 | 834 | } |
722 | 835 | |
1178 | 1291 | override: false, |
1179 | 1292 | }, |
1180 | 1293 | { |
1294 | tag: "ulid", | |
1295 | translation: "{0} должен быть ULID", | |
1296 | override: false, | |
1297 | }, | |
1298 | { | |
1181 | 1299 | tag: "ascii", |
1182 | 1300 | translation: "{0} должен содержать только ascii символы", |
1183 | 1301 | override: false, |
6 | 6 | "time" |
7 | 7 | |
8 | 8 | . "github.com/go-playground/assert/v2" |
9 | russian "github.com/go-playground/locales/en" | |
9 | russian "github.com/go-playground/locales/ru" | |
10 | 10 | ut "github.com/go-playground/universal-translator" |
11 | 11 | "github.com/go-playground/validator/v10" |
12 | 12 | ) |
32 | 32 | } |
33 | 33 | |
34 | 34 | type Test struct { |
35 | Inner Inner | |
36 | RequiredString string `validate:"required"` | |
37 | RequiredNumber int `validate:"required"` | |
38 | RequiredMultiple []string `validate:"required"` | |
39 | LenString string `validate:"len=1"` | |
40 | LenNumber float64 `validate:"len=1113.00"` | |
41 | LenMultiple []string `validate:"len=7"` | |
42 | MinString string `validate:"min=1"` | |
43 | MinNumber float64 `validate:"min=1113.00"` | |
44 | MinMultiple []string `validate:"min=7"` | |
45 | MaxString string `validate:"max=3"` | |
46 | MaxNumber float64 `validate:"max=1113.00"` | |
47 | MaxMultiple []string `validate:"max=7"` | |
48 | EqString string `validate:"eq=3"` | |
49 | EqNumber float64 `validate:"eq=2.33"` | |
50 | EqMultiple []string `validate:"eq=7"` | |
51 | NeString string `validate:"ne="` | |
52 | NeNumber float64 `validate:"ne=0.00"` | |
53 | NeMultiple []string `validate:"ne=0"` | |
54 | LtString string `validate:"lt=3"` | |
55 | LtNumber float64 `validate:"lt=5.56"` | |
56 | LtMultiple []string `validate:"lt=2"` | |
57 | LtTime time.Time `validate:"lt"` | |
58 | LteString string `validate:"lte=3"` | |
59 | LteNumber float64 `validate:"lte=5.56"` | |
60 | LteMultiple []string `validate:"lte=2"` | |
61 | LteTime time.Time `validate:"lte"` | |
62 | GtString string `validate:"gt=3"` | |
63 | GtNumber float64 `validate:"gt=5.56"` | |
64 | GtMultiple []string `validate:"gt=2"` | |
65 | GtTime time.Time `validate:"gt"` | |
66 | GteString string `validate:"gte=3"` | |
67 | GteNumber float64 `validate:"gte=5.56"` | |
68 | GteMultiple []string `validate:"gte=2"` | |
69 | GteTime time.Time `validate:"gte"` | |
70 | EqFieldString string `validate:"eqfield=MaxString"` | |
71 | EqCSFieldString string `validate:"eqcsfield=Inner.EqCSFieldString"` | |
72 | NeCSFieldString string `validate:"necsfield=Inner.NeCSFieldString"` | |
73 | GtCSFieldString string `validate:"gtcsfield=Inner.GtCSFieldString"` | |
74 | GteCSFieldString string `validate:"gtecsfield=Inner.GteCSFieldString"` | |
75 | LtCSFieldString string `validate:"ltcsfield=Inner.LtCSFieldString"` | |
76 | LteCSFieldString string `validate:"ltecsfield=Inner.LteCSFieldString"` | |
77 | NeFieldString string `validate:"nefield=EqFieldString"` | |
78 | GtFieldString string `validate:"gtfield=MaxString"` | |
79 | GteFieldString string `validate:"gtefield=MaxString"` | |
80 | LtFieldString string `validate:"ltfield=MaxString"` | |
81 | LteFieldString string `validate:"ltefield=MaxString"` | |
82 | AlphaString string `validate:"alpha"` | |
83 | AlphanumString string `validate:"alphanum"` | |
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 | Excludes string `validate:"excludes=text"` | |
99 | ExcludesAll string `validate:"excludesall=!@#$"` | |
100 | ExcludesRune string `validate:"excludesrune=☻"` | |
101 | ISBN string `validate:"isbn"` | |
102 | ISBN10 string `validate:"isbn10"` | |
103 | ISBN13 string `validate:"isbn13"` | |
104 | UUID string `validate:"uuid"` | |
105 | UUID3 string `validate:"uuid3"` | |
106 | UUID4 string `validate:"uuid4"` | |
107 | UUID5 string `validate:"uuid5"` | |
108 | ASCII string `validate:"ascii"` | |
109 | PrintableASCII string `validate:"printascii"` | |
110 | MultiByte string `validate:"multibyte"` | |
111 | DataURI string `validate:"datauri"` | |
112 | Latitude string `validate:"latitude"` | |
113 | Longitude string `validate:"longitude"` | |
114 | SSN string `validate:"ssn"` | |
115 | IP string `validate:"ip"` | |
116 | IPv4 string `validate:"ipv4"` | |
117 | IPv6 string `validate:"ipv6"` | |
118 | CIDR string `validate:"cidr"` | |
119 | CIDRv4 string `validate:"cidrv4"` | |
120 | CIDRv6 string `validate:"cidrv6"` | |
121 | TCPAddr string `validate:"tcp_addr"` | |
122 | TCPAddrv4 string `validate:"tcp4_addr"` | |
123 | TCPAddrv6 string `validate:"tcp6_addr"` | |
124 | UDPAddr string `validate:"udp_addr"` | |
125 | UDPAddrv4 string `validate:"udp4_addr"` | |
126 | UDPAddrv6 string `validate:"udp6_addr"` | |
127 | IPAddr string `validate:"ip_addr"` | |
128 | IPAddrv4 string `validate:"ip4_addr"` | |
129 | IPAddrv6 string `validate:"ip6_addr"` | |
130 | UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future | |
131 | MAC string `validate:"mac"` | |
132 | IsColor string `validate:"iscolor"` | |
133 | StrPtrMinLen *string `validate:"min=10"` | |
134 | StrPtrMaxLen *string `validate:"max=1"` | |
135 | StrPtrLen *string `validate:"len=2"` | |
136 | StrPtrLt *string `validate:"lt=1"` | |
137 | StrPtrLte *string `validate:"lte=1"` | |
138 | StrPtrGt *string `validate:"gt=10"` | |
139 | StrPtrGte *string `validate:"gte=10"` | |
140 | OneOfString string `validate:"oneof=red green"` | |
141 | OneOfInt int `validate:"oneof=5 63"` | |
142 | UniqueSlice []string `validate:"unique"` | |
143 | UniqueArray [3]string `validate:"unique"` | |
144 | UniqueMap map[string]string `validate:"unique"` | |
35 | Inner Inner | |
36 | RequiredString string `validate:"required"` | |
37 | RequiredNumber int `validate:"required"` | |
38 | RequiredMultiple []string `validate:"required"` | |
39 | LenString string `validate:"len=1"` | |
40 | LenNumber float64 `validate:"len=1113.00"` | |
41 | LenMultiple []string `validate:"len=7"` | |
42 | LenMultipleSecond []string `validate:"len=2"` | |
43 | MinString string `validate:"min=1"` | |
44 | MinStringMultiple string `validate:"min=2"` | |
45 | MinStringMultipleSecond string `validate:"min=7"` | |
46 | MinNumber float64 `validate:"min=1113.00"` | |
47 | MinMultiple []string `validate:"min=7"` | |
48 | MinMultipleSecond []string `validate:"min=2"` | |
49 | MaxString string `validate:"max=3"` | |
50 | MaxStringSecond string `validate:"max=7"` | |
51 | MaxNumber float64 `validate:"max=1113.00"` | |
52 | MaxMultiple []string `validate:"max=7"` | |
53 | MaxMultipleSecond []string `validate:"max=2"` | |
54 | EqString string `validate:"eq=3"` | |
55 | EqNumber float64 `validate:"eq=2.33"` | |
56 | EqMultiple []string `validate:"eq=7"` | |
57 | NeString string `validate:"ne="` | |
58 | NeNumber float64 `validate:"ne=0.00"` | |
59 | NeMultiple []string `validate:"ne=0"` | |
60 | LtString string `validate:"lt=3"` | |
61 | LtStringSecond string `validate:"lt=7"` | |
62 | LtNumber float64 `validate:"lt=5.56"` | |
63 | LtMultiple []string `validate:"lt=2"` | |
64 | LtMultipleSecond []string `validate:"lt=7"` | |
65 | LtTime time.Time `validate:"lt"` | |
66 | LteString string `validate:"lte=3"` | |
67 | LteStringSecond string `validate:"lte=7"` | |
68 | LteNumber float64 `validate:"lte=5.56"` | |
69 | LteMultiple []string `validate:"lte=2"` | |
70 | LteMultipleSecond []string `validate:"lte=7"` | |
71 | LteTime time.Time `validate:"lte"` | |
72 | GtString string `validate:"gt=3"` | |
73 | GtStringSecond string `validate:"gt=7"` | |
74 | GtNumber float64 `validate:"gt=5.56"` | |
75 | GtMultiple []string `validate:"gt=2"` | |
76 | GtMultipleSecond []string `validate:"gt=7"` | |
77 | GtTime time.Time `validate:"gt"` | |
78 | GteString string `validate:"gte=3"` | |
79 | GteStringSecond string `validate:"gte=7"` | |
80 | GteNumber float64 `validate:"gte=5.56"` | |
81 | GteMultiple []string `validate:"gte=2"` | |
82 | GteMultipleSecond []string `validate:"gte=7"` | |
83 | GteTime time.Time `validate:"gte"` | |
84 | EqFieldString string `validate:"eqfield=MaxString"` | |
85 | EqCSFieldString string `validate:"eqcsfield=Inner.EqCSFieldString"` | |
86 | NeCSFieldString string `validate:"necsfield=Inner.NeCSFieldString"` | |
87 | GtCSFieldString string `validate:"gtcsfield=Inner.GtCSFieldString"` | |
88 | GteCSFieldString string `validate:"gtecsfield=Inner.GteCSFieldString"` | |
89 | LtCSFieldString string `validate:"ltcsfield=Inner.LtCSFieldString"` | |
90 | LteCSFieldString string `validate:"ltecsfield=Inner.LteCSFieldString"` | |
91 | NeFieldString string `validate:"nefield=EqFieldString"` | |
92 | GtFieldString string `validate:"gtfield=MaxString"` | |
93 | GteFieldString string `validate:"gtefield=MaxString"` | |
94 | LtFieldString string `validate:"ltfield=MaxString"` | |
95 | LteFieldString string `validate:"ltefield=MaxString"` | |
96 | AlphaString string `validate:"alpha"` | |
97 | AlphanumString string `validate:"alphanum"` | |
98 | NumericString string `validate:"numeric"` | |
99 | NumberString string `validate:"number"` | |
100 | HexadecimalString string `validate:"hexadecimal"` | |
101 | HexColorString string `validate:"hexcolor"` | |
102 | RGBColorString string `validate:"rgb"` | |
103 | RGBAColorString string `validate:"rgba"` | |
104 | HSLColorString string `validate:"hsl"` | |
105 | HSLAColorString string `validate:"hsla"` | |
106 | Email string `validate:"email"` | |
107 | URL string `validate:"url"` | |
108 | URI string `validate:"uri"` | |
109 | Base64 string `validate:"base64"` | |
110 | Contains string `validate:"contains=purpose"` | |
111 | ContainsAny string `validate:"containsany=!@#$"` | |
112 | Excludes string `validate:"excludes=text"` | |
113 | ExcludesAll string `validate:"excludesall=!@#$"` | |
114 | ExcludesRune string `validate:"excludesrune=☻"` | |
115 | ISBN string `validate:"isbn"` | |
116 | ISBN10 string `validate:"isbn10"` | |
117 | ISBN13 string `validate:"isbn13"` | |
118 | UUID string `validate:"uuid"` | |
119 | UUID3 string `validate:"uuid3"` | |
120 | UUID4 string `validate:"uuid4"` | |
121 | UUID5 string `validate:"uuid5"` | |
122 | ULID string `validate:"ulid"` | |
123 | ASCII string `validate:"ascii"` | |
124 | PrintableASCII string `validate:"printascii"` | |
125 | MultiByte string `validate:"multibyte"` | |
126 | DataURI string `validate:"datauri"` | |
127 | Latitude string `validate:"latitude"` | |
128 | Longitude string `validate:"longitude"` | |
129 | SSN string `validate:"ssn"` | |
130 | IP string `validate:"ip"` | |
131 | IPv4 string `validate:"ipv4"` | |
132 | IPv6 string `validate:"ipv6"` | |
133 | CIDR string `validate:"cidr"` | |
134 | CIDRv4 string `validate:"cidrv4"` | |
135 | CIDRv6 string `validate:"cidrv6"` | |
136 | TCPAddr string `validate:"tcp_addr"` | |
137 | TCPAddrv4 string `validate:"tcp4_addr"` | |
138 | TCPAddrv6 string `validate:"tcp6_addr"` | |
139 | UDPAddr string `validate:"udp_addr"` | |
140 | UDPAddrv4 string `validate:"udp4_addr"` | |
141 | UDPAddrv6 string `validate:"udp6_addr"` | |
142 | IPAddr string `validate:"ip_addr"` | |
143 | IPAddrv4 string `validate:"ip4_addr"` | |
144 | IPAddrv6 string `validate:"ip6_addr"` | |
145 | UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future | |
146 | MAC string `validate:"mac"` | |
147 | IsColor string `validate:"iscolor"` | |
148 | StrPtrMinLen *string `validate:"min=10"` | |
149 | StrPtrMinLenSecond *string `validate:"min=2"` | |
150 | StrPtrMaxLen *string `validate:"max=1"` | |
151 | StrPtrLen *string `validate:"len=2"` | |
152 | StrPtrLenSecond *string `validate:"len=7"` | |
153 | StrPtrLt *string `validate:"lt=1"` | |
154 | StrPtrLte *string `validate:"lte=1"` | |
155 | StrPtrLteMultiple *string `validate:"lte=2"` | |
156 | StrPtrLteMultipleSecond *string `validate:"lte=7"` | |
157 | StrPtrGt *string `validate:"gt=10"` | |
158 | StrPtrGte *string `validate:"gte=10"` | |
159 | StrPtrGtSecond *string `validate:"gt=2"` | |
160 | StrPtrGteSecond *string `validate:"gte=2"` | |
161 | OneOfString string `validate:"oneof=red green"` | |
162 | OneOfInt int `validate:"oneof=5 63"` | |
163 | UniqueSlice []string `validate:"unique"` | |
164 | UniqueArray [3]string `validate:"unique"` | |
165 | UniqueMap map[string]string `validate:"unique"` | |
145 | 166 | } |
146 | 167 | |
147 | 168 | var test Test |
151 | 172 | test.Inner.GteCSFieldString = "1234" |
152 | 173 | |
153 | 174 | test.MaxString = "1234" |
175 | test.MaxStringSecond = "12345678" | |
154 | 176 | test.MaxNumber = 2000 |
155 | 177 | test.MaxMultiple = make([]string, 9) |
178 | test.MaxMultipleSecond = make([]string, 3) | |
156 | 179 | |
157 | 180 | test.LtString = "1234" |
181 | test.LtStringSecond = "12345678" | |
158 | 182 | test.LtNumber = 6 |
159 | 183 | test.LtMultiple = make([]string, 3) |
184 | test.LtMultipleSecond = make([]string, 8) | |
160 | 185 | test.LtTime = time.Now().Add(time.Hour * 24) |
161 | 186 | |
162 | 187 | test.LteString = "1234" |
188 | test.LteStringSecond = "12345678" | |
163 | 189 | test.LteNumber = 6 |
164 | 190 | test.LteMultiple = make([]string, 3) |
191 | test.LteMultipleSecond = make([]string, 8) | |
165 | 192 | test.LteTime = time.Now().Add(time.Hour * 24) |
166 | 193 | |
167 | 194 | test.LtFieldString = "12345" |
314 | 341 | expected: "UUID5 должен быть UUID 5 версии", |
315 | 342 | }, |
316 | 343 | { |
344 | ns: "Test.ULID", | |
345 | expected: "ULID должен быть ULID", | |
346 | }, | |
347 | { | |
317 | 348 | ns: "Test.ISBN", |
318 | 349 | expected: "ISBN должен быть ISBN номером", |
319 | 350 | }, |
451 | 482 | }, |
452 | 483 | { |
453 | 484 | ns: "Test.GteString", |
454 | expected: "GteString должен содержать минимум 3 символы", | |
485 | expected: "GteString должен содержать минимум 3 символа", | |
486 | }, | |
487 | { | |
488 | ns: "Test.GteStringSecond", | |
489 | expected: "GteStringSecond должен содержать минимум 7 символов", | |
455 | 490 | }, |
456 | 491 | { |
457 | 492 | ns: "Test.GteNumber", |
458 | expected: "GteNumber должен быть больше или равно 5.56", | |
493 | expected: "GteNumber должен быть больше или равно 5,56", | |
459 | 494 | }, |
460 | 495 | { |
461 | 496 | ns: "Test.GteMultiple", |
462 | expected: "GteMultiple должен содержать минимум 2 элементы", | |
497 | expected: "GteMultiple должен содержать минимум 2 элемента", | |
498 | }, | |
499 | { | |
500 | ns: "Test.GteMultipleSecond", | |
501 | expected: "GteMultipleSecond должен содержать минимум 7 элементов", | |
463 | 502 | }, |
464 | 503 | { |
465 | 504 | ns: "Test.GteTime", |
467 | 506 | }, |
468 | 507 | { |
469 | 508 | ns: "Test.GtString", |
470 | expected: "GtString должен быть длиннее 3 символы", | |
509 | expected: "GtString должен быть длиннее 3 символов", | |
510 | }, | |
511 | { | |
512 | ns: "Test.GtStringSecond", | |
513 | expected: "GtStringSecond должен быть длиннее 7 символов", | |
471 | 514 | }, |
472 | 515 | { |
473 | 516 | ns: "Test.GtNumber", |
474 | expected: "GtNumber должен быть больше 5.56", | |
517 | expected: "GtNumber должен быть больше 5,56", | |
475 | 518 | }, |
476 | 519 | { |
477 | 520 | ns: "Test.GtMultiple", |
478 | expected: "GtMultiple должен содержать более 2 элементы", | |
521 | expected: "GtMultiple должен содержать более 2 элементов", | |
522 | }, | |
523 | { | |
524 | ns: "Test.GtMultipleSecond", | |
525 | expected: "GtMultipleSecond должен содержать более 7 элементов", | |
479 | 526 | }, |
480 | 527 | { |
481 | 528 | ns: "Test.GtTime", |
483 | 530 | }, |
484 | 531 | { |
485 | 532 | ns: "Test.LteString", |
486 | expected: "LteString должен содержать максимум 3 символы", | |
533 | expected: "LteString должен содержать максимум 3 символа", | |
534 | }, | |
535 | { | |
536 | ns: "Test.LteStringSecond", | |
537 | expected: "LteStringSecond должен содержать максимум 7 символов", | |
487 | 538 | }, |
488 | 539 | { |
489 | 540 | ns: "Test.LteNumber", |
490 | expected: "LteNumber должен быть менее или равен 5.56", | |
541 | expected: "LteNumber должен быть менее или равен 5,56", | |
491 | 542 | }, |
492 | 543 | { |
493 | 544 | ns: "Test.LteMultiple", |
494 | expected: "LteMultiple должен содержать максимум 2 элементы", | |
545 | expected: "LteMultiple должен содержать максимум 2 элемента", | |
546 | }, | |
547 | { | |
548 | ns: "Test.LteMultipleSecond", | |
549 | expected: "LteMultipleSecond должен содержать максимум 7 элементов", | |
495 | 550 | }, |
496 | 551 | { |
497 | 552 | ns: "Test.LteTime", |
499 | 554 | }, |
500 | 555 | { |
501 | 556 | ns: "Test.LtString", |
502 | expected: "LtString должен иметь менее 3 символы", | |
557 | expected: "LtString должен иметь менее 3 символов", | |
558 | }, | |
559 | { | |
560 | ns: "Test.LtStringSecond", | |
561 | expected: "LtStringSecond должен иметь менее 7 символов", | |
503 | 562 | }, |
504 | 563 | { |
505 | 564 | ns: "Test.LtNumber", |
506 | expected: "LtNumber должен быть менее 5.56", | |
565 | expected: "LtNumber должен быть менее 5,56", | |
507 | 566 | }, |
508 | 567 | { |
509 | 568 | ns: "Test.LtMultiple", |
510 | expected: "LtMultiple должен содержать менее 2 элементы", | |
569 | expected: "LtMultiple должен содержать менее 2 элементов", | |
570 | }, | |
571 | { | |
572 | ns: "Test.LtMultipleSecond", | |
573 | expected: "LtMultipleSecond должен содержать менее 7 элементов", | |
511 | 574 | }, |
512 | 575 | { |
513 | 576 | ns: "Test.LtTime", |
539 | 602 | }, |
540 | 603 | { |
541 | 604 | ns: "Test.MaxString", |
542 | expected: "MaxString должен содержать максимум 3 символы", | |
605 | expected: "MaxString должен содержать максимум 3 символа", | |
606 | }, | |
607 | { | |
608 | ns: "Test.MaxStringSecond", | |
609 | expected: "MaxStringSecond должен содержать максимум 7 символов", | |
543 | 610 | }, |
544 | 611 | { |
545 | 612 | ns: "Test.MaxNumber", |
546 | expected: "MaxNumber должен быть меньше или равно 1,113.00", | |
613 | expected: "MaxNumber должен быть меньше или равно 1 113,00", | |
547 | 614 | }, |
548 | 615 | { |
549 | 616 | ns: "Test.MaxMultiple", |
550 | expected: "MaxMultiple должен содержать максимум 7 элементы", | |
617 | expected: "MaxMultiple должен содержать максимум 7 элементов", | |
618 | }, | |
619 | { | |
620 | ns: "Test.MaxMultipleSecond", | |
621 | expected: "MaxMultipleSecond должен содержать максимум 2 элемента", | |
551 | 622 | }, |
552 | 623 | { |
553 | 624 | ns: "Test.MinString", |
554 | 625 | expected: "MinString должен содержать минимум 1 символ", |
555 | 626 | }, |
556 | 627 | { |
628 | ns: "Test.MinStringMultiple", | |
629 | expected: "MinStringMultiple должен содержать минимум 2 символа", | |
630 | }, | |
631 | { | |
632 | ns: "Test.MinStringMultipleSecond", | |
633 | expected: "MinStringMultipleSecond должен содержать минимум 7 символов", | |
634 | }, | |
635 | { | |
557 | 636 | ns: "Test.MinNumber", |
558 | expected: "MinNumber должен быть больше или равно 1,113.00", | |
637 | expected: "MinNumber должен быть больше или равно 1 113,00", | |
559 | 638 | }, |
560 | 639 | { |
561 | 640 | ns: "Test.MinMultiple", |
562 | expected: "MinMultiple должен содержать минимум 7 элементы", | |
641 | expected: "MinMultiple должен содержать минимум 7 элементов", | |
642 | }, | |
643 | { | |
644 | ns: "Test.MinMultipleSecond", | |
645 | expected: "MinMultipleSecond должен содержать минимум 2 элемента", | |
563 | 646 | }, |
564 | 647 | { |
565 | 648 | ns: "Test.LenString", |
567 | 650 | }, |
568 | 651 | { |
569 | 652 | ns: "Test.LenNumber", |
570 | expected: "LenNumber должен быть равен 1,113.00", | |
653 | expected: "LenNumber должен быть равен 1 113,00", | |
571 | 654 | }, |
572 | 655 | { |
573 | 656 | ns: "Test.LenMultiple", |
574 | expected: "LenMultiple должен содержать 7 элементы", | |
657 | expected: "LenMultiple должен содержать 7 элементов", | |
658 | }, | |
659 | { | |
660 | ns: "Test.LenMultipleSecond", | |
661 | expected: "LenMultipleSecond должен содержать 2 элемента", | |
575 | 662 | }, |
576 | 663 | { |
577 | 664 | ns: "Test.RequiredString", |
587 | 674 | }, |
588 | 675 | { |
589 | 676 | ns: "Test.StrPtrMinLen", |
590 | expected: "StrPtrMinLen должен содержать минимум 10 символы", | |
677 | expected: "StrPtrMinLen должен содержать минимум 10 символов", | |
678 | }, | |
679 | { | |
680 | ns: "Test.StrPtrMinLenSecond", | |
681 | expected: "StrPtrMinLenSecond должен содержать минимум 2 символа", | |
591 | 682 | }, |
592 | 683 | { |
593 | 684 | ns: "Test.StrPtrMaxLen", |
595 | 686 | }, |
596 | 687 | { |
597 | 688 | ns: "Test.StrPtrLen", |
598 | expected: "StrPtrLen должен быть длиной в 2 символы", | |
689 | expected: "StrPtrLen должен быть длиной в 2 символа", | |
690 | }, | |
691 | { | |
692 | ns: "Test.StrPtrLenSecond", | |
693 | expected: "StrPtrLenSecond должен быть длиной в 7 символов", | |
599 | 694 | }, |
600 | 695 | { |
601 | 696 | ns: "Test.StrPtrLt", |
606 | 701 | expected: "StrPtrLte должен содержать максимум 1 символ", |
607 | 702 | }, |
608 | 703 | { |
704 | ns: "Test.StrPtrLteMultiple", | |
705 | expected: "StrPtrLteMultiple должен содержать максимум 2 символа", | |
706 | }, | |
707 | { | |
708 | ns: "Test.StrPtrLteMultipleSecond", | |
709 | expected: "StrPtrLteMultipleSecond должен содержать максимум 7 символов", | |
710 | }, | |
711 | { | |
609 | 712 | ns: "Test.StrPtrGt", |
610 | expected: "StrPtrGt должен быть длиннее 10 символы", | |
713 | expected: "StrPtrGt должен быть длиннее 10 символов", | |
714 | }, | |
715 | { | |
716 | ns: "Test.StrPtrGtSecond", | |
717 | expected: "StrPtrGtSecond должен быть длиннее 2 символов", | |
611 | 718 | }, |
612 | 719 | { |
613 | 720 | ns: "Test.StrPtrGte", |
614 | expected: "StrPtrGte должен содержать минимум 10 символы", | |
721 | expected: "StrPtrGte должен содержать минимум 10 символов", | |
722 | }, | |
723 | { | |
724 | ns: "Test.StrPtrGteSecond", | |
725 | expected: "StrPtrGteSecond должен содержать минимум 2 символа", | |
615 | 726 | }, |
616 | 727 | { |
617 | 728 | ns: "Test.OneOfString", |
1173 | 1173 | override: false, |
1174 | 1174 | }, |
1175 | 1175 | { |
1176 | tag: "ulid", | |
1177 | translation: "{0} geçerli bir ULID olmalıdır", | |
1178 | override: false, | |
1179 | }, | |
1180 | { | |
1176 | 1181 | tag: "ascii", |
1177 | 1182 | translation: "{0} yalnızca ascii karakterler içermelidir", |
1178 | 1183 | override: false, |
3 | 3 | "testing" |
4 | 4 | "time" |
5 | 5 | |
6 | . "github.com/go-playground/assert/v2" | |
6 | 7 | turkish "github.com/go-playground/locales/tr" |
7 | 8 | ut "github.com/go-playground/universal-translator" |
8 | . "github.com/go-playground/assert/v2" | |
9 | 9 | "github.com/go-playground/validator/v10" |
10 | 10 | ) |
11 | 11 | |
103 | 103 | UUID3 string `validate:"uuid3"` |
104 | 104 | UUID4 string `validate:"uuid4"` |
105 | 105 | UUID5 string `validate:"uuid5"` |
106 | ULID string `validate:"ulid"` | |
106 | 107 | ASCII string `validate:"ascii"` |
107 | 108 | PrintableASCII string `validate:"printascii"` |
108 | 109 | MultiByte string `validate:"multibyte"` |
312 | 313 | expected: "UUID5 geçerli bir sürüm 5 UUID olmalıdır", |
313 | 314 | }, |
314 | 315 | { |
316 | ns: "Test.ULID", | |
317 | expected: "ULID geçerli bir ULID olmalıdır", | |
318 | }, | |
319 | { | |
315 | 320 | ns: "Test.ISBN", |
316 | 321 | expected: "ISBN geçerli bir ISBN numarası olmalıdır", |
317 | 322 | }, |
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, |
1135 | 1160 | }, |
1136 | 1161 | }, |
1137 | 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}'开头", | |
1180 | override: false, | |
1181 | customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { | |
1182 | ||
1183 | t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) | |
1184 | if err != nil { | |
1185 | log.Printf("警告: 翻译字段错误: %#v", fe) | |
1186 | return fe.(error).Error() | |
1187 | } | |
1188 | ||
1189 | return t | |
1190 | }, | |
1191 | }, | |
1192 | { | |
1138 | 1193 | tag: "isbn", |
1139 | 1194 | translation: "{0}必须是一个有效的ISBN编号", |
1140 | 1195 | override: false, |
1167 | 1222 | { |
1168 | 1223 | tag: "uuid5", |
1169 | 1224 | translation: "{0}必须是一个有效的V5 UUID", |
1225 | override: false, | |
1226 | }, | |
1227 | { | |
1228 | tag: "ulid", | |
1229 | translation: "{0}必须是一个有效的ULID", | |
1170 | 1230 | override: false, |
1171 | 1231 | }, |
1172 | 1232 | { |
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 | ULID string `validate:"ulid"` | |
112 | ASCII string `validate:"ascii"` | |
113 | PrintableASCII string `validate:"printascii"` | |
114 | MultiByte string `validate:"multibyte"` | |
115 | DataURI string `validate:"datauri"` | |
116 | Latitude string `validate:"latitude"` | |
117 | Longitude string `validate:"longitude"` | |
118 | SSN string `validate:"ssn"` | |
119 | IP string `validate:"ip"` | |
120 | IPv4 string `validate:"ipv4"` | |
121 | IPv6 string `validate:"ipv6"` | |
122 | CIDR string `validate:"cidr"` | |
123 | CIDRv4 string `validate:"cidrv4"` | |
124 | CIDRv6 string `validate:"cidrv6"` | |
125 | TCPAddr string `validate:"tcp_addr"` | |
126 | TCPAddrv4 string `validate:"tcp4_addr"` | |
127 | TCPAddrv6 string `validate:"tcp6_addr"` | |
128 | UDPAddr string `validate:"udp_addr"` | |
129 | UDPAddrv4 string `validate:"udp4_addr"` | |
130 | UDPAddrv6 string `validate:"udp6_addr"` | |
131 | IPAddr string `validate:"ip_addr"` | |
132 | IPAddrv4 string `validate:"ip4_addr"` | |
133 | IPAddrv6 string `validate:"ip6_addr"` | |
134 | UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future | |
135 | MAC string `validate:"mac"` | |
136 | IsColor string `validate:"iscolor"` | |
137 | StrPtrMinLen *string `validate:"min=10"` | |
138 | StrPtrMaxLen *string `validate:"max=1"` | |
139 | StrPtrLen *string `validate:"len=2"` | |
140 | StrPtrLt *string `validate:"lt=1"` | |
141 | StrPtrLte *string `validate:"lte=1"` | |
142 | StrPtrGt *string `validate:"gt=10"` | |
143 | StrPtrGte *string `validate:"gte=10"` | |
144 | OneOfString string `validate:"oneof=red green"` | |
145 | OneOfInt int `validate:"oneof=5 63"` | |
146 | JsonString string `validate:"json"` | |
147 | LowercaseString string `validate:"lowercase"` | |
148 | UppercaseString string `validate:"uppercase"` | |
149 | Datetime string `validate:"datetime=2006-01-02"` | |
144 | 150 | } |
145 | 151 | |
146 | 152 | var test Test |
171 | 177 | |
172 | 178 | test.AlphaString = "abc3" |
173 | 179 | test.AlphanumString = "abc3!" |
180 | test.AlphanumUnicodeString = "abc3啊!" | |
181 | test.AlphaUnicodeString = "abc3啊" | |
174 | 182 | test.NumericString = "12E.00" |
175 | 183 | test.NumberString = "12E" |
176 | 184 | |
177 | 185 | test.Excludes = "this is some test text" |
178 | 186 | test.ExcludesAll = "This is Great!" |
179 | 187 | test.ExcludesRune = "Love it ☻" |
188 | ||
189 | test.EndsWith = "this is some test text" | |
190 | test.StartsWith = "this is some test text" | |
180 | 191 | |
181 | 192 | test.ASCII = "カタカナ" |
182 | 193 | test.PrintableASCII = "カタカナ" |
317 | 328 | expected: "UUID5必须是一个有效的V5 UUID", |
318 | 329 | }, |
319 | 330 | { |
331 | ns: "Test.ULID", | |
332 | expected: "ULID必须是一个有效的ULID", | |
333 | }, | |
334 | { | |
320 | 335 | ns: "Test.ISBN", |
321 | 336 | expected: "ISBN必须是一个有效的ISBN编号", |
322 | 337 | }, |
329 | 344 | expected: "ISBN13必须是一个有效的ISBN-13编号", |
330 | 345 | }, |
331 | 346 | { |
347 | ns: "Test.EndsWith", | |
348 | expected: "EndsWith必须以文本'end'结尾", | |
349 | }, | |
350 | { | |
351 | ns: "Test.StartsWith", | |
352 | expected: "StartsWith必须以文本'start'开头", | |
353 | }, | |
354 | { | |
332 | 355 | ns: "Test.Excludes", |
333 | 356 | expected: "Excludes不能包含文本'text'", |
334 | 357 | }, |
341 | 364 | expected: "ExcludesRune不能包含'☻'", |
342 | 365 | }, |
343 | 366 | { |
367 | ns: "Test.ContainsRune", | |
368 | expected: "ContainsRune必须包含字符'☻'", | |
369 | }, | |
370 | { | |
344 | 371 | ns: "Test.ContainsAny", |
345 | 372 | expected: "ContainsAny必须包含至少一个以下字符'!@#$'", |
346 | 373 | }, |
395 | 422 | { |
396 | 423 | ns: "Test.NumericString", |
397 | 424 | expected: "NumericString必须是一个有效的数值", |
425 | }, | |
426 | { | |
427 | ns: "Test.AlphaUnicodeString", | |
428 | expected: "AlphaUnicodeString只能包含字母和Unicode字符", | |
429 | }, | |
430 | { | |
431 | ns: "Test.AlphanumUnicodeString", | |
432 | expected: "AlphanumUnicodeString只能包含字母数字和Unicode字符", | |
398 | 433 | }, |
399 | 434 | { |
400 | 435 | ns: "Test.AlphanumString", |
1166 | 1166 | override: false, |
1167 | 1167 | }, |
1168 | 1168 | { |
1169 | tag: "ulid", | |
1170 | translation: "{0}必須是一個有效的ULID", | |
1171 | override: false, | |
1172 | }, | |
1173 | { | |
1169 | 1174 | tag: "ascii", |
1170 | 1175 | translation: "{0}必須只包含ascii字元", |
1171 | 1176 | override: false, |
103 | 103 | UUID3 string `validate:"uuid3"` |
104 | 104 | UUID4 string `validate:"uuid4"` |
105 | 105 | UUID5 string `validate:"uuid5"` |
106 | ULID string `validate:"ulid"` | |
106 | 107 | ASCII string `validate:"ascii"` |
107 | 108 | PrintableASCII string `validate:"printascii"` |
108 | 109 | MultiByte string `validate:"multibyte"` |
309 | 310 | expected: "UUID5必須是一個有效的V5 UUID", |
310 | 311 | }, |
311 | 312 | { |
313 | ns: "Test.ULID", | |
314 | expected: "ULID必須是一個有效的ULID", | |
315 | }, | |
316 | { | |
312 | 317 | ns: "Test.ISBN", |
313 | 318 | expected: "ISBN必須是一個有效的ISBN編號", |
314 | 319 | }, |
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" |
84 | 88 | } |
85 | 89 | |
86 | 90 | // New returns a new instance of 'validate' with sane defaults. |
91 | // Validate is designed to be thread-safe and used as a singleton instance. | |
92 | // It caches information about your struct and validations, | |
93 | // in essence only parsing your validation tags once per struct type. | |
94 | // Using multiple instances neglects the benefit of caching. | |
87 | 95 | func New() *Validate { |
88 | 96 | |
89 | 97 | tc := new(tagCache) |
110 | 118 | |
111 | 119 | switch k { |
112 | 120 | // 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: | |
121 | case requiredIfTag, requiredUnlessTag, requiredWithTag, requiredWithAllTag, requiredWithoutTag, requiredWithoutAllTag, | |
122 | excludedWithTag, excludedWithAllTag, excludedWithoutTag, excludedWithoutAllTag: | |
114 | 123 | _ = v.registerValidation(k, wrapFunc(val), true, true) |
115 | 124 | default: |
116 | 125 | // no need to error check here, baked in will always be valid |
135 | 144 | // SetTagName allows for changing of the default tag name of 'validate' |
136 | 145 | func (v *Validate) SetTagName(name string) { |
137 | 146 | v.tagName = name |
147 | } | |
148 | ||
149 | // ValidateMapCtx validates a map using a map of validation rules and allows passing of contextual | |
150 | // validation validation information via context.Context. | |
151 | func (v Validate) ValidateMapCtx(ctx context.Context, data map[string]interface{}, rules map[string]interface{}) map[string]interface{} { | |
152 | errs := make(map[string]interface{}) | |
153 | for field, rule := range rules { | |
154 | if reflect.ValueOf(rule).Kind() == reflect.Map && reflect.ValueOf(data[field]).Kind() == reflect.Map { | |
155 | err := v.ValidateMapCtx(ctx, data[field].(map[string]interface{}), rule.(map[string]interface{})) | |
156 | if len(err) > 0 { | |
157 | errs[field] = err | |
158 | } | |
159 | } else if reflect.ValueOf(rule).Kind() == reflect.Map { | |
160 | errs[field] = errors.New("The field: '" + field + "' is not a map to dive") | |
161 | } else { | |
162 | err := v.VarCtx(ctx, data[field], rule.(string)) | |
163 | if err != nil { | |
164 | errs[field] = err | |
165 | } | |
166 | } | |
167 | } | |
168 | return errs | |
169 | } | |
170 | ||
171 | // ValidateMap validates map data form a map of tags | |
172 | func (v *Validate) ValidateMap(data map[string]interface{}, rules map[string]interface{}) map[string]interface{} { | |
173 | return v.ValidateMapCtx(context.Background(), data, rules) | |
138 | 174 | } |
139 | 175 | |
140 | 176 | // RegisterTagNameFunc registers a function to get alternate names for StructFields. |
174 | 210 | |
175 | 211 | func (v *Validate) registerValidation(tag string, fn FuncCtx, bakedIn bool, nilCheckable bool) error { |
176 | 212 | if len(tag) == 0 { |
177 | return errors.New("Function Key cannot be empty") | |
213 | return errors.New("function Key cannot be empty") | |
178 | 214 | } |
179 | 215 | |
180 | 216 | if fn == nil { |
181 | return errors.New("Function cannot be empty") | |
217 | return errors.New("function cannot be empty") | |
182 | 218 | } |
183 | 219 | |
184 | 220 | _, ok := restrictedTags[tag] |
408 | 444 | if len(flds) > 0 { |
409 | 445 | |
410 | 446 | vd.misc = append(vd.misc[0:0], name...) |
411 | vd.misc = append(vd.misc, '.') | |
447 | // Don't append empty name for unnamed structs | |
448 | if len(vd.misc) != 0 { | |
449 | vd.misc = append(vd.misc, '.') | |
450 | } | |
412 | 451 | |
413 | 452 | for _, s := range flds { |
414 | 453 |
70 | 70 | Gt string `validate:"gt=10"` |
71 | 71 | Gte string `validate:"gte=10"` |
72 | 72 | OmitEmpty string `validate:"omitempty,min=1,max=10"` |
73 | Boolean string `validate:"boolean"` | |
73 | 74 | Sub *SubTest |
74 | 75 | SubIgnore *SubTest `validate:"-"` |
75 | 76 | Anonymous struct { |
107 | 108 | } |
108 | 109 | |
109 | 110 | func AssertError(t *testing.T, err error, nsKey, structNsKey, field, structField, expectedTag string) { |
110 | ||
111 | 111 | errs := err.(ValidationErrors) |
112 | 112 | |
113 | 113 | found := false |
149 | 149 | } |
150 | 150 | |
151 | 151 | func getError(err error, nsKey, structNsKey string) FieldError { |
152 | ||
153 | 152 | errs := err.(ValidationErrors) |
154 | 153 | |
155 | 154 | var fe FieldError |
169 | 168 | } |
170 | 169 | |
171 | 170 | func (v valuer) Value() (driver.Value, error) { |
172 | ||
173 | 171 | if v.Name == "errorme" { |
174 | 172 | panic("SQL Driver Valuer error: some kind of error") |
175 | 173 | // return nil, errors.New("some kind of error") |
188 | 186 | } |
189 | 187 | |
190 | 188 | func ValidateCustomType(field reflect.Value) interface{} { |
191 | ||
192 | 189 | if cust, ok := field.Interface().(MadeUpCustomType); ok { |
193 | 190 | |
194 | 191 | if len(cust.FirstName) == 0 || len(cust.LastName) == 0 { |
202 | 199 | } |
203 | 200 | |
204 | 201 | func OverrideIntTypeForSomeReason(field reflect.Value) interface{} { |
205 | ||
206 | 202 | if i, ok := field.Interface().(int); ok { |
207 | 203 | if i == 1 { |
208 | 204 | return "1" |
222 | 218 | } |
223 | 219 | |
224 | 220 | func ValidateValuerType(field reflect.Value) interface{} { |
225 | ||
226 | 221 | if valuer, ok := field.Interface().(driver.Valuer); ok { |
227 | 222 | |
228 | 223 | val, err := valuer.Value() |
260 | 255 | } |
261 | 256 | |
262 | 257 | func StructValidationTestStructSuccess(sl StructLevel) { |
263 | ||
264 | 258 | st := sl.Current().Interface().(TestStruct) |
265 | 259 | |
266 | 260 | if st.String != "good value" { |
269 | 263 | } |
270 | 264 | |
271 | 265 | func StructValidationTestStruct(sl StructLevel) { |
272 | ||
273 | 266 | st := sl.Current().Interface().(TestStruct) |
274 | 267 | |
275 | 268 | if st.String != "bad value" { |
278 | 271 | } |
279 | 272 | |
280 | 273 | func StructValidationNoTestStructCustomName(sl StructLevel) { |
281 | ||
282 | 274 | st := sl.Current().Interface().(TestStruct) |
283 | 275 | |
284 | 276 | if st.String != "bad value" { |
287 | 279 | } |
288 | 280 | |
289 | 281 | func StructValidationTestStructInvalid(sl StructLevel) { |
290 | ||
291 | 282 | st := sl.Current().Interface().(TestStruct) |
292 | 283 | |
293 | 284 | if st.String != "bad value" { |
296 | 287 | } |
297 | 288 | |
298 | 289 | func StructValidationTestStructReturnValidationErrors(sl StructLevel) { |
299 | ||
300 | 290 | s := sl.Current().Interface().(TestStructReturnValidationErrors) |
301 | 291 | |
302 | 292 | errs := sl.Validator().Struct(s.Inner1.Inner2) |
308 | 298 | } |
309 | 299 | |
310 | 300 | func StructValidationTestStructReturnValidationErrors2(sl StructLevel) { |
311 | ||
312 | 301 | s := sl.Current().Interface().(TestStructReturnValidationErrors) |
313 | 302 | |
314 | 303 | errs := sl.Validator().Struct(s.Inner1.Inner2) |
336 | 325 | } |
337 | 326 | |
338 | 327 | func StructLevelInvalidError(sl StructLevel) { |
339 | ||
340 | 328 | top := sl.Top().Interface().(StructLevelInvalidErr) |
341 | 329 | s := sl.Current().Interface().(StructLevelInvalidErr) |
342 | 330 | |
358 | 346 | } |
359 | 347 | |
360 | 348 | func TestStructLevelInvalidError(t *testing.T) { |
361 | ||
362 | 349 | validate := New() |
363 | 350 | validate.RegisterStructValidation(StructLevelInvalidError, StructLevelInvalidErr{}) |
364 | 351 | |
382 | 369 | } |
383 | 370 | |
384 | 371 | func TestNameNamespace(t *testing.T) { |
385 | ||
386 | 372 | type Inner2Namespace struct { |
387 | 373 | String []string `validate:"dive,required" json:"JSONString"` |
388 | 374 | } |
431 | 417 | } |
432 | 418 | |
433 | 419 | func TestAnonymous(t *testing.T) { |
434 | ||
435 | 420 | validate := New() |
436 | 421 | validate.RegisterTagNameFunc(func(fld reflect.StructField) string { |
437 | 422 | name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] |
499 | 484 | } |
500 | 485 | |
501 | 486 | func TestAnonymousSameStructDifferentTags(t *testing.T) { |
502 | ||
503 | 487 | validate := New() |
504 | 488 | validate.RegisterTagNameFunc(func(fld reflect.StructField) string { |
505 | 489 | name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] |
544 | 528 | } |
545 | 529 | |
546 | 530 | func TestStructLevelReturnValidationErrors(t *testing.T) { |
547 | ||
548 | 531 | validate := New() |
549 | 532 | validate.RegisterStructValidation(StructValidationTestStructReturnValidationErrors, TestStructReturnValidationErrors{}) |
550 | 533 | |
574 | 557 | } |
575 | 558 | |
576 | 559 | func TestStructLevelReturnValidationErrorsWithJSON(t *testing.T) { |
577 | ||
578 | 560 | validate := New() |
579 | 561 | validate.RegisterTagNameFunc(func(fld reflect.StructField) string { |
580 | 562 | name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] |
631 | 613 | } |
632 | 614 | |
633 | 615 | func TestStructLevelValidations(t *testing.T) { |
634 | ||
635 | 616 | v1 := New() |
636 | 617 | v1.RegisterStructValidation(StructValidationTestStruct, TestStruct{}) |
637 | 618 | |
665 | 646 | } |
666 | 647 | |
667 | 648 | func TestAliasTags(t *testing.T) { |
668 | ||
669 | 649 | validate := New() |
670 | 650 | validate.RegisterAlias("iscoloralias", "hexcolor|rgb|rgba|hsl|hsla") |
671 | 651 | |
713 | 693 | } |
714 | 694 | |
715 | 695 | func TestNilValidator(t *testing.T) { |
716 | ||
717 | 696 | type TestStruct struct { |
718 | 697 | Test string `validate:"required"` |
719 | 698 | } |
723 | 702 | var val *Validate |
724 | 703 | |
725 | 704 | fn := func(fl FieldLevel) bool { |
726 | ||
727 | 705 | return fl.Parent().String() == fl.Field().String() |
728 | 706 | } |
729 | 707 | |
948 | 926 | NotEqual(t, errs, nil) |
949 | 927 | AssertError(t, errs, "TestPartial.Anonymous.SubAnonStruct[0].Test", "TestPartial.Anonymous.SubAnonStruct[0].Test", "Test", "Test", "required") |
950 | 928 | |
929 | // Test for unnamed struct | |
930 | testStruct := &TestStruct{ | |
931 | String: "test", | |
932 | } | |
933 | unnamedStruct := struct { | |
934 | String string `validate:"required" json:"StringVal"` | |
935 | }{String: "test"} | |
936 | composedUnnamedStruct := struct{ *TestStruct }{&TestStruct{String: "test"}} | |
937 | ||
938 | errs = validate.StructPartial(testStruct, "String") | |
939 | Equal(t, errs, nil) | |
940 | ||
941 | errs = validate.StructPartial(unnamedStruct, "String") | |
942 | Equal(t, errs, nil) | |
943 | ||
944 | errs = validate.StructPartial(composedUnnamedStruct, "TestStruct.String") | |
945 | Equal(t, errs, nil) | |
946 | ||
947 | testStruct.String = "" | |
948 | errs = validate.StructPartial(testStruct, "String") | |
949 | NotEqual(t, errs, nil) | |
950 | AssertError(t, errs, "TestStruct.String", "TestStruct.String", "String", "String", "required") | |
951 | ||
952 | unnamedStruct.String = "" | |
953 | errs = validate.StructPartial(unnamedStruct, "String") | |
954 | NotEqual(t, errs, nil) | |
955 | AssertError(t, errs, "String", "String", "String", "String", "required") | |
956 | ||
957 | composedUnnamedStruct.String = "" | |
958 | errs = validate.StructPartial(composedUnnamedStruct, "TestStruct.String") | |
959 | NotEqual(t, errs, nil) | |
960 | AssertError(t, errs, "TestStruct.String", "TestStruct.String", "String", "String", "required") | |
951 | 961 | } |
952 | 962 | |
953 | 963 | func TestCrossStructLteFieldValidation(t *testing.T) { |
1637 | 1647 | i := 1 |
1638 | 1648 | j = 1 |
1639 | 1649 | k = 1.543 |
1650 | b := true | |
1640 | 1651 | arr := []string{"test"} |
1641 | 1652 | |
1642 | 1653 | s2 := "abcd" |
1643 | 1654 | i2 := 1 |
1644 | 1655 | j2 = 1 |
1645 | 1656 | k2 = 1.543 |
1657 | b2 := true | |
1646 | 1658 | arr2 := []string{"test"} |
1647 | 1659 | arr3 := []string{"test", "test2"} |
1648 | 1660 | now2 := now |
1663 | 1675 | NotEqual(t, errs, nil) |
1664 | 1676 | AssertError(t, errs, "", "", "", "", "necsfield") |
1665 | 1677 | |
1678 | errs = validate.VarWithValue(b2, b, "necsfield") | |
1679 | NotEqual(t, errs, nil) | |
1680 | AssertError(t, errs, "", "", "", "", "necsfield") | |
1681 | ||
1666 | 1682 | errs = validate.VarWithValue(arr2, arr, "necsfield") |
1667 | 1683 | NotEqual(t, errs, nil) |
1668 | 1684 | AssertError(t, errs, "", "", "", "", "necsfield") |
1788 | 1804 | errs = validate.Struct(test) |
1789 | 1805 | Equal(t, errs, nil) |
1790 | 1806 | |
1791 | newTime := time.Now().UTC() | |
1807 | newTime := time.Now().Add(time.Hour).UTC() | |
1792 | 1808 | test.CreatedAt = &newTime |
1793 | 1809 | |
1794 | 1810 | errs = validate.Struct(test) |
1801 | 1817 | i := 1 |
1802 | 1818 | j = 1 |
1803 | 1819 | k = 1.543 |
1820 | b := true | |
1804 | 1821 | arr := []string{"test"} |
1805 | 1822 | |
1806 | 1823 | var j2 uint64 |
1809 | 1826 | i2 := 1 |
1810 | 1827 | j2 = 1 |
1811 | 1828 | k2 = 1.543 |
1829 | b2 := true | |
1812 | 1830 | arr2 := []string{"test"} |
1813 | 1831 | arr3 := []string{"test", "test2"} |
1814 | 1832 | now2 := now |
1825 | 1843 | errs = validate.VarWithValue(k2, k, "eqcsfield") |
1826 | 1844 | Equal(t, errs, nil) |
1827 | 1845 | |
1846 | errs = validate.VarWithValue(b2, b, "eqcsfield") | |
1847 | Equal(t, errs, nil) | |
1848 | ||
1828 | 1849 | errs = validate.VarWithValue(arr2, arr, "eqcsfield") |
1829 | 1850 | Equal(t, errs, nil) |
1830 | 1851 | |
1927 | 1948 | } |
1928 | 1949 | |
1929 | 1950 | func TestCrossNamespaceFieldValidation(t *testing.T) { |
1930 | ||
1931 | 1951 | type SliceStruct struct { |
1932 | 1952 | Name string |
1933 | 1953 | } |
2165 | 2185 | } |
2166 | 2186 | |
2167 | 2187 | func TestExistsValidation(t *testing.T) { |
2168 | ||
2169 | 2188 | jsonText := "{ \"truthiness2\": true }" |
2170 | 2189 | |
2171 | 2190 | type Thing struct { |
2196 | 2215 | } |
2197 | 2216 | |
2198 | 2217 | func TestSQLValue2Validation(t *testing.T) { |
2199 | ||
2200 | 2218 | validate := New() |
2201 | 2219 | validate.RegisterCustomTypeFunc(ValidateValuerType, valuer{}, (*driver.Valuer)(nil), sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{}) |
2202 | 2220 | validate.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{}) |
2247 | 2265 | } |
2248 | 2266 | |
2249 | 2267 | func TestSQLValueValidation(t *testing.T) { |
2250 | ||
2251 | 2268 | validate := New() |
2252 | 2269 | validate.RegisterCustomTypeFunc(ValidateValuerType, (*driver.Valuer)(nil), valuer{}) |
2253 | 2270 | validate.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{}) |
2925 | 2942 | } |
2926 | 2943 | |
2927 | 2944 | func TestSliceMapArrayChanFuncPtrInterfaceRequiredValidation(t *testing.T) { |
2928 | ||
2929 | 2945 | validate := New() |
2930 | 2946 | |
2931 | 2947 | var m map[string]string |
3003 | 3019 | } |
3004 | 3020 | |
3005 | 3021 | func TestDatePtrValidationIssueValidation(t *testing.T) { |
3006 | ||
3007 | 3022 | type Test struct { |
3008 | 3023 | LastViewed *time.Time |
3009 | 3024 | Reminder *time.Time |
3055 | 3070 | } |
3056 | 3071 | |
3057 | 3072 | func TestInterfaceErrValidation(t *testing.T) { |
3058 | ||
3059 | 3073 | var v2 interface{} = 1 |
3060 | 3074 | var v1 interface{} = v2 |
3061 | 3075 | |
3229 | 3243 | } |
3230 | 3244 | |
3231 | 3245 | func TestMapDiveValidation(t *testing.T) { |
3232 | ||
3233 | 3246 | validate := New() |
3234 | 3247 | |
3235 | 3248 | n := map[int]interface{}{0: nil} |
3270 | 3283 | // for full test coverage |
3271 | 3284 | s := fmt.Sprint(errs.Error()) |
3272 | 3285 | NotEqual(t, s, "") |
3286 | ||
3287 | type TestMapInterface struct { | |
3288 | Errs map[int]interface{} `validate:"dive"` | |
3289 | } | |
3290 | ||
3291 | mit := map[int]interface{}{0: Inner{"ok"}, 1: Inner{""}, 3: nil, 5: "string", 6: 33} | |
3292 | ||
3293 | msi := &TestMapInterface{ | |
3294 | Errs: mit, | |
3295 | } | |
3296 | ||
3297 | errs = validate.Struct(msi) | |
3298 | NotEqual(t, errs, nil) | |
3299 | Equal(t, len(errs.(ValidationErrors)), 1) | |
3300 | AssertError(t, errs, "TestMapInterface.Errs[1].Name", "TestMapInterface.Errs[1].Name", "Name", "Name", "required") | |
3273 | 3301 | |
3274 | 3302 | type TestMapTimeStruct struct { |
3275 | 3303 | Errs map[int]*time.Time `validate:"gt=0,dive,required"` |
3352 | 3380 | } |
3353 | 3381 | |
3354 | 3382 | func TestArrayDiveValidation(t *testing.T) { |
3355 | ||
3356 | 3383 | validate := New() |
3357 | 3384 | |
3358 | 3385 | arr := []string{"ok", "", "ok"} |
4241 | 4268 | } |
4242 | 4269 | } |
4243 | 4270 | |
4271 | func TestULIDValidation(t *testing.T) { | |
4272 | tests := []struct { | |
4273 | param string | |
4274 | expected bool | |
4275 | }{ | |
4276 | {"", false}, | |
4277 | {"01BX5ZZKBKACT-V9WEVGEMMVRZ", false}, | |
4278 | {"01bx5zzkbkactav9wevgemmvrz", false}, | |
4279 | {"a987Fbc9-4bed-3078-cf07-9141ba07c9f3xxx", false}, | |
4280 | {"01BX5ZZKBKACTAV9WEVGEMMVRZABC", false}, | |
4281 | {"01BX5ZZKBKACTAV9WEVGEMMVRZABC", false}, | |
4282 | {"0IBX5ZZKBKACTAV9WEVGEMMVRZ", false}, | |
4283 | {"O1BX5ZZKBKACTAV9WEVGEMMVRZ", false}, | |
4284 | {"01BX5ZZKBKACTAVLWEVGEMMVRZ", false}, | |
4285 | {"01BX5ZZKBKACTAV9WEVGEMMVRZ", true}, | |
4286 | } | |
4287 | ||
4288 | validate := New() | |
4289 | ||
4290 | for i, test := range tests { | |
4291 | ||
4292 | errs := validate.Var(test.param, "ulid") | |
4293 | ||
4294 | if test.expected { | |
4295 | if !IsEqual(errs, nil) { | |
4296 | t.Fatalf("Index: %d ULID failed Error: %s", i, errs) | |
4297 | } | |
4298 | } else { | |
4299 | if IsEqual(errs, nil) { | |
4300 | t.Fatalf("Index: %d ULID failed Error: %s", i, errs) | |
4301 | } else { | |
4302 | val := getError(errs, "", "") | |
4303 | if val.Tag() != "ulid" { | |
4304 | t.Fatalf("Index: %d ULID failed Error: %s", i, errs) | |
4305 | } | |
4306 | } | |
4307 | } | |
4308 | } | |
4309 | } | |
4310 | ||
4244 | 4311 | func TestISBNValidation(t *testing.T) { |
4245 | 4312 | tests := []struct { |
4246 | 4313 | param string |
4361 | 4428 | } |
4362 | 4429 | |
4363 | 4430 | func TestExcludesRuneValidation(t *testing.T) { |
4364 | ||
4365 | 4431 | tests := []struct { |
4366 | 4432 | Value string `validate:"excludesrune=☻"` |
4367 | 4433 | Tag string |
4389 | 4455 | } |
4390 | 4456 | |
4391 | 4457 | func TestExcludesAllValidation(t *testing.T) { |
4392 | ||
4393 | 4458 | tests := []struct { |
4394 | 4459 | Value string `validate:"excludesall=@!{}[]"` |
4395 | 4460 | Tag string |
4435 | 4500 | } |
4436 | 4501 | |
4437 | 4502 | func TestExcludesValidation(t *testing.T) { |
4438 | ||
4439 | 4503 | tests := []struct { |
4440 | 4504 | Value string `validate:"excludes=@"` |
4441 | 4505 | Tag string |
4463 | 4527 | } |
4464 | 4528 | |
4465 | 4529 | func TestContainsRuneValidation(t *testing.T) { |
4466 | ||
4467 | 4530 | tests := []struct { |
4468 | 4531 | Value string `validate:"containsrune=☻"` |
4469 | 4532 | Tag string |
4491 | 4554 | } |
4492 | 4555 | |
4493 | 4556 | func TestContainsAnyValidation(t *testing.T) { |
4494 | ||
4495 | 4557 | tests := []struct { |
4496 | 4558 | Value string `validate:"containsany=@!{}[]"` |
4497 | 4559 | Tag string |
4519 | 4581 | } |
4520 | 4582 | |
4521 | 4583 | func TestContainsValidation(t *testing.T) { |
4522 | ||
4523 | 4584 | tests := []struct { |
4524 | 4585 | Value string `validate:"contains=@"` |
4525 | 4586 | Tag string |
4556 | 4617 | i := 1 |
4557 | 4618 | j = 1 |
4558 | 4619 | k = 1.543 |
4620 | b := true | |
4559 | 4621 | arr := []string{"test"} |
4560 | 4622 | now := time.Now().UTC() |
4561 | 4623 | |
4565 | 4627 | i2 := 3 |
4566 | 4628 | j2 = 2 |
4567 | 4629 | k2 = 1.5434456 |
4630 | b2 := false | |
4568 | 4631 | arr2 := []string{"test", "test2"} |
4569 | 4632 | arr3 := []string{"test"} |
4570 | 4633 | now2 := now |
4581 | 4644 | errs = validate.VarWithValue(k2, k, "nefield") |
4582 | 4645 | Equal(t, errs, nil) |
4583 | 4646 | |
4647 | errs = validate.VarWithValue(b2, b, "nefield") | |
4648 | Equal(t, errs, nil) | |
4649 | ||
4584 | 4650 | errs = validate.VarWithValue(arr2, arr, "nefield") |
4585 | 4651 | Equal(t, errs, nil) |
4586 | 4652 | |
4606 | 4672 | NotEqual(t, errs, nil) |
4607 | 4673 | AssertError(t, errs, "Test.Start", "Test.Start", "Start", "Start", "nefield") |
4608 | 4674 | |
4609 | now3 := time.Now().UTC() | |
4675 | now3 := time.Now().Add(time.Hour).UTC() | |
4610 | 4676 | |
4611 | 4677 | sv = &Test{ |
4612 | 4678 | Start: &now, |
4791 | 4857 | i := 1 |
4792 | 4858 | j = 1 |
4793 | 4859 | k = 1.543 |
4860 | b := true | |
4794 | 4861 | arr := []string{"test"} |
4795 | 4862 | now := time.Now().UTC() |
4796 | 4863 | |
4800 | 4867 | i2 := 1 |
4801 | 4868 | j2 = 1 |
4802 | 4869 | k2 = 1.543 |
4870 | b2 := true | |
4803 | 4871 | arr2 := []string{"test"} |
4804 | 4872 | arr3 := []string{"test", "test2"} |
4805 | 4873 | now2 := now |
4816 | 4884 | errs = validate.VarWithValue(k2, k, "eqfield") |
4817 | 4885 | Equal(t, errs, nil) |
4818 | 4886 | |
4887 | errs = validate.VarWithValue(b2, b, "eqfield") | |
4888 | Equal(t, errs, nil) | |
4889 | ||
4819 | 4890 | errs = validate.VarWithValue(arr2, arr, "eqfield") |
4820 | 4891 | Equal(t, errs, nil) |
4821 | 4892 | |
4839 | 4910 | errs = validate.Struct(sv) |
4840 | 4911 | Equal(t, errs, nil) |
4841 | 4912 | |
4842 | now3 := time.Now().UTC() | |
4913 | now3 := time.Now().Add(time.Hour).UTC() | |
4843 | 4914 | |
4844 | 4915 | sv = &Test{ |
4845 | 4916 | Start: &now, |
5095 | 5166 | } |
5096 | 5167 | |
5097 | 5168 | func TestBase64Validation(t *testing.T) { |
5098 | ||
5099 | 5169 | validate := New() |
5100 | 5170 | |
5101 | 5171 | s := "dW5pY29ybg==" |
5199 | 5269 | } |
5200 | 5270 | |
5201 | 5271 | func TestEthereumAddressValidation(t *testing.T) { |
5202 | ||
5203 | 5272 | validate := New() |
5204 | 5273 | |
5205 | 5274 | tests := []struct { |
5253 | 5322 | } |
5254 | 5323 | |
5255 | 5324 | func TestBitcoinAddressValidation(t *testing.T) { |
5256 | ||
5257 | 5325 | validate := New() |
5258 | 5326 | |
5259 | 5327 | tests := []struct { |
5363 | 5431 | } |
5364 | 5432 | |
5365 | 5433 | func TestBitcoinBech32AddressValidation(t *testing.T) { |
5366 | ||
5367 | 5434 | validate := New() |
5368 | 5435 | |
5369 | 5436 | tests := []struct { |
5414 | 5481 | } |
5415 | 5482 | |
5416 | 5483 | func TestNoStructLevelValidation(t *testing.T) { |
5417 | ||
5418 | 5484 | type Inner struct { |
5419 | 5485 | Test string `validate:"len=5"` |
5420 | 5486 | } |
5446 | 5512 | } |
5447 | 5513 | |
5448 | 5514 | func TestStructOnlyValidation(t *testing.T) { |
5449 | ||
5450 | 5515 | type Inner struct { |
5451 | 5516 | Test string `validate:"len=5"` |
5452 | 5517 | } |
6512 | 6577 | Equal(t, errs, nil) |
6513 | 6578 | |
6514 | 6579 | fn := func(fl FieldLevel) bool { |
6515 | ||
6516 | 6580 | return fl.Parent().String() == fl.Field().String() |
6517 | 6581 | } |
6518 | 6582 | |
6530 | 6594 | } |
6531 | 6595 | |
6532 | 6596 | func TestAddFunctions(t *testing.T) { |
6533 | ||
6534 | 6597 | fn := func(fl FieldLevel) bool { |
6535 | ||
6536 | 6598 | return true |
6537 | 6599 | } |
6538 | 6600 | |
6561 | 6623 | } |
6562 | 6624 | |
6563 | 6625 | func TestChangeTag(t *testing.T) { |
6564 | ||
6565 | 6626 | validate := New() |
6566 | 6627 | validate.SetTagName("val") |
6567 | 6628 | |
7208 | 7269 | } |
7209 | 7270 | |
7210 | 7271 | func TestUrnRFC2141(t *testing.T) { |
7211 | ||
7212 | var tests = []struct { | |
7272 | tests := []struct { | |
7213 | 7273 | param string |
7214 | 7274 | expected bool |
7215 | 7275 | }{ |
7285 | 7345 | } |
7286 | 7346 | |
7287 | 7347 | func TestUrl(t *testing.T) { |
7288 | ||
7289 | var tests = []struct { | |
7348 | tests := []struct { | |
7290 | 7349 | param string |
7291 | 7350 | expected bool |
7292 | 7351 | }{ |
7353 | 7412 | } |
7354 | 7413 | |
7355 | 7414 | func TestUri(t *testing.T) { |
7356 | ||
7357 | var tests = []struct { | |
7415 | tests := []struct { | |
7358 | 7416 | param string |
7359 | 7417 | expected bool |
7360 | 7418 | }{ |
7420 | 7478 | } |
7421 | 7479 | |
7422 | 7480 | func TestOrTag(t *testing.T) { |
7423 | ||
7424 | 7481 | validate := New() |
7425 | 7482 | |
7426 | 7483 | s := "rgba(0,31,255,0.5)" |
7450 | 7507 | Equal(t, errs, nil) |
7451 | 7508 | |
7452 | 7509 | s = "green" |
7453 | errs = validate.Var(s, "eq=|eq=blue,rgb|rgba") //should fail on first validation block | |
7510 | errs = validate.Var(s, "eq=|eq=blue,rgb|rgba") // should fail on first validation block | |
7454 | 7511 | NotEqual(t, errs, nil) |
7455 | 7512 | ve := errs.(ValidationErrors) |
7456 | 7513 | Equal(t, len(ve), 1) |
7463 | 7520 | |
7464 | 7521 | v2 := New() |
7465 | 7522 | v2.RegisterTagNameFunc(func(fld reflect.StructField) string { |
7466 | ||
7467 | 7523 | name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] |
7468 | 7524 | |
7469 | 7525 | if name == "-" { |
7488 | 7544 | } |
7489 | 7545 | |
7490 | 7546 | func TestHsla(t *testing.T) { |
7491 | ||
7492 | 7547 | validate := New() |
7493 | 7548 | |
7494 | 7549 | s := "hsla(360,100%,100%,1)" |
7535 | 7590 | } |
7536 | 7591 | |
7537 | 7592 | func TestHsl(t *testing.T) { |
7538 | ||
7539 | 7593 | validate := New() |
7540 | 7594 | |
7541 | 7595 | s := "hsl(360,100%,50%)" |
7573 | 7627 | } |
7574 | 7628 | |
7575 | 7629 | func TestRgba(t *testing.T) { |
7576 | ||
7577 | 7630 | validate := New() |
7578 | 7631 | |
7579 | 7632 | s := "rgba(0,31,255,0.5)" |
7619 | 7672 | } |
7620 | 7673 | |
7621 | 7674 | func TestRgb(t *testing.T) { |
7622 | ||
7623 | 7675 | validate := New() |
7624 | 7676 | |
7625 | 7677 | s := "rgb(0,31,255)" |
7661 | 7713 | } |
7662 | 7714 | |
7663 | 7715 | func TestEmail(t *testing.T) { |
7664 | ||
7665 | 7716 | validate := New() |
7666 | 7717 | |
7667 | 7718 | s := "test@mail.com" |
7729 | 7780 | } |
7730 | 7781 | |
7731 | 7782 | func TestHexColor(t *testing.T) { |
7732 | ||
7733 | 7783 | validate := New() |
7734 | 7784 | |
7735 | 7785 | s := "#fff" |
7757 | 7807 | } |
7758 | 7808 | |
7759 | 7809 | func TestHexadecimal(t *testing.T) { |
7760 | ||
7761 | 7810 | validate := New() |
7762 | 7811 | |
7763 | 7812 | s := "ff0044" |
7784 | 7833 | } |
7785 | 7834 | |
7786 | 7835 | func TestNumber(t *testing.T) { |
7787 | ||
7788 | 7836 | validate := New() |
7789 | 7837 | |
7790 | 7838 | s := "1" |
7832 | 7880 | } |
7833 | 7881 | |
7834 | 7882 | func TestNumeric(t *testing.T) { |
7835 | ||
7836 | 7883 | validate := New() |
7837 | 7884 | |
7838 | 7885 | s := "1" |
7875 | 7922 | } |
7876 | 7923 | |
7877 | 7924 | func TestAlphaNumeric(t *testing.T) { |
7878 | ||
7879 | 7925 | validate := New() |
7880 | 7926 | |
7881 | 7927 | s := "abcd123" |
7893 | 7939 | } |
7894 | 7940 | |
7895 | 7941 | func TestAlpha(t *testing.T) { |
7896 | ||
7897 | 7942 | validate := New() |
7898 | 7943 | |
7899 | 7944 | s := "abcd" |
7923 | 7968 | errs = validate.Var(1, "alpha") |
7924 | 7969 | NotEqual(t, errs, nil) |
7925 | 7970 | AssertError(t, errs, "", "", "", "", "alpha") |
7926 | ||
7927 | 7971 | } |
7928 | 7972 | |
7929 | 7973 | func TestStructStringValidation(t *testing.T) { |
7930 | ||
7931 | 7974 | validate := New() |
7932 | 7975 | |
7933 | 7976 | tSuccess := &TestString{ |
7940 | 7983 | Lte: "0123456789", |
7941 | 7984 | Gt: "01234567890", |
7942 | 7985 | Gte: "0123456789", |
7986 | Boolean: "true", | |
7943 | 7987 | OmitEmpty: "", |
7944 | 7988 | Sub: &SubTest{ |
7945 | 7989 | Test: "1", |
7971 | 8015 | Gt: "1", |
7972 | 8016 | Gte: "1", |
7973 | 8017 | OmitEmpty: "12345678901", |
8018 | Boolean: "nope", | |
7974 | 8019 | Sub: &SubTest{ |
7975 | 8020 | Test: "", |
7976 | 8021 | }, |
7988 | 8033 | |
7989 | 8034 | // Assert Top Level |
7990 | 8035 | NotEqual(t, errs, nil) |
7991 | Equal(t, len(errs.(ValidationErrors)), 13) | |
8036 | Equal(t, len(errs.(ValidationErrors)), 14) | |
7992 | 8037 | |
7993 | 8038 | // Assert Fields |
7994 | 8039 | AssertError(t, errs, "TestString.Required", "TestString.Required", "Required", "Required", "required") |
8001 | 8046 | AssertError(t, errs, "TestString.Gt", "TestString.Gt", "Gt", "Gt", "gt") |
8002 | 8047 | AssertError(t, errs, "TestString.Gte", "TestString.Gte", "Gte", "Gte", "gte") |
8003 | 8048 | AssertError(t, errs, "TestString.OmitEmpty", "TestString.OmitEmpty", "OmitEmpty", "OmitEmpty", "max") |
8049 | AssertError(t, errs, "TestString.Boolean", "TestString.Boolean", "Boolean", "Boolean", "boolean") | |
8004 | 8050 | |
8005 | 8051 | // Nested Struct Field Errs |
8006 | 8052 | AssertError(t, errs, "TestString.Anonymous.A", "TestString.Anonymous.A", "A", "A", "required") |
8009 | 8055 | } |
8010 | 8056 | |
8011 | 8057 | func TestStructInt32Validation(t *testing.T) { |
8012 | ||
8013 | 8058 | type TestInt32 struct { |
8014 | 8059 | Required int `validate:"required"` |
8015 | 8060 | Len int `validate:"len=10"` |
8073 | 8118 | } |
8074 | 8119 | |
8075 | 8120 | func TestStructUint64Validation(t *testing.T) { |
8076 | ||
8077 | 8121 | validate := New() |
8078 | 8122 | |
8079 | 8123 | tSuccess := &TestUint64{ |
8113 | 8157 | } |
8114 | 8158 | |
8115 | 8159 | func TestStructFloat64Validation(t *testing.T) { |
8116 | ||
8117 | 8160 | validate := New() |
8118 | 8161 | |
8119 | 8162 | tSuccess := &TestFloat64{ |
8153 | 8196 | } |
8154 | 8197 | |
8155 | 8198 | func TestStructSliceValidation(t *testing.T) { |
8156 | ||
8157 | 8199 | validate := New() |
8158 | 8200 | |
8159 | 8201 | tSuccess := &TestSlice{ |
8203 | 8245 | |
8204 | 8246 | _, ok := fe.Value().([]int) |
8205 | 8247 | Equal(t, ok, true) |
8206 | ||
8207 | 8248 | } |
8208 | 8249 | |
8209 | 8250 | func TestInvalidStruct(t *testing.T) { |
8210 | ||
8211 | 8251 | validate := New() |
8212 | 8252 | |
8213 | 8253 | s := &SubTest{ |
8232 | 8272 | } |
8233 | 8273 | |
8234 | 8274 | func TestInvalidValidatorFunction(t *testing.T) { |
8235 | ||
8236 | 8275 | validate := New() |
8237 | 8276 | |
8238 | 8277 | s := &SubTest{ |
8243 | 8282 | } |
8244 | 8283 | |
8245 | 8284 | func TestCustomFieldName(t *testing.T) { |
8246 | ||
8247 | 8285 | validate := New() |
8248 | 8286 | validate.RegisterTagNameFunc(func(fld reflect.StructField) string { |
8249 | 8287 | name := strings.SplitN(fld.Tag.Get("schema"), ",", 2)[0] |
8287 | 8325 | } |
8288 | 8326 | |
8289 | 8327 | func TestMutipleRecursiveExtractStructCache(t *testing.T) { |
8290 | ||
8291 | 8328 | validate := New() |
8292 | 8329 | |
8293 | 8330 | type Recursive struct { |
8304 | 8341 | ptr := fmt.Sprintf("%p", sc) |
8305 | 8342 | |
8306 | 8343 | for i := 0; i < 100; i++ { |
8307 | ||
8308 | 8344 | go func() { |
8309 | 8345 | <-proceed |
8310 | 8346 | sc := validate.extractStructCache(current, name) |
8317 | 8353 | |
8318 | 8354 | // Thanks @robbrockbank, see https://github.com/go-playground/validator/issues/249 |
8319 | 8355 | func TestPointerAndOmitEmpty(t *testing.T) { |
8320 | ||
8321 | 8356 | validate := New() |
8322 | 8357 | |
8323 | 8358 | type Test struct { |
8363 | 8398 | } |
8364 | 8399 | |
8365 | 8400 | func TestRequired(t *testing.T) { |
8366 | ||
8367 | 8401 | validate := New() |
8368 | 8402 | validate.RegisterTagNameFunc(func(fld reflect.StructField) string { |
8369 | 8403 | name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] |
8387 | 8421 | } |
8388 | 8422 | |
8389 | 8423 | func TestBoolEqual(t *testing.T) { |
8390 | ||
8391 | 8424 | validate := New() |
8392 | 8425 | |
8393 | 8426 | type Test struct { |
8415 | 8448 | validate := New() |
8416 | 8449 | err := validate.RegisterTranslation("required", trans, |
8417 | 8450 | func(ut ut.Translator) (err error) { |
8418 | ||
8419 | 8451 | // using this stype because multiple translation may have to be added for the full translation |
8420 | 8452 | if err = ut.Add("required", "{0} is a required field", false); err != nil { |
8421 | 8453 | return |
8422 | 8454 | } |
8423 | 8455 | |
8424 | 8456 | return |
8425 | ||
8426 | 8457 | }, func(ut ut.Translator, fe FieldError) string { |
8427 | ||
8428 | 8458 | t, err := ut.T(fe.Tag(), fe.Field()) |
8429 | 8459 | if err != nil { |
8430 | 8460 | fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError)) |
8437 | 8467 | |
8438 | 8468 | err = validate.RegisterTranslation("required", fr, |
8439 | 8469 | func(ut ut.Translator) (err error) { |
8440 | ||
8441 | 8470 | // using this stype because multiple translation may have to be added for the full translation |
8442 | 8471 | if err = ut.Add("required", "{0} est un champ obligatoire", false); err != nil { |
8443 | 8472 | return |
8444 | 8473 | } |
8445 | 8474 | |
8446 | 8475 | return |
8447 | ||
8448 | 8476 | }, func(ut ut.Translator, fe FieldError) string { |
8449 | ||
8450 | 8477 | t, transErr := ut.T(fe.Tag(), fe.Field()) |
8451 | 8478 | if transErr != nil { |
8452 | 8479 | fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError)) |
8524 | 8551 | validate := New() |
8525 | 8552 | err = validate.RegisterTranslation("required", trans, |
8526 | 8553 | func(ut ut.Translator) (err error) { |
8527 | ||
8528 | 8554 | // using this stype because multiple translation may have to be added for the full translation |
8529 | 8555 | if err = ut.Add("required", "{0} is a required field", false); err != nil { |
8530 | 8556 | return |
8531 | 8557 | } |
8532 | 8558 | |
8533 | 8559 | return |
8534 | ||
8535 | 8560 | }, func(ut ut.Translator, fe FieldError) string { |
8536 | ||
8537 | 8561 | t, err := ut.T(fe.Tag(), fe.Field()) |
8538 | 8562 | if err != nil { |
8539 | 8563 | fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError)) |
8548 | 8572 | } |
8549 | 8573 | |
8550 | 8574 | func TestStructFiltered(t *testing.T) { |
8551 | ||
8552 | 8575 | p1 := func(ns []byte) bool { |
8553 | 8576 | if bytes.HasSuffix(ns, []byte("NoTag")) || bytes.HasSuffix(ns, []byte("Required")) { |
8554 | 8577 | return false |
8714 | 8737 | } |
8715 | 8738 | |
8716 | 8739 | func TestRequiredPtr(t *testing.T) { |
8717 | ||
8718 | 8740 | type Test struct { |
8719 | 8741 | Bool *bool `validate:"required"` |
8720 | 8742 | } |
8848 | 8870 | } |
8849 | 8871 | |
8850 | 8872 | func TestAlphanumericUnicodeValidation(t *testing.T) { |
8851 | ||
8852 | 8873 | tests := []struct { |
8853 | 8874 | param string |
8854 | 8875 | expected bool |
8891 | 8912 | } |
8892 | 8913 | |
8893 | 8914 | func TestArrayStructNamespace(t *testing.T) { |
8894 | ||
8895 | 8915 | validate := New() |
8896 | 8916 | validate.RegisterTagNameFunc(func(fld reflect.StructField) string { |
8897 | 8917 | name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] |
8920 | 8940 | } |
8921 | 8941 | |
8922 | 8942 | func TestMapStructNamespace(t *testing.T) { |
8923 | ||
8924 | 8943 | validate := New() |
8925 | 8944 | validate.RegisterTagNameFunc(func(fld reflect.StructField) string { |
8926 | 8945 | name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] |
9575 | 9594 | {"a%b", false}, |
9576 | 9595 | {"1%2", false}, |
9577 | 9596 | {"%%a%%", false}, |
9597 | {"hello", true}, | |
9598 | {"", true}, | |
9599 | {"+", true}, | |
9578 | 9600 | } |
9579 | 9601 | |
9580 | 9602 | validate := New() |
9601 | 9623 | } |
9602 | 9624 | |
9603 | 9625 | func TestKeys(t *testing.T) { |
9604 | ||
9605 | 9626 | type Test struct { |
9606 | 9627 | Test1 map[string]string `validate:"gt=0,dive,keys,eq=testkey,endkeys,eq=testval" json:"test1"` |
9607 | 9628 | Test2 map[int]int `validate:"gt=0,dive,keys,eq=3,endkeys,eq=4" json:"test2"` |
9660 | 9681 | AssertError(t, err.(ValidationErrors), "Test2.NestedKeys", "Test2.NestedKeys", "NestedKeys", "NestedKeys", "gt") |
9661 | 9682 | |
9662 | 9683 | tst2.NestedKeys = map[[1]string]string{ |
9663 | [1]string{"innertestkey"}: "outertestval", | |
9684 | {"innertestkey"}: "outertestval", | |
9664 | 9685 | } |
9665 | 9686 | |
9666 | 9687 | err = validate.Struct(tst2) |
9770 | 9791 | } |
9771 | 9792 | |
9772 | 9793 | func TestKeyOrs(t *testing.T) { |
9773 | ||
9774 | 9794 | type Test struct { |
9775 | 9795 | Test1 map[string]string `validate:"gt=0,dive,keys,eq=testkey|eq=testkeyok,endkeys,eq=testval" json:"test1"` |
9776 | 9796 | } |
10027 | 10047 | Field6 uint `validate:"required_unless=Field5 2" json:"field_6"` |
10028 | 10048 | Field7 float32 `validate:"required_unless=Field6 0" json:"field_7"` |
10029 | 10049 | Field8 float64 `validate:"required_unless=Field7 0.0" json:"field_8"` |
10050 | Field9 bool `validate:"omitempty" json:"field_9"` | |
10051 | Field10 string `validate:"required_unless=Field9 true" json:"field_10"` | |
10030 | 10052 | }{ |
10031 | 10053 | FieldE: "test", |
10032 | 10054 | Field2: &fieldVal, |
10033 | 10055 | Field3: map[string]string{"key": "val"}, |
10034 | 10056 | Field4: "test", |
10035 | 10057 | Field5: 2, |
10058 | Field9: true, | |
10036 | 10059 | } |
10037 | 10060 | |
10038 | 10061 | validate := New() |
10052 | 10075 | Field5 string `validate:"required_unless=Field3 0" json:"field_5"` |
10053 | 10076 | Field6 string `validate:"required_unless=Inner.Field test" json:"field_6"` |
10054 | 10077 | Field7 string `validate:"required_unless=Inner2.Field test" json:"field_7"` |
10078 | Field8 bool `validate:"omitempty" json:"field_8"` | |
10079 | Field9 string `validate:"required_unless=Field8 true" json:"field_9"` | |
10055 | 10080 | }{ |
10056 | 10081 | Inner: &Inner{Field: &fieldVal}, |
10057 | 10082 | FieldE: "test", |
10062 | 10087 | NotEqual(t, errs, nil) |
10063 | 10088 | |
10064 | 10089 | ve := errs.(ValidationErrors) |
10065 | Equal(t, len(ve), 3) | |
10090 | Equal(t, len(ve), 4) | |
10066 | 10091 | AssertError(t, errs, "Field3", "Field3", "Field3", "Field3", "required_unless") |
10067 | 10092 | AssertError(t, errs, "Field4", "Field4", "Field4", "Field4", "required_unless") |
10068 | 10093 | AssertError(t, errs, "Field7", "Field7", "Field7", "Field7", "required_unless") |
10094 | AssertError(t, errs, "Field9", "Field9", "Field9", "Field9", "required_unless") | |
10069 | 10095 | |
10070 | 10096 | defer func() { |
10071 | 10097 | if r := recover(); r == nil { |
10201 | 10227 | name := fmt.Sprintf("Field%d", i) |
10202 | 10228 | AssertError(t, errs, name, name, name, name, "excluded_with") |
10203 | 10229 | } |
10230 | ||
10231 | test3 := struct { | |
10232 | Inner *Inner | |
10233 | Inner2 *Inner | |
10234 | Field string `validate:"omitempty" json:"field"` | |
10235 | FieldE string `validate:"omitempty" json:"field_e"` | |
10236 | Field1 string `validate:"excluded_with=FieldE" json:"field_1"` | |
10237 | Field2 *string `validate:"excluded_with=FieldE" json:"field_2"` | |
10238 | Field3 map[string]string `validate:"excluded_with=FieldE" json:"field_3"` | |
10239 | Field4 interface{} `validate:"excluded_with=FieldE" json:"field_4"` | |
10240 | Field5 string `validate:"excluded_with=Inner.FieldE" json:"field_5"` | |
10241 | Field6 string `validate:"excluded_with=Inner2.FieldE" json:"field_6"` | |
10242 | }{ | |
10243 | Inner: &Inner{FieldE: "populated"}, | |
10244 | Inner2: &Inner{FieldE: "populated"}, | |
10245 | FieldE: "populated", | |
10246 | } | |
10247 | ||
10248 | validate = New() | |
10249 | ||
10250 | errs = validate.Struct(test3) | |
10251 | Equal(t, errs, nil) | |
10204 | 10252 | } |
10205 | 10253 | |
10206 | 10254 | func TestExcludedWithout(t *testing.T) { |
10265 | 10313 | name := fmt.Sprintf("Field%d", i) |
10266 | 10314 | AssertError(t, errs, name, name, name, name, "excluded_without") |
10267 | 10315 | } |
10316 | ||
10317 | test3 := struct { | |
10318 | Inner *Inner | |
10319 | Inner2 *Inner | |
10320 | Field string `validate:"omitempty" json:"field"` | |
10321 | FieldE string `validate:"omitempty" json:"field_e"` | |
10322 | Field1 string `validate:"excluded_without=Field" json:"field_1"` | |
10323 | Field2 *string `validate:"excluded_without=Field" json:"field_2"` | |
10324 | Field3 map[string]string `validate:"excluded_without=Field" json:"field_3"` | |
10325 | Field4 interface{} `validate:"excluded_without=Field" json:"field_4"` | |
10326 | Field5 string `validate:"excluded_without=Inner.Field" json:"field_5"` | |
10327 | }{ | |
10328 | Inner: &Inner{Field: &fieldVal}, | |
10329 | Field: "populated", | |
10330 | } | |
10331 | ||
10332 | validate = New() | |
10333 | ||
10334 | errs = validate.Struct(test3) | |
10335 | Equal(t, errs, nil) | |
10268 | 10336 | } |
10269 | 10337 | |
10270 | 10338 | func TestExcludedWithAll(t *testing.T) { |
10333 | 10401 | name := fmt.Sprintf("Field%d", i) |
10334 | 10402 | AssertError(t, errs, name, name, name, name, "excluded_with_all") |
10335 | 10403 | } |
10404 | ||
10405 | test3 := struct { | |
10406 | Inner *Inner | |
10407 | Inner2 *Inner | |
10408 | Field string `validate:"omitempty" json:"field"` | |
10409 | FieldE string `validate:"omitempty" json:"field_e"` | |
10410 | Field1 string `validate:"excluded_with_all=FieldE Field" json:"field_1"` | |
10411 | Field2 *string `validate:"excluded_with_all=FieldE Field" json:"field_2"` | |
10412 | Field3 map[string]string `validate:"excluded_with_all=FieldE Field" json:"field_3"` | |
10413 | Field4 interface{} `validate:"excluded_with_all=FieldE Field" json:"field_4"` | |
10414 | Field5 string `validate:"excluded_with_all=Inner.FieldE" json:"field_5"` | |
10415 | Field6 string `validate:"excluded_with_all=Inner2.FieldE" json:"field_6"` | |
10416 | }{ | |
10417 | Inner: &Inner{FieldE: "populated"}, | |
10418 | Inner2: &Inner{FieldE: "populated"}, | |
10419 | Field: "populated", | |
10420 | FieldE: "populated", | |
10421 | } | |
10422 | ||
10423 | validate = New() | |
10424 | ||
10425 | errs = validate.Struct(test3) | |
10426 | Equal(t, errs, nil) | |
10336 | 10427 | } |
10337 | 10428 | |
10338 | 10429 | func TestExcludedWithoutAll(t *testing.T) { |
10351 | 10442 | Field2 *string `validate:"excluded_without_all=Field FieldE" json:"field_2"` |
10352 | 10443 | Field3 map[string]string `validate:"excluded_without_all=Field FieldE" json:"field_3"` |
10353 | 10444 | 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"` | |
10445 | Field5 string `validate:"excluded_without_all=Inner.Field Inner2.Field" json:"field_5"` | |
10355 | 10446 | }{ |
10356 | 10447 | Inner: &Inner{Field: &fieldVal}, |
10448 | Inner2: &Inner{Field: &fieldVal}, | |
10357 | 10449 | Field: "populated", |
10358 | 10450 | Field1: fieldVal, |
10359 | 10451 | Field2: &fieldVal, |
10397 | 10489 | name := fmt.Sprintf("Field%d", i) |
10398 | 10490 | AssertError(t, errs, name, name, name, name, "excluded_without_all") |
10399 | 10491 | } |
10492 | ||
10493 | test3 := struct { | |
10494 | Inner *Inner | |
10495 | Inner2 *Inner | |
10496 | Field string `validate:"omitempty" json:"field"` | |
10497 | FieldE string `validate:"omitempty" json:"field_e"` | |
10498 | Field1 string `validate:"excluded_without_all=Field FieldE" json:"field_1"` | |
10499 | Field2 *string `validate:"excluded_without_all=Field FieldE" json:"field_2"` | |
10500 | Field3 map[string]string `validate:"excluded_without_all=Field FieldE" json:"field_3"` | |
10501 | Field4 interface{} `validate:"excluded_without_all=Field FieldE" json:"field_4"` | |
10502 | Field5 string `validate:"excluded_without_all=Inner.Field Inner2.Field" json:"field_5"` | |
10503 | }{ | |
10504 | Inner: &Inner{Field: &fieldVal}, | |
10505 | Inner2: &Inner{Field: &fieldVal}, | |
10506 | Field: "populated", | |
10507 | FieldE: "populated", | |
10508 | } | |
10509 | ||
10510 | validate = New() | |
10511 | ||
10512 | errs = validate.Struct(test3) | |
10513 | Equal(t, errs, nil) | |
10400 | 10514 | } |
10401 | 10515 | |
10402 | 10516 | func TestRequiredWithAll(t *testing.T) { |
10454 | 10568 | } |
10455 | 10569 | |
10456 | 10570 | func TestRequiredWithout(t *testing.T) { |
10457 | ||
10458 | 10571 | type Inner struct { |
10459 | 10572 | Field *string |
10460 | 10573 | } |
10520 | 10633 | } |
10521 | 10634 | |
10522 | 10635 | func TestRequiredWithoutAll(t *testing.T) { |
10523 | ||
10524 | 10636 | fieldVal := "test" |
10525 | 10637 | test := struct { |
10526 | 10638 | Field1 string `validate:"omitempty" json:"field_1"` |
10577 | 10689 | } |
10578 | 10690 | |
10579 | 10691 | func TestAbilityToValidateNils(t *testing.T) { |
10580 | ||
10581 | 10692 | type TestStruct struct { |
10582 | 10693 | Test *string `validate:"nil"` |
10583 | 10694 | } |
10718 | 10829 | }, "Bad field type int") |
10719 | 10830 | } |
10720 | 10831 | |
10832 | func TestJWTValidation(t *testing.T) { | |
10833 | tests := []struct { | |
10834 | param string | |
10835 | expected bool | |
10836 | }{ | |
10837 | {"eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiZ29waGVyIn0.O_bROM_szPq9qBql-XDHMranHwP48ODdoLICWzqBr_U", true}, | |
10838 | {"acb123-_.def456-_.ghi789-_", true}, | |
10839 | {"eyJhbGciOiJOT05FIn0.e30.", true}, | |
10840 | {"eyJhbGciOiJOT05FIn0.e30.\n", false}, | |
10841 | {"\x00.\x00.\x00", false}, | |
10842 | {"", false}, | |
10843 | } | |
10844 | ||
10845 | validate := New() | |
10846 | ||
10847 | for i, test := range tests { | |
10848 | ||
10849 | errs := validate.Var(test.param, "jwt") | |
10850 | ||
10851 | if test.expected { | |
10852 | if !IsEqual(errs, nil) { | |
10853 | t.Fatalf("Index: %d jwt failed Error: %s", i, errs) | |
10854 | } | |
10855 | } else { | |
10856 | if IsEqual(errs, nil) { | |
10857 | t.Fatalf("Index: %d jwt failed Error: %s", i, errs) | |
10858 | } else { | |
10859 | val := getError(errs, "", "") | |
10860 | if val.Tag() != "jwt" { | |
10861 | t.Fatalf("Index: %d jwt failed Error: %s", i, errs) | |
10862 | } | |
10863 | } | |
10864 | } | |
10865 | } | |
10866 | } | |
10867 | ||
10721 | 10868 | func Test_hostnameport_validator(t *testing.T) { |
10722 | ||
10723 | 10869 | type Host struct { |
10724 | 10870 | Addr string `validate:"hostname_port"` |
10725 | 10871 | } |
10821 | 10967 | PanicMatches(t, func() { |
10822 | 10968 | _ = validate.Var(2, "uppercase") |
10823 | 10969 | }, "Bad field type int") |
10824 | ||
10825 | 10970 | } |
10826 | 10971 | |
10827 | 10972 | func TestDatetimeValidation(t *testing.T) { |
10889 | 11034 | } |
10890 | 11035 | } |
10891 | 11036 | |
11037 | func TestIsIso31662Validation(t *testing.T) { | |
11038 | tests := []struct { | |
11039 | value string `validate:"iso3166_2"` | |
11040 | expected bool | |
11041 | }{ | |
11042 | {"US-FL", true}, | |
11043 | {"US-F", false}, | |
11044 | {"US", false}, | |
11045 | } | |
11046 | ||
11047 | validate := New() | |
11048 | ||
11049 | for i, test := range tests { | |
11050 | ||
11051 | errs := validate.Var(test.value, "iso3166_2") | |
11052 | ||
11053 | if test.expected { | |
11054 | if !IsEqual(errs, nil) { | |
11055 | t.Fatalf("Index: %d iso3166_2 failed Error: %s", i, errs) | |
11056 | } | |
11057 | } else { | |
11058 | if IsEqual(errs, nil) { | |
11059 | t.Fatalf("Index: %d iso3166_2 failed Error: %s", i, errs) | |
11060 | } | |
11061 | } | |
11062 | } | |
11063 | } | |
11064 | ||
10892 | 11065 | func TestIsIso3166Alpha3Validation(t *testing.T) { |
10893 | 11066 | tests := []struct { |
10894 | 11067 | value string `validate:"iso3166_1_alpha3"` |
10919 | 11092 | |
10920 | 11093 | func TestIsIso3166AlphaNumericValidation(t *testing.T) { |
10921 | 11094 | tests := []struct { |
10922 | value int | |
11095 | value interface{} | |
11096 | expected bool | |
11097 | }{ | |
11098 | {248, true}, | |
11099 | {"248", true}, | |
11100 | {0, false}, | |
11101 | {1, false}, | |
11102 | {"1", false}, | |
11103 | {"invalid_int", false}, | |
11104 | } | |
11105 | ||
11106 | validate := New() | |
11107 | ||
11108 | for i, test := range tests { | |
11109 | ||
11110 | errs := validate.Var(test.value, "iso3166_1_alpha_numeric") | |
11111 | ||
11112 | if test.expected { | |
11113 | if !IsEqual(errs, nil) { | |
11114 | t.Fatalf("Index: %d iso3166_1_alpha_numeric failed Error: %s", i, errs) | |
11115 | } | |
11116 | } else { | |
11117 | if IsEqual(errs, nil) { | |
11118 | t.Fatalf("Index: %d iso3166_1_alpha_numeric failed Error: %s", i, errs) | |
11119 | } | |
11120 | } | |
11121 | } | |
11122 | ||
11123 | PanicMatches(t, func() { | |
11124 | _ = validate.Var([]string{"1"}, "iso3166_1_alpha_numeric") | |
11125 | }, "Bad field type []string") | |
11126 | } | |
11127 | ||
11128 | func TestCountryCodeValidation(t *testing.T) { | |
11129 | tests := []struct { | |
11130 | value interface{} | |
10923 | 11131 | expected bool |
10924 | 11132 | }{ |
10925 | 11133 | {248, true}, |
10926 | 11134 | {0, false}, |
10927 | 11135 | {1, false}, |
11136 | {"POL", true}, | |
11137 | {"NO", true}, | |
11138 | {"248", true}, | |
11139 | {"1", false}, | |
11140 | {"0", false}, | |
10928 | 11141 | } |
10929 | 11142 | |
10930 | 11143 | validate := New() |
10931 | 11144 | |
10932 | 11145 | for i, test := range tests { |
10933 | 11146 | |
10934 | errs := validate.Var(test.value, "iso3166_1_alpha_numeric") | |
11147 | errs := validate.Var(test.value, "country_code") | |
10935 | 11148 | |
10936 | 11149 | if test.expected { |
10937 | 11150 | if !IsEqual(errs, nil) { |
10938 | t.Fatalf("Index: %d iso3166_1_alpha_numeric failed Error: %s", i, errs) | |
11151 | t.Fatalf("Index: %d country_code failed Error: %s", i, errs) | |
10939 | 11152 | } |
10940 | 11153 | } else { |
10941 | 11154 | if IsEqual(errs, nil) { |
10942 | t.Fatalf("Index: %d iso3166_1_alpha_numeric failed Error: %s", i, errs) | |
10943 | } | |
10944 | } | |
10945 | } | |
10946 | ||
10947 | PanicMatches(t, func() { | |
10948 | _ = validate.Var("1", "iso3166_1_alpha_numeric") | |
10949 | }, "Bad field type string") | |
11155 | t.Fatalf("Index: %d country_code failed Error: %s", i, errs) | |
11156 | } | |
11157 | } | |
11158 | } | |
11159 | } | |
11160 | ||
11161 | func TestIsIso4217Validation(t *testing.T) { | |
11162 | tests := []struct { | |
11163 | value string `validate:"iso4217"` | |
11164 | expected bool | |
11165 | }{ | |
11166 | {"TRY", true}, | |
11167 | {"EUR", true}, | |
11168 | {"USA", false}, | |
11169 | } | |
11170 | ||
11171 | validate := New() | |
11172 | ||
11173 | for i, test := range tests { | |
11174 | ||
11175 | errs := validate.Var(test.value, "iso4217") | |
11176 | ||
11177 | if test.expected { | |
11178 | if !IsEqual(errs, nil) { | |
11179 | t.Fatalf("Index: %d iso4217 failed Error: %s", i, errs) | |
11180 | } | |
11181 | } else { | |
11182 | if IsEqual(errs, nil) { | |
11183 | t.Fatalf("Index: %d iso4217 failed Error: %s", i, errs) | |
11184 | } | |
11185 | } | |
11186 | } | |
11187 | } | |
11188 | ||
11189 | func TestIsIso4217NumericValidation(t *testing.T) { | |
11190 | tests := []struct { | |
11191 | value int `validate:"iso4217_numeric"` | |
11192 | expected bool | |
11193 | }{ | |
11194 | {8, true}, | |
11195 | {12, true}, | |
11196 | {13, false}, | |
11197 | } | |
11198 | ||
11199 | validate := New() | |
11200 | ||
11201 | for i, test := range tests { | |
11202 | ||
11203 | errs := validate.Var(test.value, "iso4217_numeric") | |
11204 | ||
11205 | if test.expected { | |
11206 | if !IsEqual(errs, nil) { | |
11207 | t.Fatalf("Index: %d iso4217 failed Error: %s", i, errs) | |
11208 | } | |
11209 | } else { | |
11210 | if IsEqual(errs, nil) { | |
11211 | t.Fatalf("Index: %d iso4217 failed Error: %s", i, errs) | |
11212 | } | |
11213 | } | |
11214 | } | |
10950 | 11215 | } |
10951 | 11216 | |
10952 | 11217 | func TestTimeZoneValidation(t *testing.T) { |
11032 | 11297 | }) |
11033 | 11298 | } |
11034 | 11299 | } |
11300 | ||
11301 | func TestBCP47LanguageTagValidation(t *testing.T) { | |
11302 | tests := []struct { | |
11303 | value string `validate:"bcp47_language_tag"` | |
11304 | tag string | |
11305 | expected bool | |
11306 | }{ | |
11307 | {"en-US", "bcp47_language_tag", true}, | |
11308 | {"en_GB", "bcp47_language_tag", true}, | |
11309 | {"es", "bcp47_language_tag", true}, | |
11310 | {"English", "bcp47_language_tag", false}, | |
11311 | {"ESES", "bcp47_language_tag", false}, | |
11312 | {"az-Cyrl-AZ", "bcp47_language_tag", true}, | |
11313 | {"en-029", "bcp47_language_tag", true}, | |
11314 | {"xog", "bcp47_language_tag", true}, | |
11315 | } | |
11316 | ||
11317 | validate := New() | |
11318 | ||
11319 | for i, test := range tests { | |
11320 | ||
11321 | errs := validate.Var(test.value, test.tag) | |
11322 | ||
11323 | if test.expected { | |
11324 | if !IsEqual(errs, nil) { | |
11325 | t.Fatalf("Index: %d locale failed Error: %s", i, errs) | |
11326 | } | |
11327 | } else { | |
11328 | if IsEqual(errs, nil) { | |
11329 | t.Fatalf("Index: %d locale failed Error: %s", i, errs) | |
11330 | } else { | |
11331 | val := getError(errs, "", "") | |
11332 | if val.Tag() != "bcp47_language_tag" { | |
11333 | t.Fatalf("Index: %d locale failed Error: %s", i, errs) | |
11334 | } | |
11335 | } | |
11336 | } | |
11337 | } | |
11338 | ||
11339 | PanicMatches(t, func() { | |
11340 | _ = validate.Var(2, "bcp47_language_tag") | |
11341 | }, "Bad field type int") | |
11342 | } | |
11343 | ||
11344 | func TestBicIsoFormatValidation(t *testing.T) { | |
11345 | tests := []struct { | |
11346 | value string `validate:"bic"` | |
11347 | tag string | |
11348 | expected bool | |
11349 | }{ | |
11350 | {"SBICKEN1345", "bic", true}, | |
11351 | {"SBICKEN1", "bic", true}, | |
11352 | {"SBICKENY", "bic", true}, | |
11353 | {"SBICKEN1YYP", "bic", true}, | |
11354 | {"SBIC23NXXX", "bic", false}, | |
11355 | {"S23CKENXXXX", "bic", false}, | |
11356 | {"SBICKENXX", "bic", false}, | |
11357 | {"SBICKENXX9", "bic", false}, | |
11358 | {"SBICKEN13458", "bic", false}, | |
11359 | {"SBICKEN", "bic", false}, | |
11360 | } | |
11361 | ||
11362 | validate := New() | |
11363 | ||
11364 | for i, test := range tests { | |
11365 | ||
11366 | errs := validate.Var(test.value, test.tag) | |
11367 | ||
11368 | if test.expected { | |
11369 | if !IsEqual(errs, nil) { | |
11370 | t.Fatalf("Index: %d bic failed Error: %s", i, errs) | |
11371 | } | |
11372 | } else { | |
11373 | if IsEqual(errs, nil) { | |
11374 | t.Fatalf("Index: %d bic failed Error: %s", i, errs) | |
11375 | } else { | |
11376 | val := getError(errs, "", "") | |
11377 | if val.Tag() != "bic" { | |
11378 | t.Fatalf("Index: %d bic failed Error: %s", i, errs) | |
11379 | } | |
11380 | } | |
11381 | } | |
11382 | } | |
11383 | } | |
11384 | ||
11385 | func TestSemverFormatValidation(t *testing.T) { | |
11386 | tests := []struct { | |
11387 | value string `validate:"semver"` | |
11388 | tag string | |
11389 | expected bool | |
11390 | }{ | |
11391 | {"1.2.3", "semver", true}, | |
11392 | {"10.20.30", "semver", true}, | |
11393 | {"1.1.2-prerelease+meta", "semver", true}, | |
11394 | {"1.1.2+meta", "semver", true}, | |
11395 | {"1.1.2+meta-valid", "semver", true}, | |
11396 | {"1.0.0-alpha", "semver", true}, | |
11397 | {"1.0.0-alpha.1", "semver", true}, | |
11398 | {"1.0.0-alpha.beta", "semver", true}, | |
11399 | {"1.0.0-alpha.beta.1", "semver", true}, | |
11400 | {"1.0.0-alpha0.valid", "semver", true}, | |
11401 | {"1.0.0-alpha.0valid", "semver", true}, | |
11402 | {"1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay", "semver", true}, | |
11403 | {"1.0.0-rc.1+build.1", "semver", true}, | |
11404 | {"1.0.0-rc.1+build.123", "semver", true}, | |
11405 | {"1.2.3-beta", "semver", true}, | |
11406 | {"1.2.3-DEV-SNAPSHOT", "semver", true}, | |
11407 | {"1.2.3-SNAPSHOT-123", "semver", true}, | |
11408 | {"2.0.0+build.1848", "semver", true}, | |
11409 | {"2.0.1-alpha.1227", "semver", true}, | |
11410 | {"1.0.0-alpha+beta", "semver", true}, | |
11411 | {"1.2.3----RC-SNAPSHOT.12.9.1--.12+788", "semver", true}, | |
11412 | {"1.2.3----R-S.12.9.1--.12+meta", "semver", true}, | |
11413 | {"1.2.3----RC-SNAPSHOT.12.9.1--.12", "semver", true}, | |
11414 | {"1.0.0+0.build.1-rc.10000aaa-kk-0.1", "semver", true}, | |
11415 | {"99999999999999999999999.999999999999999999.99999999999999999", "semver", true}, | |
11416 | {"1.0.0-0A.is.legal", "semver", true}, | |
11417 | {"1", "semver", false}, | |
11418 | {"1.2", "semver", false}, | |
11419 | {"1.2.3-0123", "semver", false}, | |
11420 | {"1.2.3-0123.0123", "semver", false}, | |
11421 | {"1.1.2+.123", "semver", false}, | |
11422 | {"+invalid", "semver", false}, | |
11423 | {"-invalid", "semver", false}, | |
11424 | {"-invalid+invalid", "semver", false}, | |
11425 | {"alpha", "semver", false}, | |
11426 | {"alpha.beta.1", "semver", false}, | |
11427 | {"alpha.1", "semver", false}, | |
11428 | {"1.0.0-alpha_beta", "semver", false}, | |
11429 | {"1.0.0-alpha_beta", "semver", false}, | |
11430 | {"1.0.0-alpha...1", "semver", false}, | |
11431 | {"01.1.1", "semver", false}, | |
11432 | {"1.01.1", "semver", false}, | |
11433 | {"1.1.01", "semver", false}, | |
11434 | {"1.2", "semver", false}, | |
11435 | {"1.2.Dev", "semver", false}, | |
11436 | {"1.2.3.Dev", "semver", false}, | |
11437 | {"1.2-SNAPSHOT", "semver", false}, | |
11438 | } | |
11439 | ||
11440 | validate := New() | |
11441 | ||
11442 | for i, test := range tests { | |
11443 | ||
11444 | errs := validate.Var(test.value, test.tag) | |
11445 | ||
11446 | if test.expected { | |
11447 | if !IsEqual(errs, nil) { | |
11448 | t.Fatalf("Index: %d semver failed Error: %s", i, errs) | |
11449 | } | |
11450 | } else { | |
11451 | if IsEqual(errs, nil) { | |
11452 | t.Fatalf("Index: %d semver failed Error: %s", i, errs) | |
11453 | } else { | |
11454 | val := getError(errs, "", "") | |
11455 | if val.Tag() != "semver" { | |
11456 | t.Fatalf("Index: %d semver failed Error: %s", i, errs) | |
11457 | } | |
11458 | } | |
11459 | } | |
11460 | } | |
11461 | } | |
11462 | ||
11463 | func TestRFC1035LabelFormatValidation(t *testing.T) { | |
11464 | tests := []struct { | |
11465 | value string `validate:"dns_rfc1035_label"` | |
11466 | tag string | |
11467 | expected bool | |
11468 | }{ | |
11469 | {"abc", "dns_rfc1035_label", true}, | |
11470 | {"abc-", "dns_rfc1035_label", false}, | |
11471 | {"abc-123", "dns_rfc1035_label", true}, | |
11472 | {"ABC", "dns_rfc1035_label", false}, | |
11473 | {"ABC-123", "dns_rfc1035_label", false}, | |
11474 | {"abc-abc", "dns_rfc1035_label", true}, | |
11475 | {"ABC-ABC", "dns_rfc1035_label", false}, | |
11476 | {"123-abc", "dns_rfc1035_label", false}, | |
11477 | {"", "dns_rfc1035_label", false}, | |
11478 | } | |
11479 | ||
11480 | validate := New() | |
11481 | ||
11482 | for i, test := range tests { | |
11483 | errs := validate.Var(test.value, test.tag) | |
11484 | ||
11485 | if test.expected { | |
11486 | if !IsEqual(errs, nil) { | |
11487 | t.Fatalf("Index: %d dns_rfc1035_label failed Error: %s", i, errs) | |
11488 | } | |
11489 | } else { | |
11490 | if IsEqual(errs, nil) { | |
11491 | t.Fatalf("Index: %d dns_rfc1035_label failed Error: %s", i, errs) | |
11492 | } else { | |
11493 | val := getError(errs, "", "") | |
11494 | if val.Tag() != "dns_rfc1035_label" { | |
11495 | t.Fatalf("Index: %d dns_rfc1035_label failed Error: %s", i, errs) | |
11496 | } | |
11497 | } | |
11498 | } | |
11499 | } | |
11500 | } | |
11501 | ||
11502 | func TestPostCodeByIso3166Alpha2(t *testing.T) { | |
11503 | tests := map[string][]struct { | |
11504 | value string | |
11505 | expected bool | |
11506 | }{ | |
11507 | "VN": { | |
11508 | {"ABC", false}, | |
11509 | {"700000", true}, | |
11510 | {"A1", false}, | |
11511 | }, | |
11512 | "GB": { | |
11513 | {"EC1A 1BB", true}, | |
11514 | {"CF10 1B1H", false}, | |
11515 | }, | |
11516 | "VI": { | |
11517 | {"00803", true}, | |
11518 | {"1234567", false}, | |
11519 | }, | |
11520 | "LC": { // not support regexp for post code | |
11521 | {"123456", false}, | |
11522 | }, | |
11523 | "XX": { // not support country | |
11524 | {"123456", false}, | |
11525 | }, | |
11526 | } | |
11527 | ||
11528 | validate := New() | |
11529 | ||
11530 | for cc, ccTests := range tests { | |
11531 | for i, test := range ccTests { | |
11532 | errs := validate.Var(test.value, fmt.Sprintf("postcode_iso3166_alpha2=%s", cc)) | |
11533 | ||
11534 | if test.expected { | |
11535 | if !IsEqual(errs, nil) { | |
11536 | t.Fatalf("Index: %d postcode_iso3166_alpha2=%s failed Error: %s", i, cc, errs) | |
11537 | } | |
11538 | } else { | |
11539 | if IsEqual(errs, nil) { | |
11540 | t.Fatalf("Index: %d postcode_iso3166_alpha2=%s failed Error: %s", i, cc, errs) | |
11541 | } | |
11542 | } | |
11543 | } | |
11544 | } | |
11545 | } | |
11546 | ||
11547 | func TestPostCodeByIso3166Alpha2Field(t *testing.T) { | |
11548 | tests := []struct { | |
11549 | Value string `validate:"postcode_iso3166_alpha2_field=CountryCode"` | |
11550 | CountryCode interface{} | |
11551 | expected bool | |
11552 | }{ | |
11553 | {"ABC", "VN", false}, | |
11554 | {"700000", "VN", true}, | |
11555 | {"A1", "VN", false}, | |
11556 | {"EC1A 1BB", "GB", true}, | |
11557 | {"CF10 1B1H", "GB", false}, | |
11558 | {"00803", "VI", true}, | |
11559 | {"1234567", "VI", false}, | |
11560 | {"123456", "LC", false}, // not support regexp for post code | |
11561 | {"123456", "XX", false}, // not support country | |
11562 | } | |
11563 | ||
11564 | validate := New() | |
11565 | ||
11566 | for i, test := range tests { | |
11567 | errs := validate.Struct(test) | |
11568 | if test.expected { | |
11569 | if !IsEqual(errs, nil) { | |
11570 | t.Fatalf("Index: %d postcode_iso3166_alpha2_field=CountryCode failed Error: %s", i, errs) | |
11571 | } | |
11572 | } else { | |
11573 | if IsEqual(errs, nil) { | |
11574 | t.Fatalf("Index: %d postcode_iso3166_alpha2_field=CountryCode failed Error: %s", i, errs) | |
11575 | } | |
11576 | } | |
11577 | } | |
11578 | } | |
11579 | ||
11580 | func TestPostCodeByIso3166Alpha2Field_WrongField(t *testing.T) { | |
11581 | type test struct { | |
11582 | Value string `validate:"postcode_iso3166_alpha2_field=CountryCode"` | |
11583 | CountryCode1 interface{} | |
11584 | expected bool | |
11585 | } | |
11586 | ||
11587 | errs := New().Struct(test{"ABC", "VN", false}) | |
11588 | NotEqual(t, nil, errs) | |
11589 | } | |
11590 | ||
11591 | func TestPostCodeByIso3166Alpha2Field_MissingParam(t *testing.T) { | |
11592 | type test struct { | |
11593 | Value string `validate:"postcode_iso3166_alpha2_field="` | |
11594 | CountryCode1 interface{} | |
11595 | expected bool | |
11596 | } | |
11597 | ||
11598 | errs := New().Struct(test{"ABC", "VN", false}) | |
11599 | NotEqual(t, nil, errs) | |
11600 | } | |
11601 | ||
11602 | func TestPostCodeByIso3166Alpha2Field_InvalidKind(t *testing.T) { | |
11603 | type test struct { | |
11604 | Value string `validate:"postcode_iso3166_alpha2_field=CountryCode"` | |
11605 | CountryCode interface{} | |
11606 | expected bool | |
11607 | } | |
11608 | defer func() { _ = recover() }() | |
11609 | ||
11610 | _ = New().Struct(test{"ABC", 123, false}) | |
11611 | t.Errorf("Didn't panic as expected") | |
11612 | } |