Codebase list golang-github-go-playground-validator-v10 / upstream/10.10.1
Import upstream version 10.10.1 Debian Janitor 2 years ago
51 changed file(s) with 5505 addition(s) and 794 deletion(s). Raw diff Collapse all Expand all
0 * @go-playground/validator-maintainers
11
22 ## Quality Standard
33
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.
55
66 ## Reporting issues
77
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:
14
25
36
0 Fixes Or Enhances # .
0 ## Fixes Or Enhances
1
12
23 **Make sure that you've checked the boxes below before you submit PR:**
34 - [ ] Tests exist or have been written that cover this particular change.
45
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
-29
.travis.yml less more
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.
22 linters-install:
33 @golangci-lint --version >/dev/null 2>&1 || { \
44 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; \
66 }
77
88 lint: linters-install
9 $(PWD)/bin/golangci-lint run
9 golangci-lint run
1010
1111 test:
1212 $(GOCMD) test -cover -race ./...
00 Package validator
1 ================
1 =================
22 <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)
44 [![Build Status](https://travis-ci.org/go-playground/validator.svg?branch=master)](https://travis-ci.org/go-playground/validator)
55 [![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=master&service=github)](https://coveralls.io/github/go-playground/validator?branch=master)
66 [![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator)
4242 * http://stackoverflow.com/a/29138676/3158232
4343 * https://github.com/go-playground/validator/issues/134
4444
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:
4646
4747 ```go
4848 err := validate.Struct(mystruct)
5252 Usage and documentation
5353 ------
5454
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.
5656
5757 ##### Examples:
5858
9999 | hostname_rfc1123 | Hostname RFC 1123 |
100100 | ip | Internet Protocol Address IP |
101101 | ip4_addr | Internet Protocol Address IPv4 |
102 | ip6_addr |Internet Protocol Address IPv6 |
102 | ip6_addr | Internet Protocol Address IPv6 |
103103 | ip_addr | Internet Protocol Address IP |
104104 | ipv4 | Internet Protocol Address IPv4 |
105105 | ipv6 | Internet Protocol Address IPv6 |
125125 | alphanumunicode | Alphanumeric Unicode |
126126 | alphaunicode | Alpha Unicode |
127127 | ascii | ASCII |
128 | boolean | Boolean |
128129 | contains | Contains |
129130 | containsany | Contains Any |
130131 | containsrune | Contains Rune |
132 | endsnotwith | Ends With |
131133 | endswith | Ends With |
134 | excludes | Excludes |
135 | excludesall | Excludes All |
136 | excludesrune | Excludes Rune |
132137 | lowercase | Lowercase |
133138 | multibyte | Multi-Byte Characters |
134139 | number | NOT DOCUMENTED IN doc.go |
135140 | numeric | Numeric |
136141 | printascii | Printable ASCII |
142 | startsnotwith | Starts Not With |
137143 | startswith | Starts With |
138144 | uppercase | Uppercase |
139145
142148 | - | - |
143149 | base64 | Base64 String |
144150 | base64url | Base64URL String |
151 | bic | Business Identifier Code (ISO 9362) |
152 | bcp47_language_tag | Language tag (BCP 47) |
145153 | btc_addr | Bitcoin Address |
146154 | btc_addr_bech32 | Bitcoin Bech32 Address (segwit) |
147155 | datetime | Datetime |
157165 | isbn | International Standard Book Number |
158166 | isbn10 | International Standard Book Number 10 |
159167 | 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) |
160173 | json | JSON |
174 | jwt | JSON Web Token (JWT) |
161175 | latitude | Latitude |
162176 | longitude | Longitude |
177 | postcode_iso3166_alpha2 | Postcode |
178 | postcode_iso3166_alpha2_field | Postcode |
163179 | rgb | RGB String |
164180 | rgba | RGBA String |
165181 | ssn | Social Security Number SSN |
182 | timezone | Timezone |
166183 | uuid | Universally Unique Identifier UUID |
167184 | uuid3 | Universally Unique Identifier UUID v3 |
168185 | uuid3_rfc4122 | Universally Unique Identifier UUID v3 RFC4122 |
171188 | uuid5 | Universally Unique Identifier UUID v5 |
172189 | uuid5_rfc4122 | Universally Unique Identifier UUID v5 RFC4122 |
173190 | uuid_rfc4122 | Universally Unique Identifier UUID RFC4122 |
191 | semver | Semantic Versioning 2.0.0 |
192 | ulid | Universally Unique Lexicographically Sortable Identifier ULID |
174193
175194 ### Comparisons:
176195 | Tag | Description |
177196 | - | - |
178197 | eq | Equals |
179198 | gt | Greater than|
180 | gte |Greater than or equal |
199 | gte | Greater than or equal |
181200 | lt | Less Than |
182201 | lte | Less Than or Equal |
183202 | ne | Not Equal |
186205 | Tag | Description |
187206 | - | - |
188207 | dir | Directory |
189 | endswith | Ends With |
190 | excludes | Excludes |
191 | excludesall | Excludes All |
192 | excludesrune | Excludes Rune |
193208 | file | File path |
194209 | isdefault | Is Default |
195210 | len | Length |
208223 | excluded_without | Excluded Without |
209224 | excluded_without_all | Excluded Without All |
210225 | 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 |
211232
212233 Benchmarks
213234 ------
294315 Make a pull request...
295316
296317 License
297 ------
318 -------
298319 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 }
4343
4444 // register validation for 'User'
4545 // 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.
4747 validate.RegisterStructValidation(UserStructLevelValidation, User{})
4848
4949 // build 'User' info, normally posted data etc...
1717 "unicode/utf8"
1818
1919 "golang.org/x/crypto/sha3"
20 "golang.org/x/text/language"
2021
2122 urn "github.com/leodido/go-urn"
2223 )
5455 isdefault: {},
5556 }
5657
57 // BakedInAliasValidators is a default mapping of a single validation tag that
58 // bakedInAliases is a default mapping of a single validation tag that
5859 // defines a common or complex set of validation(s) to simplify
5960 // adding validation to structs.
6061 bakedInAliases = map[string]string{
6263 "country_code": "iso3166_1_alpha2|iso3166_1_alpha3|iso3166_1_alpha_numeric",
6364 }
6465
65 // BakedInValidators is the default map of ValidationFunc
66 // bakedInValidators is the default map of ValidationFunc
6667 // you can add, remove or even replace items to suite your needs,
6768 // or even disregard and use your own map if so desired.
6869 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,
190203 }
191204 )
192205
295308 }
296309 }
297310
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.
299312 func isMAC(fl FieldLevel) bool {
300313
301314 _, err := net.ParseMAC(fl.Field().String())
303316 return err == nil
304317 }
305318
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.
307320 func isCIDRv4(fl FieldLevel) bool {
308321
309322 ip, _, err := net.ParseCIDR(fl.Field().String())
311324 return err == nil && ip.To4() != nil
312325 }
313326
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.
315328 func isCIDRv6(fl FieldLevel) bool {
316329
317330 ip, _, err := net.ParseCIDR(fl.Field().String())
319332 return err == nil && ip.To4() == nil
320333 }
321334
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.
323336 func isCIDR(fl FieldLevel) bool {
324337
325338 _, _, err := net.ParseCIDR(fl.Field().String())
327340 return err == nil
328341 }
329342
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.
331344 func isIPv4(fl FieldLevel) bool {
332345
333346 ip := net.ParseIP(fl.Field().String())
335348 return ip != nil && ip.To4() != nil
336349 }
337350
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.
339352 func isIPv6(fl FieldLevel) bool {
340353
341354 ip := net.ParseIP(fl.Field().String())
343356 return ip != nil && ip.To4() == nil
344357 }
345358
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.
347360 func isIP(fl FieldLevel) bool {
348361
349362 ip := net.ParseIP(fl.Field().String())
351364 return ip != nil
352365 }
353366
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.
355368 func isSSN(fl FieldLevel) bool {
356369
357370 field := fl.Field()
363376 return sSNRegex.MatchString(field.String())
364377 }
365378
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.
367380 func isLongitude(fl FieldLevel) bool {
368381 field := fl.Field()
369382
386399 return longitudeRegex.MatchString(v)
387400 }
388401
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.
390403 func isLatitude(fl FieldLevel) bool {
391404 field := fl.Field()
392405
409422 return latitudeRegex.MatchString(v)
410423 }
411424
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.
413426 func isDataURI(fl FieldLevel) bool {
414427
415428 uri := strings.SplitN(fl.Field().String(), ",", 2)
425438 return base64Regex.MatchString(uri[1])
426439 }
427440
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.
429442 func hasMultiByteCharacter(fl FieldLevel) bool {
430443
431444 field := fl.Field()
437450 return multibyteRegex.MatchString(field.String())
438451 }
439452
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.
441454 func isPrintableASCII(fl FieldLevel) bool {
442455 return printableASCIIRegex.MatchString(fl.Field().String())
443456 }
444457
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.
446459 func isASCII(fl FieldLevel) bool {
447460 return aSCIIRegex.MatchString(fl.Field().String())
448461 }
449462
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.
451464 func isUUID5(fl FieldLevel) bool {
452465 return uUID5Regex.MatchString(fl.Field().String())
453466 }
454467
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.
456469 func isUUID4(fl FieldLevel) bool {
457470 return uUID4Regex.MatchString(fl.Field().String())
458471 }
459472
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.
461474 func isUUID3(fl FieldLevel) bool {
462475 return uUID3Regex.MatchString(fl.Field().String())
463476 }
464477
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.
466479 func isUUID(fl FieldLevel) bool {
467480 return uUIDRegex.MatchString(fl.Field().String())
468481 }
469482
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.
471484 func isUUID5RFC4122(fl FieldLevel) bool {
472485 return uUID5RFC4122Regex.MatchString(fl.Field().String())
473486 }
474487
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.
476489 func isUUID4RFC4122(fl FieldLevel) bool {
477490 return uUID4RFC4122Regex.MatchString(fl.Field().String())
478491 }
479492
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.
481494 func isUUID3RFC4122(fl FieldLevel) bool {
482495 return uUID3RFC4122Regex.MatchString(fl.Field().String())
483496 }
484497
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.
486499 func isUUIDRFC4122(fl FieldLevel) bool {
487500 return uUIDRFC4122Regex.MatchString(fl.Field().String())
488501 }
489502
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.
491509 func isISBN(fl FieldLevel) bool {
492510 return isISBN10(fl) || isISBN13(fl)
493511 }
494512
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.
496514 func isISBN13(fl FieldLevel) bool {
497515
498516 s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 4), " ", "", 4)
513531 return (int32(s[12]-'0'))-((10-(checksum%10))%10) == 0
514532 }
515533
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.
517535 func isISBN10(fl FieldLevel) bool {
518536
519537 s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 3), " ", "", 3)
538556 return checksum%11 == 0
539557 }
540558
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.
542560 func isEthereumAddress(fl FieldLevel) bool {
543561 address := fl.Field().String()
544562
546564 return false
547565 }
548566
549 if ethaddressRegexUpper.MatchString(address) || ethAddressRegexLower.MatchString(address) {
567 if ethAddressRegexUpper.MatchString(address) || ethAddressRegexLower.MatchString(address) {
550568 return true
551569 }
552570
569587 return true
570588 }
571589
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
573591 func isBitcoinAddress(fl FieldLevel) bool {
574592 address := fl.Field().String()
575593
606624 return validchecksum == computedchecksum
607625 }
608626
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
610628 func isBitcoinBech32Address(fl FieldLevel) bool {
611629 address := fl.Field().String()
612630
686704 return true
687705 }
688706
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.
690708 func excludesRune(fl FieldLevel) bool {
691709 return !containsRune(fl)
692710 }
693711
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.
695713 func excludesAll(fl FieldLevel) bool {
696714 return !containsAny(fl)
697715 }
698716
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.
700718 func excludes(fl FieldLevel) bool {
701719 return !contains(fl)
702720 }
703721
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.
705723 func containsRune(fl FieldLevel) bool {
706724
707725 r, _ := utf8.DecodeRuneInString(fl.Param())
709727 return strings.ContainsRune(fl.Field().String(), r)
710728 }
711729
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.
713731 func containsAny(fl FieldLevel) bool {
714732 return strings.ContainsAny(fl.Field().String(), fl.Param())
715733 }
716734
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.
718736 func contains(fl FieldLevel) bool {
719737 return strings.Contains(fl.Field().String(), fl.Param())
720738 }
721739
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.
723741 func startsWith(fl FieldLevel) bool {
724742 return strings.HasPrefix(fl.Field().String(), fl.Param())
725743 }
726744
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.
728746 func endsWith(fl FieldLevel) bool {
729747 return strings.HasSuffix(fl.Field().String(), fl.Param())
730748 }
731749
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.
733751 func startsNotWith(fl FieldLevel) bool {
734752 return !startsWith(fl)
735753 }
736754
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.
738756 func endsNotWith(fl FieldLevel) bool {
739757 return !endsWith(fl)
740758 }
741759
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.
743761 func fieldContains(fl FieldLevel) bool {
744762 field := fl.Field()
745763
752770 return strings.Contains(field.String(), currentField.String())
753771 }
754772
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.
756774 func fieldExcludes(fl FieldLevel) bool {
757775 field := fl.Field()
758776
764782 return !strings.Contains(field.String(), currentField.String())
765783 }
766784
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.
768786 func isNeField(fl FieldLevel) bool {
769787
770788 field := fl.Field()
789807
790808 case reflect.Slice, reflect.Map, reflect.Array:
791809 return int64(field.Len()) != int64(currentField.Len())
810
811 case reflect.Bool:
812 return field.Bool() != currentField.Bool()
792813
793814 case reflect.Struct:
794815
813834 return field.String() != currentField.String()
814835 }
815836
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.
817838 func isNe(fl FieldLevel) bool {
818839 return !isEq(fl)
819840 }
820841
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.
822843 func isLteCrossStructField(fl FieldLevel) bool {
823844
824845 field := fl.Field()
865886 return field.String() <= topField.String()
866887 }
867888
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.
869890 // NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
870891 func isLtCrossStructField(fl FieldLevel) bool {
871892
913934 return field.String() < topField.String()
914935 }
915936
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.
917938 func isGteCrossStructField(fl FieldLevel) bool {
918939
919940 field := fl.Field()
960981 return field.String() >= topField.String()
961982 }
962983
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.
964985 func isGtCrossStructField(fl FieldLevel) bool {
965986
966987 field := fl.Field()
10071028 return field.String() > topField.String()
10081029 }
10091030
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.
10111032 func isNeCrossStructField(fl FieldLevel) bool {
10121033
10131034 field := fl.Field()
10321053 case reflect.Slice, reflect.Map, reflect.Array:
10331054 return int64(topField.Len()) != int64(field.Len())
10341055
1056 case reflect.Bool:
1057 return topField.Bool() != field.Bool()
1058
10351059 case reflect.Struct:
10361060
10371061 fieldType := field.Type()
10541078 return topField.String() != field.String()
10551079 }
10561080
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.
10581082 func isEqCrossStructField(fl FieldLevel) bool {
10591083
10601084 field := fl.Field()
10781102
10791103 case reflect.Slice, reflect.Map, reflect.Array:
10801104 return int64(topField.Len()) == int64(field.Len())
1105
1106 case reflect.Bool:
1107 return topField.Bool() == field.Bool()
10811108
10821109 case reflect.Struct:
10831110
11011128 return topField.String() == field.String()
11021129 }
11031130
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.
11051132 func isEqField(fl FieldLevel) bool {
11061133
11071134 field := fl.Field()
11251152
11261153 case reflect.Slice, reflect.Map, reflect.Array:
11271154 return int64(field.Len()) == int64(currentField.Len())
1155
1156 case reflect.Bool:
1157 return field.Bool() == currentField.Bool()
11281158
11291159 case reflect.Struct:
11301160
11491179 return field.String() == currentField.String()
11501180 }
11511181
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.
11531183 func isEq(fl FieldLevel) bool {
11541184
11551185 field := fl.Field()
11891219 panic(fmt.Sprintf("Bad field type %T", field.Interface()))
11901220 }
11911221
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.
11931264 func isBase64(fl FieldLevel) bool {
11941265 return base64Regex.MatchString(fl.Field().String())
11951266 }
11961267
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.
11981269 func isBase64URL(fl FieldLevel) bool {
11991270 return base64URLRegex.MatchString(fl.Field().String())
12001271 }
12011272
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.
12031274 func isURI(fl FieldLevel) bool {
12041275
12051276 field := fl.Field()
12281299 panic(fmt.Sprintf("Bad field type %T", field.Interface()))
12291300 }
12301301
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.
12321303 func isURL(fl FieldLevel) bool {
12331304
12341305 field := fl.Field()
12801351 panic(fmt.Sprintf("Bad field type %T", field.Interface()))
12811352 }
12821353
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.
12841355 func isFile(fl FieldLevel) bool {
12851356 field := fl.Field()
12861357
12971368 panic(fmt.Sprintf("Bad field type %T", field.Interface()))
12981369 }
12991370
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.
13011372 func isE164(fl FieldLevel) bool {
13021373 return e164Regex.MatchString(fl.Field().String())
13031374 }
13041375
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.
13061377 func isEmail(fl FieldLevel) bool {
13071378 return emailRegex.MatchString(fl.Field().String())
13081379 }
13091380
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.
13111382 func isHSLA(fl FieldLevel) bool {
13121383 return hslaRegex.MatchString(fl.Field().String())
13131384 }
13141385
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.
13161387 func isHSL(fl FieldLevel) bool {
13171388 return hslRegex.MatchString(fl.Field().String())
13181389 }
13191390
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.
13211392 func isRGBA(fl FieldLevel) bool {
13221393 return rgbaRegex.MatchString(fl.Field().String())
13231394 }
13241395
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.
13261397 func isRGB(fl FieldLevel) bool {
13271398 return rgbRegex.MatchString(fl.Field().String())
13281399 }
13291400
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.
13311402 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.
13361407 func isHexadecimal(fl FieldLevel) bool {
13371408 return hexadecimalRegex.MatchString(fl.Field().String())
13381409 }
13391410
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.
13411412 func isNumber(fl FieldLevel) bool {
13421413 switch fl.Field().Kind() {
13431414 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:
13471418 }
13481419 }
13491420
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.
13511422 func isNumeric(fl FieldLevel) bool {
13521423 switch fl.Field().Kind() {
13531424 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:
13571428 }
13581429 }
13591430
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.
13611432 func isAlphanum(fl FieldLevel) bool {
13621433 return alphaNumericRegex.MatchString(fl.Field().String())
13631434 }
13641435
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.
13661437 func isAlpha(fl FieldLevel) bool {
13671438 return alphaRegex.MatchString(fl.Field().String())
13681439 }
13691440
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.
13711442 func isAlphanumUnicode(fl FieldLevel) bool {
13721443 return alphaUnicodeNumericRegex.MatchString(fl.Field().String())
13731444 }
13741445
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.
13761447 func isAlphaUnicode(fl FieldLevel) bool {
13771448 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
13781455 }
13791456
13801457 // isDefault is the opposite of required aka hasValue
13821459 return !hasValue(fl)
13831460 }
13841461
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.
13861463 func hasValue(fl FieldLevel) bool {
13871464 field := fl.Field()
13881465 switch field.Kind() {
14401517
14411518 case reflect.Slice, reflect.Map, reflect.Array:
14421519 return int64(field.Len()) == asInt(value)
1520
1521 case reflect.Bool:
1522 return field.Bool() == asBool(value)
14431523 }
14441524
14451525 // default reflect.String:
14771557 return hasValue(fl)
14781558 }
14791559
1480 // ExcludedWith is the validation function
1560 // excludedWith is the validation function
14811561 // The field under validation must not be present or is empty if any of the other specified fields are present.
14821562 func excludedWith(fl FieldLevel) bool {
14831563 params := parseOneOfParam2(fl.Param())
14891569 return true
14901570 }
14911571
1492 // RequiredWith is the validation function
1572 // requiredWith is the validation function
14931573 // The field under validation must be present and not empty only if any of the other specified fields are present.
14941574 func requiredWith(fl FieldLevel) bool {
14951575 params := parseOneOfParam2(fl.Param())
15011581 return true
15021582 }
15031583
1504 // ExcludedWithAll is the validation function
1584 // excludedWithAll is the validation function
15051585 // The field under validation must not be present or is empty if all of the other specified fields are present.
15061586 func excludedWithAll(fl FieldLevel) bool {
15071587 params := parseOneOfParam2(fl.Param())
15131593 return !hasValue(fl)
15141594 }
15151595
1516 // RequiredWithAll is the validation function
1596 // requiredWithAll is the validation function
15171597 // The field under validation must be present and not empty only if all of the other specified fields are present.
15181598 func requiredWithAll(fl FieldLevel) bool {
15191599 params := parseOneOfParam2(fl.Param())
15251605 return hasValue(fl)
15261606 }
15271607
1528 // ExcludedWithout is the validation function
1608 // excludedWithout is the validation function
15291609 // The field under validation must not be present or is empty when any of the other specified fields are not present.
15301610 func excludedWithout(fl FieldLevel) bool {
15311611 if requireCheckFieldKind(fl, strings.TrimSpace(fl.Param()), true) {
15341614 return true
15351615 }
15361616
1537 // RequiredWithout is the validation function
1617 // requiredWithout is the validation function
15381618 // The field under validation must be present and not empty only when any of the other specified fields are not present.
15391619 func requiredWithout(fl FieldLevel) bool {
15401620 if requireCheckFieldKind(fl, strings.TrimSpace(fl.Param()), true) {
15431623 return true
15441624 }
15451625
1546 // RequiredWithoutAll is the validation function
1626 // excludedWithoutAll is the validation function
15471627 // The field under validation must not be present or is empty when all of the other specified fields are not present.
15481628 func excludedWithoutAll(fl FieldLevel) bool {
15491629 params := parseOneOfParam2(fl.Param())
15551635 return !hasValue(fl)
15561636 }
15571637
1558 // RequiredWithoutAll is the validation function
1638 // requiredWithoutAll is the validation function
15591639 // The field under validation must be present and not empty only when all of the other specified fields are not present.
15601640 func requiredWithoutAll(fl FieldLevel) bool {
15611641 params := parseOneOfParam2(fl.Param())
15671647 return hasValue(fl)
15681648 }
15691649
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.
15711651 func isGteField(fl FieldLevel) bool {
15721652
15731653 field := fl.Field()
16141694 return len(field.String()) >= len(currentField.String())
16151695 }
16161696
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.
16181698 func isGtField(fl FieldLevel) bool {
16191699
16201700 field := fl.Field()
16611741 return len(field.String()) > len(currentField.String())
16621742 }
16631743
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.
16651745 func isGte(fl FieldLevel) bool {
16661746
16671747 field := fl.Field()
17081788 panic(fmt.Sprintf("Bad field type %T", field.Interface()))
17091789 }
17101790
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.
17121792 func isGt(fl FieldLevel) bool {
17131793
17141794 field := fl.Field()
17511831 panic(fmt.Sprintf("Bad field type %T", field.Interface()))
17521832 }
17531833
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.
17551835 func hasLengthOf(fl FieldLevel) bool {
17561836
17571837 field := fl.Field()
17881868 panic(fmt.Sprintf("Bad field type %T", field.Interface()))
17891869 }
17901870
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.
17921872 func hasMinOf(fl FieldLevel) bool {
17931873 return isGte(fl)
17941874 }
17951875
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.
17971877 func isLteField(fl FieldLevel) bool {
17981878
17991879 field := fl.Field()
18401920 return len(field.String()) <= len(currentField.String())
18411921 }
18421922
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.
18441924 func isLtField(fl FieldLevel) bool {
18451925
18461926 field := fl.Field()
18871967 return len(field.String()) < len(currentField.String())
18881968 }
18891969
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.
18911971 func isLte(fl FieldLevel) bool {
18921972
18931973 field := fl.Field()
19342014 panic(fmt.Sprintf("Bad field type %T", field.Interface()))
19352015 }
19362016
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.
19382018 func isLt(fl FieldLevel) bool {
19392019
19402020 field := fl.Field()
19782058 panic(fmt.Sprintf("Bad field type %T", field.Interface()))
19792059 }
19802060
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.
19822062 func hasMaxOf(fl FieldLevel) bool {
19832063 return isLte(fl)
19842064 }
19852065
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.
19872067 func isTCP4AddrResolvable(fl FieldLevel) bool {
19882068
19892069 if !isIP4Addr(fl) {
19942074 return err == nil
19952075 }
19962076
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.
19982078 func isTCP6AddrResolvable(fl FieldLevel) bool {
19992079
20002080 if !isIP6Addr(fl) {
20062086 return err == nil
20072087 }
20082088
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.
20102090 func isTCPAddrResolvable(fl FieldLevel) bool {
20112091
20122092 if !isIP4Addr(fl) && !isIP6Addr(fl) {
20182098 return err == nil
20192099 }
20202100
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.
20222102 func isUDP4AddrResolvable(fl FieldLevel) bool {
20232103
20242104 if !isIP4Addr(fl) {
20302110 return err == nil
20312111 }
20322112
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.
20342114 func isUDP6AddrResolvable(fl FieldLevel) bool {
20352115
20362116 if !isIP6Addr(fl) {
20422122 return err == nil
20432123 }
20442124
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.
20462126 func isUDPAddrResolvable(fl FieldLevel) bool {
20472127
20482128 if !isIP4Addr(fl) && !isIP6Addr(fl) {
20542134 return err == nil
20552135 }
20562136
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.
20582138 func isIP4AddrResolvable(fl FieldLevel) bool {
20592139
20602140 if !isIPv4(fl) {
20662146 return err == nil
20672147 }
20682148
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.
20702150 func isIP6AddrResolvable(fl FieldLevel) bool {
20712151
20722152 if !isIPv6(fl) {
20782158 return err == nil
20792159 }
20802160
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.
20822162 func isIPAddrResolvable(fl FieldLevel) bool {
20832163
20842164 if !isIP(fl) {
20902170 return err == nil
20912171 }
20922172
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.
20942174 func isUnixAddrResolvable(fl FieldLevel) bool {
20952175
20962176 _, err := net.ResolveUnixAddr("unix", fl.Field().String())
21442224 return fqdnRegexRFC1123.MatchString(val)
21452225 }
21462226
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.
21482228 func isDir(fl FieldLevel) bool {
21492229 field := fl.Field()
21502230
21702250 }
21712251
21722252 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())
21732258 }
21742259
21752260 // isHostnamePort validates a <dns>:<port> combination for fields typically used for socket address.
22732358
22742359 var code int
22752360 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
22762367 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
22772368 code = int(field.Int() % 1000)
22782369 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
22822373 }
22832374 return iso3166_1_alpha_numeric[code]
22842375 }
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 }
159159 704: true, 92: true, 850: true, 876: true, 732: true,
160160 887: true, 894: true, 716: true, 248: true,
161161 }
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 }
55 and has the ability to dive into arrays and maps of any type.
66
77 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.
816
917 Validation Functions Return Type error
1018
725733
726734 Usage: alphanumunicode
727735
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
728742 Number
729743
730744 This validates that a string value contains number values only.
809823 This validates that a string value is valid JSON
810824
811825 Usage: json
826
827 JWT String
828
829 This validates that a string value is a valid JWT
830
831 Usage: jwt
812832
813833 File path
814834
9861006
9871007 Usage: uuid5
9881008
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
9891015 ASCII
9901016
9911017 This validates that a string value contains only ASCII characters.
12201246
12211247 Usage: iso3166_1_alpha3
12221248
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
12231270 TimeZone
12241271
12251272 This validates that a string value is a valid time zone based on the time zone database present on the system.
12271274 More information on https://golang.org/pkg/time/#LoadLocation
12281275
12291276 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
12311284
12321285 Alias Validators and Tags
12331286
8181 // FieldError contains all functions to get error details
8282 type FieldError interface {
8383
84 // returns the validation tag that failed. if the
84 // Tag returns the validation tag that failed. if the
8585 // validation was an alias, this will return the
8686 // alias name and not the underlying tag that failed.
8787 //
8989 // will return "iscolor"
9090 Tag() string
9191
92 // returns the validation tag that failed, even if an
92 // ActualTag returns the validation tag that failed, even if an
9393 // alias the actual tag within the alias will be returned.
9494 // If an 'or' validation fails the entire or will be returned.
9595 //
9797 // will return "hexcolor|rgb|rgba|hsl|hsla"
9898 ActualTag() string
9999
100 // returns the namespace for the field error, with the tag
100 // Namespace returns the namespace for the field error, with the tag
101101 // name taking precedence over the field's actual name.
102102 //
103103 // eg. JSON name "User.fname"
108108 // using validate.Field(...) as there is no way to extract it's name
109109 Namespace() string
110110
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
112112 // actual name.
113113 //
114114 // eq. "User.FirstName" see Namespace for comparison
117117 // using validate.Field(...) as there is no way to extract its name
118118 StructNamespace() string
119119
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
121121 // field's actual name.
122122 //
123123 // eq. JSON name "fname"
124124 // see StructField for comparison
125125 Field() string
126126
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.
128128 //
129129 // eq. "FirstName"
130130 // see Field for comparison
131131 StructField() string
132132
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
134134 // message
135135 Value() interface{}
136136
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
138138 // help with generating an error message
139139 Param() string
140140
145145
146146 // Type returns the Field's reflect Type
147147 //
148 // // eg. time.Time's type is time.Time
148 // eg. time.Time's type is time.Time
149149 Type() reflect.Type
150150
151 // returns the FieldError's translated error
151 // Translate returns the FieldError's translated error
152152 // from the provided 'ut.Translator' and registered 'TranslationFunc'
153153 //
154154 // NOTE: if no registered translator can be found it returns the same as
220220 // return fld
221221 }
222222
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.
224224 func (fe *fieldError) StructField() string {
225225 // return fe.structField
226226 return fe.structNs[len(fe.structNs)-int(fe.structfieldLen):]
44 // FieldLevel contains all the information and helper functions
55 // to validate a field
66 type FieldLevel interface {
7 // returns the top level struct, if any
7
8 // Top returns the top level struct, if any
89 Top() reflect.Value
910
10 // returns the current fields parent struct, if any or
11 // Parent returns the current fields parent struct, if any or
1112 // the comparison value if called 'VarWithValue'
1213 Parent() reflect.Value
1314
14 // returns current field for validation
15 // Field returns current field for validation
1516 Field() reflect.Value
1617
17 // returns the field's name with the tag
18 // FieldName returns the field's name with the tag
1819 // name taking precedence over the fields actual name.
1920 FieldName() string
2021
21 // returns the struct field's name
22 // StructFieldName returns the struct field's name
2223 StructFieldName() string
2324
24 // returns param for validation against current field
25 // Param returns param for validation against current field
2526 Param() string
2627
2728 // GetTag returns the current validations tag name
3233 // underlying value and it's kind.
3334 ExtractType(field reflect.Value) (value reflect.Value, kind reflect.Kind, nullable bool)
3435
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
3637 // in the param and returns the field, field kind and whether is was successful in retrieving
3738 // the field at all.
3839 //
4849 // Deprecated: Use GetStructFieldOKAdvanced2() instead which also return if the value is nullable.
4950 GetStructFieldOKAdvanced(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool)
5051
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
5253 // in the param and returns the field, field kind, if it's a nullable type and whether is was successful in retrieving
5354 // the field at all.
5455 //
5657 // could not be retrieved because it didn't exist.
5758 GetStructFieldOK2() (reflect.Value, reflect.Kind, bool, bool)
5859
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
6061 // the field and namespace allowing more extensibility for validators.
6162 GetStructFieldOKAdvanced2(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool, bool)
6263 }
106107 return current, kind, found
107108 }
108109
109 // GetStructFieldOK returns Param returns param for validation against current field
110 // GetStructFieldOK2 returns Param returns param for validation against current field
110111 func (v *validate) GetStructFieldOK2() (reflect.Value, reflect.Kind, bool, bool) {
111112 return v.getStructFieldOKInternal(v.slflParent, v.ct.param)
112113 }
113114
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
115116 // the field and namespace allowing more extensibility for validators.
116117 func (v *validate) GetStructFieldOKAdvanced2(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool, bool) {
117118 return v.getStructFieldOKInternal(val, namespace)
22 go 1.13
33
44 require (
5 github.com/davecgh/go-spew v1.1.1 // indirect
56 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
1018 )
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=
11 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=
24 github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
35 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=
1021 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1122 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=
1226 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=
2343 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=
2544 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 }
99 numericRegexString = "^[-+]?[0-9]+(?:\\.[0-9]+)?$"
1010 numberRegexString = "^[0-9]+$"
1111 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})$"
1313 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*\\)$"
1414 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*\\)$"
1515 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*\\)$"
2828 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}$"
2929 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}$"
3030 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}$"
3132 aSCIIRegexString = "^[\x00-\x7F]*$"
3233 printableASCIIRegexString = "^[\x20-\x7E]*$"
3334 multibyteRegexString = "[^\x00-\x7F]"
4445 ethAddressRegexString = `^0x[0-9a-fA-F]{40}$`
4546 ethAddressUpperRegexString = `^0x[0-9A-F]{40}$`
4647 ethAddressLowerRegexString = `^0x[0-9a-f]{40}$`
47 uRLEncodedRegexString = `(%[A-Fa-f0-9]{2})`
48 uRLEncodedRegexString = `^(?:[^%]|%[0-9A-Fa-f]{2})*$`
4849 hTMLEncodedRegexString = `&#[x]?([0-9a-fA-F]{2})|(&gt)|(&lt)|(&quot)|(&amp)+[;]?`
4950 hTMLRegexString = `<[/]?([a-zA-Z]+).*?>`
51 jWTRegexString = "^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$"
5052 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}$"
5156 )
5257
5358 var (
5863 numericRegex = regexp.MustCompile(numericRegexString)
5964 numberRegex = regexp.MustCompile(numberRegexString)
6065 hexadecimalRegex = regexp.MustCompile(hexadecimalRegexString)
61 hexcolorRegex = regexp.MustCompile(hexcolorRegexString)
66 hexColorRegex = regexp.MustCompile(hexColorRegexString)
6267 rgbRegex = regexp.MustCompile(rgbRegexString)
6368 rgbaRegex = regexp.MustCompile(rgbaRegexString)
6469 hslRegex = regexp.MustCompile(hslRegexString)
7782 uUID4RFC4122Regex = regexp.MustCompile(uUID4RFC4122RegexString)
7883 uUID5RFC4122Regex = regexp.MustCompile(uUID5RFC4122RegexString)
7984 uUIDRFC4122Regex = regexp.MustCompile(uUIDRFC4122RegexString)
85 uLIDRegex = regexp.MustCompile(uLIDRegexString)
8086 aSCIIRegex = regexp.MustCompile(aSCIIRegexString)
8187 printableASCIIRegex = regexp.MustCompile(printableASCIIRegexString)
8288 multibyteRegex = regexp.MustCompile(multibyteRegexString)
9197 btcUpperAddressRegexBech32 = regexp.MustCompile(btcAddressUpperRegexStringBech32)
9298 btcLowerAddressRegexBech32 = regexp.MustCompile(btcAddressLowerRegexStringBech32)
9399 ethAddressRegex = regexp.MustCompile(ethAddressRegexString)
94 ethaddressRegexUpper = regexp.MustCompile(ethAddressUpperRegexString)
100 ethAddressRegexUpper = regexp.MustCompile(ethAddressUpperRegexString)
95101 ethAddressRegexLower = regexp.MustCompile(ethAddressLowerRegexString)
96102 uRLEncodedRegex = regexp.MustCompile(uRLEncodedRegexString)
97103 hTMLEncodedRegex = regexp.MustCompile(hTMLEncodedRegexString)
98104 hTMLRegex = regexp.MustCompile(hTMLRegexString)
105 jWTRegex = regexp.MustCompile(jWTRegexString)
99106 splitParamsRegex = regexp.MustCompile(splitParamsRegexString)
107 bicRegex = regexp.MustCompile(bicRegexString)
108 semverRegex = regexp.MustCompile(semverRegexString)
109 dnsRegexRFC1035Label = regexp.MustCompile(dnsRegexStringRFC1035Label)
100110 )
2222 // to validate a struct
2323 type StructLevel interface {
2424
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.
2626 // this is so you don't have to use anonymous functions to get access to the validate
2727 // instance.
2828 Validator() *Validate
2929
30 // returns the top level struct, if any
30 // Top returns the top level struct, if any
3131 Top() reflect.Value
3232
33 // returns the current fields parent struct, if any
33 // Parent returns the current fields parent struct, if any
3434 Parent() reflect.Value
3535
36 // returns the current struct.
36 // Current returns the current struct.
3737 Current() reflect.Value
3838
3939 // ExtractType gets the actual underlying type of field value.
4141 // underlying value and its kind.
4242 ExtractType(field reflect.Value) (value reflect.Value, kind reflect.Kind, nullable bool)
4343
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
4545 //
4646 // NOTES:
4747 //
5353 // and process on the flip side it's up to you.
5454 ReportError(field interface{}, fieldName, structFieldName string, tag, param string)
5555
56 // reports an error just by passing ValidationErrors
56 // ReportValidationErrors reports an error just by passing ValidationErrors
5757 //
5858 // NOTES:
5959 //
1515 // RegisterDefaultTranslations registers a set of default translations
1616 // for all built in tag's in validator; you may add your own as desired.
1717 func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (err error) {
18
1918 translations := []struct {
2019 tag string
2120 translation string
3130 {
3231 tag: "len",
3332 customRegisFunc: func(ut ut.Translator) (err error) {
34
3533 if err = ut.Add("len-string", "{0} must be {1} in length", false); err != nil {
3634 return
3735 }
6058 }
6159
6260 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 {
6763 var err error
6864 var t string
6965
122118 {
123119 tag: "min",
124120 customRegisFunc: func(ut ut.Translator) (err error) {
125
126121 if err = ut.Add("min-string", "{0} must be at least {1} in length", false); err != nil {
127122 return
128123 }
151146 }
152147
153148 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 {
158151 var err error
159152 var t string
160153
213206 {
214207 tag: "max",
215208 customRegisFunc: func(ut ut.Translator) (err error) {
216
217209 if err = ut.Add("max-string", "{0} must be a maximum of {1} in length", false); err != nil {
218210 return
219211 }
242234 }
243235
244236 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 {
249239 var err error
250240 var t string
251241
306296 translation: "{0} is not equal to {1}",
307297 override: false,
308298 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
309
310299 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
311300 if err != nil {
312301 fmt.Printf("warning: error translating FieldError: %#v", fe)
321310 translation: "{0} should not be equal to {1}",
322311 override: false,
323312 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
324
325313 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
326314 if err != nil {
327315 fmt.Printf("warning: error translating FieldError: %#v", fe)
334322 {
335323 tag: "lt",
336324 customRegisFunc: func(ut ut.Translator) (err error) {
337
338325 if err = ut.Add("lt-string", "{0} must be less than {1} in length", false); err != nil {
339326 return
340327 }
368355 }
369356
370357 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 {
375360 var err error
376361 var t string
377362 var f64 float64
379364 var kind reflect.Kind
380365
381366 fn := func() (err error) {
382
383367 if idx := strings.Index(fe.Param(), "."); idx != -1 {
384368 digits = uint64(len(fe.Param()[idx+1:]))
385369 }
455439 {
456440 tag: "lte",
457441 customRegisFunc: func(ut ut.Translator) (err error) {
458
459442 if err = ut.Add("lte-string", "{0} must be at maximum {1} in length", false); err != nil {
460443 return
461444 }
491474 return
492475 },
493476 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
494
495477 var err error
496478 var t string
497479 var f64 float64
499481 var kind reflect.Kind
500482
501483 fn := func() (err error) {
502
503484 if idx := strings.Index(fe.Param(), "."); idx != -1 {
504485 digits = uint64(len(fe.Param()[idx+1:]))
505486 }
575556 {
576557 tag: "gt",
577558 customRegisFunc: func(ut ut.Translator) (err error) {
578
579559 if err = ut.Add("gt-string", "{0} must be greater than {1} in length", false); err != nil {
580560 return
581561 }
611591 return
612592 },
613593 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
614
615594 var err error
616595 var t string
617596 var f64 float64
619598 var kind reflect.Kind
620599
621600 fn := func() (err error) {
622
623601 if idx := strings.Index(fe.Param(), "."); idx != -1 {
624602 digits = uint64(len(fe.Param()[idx+1:]))
625603 }
695673 {
696674 tag: "gte",
697675 customRegisFunc: func(ut ut.Translator) (err error) {
698
699676 if err = ut.Add("gte-string", "{0} must be at least {1} in length", false); err != nil {
700677 return
701678 }
731708 return
732709 },
733710 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
734
735711 var err error
736712 var t string
737713 var f64 float64
739715 var kind reflect.Kind
740716
741717 fn := func() (err error) {
742
743718 if idx := strings.Index(fe.Param(), "."); idx != -1 {
744719 digits = uint64(len(fe.Param()[idx+1:]))
745720 }
817792 translation: "{0} must be equal to {1}",
818793 override: false,
819794 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
820
821795 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
822796 if err != nil {
823797 log.Printf("warning: error translating FieldError: %#v", fe)
832806 translation: "{0} must be equal to {1}",
833807 override: false,
834808 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
835
836809 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
837810 if err != nil {
838811 log.Printf("warning: error translating FieldError: %#v", fe)
847820 translation: "{0} cannot be equal to {1}",
848821 override: false,
849822 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
850
851823 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
852824 if err != nil {
853825 log.Printf("warning: error translating FieldError: %#v", fe)
862834 translation: "{0} must be greater than {1}",
863835 override: false,
864836 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
865
866837 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
867838 if err != nil {
868839 log.Printf("warning: error translating FieldError: %#v", fe)
877848 translation: "{0} must be greater than or equal to {1}",
878849 override: false,
879850 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
880
881851 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
882852 if err != nil {
883853 log.Printf("warning: error translating FieldError: %#v", fe)
892862 translation: "{0} must be less than {1}",
893863 override: false,
894864 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
895
896865 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
897866 if err != nil {
898867 log.Printf("warning: error translating FieldError: %#v", fe)
907876 translation: "{0} must be less than or equal to {1}",
908877 override: false,
909878 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
910
911879 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
912880 if err != nil {
913881 log.Printf("warning: error translating FieldError: %#v", fe)
922890 translation: "{0} cannot be equal to {1}",
923891 override: false,
924892 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
925
926893 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
927894 if err != nil {
928895 log.Printf("warning: error translating FieldError: %#v", fe)
937904 translation: "{0} must be greater than {1}",
938905 override: false,
939906 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
940
941907 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
942908 if err != nil {
943909 log.Printf("warning: error translating FieldError: %#v", fe)
952918 translation: "{0} must be greater than or equal to {1}",
953919 override: false,
954920 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
955
956921 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
957922 if err != nil {
958923 log.Printf("warning: error translating FieldError: %#v", fe)
967932 translation: "{0} must be less than {1}",
968933 override: false,
969934 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
970
971935 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
972936 if err != nil {
973937 log.Printf("warning: error translating FieldError: %#v", fe)
982946 translation: "{0} must be less than or equal to {1}",
983947 override: false,
984948 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
985
986949 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
987950 if err != nil {
988951 log.Printf("warning: error translating FieldError: %#v", fe)
10721035 translation: "{0} must contain the text '{1}'",
10731036 override: false,
10741037 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1075
10761038 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
10771039 if err != nil {
10781040 log.Printf("warning: error translating FieldError: %#v", fe)
10871049 translation: "{0} must contain at least one of the following characters '{1}'",
10881050 override: false,
10891051 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1090
10911052 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
10921053 if err != nil {
10931054 log.Printf("warning: error translating FieldError: %#v", fe)
11021063 translation: "{0} cannot contain the text '{1}'",
11031064 override: false,
11041065 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1105
11061066 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
11071067 if err != nil {
11081068 log.Printf("warning: error translating FieldError: %#v", fe)
11171077 translation: "{0} cannot contain any of the following characters '{1}'",
11181078 override: false,
11191079 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1120
11211080 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
11221081 if err != nil {
11231082 log.Printf("warning: error translating FieldError: %#v", fe)
11321091 translation: "{0} cannot contain the following '{1}'",
11331092 override: false,
11341093 customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
1135
11361094 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
11371095 if err != nil {
11381096 log.Printf("warning: error translating FieldError: %#v", fe)
11781136 override: false,
11791137 },
11801138 {
1139 tag: "ulid",
1140 translation: "{0} must be a valid ULID",
1141 override: false,
1142 },
1143 {
11811144 tag: "ascii",
11821145 translation: "{0} must contain only ascii characters",
11831146 override: false,
13241287 tag: "json",
13251288 translation: "{0} must be a valid json string",
13261289 override: false,
1327 },
1328 {
1290 },
1291 {
1292 tag: "jwt",
1293 translation: "{0} must be a valid jwt string",
1294 override: false,
1295 },
1296 {
13291297 tag: "lowercase",
13301298 translation: "{0} must be a lowercase string",
13311299 override: false,
13401308 translation: "{0} does not match the {1} format",
13411309 override: false,
13421310 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 {
13441339 t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
13451340 if err != nil {
13461341 log.Printf("warning: error translating FieldError: %#v", fe)
13551350 for _, t := range translations {
13561351
13571352 if t.customTransFunc != nil && t.customRegisFunc != nil {
1358
13591353 err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, t.customTransFunc)
1360
13611354 } else if t.customTransFunc != nil && t.customRegisFunc == nil {
1362
13631355 err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), t.customTransFunc)
1364
13651356 } else if t.customTransFunc == nil && t.customRegisFunc != nil {
1366
13671357 err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, translateFunc)
1368
13691358 } else {
13701359 err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), translateFunc)
13711360 }
13791368 }
13801369
13811370 func registrationFunc(tag string, translation string, override bool) validator.RegisterTranslationsFunc {
1382
13831371 return func(ut ut.Translator) (err error) {
1384
13851372 if err = ut.Add(tag, translation, override); err != nil {
13861373 return
13871374 }
13881375
13891376 return
1390
13911377 }
1392
13931378 }
13941379
13951380 func translateFunc(ut ut.Translator, fe validator.FieldError) string {
1396
13971381 t, err := ut.T(fe.Tag(), fe.Field())
13981382 if err != nil {
13991383 log.Printf("warning: error translating FieldError: %#v", fe)
1010 )
1111
1212 func TestTranslations(t *testing.T) {
13
1413 eng := english.New()
1514 uni := ut.New(eng, eng)
1615 trans, _ := uni.GetTranslator("en")
103102 UUID3 string `validate:"uuid3"`
104103 UUID4 string `validate:"uuid4"`
105104 UUID5 string `validate:"uuid5"`
105 ULID string `validate:"ulid"`
106106 ASCII string `validate:"ascii"`
107107 PrintableASCII string `validate:"printascii"`
108108 MultiByte string `validate:"multibyte"`
141141 UniqueArray [3]string `validate:"unique"`
142142 UniqueMap map[string]string `validate:"unique"`
143143 JSONString string `validate:"json"`
144 JWTString string `validate:"jwt"`
144145 LowercaseString string `validate:"lowercase"`
145146 UppercaseString string `validate:"uppercase"`
146147 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"`
147151 }
148152
149153 var test Test
320324 expected: "UUID5 must be a valid version 5 UUID",
321325 },
322326 {
327 ns: "Test.ULID",
328 expected: "ULID must be a valid ULID",
329 },
330 {
323331 ns: "Test.ISBN",
324332 expected: "ISBN must be a valid ISBN number",
325333 },
644652 expected: "JSONString must be a valid json string",
645653 },
646654 {
655 ns: "Test.JWTString",
656 expected: "JWTString must be a valid jwt string",
657 },
658 {
647659 ns: "Test.LowercaseString",
648660 expected: "LowercaseString must be a lowercase string",
649661 },
654666 {
655667 ns: "Test.Datetime",
656668 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",
657677 },
658678 }
659679
671691 NotEqual(t, fe, nil)
672692 Equal(t, tt.expected, fe.Translate(trans))
673693 }
674
675694 }
11781178 override: false,
11791179 },
11801180 {
1181 tag: "ulid",
1182 translation: "{0} debe ser un ULID válido",
1183 override: false,
1184 },
1185 {
11811186 tag: "ascii",
11821187 translation: "{0} debe contener sólo caracteres ascii",
11831188 override: false,
33 "testing"
44 "time"
55
6 . "github.com/go-playground/assert/v2"
67 spanish "github.com/go-playground/locales/es"
78 ut "github.com/go-playground/universal-translator"
8 . "github.com/go-playground/assert/v2"
99 "github.com/go-playground/validator/v10"
1010 )
1111
103103 UUID3 string `validate:"uuid3"`
104104 UUID4 string `validate:"uuid4"`
105105 UUID5 string `validate:"uuid5"`
106 ULID string `validate:"ulid"`
106107 ASCII string `validate:"ascii"`
107108 PrintableASCII string `validate:"printascii"`
108109 MultiByte string `validate:"multibyte"`
312313 expected: "UUID5 debe ser una versión válida 5 UUID",
313314 },
314315 {
316 ns: "Test.ULID",
317 expected: "ULID debe ser un ULID válido",
318 },
319 {
315320 ns: "Test.ISBN",
316321 expected: "ISBN debe ser un número ISBN válido",
317322 },
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 }
11731173 override: false,
11741174 },
11751175 {
1176 tag: "ulid",
1177 translation: "{0} doit être une ULID valide",
1178 override: false,
1179 },
1180 {
11761181 tag: "ascii",
11771182 translation: "{0} ne doit contenir que des caractères ascii",
11781183 override: false,
33 "testing"
44 "time"
55
6 . "github.com/go-playground/assert/v2"
67 french "github.com/go-playground/locales/fr"
78 ut "github.com/go-playground/universal-translator"
8 . "github.com/go-playground/assert/v2"
99 "github.com/go-playground/validator/v10"
1010 )
1111
103103 UUID3 string `validate:"uuid3"`
104104 UUID4 string `validate:"uuid4"`
105105 UUID5 string `validate:"uuid5"`
106 ULID string `validate:"ulid"`
106107 ASCII string `validate:"ascii"`
107108 PrintableASCII string `validate:"printascii"`
108109 MultiByte string `validate:"multibyte"`
306307 expected: "UUID5 doit être un UUID version 5 valid",
307308 },
308309 {
310 ns: "Test.ULID",
311 expected: "ULID doit être une ULID valide",
312 },
313 {
309314 ns: "Test.ISBN",
310315 expected: "ISBN doit être un numéro ISBN valid",
311316 },
535540 },
536541 {
537542 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",
539544 },
540545 {
541546 ns: "Test.MaxMultiple",
547552 },
548553 {
549554 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",
551556 },
552557 {
553558 ns: "Test.MinMultiple",
559564 },
560565 {
561566 ns: "Test.LenNumber",
562 expected: "LenNumber doit être égal à 1 113,00",
567 expected: "LenNumber doit être égal à 1 113,00",
563568 },
564569 {
565570 ns: "Test.LenMultiple",
11731173 override: false,
11741174 },
11751175 {
1176 tag: "ulid",
1177 translation: "{0} harus berupa ULID yang valid",
1178 override: false,
1179 },
1180 {
11761181 tag: "ascii",
11771182 translation: "{0} hanya boleh berisi karakter ascii",
11781183 override: false,
33 "testing"
44 "time"
55
6 . "github.com/go-playground/assert/v2"
67 indonesia "github.com/go-playground/locales/id"
78 ut "github.com/go-playground/universal-translator"
8 . "github.com/go-playground/assert/v2"
99 "github.com/go-playground/validator/v10"
1010 )
1111
103103 UUID3 string `validate:"uuid3"`
104104 UUID4 string `validate:"uuid4"`
105105 UUID5 string `validate:"uuid5"`
106 ULID string `validate:"ulid"`
106107 ASCII string `validate:"ascii"`
107108 PrintableASCII string `validate:"printascii"`
108109 MultiByte string `validate:"multibyte"`
306307 expected: "UUID5 harus berupa UUID versi 5 yang valid",
307308 },
308309 {
310 ns: "Test.ULID",
311 expected: "ULID harus berupa ULID yang valid",
312 },
313 {
309314 ns: "Test.ISBN",
310315 expected: "ISBN harus berupa nomor ISBN yang valid",
311316 },
12251225 },
12261226 {
12271227 tag: "uuid5",
1228 translation: "{0}はバージョンが4の正しいUUIDでなければなりません",
1228 translation: "{0}はバージョンが5の正しいUUIDでなければなりません",
1229 override: false,
1230 },
1231 {
1232 tag: "ulid",
1233 translation: "{0}は正しいULIDでなければなりません",
12291234 override: false,
12301235 },
12311236 {
33 "testing"
44 "time"
55
6 . "github.com/go-playground/assert/v2"
67 ja_locale "github.com/go-playground/locales/ja"
78 ut "github.com/go-playground/universal-translator"
8 . "github.com/go-playground/assert/v2"
99 "github.com/go-playground/validator/v10"
1010 )
1111
103103 UUID3 string `validate:"uuid3"`
104104 UUID4 string `validate:"uuid4"`
105105 UUID5 string `validate:"uuid5"`
106 ULID string `validate:"ulid"`
106107 ASCII string `validate:"ascii"`
107108 PrintableASCII string `validate:"printascii"`
108109 MultiByte string `validate:"multibyte"`
303304 },
304305 {
305306 ns: "Test.UUID5",
306 expected: "UUID5はバージョンが4の正しいUUIDでなければなりません",
307 expected: "UUID5はバージョンが5の正しいUUIDでなければなりません",
308 },
309 {
310 ns: "Test.ULID",
311 expected: "ULIDは正しいULIDでなければなりません",
307312 },
308313 {
309314 ns: "Test.ISBN",
11731173 override: false,
11741174 },
11751175 {
1176 tag: "ulid",
1177 translation: "{0} moet een geldige ULID zijn",
1178 override: false,
1179 },
1180 {
11761181 tag: "ascii",
11771182 translation: "{0} mag alleen ascii karakters bevatten",
11781183 override: false,
33 "testing"
44 "time"
55
6 . "github.com/go-playground/assert/v2"
67 english "github.com/go-playground/locales/en"
78 ut "github.com/go-playground/universal-translator"
8 . "github.com/go-playground/assert/v2"
99 "github.com/go-playground/validator/v10"
1010 )
1111
103103 UUID3 string `validate:"uuid3"`
104104 UUID4 string `validate:"uuid4"`
105105 UUID5 string `validate:"uuid5"`
106 ULID string `validate:"ulid"`
106107 ASCII string `validate:"ascii"`
107108 PrintableASCII string `validate:"printascii"`
108109 MultiByte string `validate:"multibyte"`
306307 expected: "UUID5 moet een geldige versie 5 UUID zijn",
307308 },
308309 {
310 ns: "Test.ULID",
311 expected: "ULID moet een geldige ULID zijn",
312 },
313 {
309314 ns: "Test.ISBN",
310315 expected: "ISBN moet een geldig ISBN nummer zijn",
311316 },
11781178 override: false,
11791179 },
11801180 {
1181 tag: "ulid",
1182 translation: "{0} deve ser um ULID válido",
1183 override: false,
1184 },
1185 {
11811186 tag: "ascii",
11821187 translation: "{0} deve conter apenas caracteres ascii",
11831188 override: false,
104104 UUID3 string `validate:"uuid3"`
105105 UUID4 string `validate:"uuid4"`
106106 UUID5 string `validate:"uuid5"`
107 ULID string `validate:"ulid"`
107108 ASCII string `validate:"ascii"`
108109 PrintableASCII string `validate:"printascii"`
109110 MultiByte string `validate:"multibyte"`
321322 expected: "UUID5 deve ser um UUID versão 5 válido",
322323 },
323324 {
325 ns: "Test.ULID",
326 expected: "ULID deve ser um ULID válido",
327 },
328 {
324329 ns: "Test.ISBN",
325330 expected: "ISBN deve ser um número de ISBN válido",
326331 },
11731173 override: false,
11741174 },
11751175 {
1176 tag: "ulid",
1177 translation: "{0} deve ser uma ULID válida",
1178 override: false,
1179 },
1180 {
11761181 tag: "ascii",
11771182 translation: "{0} deve conter apenas caracteres ascii",
11781183 override: false,
33 "testing"
44 "time"
55
6 . "github.com/go-playground/assert/v2"
67 brazilian_portuguese "github.com/go-playground/locales/pt_BR"
78 ut "github.com/go-playground/universal-translator"
89 "github.com/go-playground/validator/v10"
9 . "github.com/go-playground/assert/v2"
1010 )
1111
1212 func TestTranslations(t *testing.T) {
103103 UUID3 string `validate:"uuid3"`
104104 UUID4 string `validate:"uuid4"`
105105 UUID5 string `validate:"uuid5"`
106 ULID string `validate:"ulid"`
106107 ASCII string `validate:"ascii"`
107108 PrintableASCII string `validate:"printascii"`
108109 MultiByte string `validate:"multibyte"`
306307 expected: "UUID5 deve ser um UUID versão 5 válido",
307308 },
308309 {
310 ns: "Test.ULID",
311 expected: "ULID deve ser uma ULID válida",
312 },
313 {
309314 ns: "Test.ISBN",
310315 expected: "ISBN deve ser um número ISBN válido",
311316 },
4040 return
4141 }
4242
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
4351 if err = ut.AddCardinal("len-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil {
4452 return
4553 }
5159 if err = ut.Add("len-items", "{0} должен содержать {1}", false); err != nil {
5260 return
5361 }
62
5463 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 {
5572 return
5673 }
5774
131148 return
132149 }
133150
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
134159 if err = ut.AddCardinal("min-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil {
135160 return
136161 }
143168 return
144169 }
145170 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 {
146179 return
147180 }
148181
222255 return
223256 }
224257
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
225266 if err = ut.AddCardinal("max-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil {
226267 return
227268 }
234275 return
235276 }
236277 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 {
237286 return
238287 }
239288
343392 return
344393 }
345394
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
346403 if err = ut.AddCardinal("lt-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil {
347404 return
348405 }
356413 }
357414
358415 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 {
359424 return
360425 }
361426
464529 return
465530 }
466531
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
467540 if err = ut.AddCardinal("lte-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil {
468541 return
469542 }
477550 }
478551
479552 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 {
480561 return
481562 }
482563
584665 return
585666 }
586667
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
587676 if err = ut.AddCardinal("gt-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil {
588677 return
589678 }
597686 }
598687
599688 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 {
600697 return
601698 }
602699
704801 return
705802 }
706803
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
707812 if err = ut.AddCardinal("gte-string-character", "{0} символы", locales.PluralRuleOther, false); err != nil {
708813 return
709814 }
717822 }
718823
719824 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 {
720833 return
721834 }
722835
11781291 override: false,
11791292 },
11801293 {
1294 tag: "ulid",
1295 translation: "{0} должен быть ULID",
1296 override: false,
1297 },
1298 {
11811299 tag: "ascii",
11821300 translation: "{0} должен содержать только ascii символы",
11831301 override: false,
66 "time"
77
88 . "github.com/go-playground/assert/v2"
9 russian "github.com/go-playground/locales/en"
9 russian "github.com/go-playground/locales/ru"
1010 ut "github.com/go-playground/universal-translator"
1111 "github.com/go-playground/validator/v10"
1212 )
3232 }
3333
3434 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"`
145166 }
146167
147168 var test Test
151172 test.Inner.GteCSFieldString = "1234"
152173
153174 test.MaxString = "1234"
175 test.MaxStringSecond = "12345678"
154176 test.MaxNumber = 2000
155177 test.MaxMultiple = make([]string, 9)
178 test.MaxMultipleSecond = make([]string, 3)
156179
157180 test.LtString = "1234"
181 test.LtStringSecond = "12345678"
158182 test.LtNumber = 6
159183 test.LtMultiple = make([]string, 3)
184 test.LtMultipleSecond = make([]string, 8)
160185 test.LtTime = time.Now().Add(time.Hour * 24)
161186
162187 test.LteString = "1234"
188 test.LteStringSecond = "12345678"
163189 test.LteNumber = 6
164190 test.LteMultiple = make([]string, 3)
191 test.LteMultipleSecond = make([]string, 8)
165192 test.LteTime = time.Now().Add(time.Hour * 24)
166193
167194 test.LtFieldString = "12345"
314341 expected: "UUID5 должен быть UUID 5 версии",
315342 },
316343 {
344 ns: "Test.ULID",
345 expected: "ULID должен быть ULID",
346 },
347 {
317348 ns: "Test.ISBN",
318349 expected: "ISBN должен быть ISBN номером",
319350 },
451482 },
452483 {
453484 ns: "Test.GteString",
454 expected: "GteString должен содержать минимум 3 символы",
485 expected: "GteString должен содержать минимум 3 символа",
486 },
487 {
488 ns: "Test.GteStringSecond",
489 expected: "GteStringSecond должен содержать минимум 7 символов",
455490 },
456491 {
457492 ns: "Test.GteNumber",
458 expected: "GteNumber должен быть больше или равно 5.56",
493 expected: "GteNumber должен быть больше или равно 5,56",
459494 },
460495 {
461496 ns: "Test.GteMultiple",
462 expected: "GteMultiple должен содержать минимум 2 элементы",
497 expected: "GteMultiple должен содержать минимум 2 элемента",
498 },
499 {
500 ns: "Test.GteMultipleSecond",
501 expected: "GteMultipleSecond должен содержать минимум 7 элементов",
463502 },
464503 {
465504 ns: "Test.GteTime",
467506 },
468507 {
469508 ns: "Test.GtString",
470 expected: "GtString должен быть длиннее 3 символы",
509 expected: "GtString должен быть длиннее 3 символов",
510 },
511 {
512 ns: "Test.GtStringSecond",
513 expected: "GtStringSecond должен быть длиннее 7 символов",
471514 },
472515 {
473516 ns: "Test.GtNumber",
474 expected: "GtNumber должен быть больше 5.56",
517 expected: "GtNumber должен быть больше 5,56",
475518 },
476519 {
477520 ns: "Test.GtMultiple",
478 expected: "GtMultiple должен содержать более 2 элементы",
521 expected: "GtMultiple должен содержать более 2 элементов",
522 },
523 {
524 ns: "Test.GtMultipleSecond",
525 expected: "GtMultipleSecond должен содержать более 7 элементов",
479526 },
480527 {
481528 ns: "Test.GtTime",
483530 },
484531 {
485532 ns: "Test.LteString",
486 expected: "LteString должен содержать максимум 3 символы",
533 expected: "LteString должен содержать максимум 3 символа",
534 },
535 {
536 ns: "Test.LteStringSecond",
537 expected: "LteStringSecond должен содержать максимум 7 символов",
487538 },
488539 {
489540 ns: "Test.LteNumber",
490 expected: "LteNumber должен быть менее или равен 5.56",
541 expected: "LteNumber должен быть менее или равен 5,56",
491542 },
492543 {
493544 ns: "Test.LteMultiple",
494 expected: "LteMultiple должен содержать максимум 2 элементы",
545 expected: "LteMultiple должен содержать максимум 2 элемента",
546 },
547 {
548 ns: "Test.LteMultipleSecond",
549 expected: "LteMultipleSecond должен содержать максимум 7 элементов",
495550 },
496551 {
497552 ns: "Test.LteTime",
499554 },
500555 {
501556 ns: "Test.LtString",
502 expected: "LtString должен иметь менее 3 символы",
557 expected: "LtString должен иметь менее 3 символов",
558 },
559 {
560 ns: "Test.LtStringSecond",
561 expected: "LtStringSecond должен иметь менее 7 символов",
503562 },
504563 {
505564 ns: "Test.LtNumber",
506 expected: "LtNumber должен быть менее 5.56",
565 expected: "LtNumber должен быть менее 5,56",
507566 },
508567 {
509568 ns: "Test.LtMultiple",
510 expected: "LtMultiple должен содержать менее 2 элементы",
569 expected: "LtMultiple должен содержать менее 2 элементов",
570 },
571 {
572 ns: "Test.LtMultipleSecond",
573 expected: "LtMultipleSecond должен содержать менее 7 элементов",
511574 },
512575 {
513576 ns: "Test.LtTime",
539602 },
540603 {
541604 ns: "Test.MaxString",
542 expected: "MaxString должен содержать максимум 3 символы",
605 expected: "MaxString должен содержать максимум 3 символа",
606 },
607 {
608 ns: "Test.MaxStringSecond",
609 expected: "MaxStringSecond должен содержать максимум 7 символов",
543610 },
544611 {
545612 ns: "Test.MaxNumber",
546 expected: "MaxNumber должен быть меньше или равно 1,113.00",
613 expected: "MaxNumber должен быть меньше или равно 1 113,00",
547614 },
548615 {
549616 ns: "Test.MaxMultiple",
550 expected: "MaxMultiple должен содержать максимум 7 элементы",
617 expected: "MaxMultiple должен содержать максимум 7 элементов",
618 },
619 {
620 ns: "Test.MaxMultipleSecond",
621 expected: "MaxMultipleSecond должен содержать максимум 2 элемента",
551622 },
552623 {
553624 ns: "Test.MinString",
554625 expected: "MinString должен содержать минимум 1 символ",
555626 },
556627 {
628 ns: "Test.MinStringMultiple",
629 expected: "MinStringMultiple должен содержать минимум 2 символа",
630 },
631 {
632 ns: "Test.MinStringMultipleSecond",
633 expected: "MinStringMultipleSecond должен содержать минимум 7 символов",
634 },
635 {
557636 ns: "Test.MinNumber",
558 expected: "MinNumber должен быть больше или равно 1,113.00",
637 expected: "MinNumber должен быть больше или равно 1 113,00",
559638 },
560639 {
561640 ns: "Test.MinMultiple",
562 expected: "MinMultiple должен содержать минимум 7 элементы",
641 expected: "MinMultiple должен содержать минимум 7 элементов",
642 },
643 {
644 ns: "Test.MinMultipleSecond",
645 expected: "MinMultipleSecond должен содержать минимум 2 элемента",
563646 },
564647 {
565648 ns: "Test.LenString",
567650 },
568651 {
569652 ns: "Test.LenNumber",
570 expected: "LenNumber должен быть равен 1,113.00",
653 expected: "LenNumber должен быть равен 1 113,00",
571654 },
572655 {
573656 ns: "Test.LenMultiple",
574 expected: "LenMultiple должен содержать 7 элементы",
657 expected: "LenMultiple должен содержать 7 элементов",
658 },
659 {
660 ns: "Test.LenMultipleSecond",
661 expected: "LenMultipleSecond должен содержать 2 элемента",
575662 },
576663 {
577664 ns: "Test.RequiredString",
587674 },
588675 {
589676 ns: "Test.StrPtrMinLen",
590 expected: "StrPtrMinLen должен содержать минимум 10 символы",
677 expected: "StrPtrMinLen должен содержать минимум 10 символов",
678 },
679 {
680 ns: "Test.StrPtrMinLenSecond",
681 expected: "StrPtrMinLenSecond должен содержать минимум 2 символа",
591682 },
592683 {
593684 ns: "Test.StrPtrMaxLen",
595686 },
596687 {
597688 ns: "Test.StrPtrLen",
598 expected: "StrPtrLen должен быть длиной в 2 символы",
689 expected: "StrPtrLen должен быть длиной в 2 символа",
690 },
691 {
692 ns: "Test.StrPtrLenSecond",
693 expected: "StrPtrLenSecond должен быть длиной в 7 символов",
599694 },
600695 {
601696 ns: "Test.StrPtrLt",
606701 expected: "StrPtrLte должен содержать максимум 1 символ",
607702 },
608703 {
704 ns: "Test.StrPtrLteMultiple",
705 expected: "StrPtrLteMultiple должен содержать максимум 2 символа",
706 },
707 {
708 ns: "Test.StrPtrLteMultipleSecond",
709 expected: "StrPtrLteMultipleSecond должен содержать максимум 7 символов",
710 },
711 {
609712 ns: "Test.StrPtrGt",
610 expected: "StrPtrGt должен быть длиннее 10 символы",
713 expected: "StrPtrGt должен быть длиннее 10 символов",
714 },
715 {
716 ns: "Test.StrPtrGtSecond",
717 expected: "StrPtrGtSecond должен быть длиннее 2 символов",
611718 },
612719 {
613720 ns: "Test.StrPtrGte",
614 expected: "StrPtrGte должен содержать минимум 10 символы",
721 expected: "StrPtrGte должен содержать минимум 10 символов",
722 },
723 {
724 ns: "Test.StrPtrGteSecond",
725 expected: "StrPtrGteSecond должен содержать минимум 2 символа",
615726 },
616727 {
617728 ns: "Test.OneOfString",
11731173 override: false,
11741174 },
11751175 {
1176 tag: "ulid",
1177 translation: "{0} geçerli bir ULID olmalıdır",
1178 override: false,
1179 },
1180 {
11761181 tag: "ascii",
11771182 translation: "{0} yalnızca ascii karakterler içermelidir",
11781183 override: false,
33 "testing"
44 "time"
55
6 . "github.com/go-playground/assert/v2"
67 turkish "github.com/go-playground/locales/tr"
78 ut "github.com/go-playground/universal-translator"
8 . "github.com/go-playground/assert/v2"
99 "github.com/go-playground/validator/v10"
1010 )
1111
103103 UUID3 string `validate:"uuid3"`
104104 UUID4 string `validate:"uuid4"`
105105 UUID5 string `validate:"uuid5"`
106 ULID string `validate:"ulid"`
106107 ASCII string `validate:"ascii"`
107108 PrintableASCII string `validate:"printascii"`
108109 MultiByte string `validate:"multibyte"`
312313 expected: "UUID5 geçerli bir sürüm 5 UUID olmalıdır",
313314 },
314315 {
316 ns: "Test.ULID",
317 expected: "ULID geçerli bir ULID olmalıdır",
318 },
319 {
315320 ns: "Test.ISBN",
316321 expected: "ISBN geçerli bir ISBN numarası olmalıdır",
317322 },
10001000 override: false,
10011001 },
10021002 {
1003 tag: "alphanumunicode",
1004 translation: "{0}只能包含字母数字和Unicode字符",
1005 override: false,
1006 },
1007 {
1008 tag: "alphaunicode",
1009 translation: "{0}只能包含字母和Unicode字符",
1010 override: false,
1011 },
1012 {
10031013 tag: "numeric",
10041014 translation: "{0}必须是一个有效的数值",
10051015 override: false,
10901100 },
10911101 },
10921102 {
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 {
10931118 tag: "excludes",
10941119 translation: "{0}不能包含文本'{1}'",
10951120 override: false,
11351160 },
11361161 },
11371162 {
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 {
11381193 tag: "isbn",
11391194 translation: "{0}必须是一个有效的ISBN编号",
11401195 override: false,
11671222 {
11681223 tag: "uuid5",
11691224 translation: "{0}必须是一个有效的V5 UUID",
1225 override: false,
1226 },
1227 {
1228 tag: "ulid",
1229 translation: "{0}必须是一个有效的ULID",
11701230 override: false,
11711231 },
11721232 {
3030 }
3131
3232 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"`
144150 }
145151
146152 var test Test
171177
172178 test.AlphaString = "abc3"
173179 test.AlphanumString = "abc3!"
180 test.AlphanumUnicodeString = "abc3啊!"
181 test.AlphaUnicodeString = "abc3啊"
174182 test.NumericString = "12E.00"
175183 test.NumberString = "12E"
176184
177185 test.Excludes = "this is some test text"
178186 test.ExcludesAll = "This is Great!"
179187 test.ExcludesRune = "Love it ☻"
188
189 test.EndsWith = "this is some test text"
190 test.StartsWith = "this is some test text"
180191
181192 test.ASCII = "カタカナ"
182193 test.PrintableASCII = "カタカナ"
317328 expected: "UUID5必须是一个有效的V5 UUID",
318329 },
319330 {
331 ns: "Test.ULID",
332 expected: "ULID必须是一个有效的ULID",
333 },
334 {
320335 ns: "Test.ISBN",
321336 expected: "ISBN必须是一个有效的ISBN编号",
322337 },
329344 expected: "ISBN13必须是一个有效的ISBN-13编号",
330345 },
331346 {
347 ns: "Test.EndsWith",
348 expected: "EndsWith必须以文本'end'结尾",
349 },
350 {
351 ns: "Test.StartsWith",
352 expected: "StartsWith必须以文本'start'开头",
353 },
354 {
332355 ns: "Test.Excludes",
333356 expected: "Excludes不能包含文本'text'",
334357 },
341364 expected: "ExcludesRune不能包含'☻'",
342365 },
343366 {
367 ns: "Test.ContainsRune",
368 expected: "ContainsRune必须包含字符'☻'",
369 },
370 {
344371 ns: "Test.ContainsAny",
345372 expected: "ContainsAny必须包含至少一个以下字符'!@#$'",
346373 },
395422 {
396423 ns: "Test.NumericString",
397424 expected: "NumericString必须是一个有效的数值",
425 },
426 {
427 ns: "Test.AlphaUnicodeString",
428 expected: "AlphaUnicodeString只能包含字母和Unicode字符",
429 },
430 {
431 ns: "Test.AlphanumUnicodeString",
432 expected: "AlphanumUnicodeString只能包含字母数字和Unicode字符",
398433 },
399434 {
400435 ns: "Test.AlphanumString",
11661166 override: false,
11671167 },
11681168 {
1169 tag: "ulid",
1170 translation: "{0}必須是一個有效的ULID",
1171 override: false,
1172 },
1173 {
11691174 tag: "ascii",
11701175 translation: "{0}必須只包含ascii字元",
11711176 override: false,
103103 UUID3 string `validate:"uuid3"`
104104 UUID4 string `validate:"uuid4"`
105105 UUID5 string `validate:"uuid5"`
106 ULID string `validate:"ulid"`
106107 ASCII string `validate:"ascii"`
107108 PrintableASCII string `validate:"printascii"`
108109 MultiByte string `validate:"multibyte"`
309310 expected: "UUID5必須是一個有效的V5 UUID",
310311 },
311312 {
313 ns: "Test.ULID",
314 expected: "ULID必須是一個有效的ULID",
315 },
316 {
312317 ns: "Test.ISBN",
313318 expected: "ISBN必須是一個有效的ISBN編號",
314319 },
7373 }
7474 }
7575
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)
7777 }
7878 }
7979
221221 structNs = append(append(structNs, cf.name...), '.')
222222 }
223223
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 {
230230 return
231231 }
232232
2828 requiredWithAllTag = "required_with_all"
2929 requiredIfTag = "required_if"
3030 requiredUnlessTag = "required_unless"
31 excludedWithoutAllTag = "excluded_without_all"
32 excludedWithoutTag = "excluded_without"
33 excludedWithTag = "excluded_with"
34 excludedWithAllTag = "excluded_with_all"
3135 skipValidationTag = "-"
3236 diveTag = "dive"
3337 keysTag = "keys"
8488 }
8589
8690 // 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.
8795 func New() *Validate {
8896
8997 tc := new(tagCache)
110118
111119 switch k {
112120 // 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:
114123 _ = v.registerValidation(k, wrapFunc(val), true, true)
115124 default:
116125 // no need to error check here, baked in will always be valid
135144 // SetTagName allows for changing of the default tag name of 'validate'
136145 func (v *Validate) SetTagName(name string) {
137146 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)
138174 }
139175
140176 // RegisterTagNameFunc registers a function to get alternate names for StructFields.
174210
175211 func (v *Validate) registerValidation(tag string, fn FuncCtx, bakedIn bool, nilCheckable bool) error {
176212 if len(tag) == 0 {
177 return errors.New("Function Key cannot be empty")
213 return errors.New("function Key cannot be empty")
178214 }
179215
180216 if fn == nil {
181 return errors.New("Function cannot be empty")
217 return errors.New("function cannot be empty")
182218 }
183219
184220 _, ok := restrictedTags[tag]
408444 if len(flds) > 0 {
409445
410446 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 }
412451
413452 for _, s := range flds {
414453
7070 Gt string `validate:"gt=10"`
7171 Gte string `validate:"gte=10"`
7272 OmitEmpty string `validate:"omitempty,min=1,max=10"`
73 Boolean string `validate:"boolean"`
7374 Sub *SubTest
7475 SubIgnore *SubTest `validate:"-"`
7576 Anonymous struct {
107108 }
108109
109110 func AssertError(t *testing.T, err error, nsKey, structNsKey, field, structField, expectedTag string) {
110
111111 errs := err.(ValidationErrors)
112112
113113 found := false
149149 }
150150
151151 func getError(err error, nsKey, structNsKey string) FieldError {
152
153152 errs := err.(ValidationErrors)
154153
155154 var fe FieldError
169168 }
170169
171170 func (v valuer) Value() (driver.Value, error) {
172
173171 if v.Name == "errorme" {
174172 panic("SQL Driver Valuer error: some kind of error")
175173 // return nil, errors.New("some kind of error")
188186 }
189187
190188 func ValidateCustomType(field reflect.Value) interface{} {
191
192189 if cust, ok := field.Interface().(MadeUpCustomType); ok {
193190
194191 if len(cust.FirstName) == 0 || len(cust.LastName) == 0 {
202199 }
203200
204201 func OverrideIntTypeForSomeReason(field reflect.Value) interface{} {
205
206202 if i, ok := field.Interface().(int); ok {
207203 if i == 1 {
208204 return "1"
222218 }
223219
224220 func ValidateValuerType(field reflect.Value) interface{} {
225
226221 if valuer, ok := field.Interface().(driver.Valuer); ok {
227222
228223 val, err := valuer.Value()
260255 }
261256
262257 func StructValidationTestStructSuccess(sl StructLevel) {
263
264258 st := sl.Current().Interface().(TestStruct)
265259
266260 if st.String != "good value" {
269263 }
270264
271265 func StructValidationTestStruct(sl StructLevel) {
272
273266 st := sl.Current().Interface().(TestStruct)
274267
275268 if st.String != "bad value" {
278271 }
279272
280273 func StructValidationNoTestStructCustomName(sl StructLevel) {
281
282274 st := sl.Current().Interface().(TestStruct)
283275
284276 if st.String != "bad value" {
287279 }
288280
289281 func StructValidationTestStructInvalid(sl StructLevel) {
290
291282 st := sl.Current().Interface().(TestStruct)
292283
293284 if st.String != "bad value" {
296287 }
297288
298289 func StructValidationTestStructReturnValidationErrors(sl StructLevel) {
299
300290 s := sl.Current().Interface().(TestStructReturnValidationErrors)
301291
302292 errs := sl.Validator().Struct(s.Inner1.Inner2)
308298 }
309299
310300 func StructValidationTestStructReturnValidationErrors2(sl StructLevel) {
311
312301 s := sl.Current().Interface().(TestStructReturnValidationErrors)
313302
314303 errs := sl.Validator().Struct(s.Inner1.Inner2)
336325 }
337326
338327 func StructLevelInvalidError(sl StructLevel) {
339
340328 top := sl.Top().Interface().(StructLevelInvalidErr)
341329 s := sl.Current().Interface().(StructLevelInvalidErr)
342330
358346 }
359347
360348 func TestStructLevelInvalidError(t *testing.T) {
361
362349 validate := New()
363350 validate.RegisterStructValidation(StructLevelInvalidError, StructLevelInvalidErr{})
364351
382369 }
383370
384371 func TestNameNamespace(t *testing.T) {
385
386372 type Inner2Namespace struct {
387373 String []string `validate:"dive,required" json:"JSONString"`
388374 }
431417 }
432418
433419 func TestAnonymous(t *testing.T) {
434
435420 validate := New()
436421 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
437422 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
499484 }
500485
501486 func TestAnonymousSameStructDifferentTags(t *testing.T) {
502
503487 validate := New()
504488 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
505489 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
544528 }
545529
546530 func TestStructLevelReturnValidationErrors(t *testing.T) {
547
548531 validate := New()
549532 validate.RegisterStructValidation(StructValidationTestStructReturnValidationErrors, TestStructReturnValidationErrors{})
550533
574557 }
575558
576559 func TestStructLevelReturnValidationErrorsWithJSON(t *testing.T) {
577
578560 validate := New()
579561 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
580562 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
631613 }
632614
633615 func TestStructLevelValidations(t *testing.T) {
634
635616 v1 := New()
636617 v1.RegisterStructValidation(StructValidationTestStruct, TestStruct{})
637618
665646 }
666647
667648 func TestAliasTags(t *testing.T) {
668
669649 validate := New()
670650 validate.RegisterAlias("iscoloralias", "hexcolor|rgb|rgba|hsl|hsla")
671651
713693 }
714694
715695 func TestNilValidator(t *testing.T) {
716
717696 type TestStruct struct {
718697 Test string `validate:"required"`
719698 }
723702 var val *Validate
724703
725704 fn := func(fl FieldLevel) bool {
726
727705 return fl.Parent().String() == fl.Field().String()
728706 }
729707
948926 NotEqual(t, errs, nil)
949927 AssertError(t, errs, "TestPartial.Anonymous.SubAnonStruct[0].Test", "TestPartial.Anonymous.SubAnonStruct[0].Test", "Test", "Test", "required")
950928
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")
951961 }
952962
953963 func TestCrossStructLteFieldValidation(t *testing.T) {
16371647 i := 1
16381648 j = 1
16391649 k = 1.543
1650 b := true
16401651 arr := []string{"test"}
16411652
16421653 s2 := "abcd"
16431654 i2 := 1
16441655 j2 = 1
16451656 k2 = 1.543
1657 b2 := true
16461658 arr2 := []string{"test"}
16471659 arr3 := []string{"test", "test2"}
16481660 now2 := now
16631675 NotEqual(t, errs, nil)
16641676 AssertError(t, errs, "", "", "", "", "necsfield")
16651677
1678 errs = validate.VarWithValue(b2, b, "necsfield")
1679 NotEqual(t, errs, nil)
1680 AssertError(t, errs, "", "", "", "", "necsfield")
1681
16661682 errs = validate.VarWithValue(arr2, arr, "necsfield")
16671683 NotEqual(t, errs, nil)
16681684 AssertError(t, errs, "", "", "", "", "necsfield")
17881804 errs = validate.Struct(test)
17891805 Equal(t, errs, nil)
17901806
1791 newTime := time.Now().UTC()
1807 newTime := time.Now().Add(time.Hour).UTC()
17921808 test.CreatedAt = &newTime
17931809
17941810 errs = validate.Struct(test)
18011817 i := 1
18021818 j = 1
18031819 k = 1.543
1820 b := true
18041821 arr := []string{"test"}
18051822
18061823 var j2 uint64
18091826 i2 := 1
18101827 j2 = 1
18111828 k2 = 1.543
1829 b2 := true
18121830 arr2 := []string{"test"}
18131831 arr3 := []string{"test", "test2"}
18141832 now2 := now
18251843 errs = validate.VarWithValue(k2, k, "eqcsfield")
18261844 Equal(t, errs, nil)
18271845
1846 errs = validate.VarWithValue(b2, b, "eqcsfield")
1847 Equal(t, errs, nil)
1848
18281849 errs = validate.VarWithValue(arr2, arr, "eqcsfield")
18291850 Equal(t, errs, nil)
18301851
19271948 }
19281949
19291950 func TestCrossNamespaceFieldValidation(t *testing.T) {
1930
19311951 type SliceStruct struct {
19321952 Name string
19331953 }
21652185 }
21662186
21672187 func TestExistsValidation(t *testing.T) {
2168
21692188 jsonText := "{ \"truthiness2\": true }"
21702189
21712190 type Thing struct {
21962215 }
21972216
21982217 func TestSQLValue2Validation(t *testing.T) {
2199
22002218 validate := New()
22012219 validate.RegisterCustomTypeFunc(ValidateValuerType, valuer{}, (*driver.Valuer)(nil), sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{})
22022220 validate.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{})
22472265 }
22482266
22492267 func TestSQLValueValidation(t *testing.T) {
2250
22512268 validate := New()
22522269 validate.RegisterCustomTypeFunc(ValidateValuerType, (*driver.Valuer)(nil), valuer{})
22532270 validate.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{})
29252942 }
29262943
29272944 func TestSliceMapArrayChanFuncPtrInterfaceRequiredValidation(t *testing.T) {
2928
29292945 validate := New()
29302946
29312947 var m map[string]string
30033019 }
30043020
30053021 func TestDatePtrValidationIssueValidation(t *testing.T) {
3006
30073022 type Test struct {
30083023 LastViewed *time.Time
30093024 Reminder *time.Time
30553070 }
30563071
30573072 func TestInterfaceErrValidation(t *testing.T) {
3058
30593073 var v2 interface{} = 1
30603074 var v1 interface{} = v2
30613075
32293243 }
32303244
32313245 func TestMapDiveValidation(t *testing.T) {
3232
32333246 validate := New()
32343247
32353248 n := map[int]interface{}{0: nil}
32703283 // for full test coverage
32713284 s := fmt.Sprint(errs.Error())
32723285 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")
32733301
32743302 type TestMapTimeStruct struct {
32753303 Errs map[int]*time.Time `validate:"gt=0,dive,required"`
33523380 }
33533381
33543382 func TestArrayDiveValidation(t *testing.T) {
3355
33563383 validate := New()
33573384
33583385 arr := []string{"ok", "", "ok"}
42414268 }
42424269 }
42434270
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
42444311 func TestISBNValidation(t *testing.T) {
42454312 tests := []struct {
42464313 param string
43614428 }
43624429
43634430 func TestExcludesRuneValidation(t *testing.T) {
4364
43654431 tests := []struct {
43664432 Value string `validate:"excludesrune=☻"`
43674433 Tag string
43894455 }
43904456
43914457 func TestExcludesAllValidation(t *testing.T) {
4392
43934458 tests := []struct {
43944459 Value string `validate:"excludesall=@!{}[]"`
43954460 Tag string
44354500 }
44364501
44374502 func TestExcludesValidation(t *testing.T) {
4438
44394503 tests := []struct {
44404504 Value string `validate:"excludes=@"`
44414505 Tag string
44634527 }
44644528
44654529 func TestContainsRuneValidation(t *testing.T) {
4466
44674530 tests := []struct {
44684531 Value string `validate:"containsrune=☻"`
44694532 Tag string
44914554 }
44924555
44934556 func TestContainsAnyValidation(t *testing.T) {
4494
44954557 tests := []struct {
44964558 Value string `validate:"containsany=@!{}[]"`
44974559 Tag string
45194581 }
45204582
45214583 func TestContainsValidation(t *testing.T) {
4522
45234584 tests := []struct {
45244585 Value string `validate:"contains=@"`
45254586 Tag string
45564617 i := 1
45574618 j = 1
45584619 k = 1.543
4620 b := true
45594621 arr := []string{"test"}
45604622 now := time.Now().UTC()
45614623
45654627 i2 := 3
45664628 j2 = 2
45674629 k2 = 1.5434456
4630 b2 := false
45684631 arr2 := []string{"test", "test2"}
45694632 arr3 := []string{"test"}
45704633 now2 := now
45814644 errs = validate.VarWithValue(k2, k, "nefield")
45824645 Equal(t, errs, nil)
45834646
4647 errs = validate.VarWithValue(b2, b, "nefield")
4648 Equal(t, errs, nil)
4649
45844650 errs = validate.VarWithValue(arr2, arr, "nefield")
45854651 Equal(t, errs, nil)
45864652
46064672 NotEqual(t, errs, nil)
46074673 AssertError(t, errs, "Test.Start", "Test.Start", "Start", "Start", "nefield")
46084674
4609 now3 := time.Now().UTC()
4675 now3 := time.Now().Add(time.Hour).UTC()
46104676
46114677 sv = &Test{
46124678 Start: &now,
47914857 i := 1
47924858 j = 1
47934859 k = 1.543
4860 b := true
47944861 arr := []string{"test"}
47954862 now := time.Now().UTC()
47964863
48004867 i2 := 1
48014868 j2 = 1
48024869 k2 = 1.543
4870 b2 := true
48034871 arr2 := []string{"test"}
48044872 arr3 := []string{"test", "test2"}
48054873 now2 := now
48164884 errs = validate.VarWithValue(k2, k, "eqfield")
48174885 Equal(t, errs, nil)
48184886
4887 errs = validate.VarWithValue(b2, b, "eqfield")
4888 Equal(t, errs, nil)
4889
48194890 errs = validate.VarWithValue(arr2, arr, "eqfield")
48204891 Equal(t, errs, nil)
48214892
48394910 errs = validate.Struct(sv)
48404911 Equal(t, errs, nil)
48414912
4842 now3 := time.Now().UTC()
4913 now3 := time.Now().Add(time.Hour).UTC()
48434914
48444915 sv = &Test{
48454916 Start: &now,
50955166 }
50965167
50975168 func TestBase64Validation(t *testing.T) {
5098
50995169 validate := New()
51005170
51015171 s := "dW5pY29ybg=="
51995269 }
52005270
52015271 func TestEthereumAddressValidation(t *testing.T) {
5202
52035272 validate := New()
52045273
52055274 tests := []struct {
52535322 }
52545323
52555324 func TestBitcoinAddressValidation(t *testing.T) {
5256
52575325 validate := New()
52585326
52595327 tests := []struct {
53635431 }
53645432
53655433 func TestBitcoinBech32AddressValidation(t *testing.T) {
5366
53675434 validate := New()
53685435
53695436 tests := []struct {
54145481 }
54155482
54165483 func TestNoStructLevelValidation(t *testing.T) {
5417
54185484 type Inner struct {
54195485 Test string `validate:"len=5"`
54205486 }
54465512 }
54475513
54485514 func TestStructOnlyValidation(t *testing.T) {
5449
54505515 type Inner struct {
54515516 Test string `validate:"len=5"`
54525517 }
65126577 Equal(t, errs, nil)
65136578
65146579 fn := func(fl FieldLevel) bool {
6515
65166580 return fl.Parent().String() == fl.Field().String()
65176581 }
65186582
65306594 }
65316595
65326596 func TestAddFunctions(t *testing.T) {
6533
65346597 fn := func(fl FieldLevel) bool {
6535
65366598 return true
65376599 }
65386600
65616623 }
65626624
65636625 func TestChangeTag(t *testing.T) {
6564
65656626 validate := New()
65666627 validate.SetTagName("val")
65676628
72087269 }
72097270
72107271 func TestUrnRFC2141(t *testing.T) {
7211
7212 var tests = []struct {
7272 tests := []struct {
72137273 param string
72147274 expected bool
72157275 }{
72857345 }
72867346
72877347 func TestUrl(t *testing.T) {
7288
7289 var tests = []struct {
7348 tests := []struct {
72907349 param string
72917350 expected bool
72927351 }{
73537412 }
73547413
73557414 func TestUri(t *testing.T) {
7356
7357 var tests = []struct {
7415 tests := []struct {
73587416 param string
73597417 expected bool
73607418 }{
74207478 }
74217479
74227480 func TestOrTag(t *testing.T) {
7423
74247481 validate := New()
74257482
74267483 s := "rgba(0,31,255,0.5)"
74507507 Equal(t, errs, nil)
74517508
74527509 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
74547511 NotEqual(t, errs, nil)
74557512 ve := errs.(ValidationErrors)
74567513 Equal(t, len(ve), 1)
74637520
74647521 v2 := New()
74657522 v2.RegisterTagNameFunc(func(fld reflect.StructField) string {
7466
74677523 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
74687524
74697525 if name == "-" {
74887544 }
74897545
74907546 func TestHsla(t *testing.T) {
7491
74927547 validate := New()
74937548
74947549 s := "hsla(360,100%,100%,1)"
75357590 }
75367591
75377592 func TestHsl(t *testing.T) {
7538
75397593 validate := New()
75407594
75417595 s := "hsl(360,100%,50%)"
75737627 }
75747628
75757629 func TestRgba(t *testing.T) {
7576
75777630 validate := New()
75787631
75797632 s := "rgba(0,31,255,0.5)"
76197672 }
76207673
76217674 func TestRgb(t *testing.T) {
7622
76237675 validate := New()
76247676
76257677 s := "rgb(0,31,255)"
76617713 }
76627714
76637715 func TestEmail(t *testing.T) {
7664
76657716 validate := New()
76667717
76677718 s := "test@mail.com"
77297780 }
77307781
77317782 func TestHexColor(t *testing.T) {
7732
77337783 validate := New()
77347784
77357785 s := "#fff"
77577807 }
77587808
77597809 func TestHexadecimal(t *testing.T) {
7760
77617810 validate := New()
77627811
77637812 s := "ff0044"
77847833 }
77857834
77867835 func TestNumber(t *testing.T) {
7787
77887836 validate := New()
77897837
77907838 s := "1"
78327880 }
78337881
78347882 func TestNumeric(t *testing.T) {
7835
78367883 validate := New()
78377884
78387885 s := "1"
78757922 }
78767923
78777924 func TestAlphaNumeric(t *testing.T) {
7878
78797925 validate := New()
78807926
78817927 s := "abcd123"
78937939 }
78947940
78957941 func TestAlpha(t *testing.T) {
7896
78977942 validate := New()
78987943
78997944 s := "abcd"
79237968 errs = validate.Var(1, "alpha")
79247969 NotEqual(t, errs, nil)
79257970 AssertError(t, errs, "", "", "", "", "alpha")
7926
79277971 }
79287972
79297973 func TestStructStringValidation(t *testing.T) {
7930
79317974 validate := New()
79327975
79337976 tSuccess := &TestString{
79407983 Lte: "0123456789",
79417984 Gt: "01234567890",
79427985 Gte: "0123456789",
7986 Boolean: "true",
79437987 OmitEmpty: "",
79447988 Sub: &SubTest{
79457989 Test: "1",
79718015 Gt: "1",
79728016 Gte: "1",
79738017 OmitEmpty: "12345678901",
8018 Boolean: "nope",
79748019 Sub: &SubTest{
79758020 Test: "",
79768021 },
79888033
79898034 // Assert Top Level
79908035 NotEqual(t, errs, nil)
7991 Equal(t, len(errs.(ValidationErrors)), 13)
8036 Equal(t, len(errs.(ValidationErrors)), 14)
79928037
79938038 // Assert Fields
79948039 AssertError(t, errs, "TestString.Required", "TestString.Required", "Required", "Required", "required")
80018046 AssertError(t, errs, "TestString.Gt", "TestString.Gt", "Gt", "Gt", "gt")
80028047 AssertError(t, errs, "TestString.Gte", "TestString.Gte", "Gte", "Gte", "gte")
80038048 AssertError(t, errs, "TestString.OmitEmpty", "TestString.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
8049 AssertError(t, errs, "TestString.Boolean", "TestString.Boolean", "Boolean", "Boolean", "boolean")
80048050
80058051 // Nested Struct Field Errs
80068052 AssertError(t, errs, "TestString.Anonymous.A", "TestString.Anonymous.A", "A", "A", "required")
80098055 }
80108056
80118057 func TestStructInt32Validation(t *testing.T) {
8012
80138058 type TestInt32 struct {
80148059 Required int `validate:"required"`
80158060 Len int `validate:"len=10"`
80738118 }
80748119
80758120 func TestStructUint64Validation(t *testing.T) {
8076
80778121 validate := New()
80788122
80798123 tSuccess := &TestUint64{
81138157 }
81148158
81158159 func TestStructFloat64Validation(t *testing.T) {
8116
81178160 validate := New()
81188161
81198162 tSuccess := &TestFloat64{
81538196 }
81548197
81558198 func TestStructSliceValidation(t *testing.T) {
8156
81578199 validate := New()
81588200
81598201 tSuccess := &TestSlice{
82038245
82048246 _, ok := fe.Value().([]int)
82058247 Equal(t, ok, true)
8206
82078248 }
82088249
82098250 func TestInvalidStruct(t *testing.T) {
8210
82118251 validate := New()
82128252
82138253 s := &SubTest{
82328272 }
82338273
82348274 func TestInvalidValidatorFunction(t *testing.T) {
8235
82368275 validate := New()
82378276
82388277 s := &SubTest{
82438282 }
82448283
82458284 func TestCustomFieldName(t *testing.T) {
8246
82478285 validate := New()
82488286 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
82498287 name := strings.SplitN(fld.Tag.Get("schema"), ",", 2)[0]
82878325 }
82888326
82898327 func TestMutipleRecursiveExtractStructCache(t *testing.T) {
8290
82918328 validate := New()
82928329
82938330 type Recursive struct {
83048341 ptr := fmt.Sprintf("%p", sc)
83058342
83068343 for i := 0; i < 100; i++ {
8307
83088344 go func() {
83098345 <-proceed
83108346 sc := validate.extractStructCache(current, name)
83178353
83188354 // Thanks @robbrockbank, see https://github.com/go-playground/validator/issues/249
83198355 func TestPointerAndOmitEmpty(t *testing.T) {
8320
83218356 validate := New()
83228357
83238358 type Test struct {
83638398 }
83648399
83658400 func TestRequired(t *testing.T) {
8366
83678401 validate := New()
83688402 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
83698403 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
83878421 }
83888422
83898423 func TestBoolEqual(t *testing.T) {
8390
83918424 validate := New()
83928425
83938426 type Test struct {
84158448 validate := New()
84168449 err := validate.RegisterTranslation("required", trans,
84178450 func(ut ut.Translator) (err error) {
8418
84198451 // using this stype because multiple translation may have to be added for the full translation
84208452 if err = ut.Add("required", "{0} is a required field", false); err != nil {
84218453 return
84228454 }
84238455
84248456 return
8425
84268457 }, func(ut ut.Translator, fe FieldError) string {
8427
84288458 t, err := ut.T(fe.Tag(), fe.Field())
84298459 if err != nil {
84308460 fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError))
84378467
84388468 err = validate.RegisterTranslation("required", fr,
84398469 func(ut ut.Translator) (err error) {
8440
84418470 // using this stype because multiple translation may have to be added for the full translation
84428471 if err = ut.Add("required", "{0} est un champ obligatoire", false); err != nil {
84438472 return
84448473 }
84458474
84468475 return
8447
84488476 }, func(ut ut.Translator, fe FieldError) string {
8449
84508477 t, transErr := ut.T(fe.Tag(), fe.Field())
84518478 if transErr != nil {
84528479 fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError))
85248551 validate := New()
85258552 err = validate.RegisterTranslation("required", trans,
85268553 func(ut ut.Translator) (err error) {
8527
85288554 // using this stype because multiple translation may have to be added for the full translation
85298555 if err = ut.Add("required", "{0} is a required field", false); err != nil {
85308556 return
85318557 }
85328558
85338559 return
8534
85358560 }, func(ut ut.Translator, fe FieldError) string {
8536
85378561 t, err := ut.T(fe.Tag(), fe.Field())
85388562 if err != nil {
85398563 fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError))
85488572 }
85498573
85508574 func TestStructFiltered(t *testing.T) {
8551
85528575 p1 := func(ns []byte) bool {
85538576 if bytes.HasSuffix(ns, []byte("NoTag")) || bytes.HasSuffix(ns, []byte("Required")) {
85548577 return false
87148737 }
87158738
87168739 func TestRequiredPtr(t *testing.T) {
8717
87188740 type Test struct {
87198741 Bool *bool `validate:"required"`
87208742 }
88488870 }
88498871
88508872 func TestAlphanumericUnicodeValidation(t *testing.T) {
8851
88528873 tests := []struct {
88538874 param string
88548875 expected bool
88918912 }
88928913
88938914 func TestArrayStructNamespace(t *testing.T) {
8894
88958915 validate := New()
88968916 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
88978917 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
89208940 }
89218941
89228942 func TestMapStructNamespace(t *testing.T) {
8923
89248943 validate := New()
89258944 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
89268945 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
95759594 {"a%b", false},
95769595 {"1%2", false},
95779596 {"%%a%%", false},
9597 {"hello", true},
9598 {"", true},
9599 {"+", true},
95789600 }
95799601
95809602 validate := New()
96019623 }
96029624
96039625 func TestKeys(t *testing.T) {
9604
96059626 type Test struct {
96069627 Test1 map[string]string `validate:"gt=0,dive,keys,eq=testkey,endkeys,eq=testval" json:"test1"`
96079628 Test2 map[int]int `validate:"gt=0,dive,keys,eq=3,endkeys,eq=4" json:"test2"`
96609681 AssertError(t, err.(ValidationErrors), "Test2.NestedKeys", "Test2.NestedKeys", "NestedKeys", "NestedKeys", "gt")
96619682
96629683 tst2.NestedKeys = map[[1]string]string{
9663 [1]string{"innertestkey"}: "outertestval",
9684 {"innertestkey"}: "outertestval",
96649685 }
96659686
96669687 err = validate.Struct(tst2)
97709791 }
97719792
97729793 func TestKeyOrs(t *testing.T) {
9773
97749794 type Test struct {
97759795 Test1 map[string]string `validate:"gt=0,dive,keys,eq=testkey|eq=testkeyok,endkeys,eq=testval" json:"test1"`
97769796 }
1002710047 Field6 uint `validate:"required_unless=Field5 2" json:"field_6"`
1002810048 Field7 float32 `validate:"required_unless=Field6 0" json:"field_7"`
1002910049 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"`
1003010052 }{
1003110053 FieldE: "test",
1003210054 Field2: &fieldVal,
1003310055 Field3: map[string]string{"key": "val"},
1003410056 Field4: "test",
1003510057 Field5: 2,
10058 Field9: true,
1003610059 }
1003710060
1003810061 validate := New()
1005210075 Field5 string `validate:"required_unless=Field3 0" json:"field_5"`
1005310076 Field6 string `validate:"required_unless=Inner.Field test" json:"field_6"`
1005410077 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"`
1005510080 }{
1005610081 Inner: &Inner{Field: &fieldVal},
1005710082 FieldE: "test",
1006210087 NotEqual(t, errs, nil)
1006310088
1006410089 ve := errs.(ValidationErrors)
10065 Equal(t, len(ve), 3)
10090 Equal(t, len(ve), 4)
1006610091 AssertError(t, errs, "Field3", "Field3", "Field3", "Field3", "required_unless")
1006710092 AssertError(t, errs, "Field4", "Field4", "Field4", "Field4", "required_unless")
1006810093 AssertError(t, errs, "Field7", "Field7", "Field7", "Field7", "required_unless")
10094 AssertError(t, errs, "Field9", "Field9", "Field9", "Field9", "required_unless")
1006910095
1007010096 defer func() {
1007110097 if r := recover(); r == nil {
1020110227 name := fmt.Sprintf("Field%d", i)
1020210228 AssertError(t, errs, name, name, name, name, "excluded_with")
1020310229 }
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)
1020410252 }
1020510253
1020610254 func TestExcludedWithout(t *testing.T) {
1026510313 name := fmt.Sprintf("Field%d", i)
1026610314 AssertError(t, errs, name, name, name, name, "excluded_without")
1026710315 }
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)
1026810336 }
1026910337
1027010338 func TestExcludedWithAll(t *testing.T) {
1033310401 name := fmt.Sprintf("Field%d", i)
1033410402 AssertError(t, errs, name, name, name, name, "excluded_with_all")
1033510403 }
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)
1033610427 }
1033710428
1033810429 func TestExcludedWithoutAll(t *testing.T) {
1035110442 Field2 *string `validate:"excluded_without_all=Field FieldE" json:"field_2"`
1035210443 Field3 map[string]string `validate:"excluded_without_all=Field FieldE" json:"field_3"`
1035310444 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"`
1035510446 }{
1035610447 Inner: &Inner{Field: &fieldVal},
10448 Inner2: &Inner{Field: &fieldVal},
1035710449 Field: "populated",
1035810450 Field1: fieldVal,
1035910451 Field2: &fieldVal,
1039710489 name := fmt.Sprintf("Field%d", i)
1039810490 AssertError(t, errs, name, name, name, name, "excluded_without_all")
1039910491 }
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)
1040010514 }
1040110515
1040210516 func TestRequiredWithAll(t *testing.T) {
1045410568 }
1045510569
1045610570 func TestRequiredWithout(t *testing.T) {
10457
1045810571 type Inner struct {
1045910572 Field *string
1046010573 }
1052010633 }
1052110634
1052210635 func TestRequiredWithoutAll(t *testing.T) {
10523
1052410636 fieldVal := "test"
1052510637 test := struct {
1052610638 Field1 string `validate:"omitempty" json:"field_1"`
1057710689 }
1057810690
1057910691 func TestAbilityToValidateNils(t *testing.T) {
10580
1058110692 type TestStruct struct {
1058210693 Test *string `validate:"nil"`
1058310694 }
1071810829 }, "Bad field type int")
1071910830 }
1072010831
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
1072110868 func Test_hostnameport_validator(t *testing.T) {
10722
1072310869 type Host struct {
1072410870 Addr string `validate:"hostname_port"`
1072510871 }
1082110967 PanicMatches(t, func() {
1082210968 _ = validate.Var(2, "uppercase")
1082310969 }, "Bad field type int")
10824
1082510970 }
1082610971
1082710972 func TestDatetimeValidation(t *testing.T) {
1088911034 }
1089011035 }
1089111036
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
1089211065 func TestIsIso3166Alpha3Validation(t *testing.T) {
1089311066 tests := []struct {
1089411067 value string `validate:"iso3166_1_alpha3"`
1091911092
1092011093 func TestIsIso3166AlphaNumericValidation(t *testing.T) {
1092111094 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{}
1092311131 expected bool
1092411132 }{
1092511133 {248, true},
1092611134 {0, false},
1092711135 {1, false},
11136 {"POL", true},
11137 {"NO", true},
11138 {"248", true},
11139 {"1", false},
11140 {"0", false},
1092811141 }
1092911142
1093011143 validate := New()
1093111144
1093211145 for i, test := range tests {
1093311146
10934 errs := validate.Var(test.value, "iso3166_1_alpha_numeric")
11147 errs := validate.Var(test.value, "country_code")
1093511148
1093611149 if test.expected {
1093711150 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)
1093911152 }
1094011153 } else {
1094111154 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 }
1095011215 }
1095111216
1095211217 func TestTimeZoneValidation(t *testing.T) {
1103211297 })
1103311298 }
1103411299 }
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 }