mirror of
https://github.com/containers/podman.git
synced 2025-09-19 00:56:15 +08:00
Add (podman {image,manifest} push --sign-by-sigstore=param-file.yaml)
(podman push) and (podman manifest push) now support --sign-by-sigstore=param-file, using the containers-sigstore-signing-params.yaml(5) file format. That notably adds support for Fulcio and Rekor signing. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
30
vendor/github.com/go-playground/validator/v10/.gitignore
generated
vendored
Normal file
30
vendor/github.com/go-playground/validator/v10/.gitignore
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
bin
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
*.test
|
||||
*.out
|
||||
*.txt
|
||||
cover.html
|
||||
README.html
|
22
vendor/github.com/go-playground/validator/v10/LICENSE
generated
vendored
Normal file
22
vendor/github.com/go-playground/validator/v10/LICENSE
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Dean Karn
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
16
vendor/github.com/go-playground/validator/v10/MAINTAINERS.md
generated
vendored
Normal file
16
vendor/github.com/go-playground/validator/v10/MAINTAINERS.md
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
## Maintainers Guide
|
||||
|
||||
### Semantic Versioning
|
||||
Semantic versioning as defined [here](https://semver.org) must be strictly adhered to.
|
||||
|
||||
### External Dependencies
|
||||
Any new external dependencies MUST:
|
||||
- Have a compatible LICENSE present.
|
||||
- Be actively maintained.
|
||||
- Be approved by @go-playground/admins
|
||||
|
||||
### PR Merge Requirements
|
||||
- Up-to-date branch.
|
||||
- Passing tests and linting.
|
||||
- CODEOWNERS approval.
|
||||
- Tests that cover both the Happy and Unhappy paths.
|
18
vendor/github.com/go-playground/validator/v10/Makefile
generated
vendored
Normal file
18
vendor/github.com/go-playground/validator/v10/Makefile
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
GOCMD=GO111MODULE=on go
|
||||
|
||||
linters-install:
|
||||
@golangci-lint --version >/dev/null 2>&1 || { \
|
||||
echo "installing linting tools..."; \
|
||||
curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v1.41.1; \
|
||||
}
|
||||
|
||||
lint: linters-install
|
||||
golangci-lint run
|
||||
|
||||
test:
|
||||
$(GOCMD) test -cover -race ./...
|
||||
|
||||
bench:
|
||||
$(GOCMD) test -bench=. -benchmem ./...
|
||||
|
||||
.PHONY: test lint linters-install
|
338
vendor/github.com/go-playground/validator/v10/README.md
generated
vendored
Normal file
338
vendor/github.com/go-playground/validator/v10/README.md
generated
vendored
Normal file
@ -0,0 +1,338 @@
|
||||
Package validator
|
||||
=================
|
||||
<img align="right" src="https://raw.githubusercontent.com/go-playground/validator/v9/logo.png">[](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||

|
||||
[](https://travis-ci.org/go-playground/validator)
|
||||
[](https://coveralls.io/github/go-playground/validator?branch=master)
|
||||
[](https://goreportcard.com/report/github.com/go-playground/validator)
|
||||
[](https://pkg.go.dev/github.com/go-playground/validator/v10)
|
||||

|
||||
|
||||
Package validator implements value validations for structs and individual fields based on tags.
|
||||
|
||||
It has the following **unique** features:
|
||||
|
||||
- Cross Field and Cross Struct validations by using validation tags or custom validators.
|
||||
- Slice, Array and Map diving, which allows any or all levels of a multidimensional field to be validated.
|
||||
- Ability to dive into both map keys and values for validation
|
||||
- Handles type interface by determining it's underlying type prior to validation.
|
||||
- Handles custom field types such as sql driver Valuer see [Valuer](https://golang.org/src/database/sql/driver/types.go?s=1210:1293#L29)
|
||||
- Alias validation tags, which allows for mapping of several validations to a single tag for easier defining of validations on structs
|
||||
- Extraction of custom defined Field Name e.g. can specify to extract the JSON name while validating and have it available in the resulting FieldError
|
||||
- Customizable i18n aware error messages.
|
||||
- Default validator for the [gin](https://github.com/gin-gonic/gin) web framework; upgrading from v8 to v9 in gin see [here](https://github.com/go-playground/validator/tree/master/_examples/gin-upgrading-overriding)
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Use go get.
|
||||
|
||||
go get github.com/go-playground/validator/v10
|
||||
|
||||
Then import the validator package into your own code.
|
||||
|
||||
import "github.com/go-playground/validator/v10"
|
||||
|
||||
Error Return Value
|
||||
-------
|
||||
|
||||
Validation functions return type error
|
||||
|
||||
They return type error to avoid the issue discussed in the following, where err is always != nil:
|
||||
|
||||
* http://stackoverflow.com/a/29138676/3158232
|
||||
* https://github.com/go-playground/validator/issues/134
|
||||
|
||||
Validator returns only InvalidValidationError for bad validation input, nil or ValidationErrors as type error; so, in your code all you need to do is check if the error returned is not nil, and if it's not check if error is InvalidValidationError ( if necessary, most of the time it isn't ) type cast it to type ValidationErrors like so:
|
||||
|
||||
```go
|
||||
err := validate.Struct(mystruct)
|
||||
validationErrors := err.(validator.ValidationErrors)
|
||||
```
|
||||
|
||||
Usage and documentation
|
||||
------
|
||||
|
||||
Please see https://pkg.go.dev/github.com/go-playground/validator/v10 for detailed usage docs.
|
||||
|
||||
##### Examples:
|
||||
|
||||
- [Simple](https://github.com/go-playground/validator/blob/master/_examples/simple/main.go)
|
||||
- [Custom Field Types](https://github.com/go-playground/validator/blob/master/_examples/custom/main.go)
|
||||
- [Struct Level](https://github.com/go-playground/validator/blob/master/_examples/struct-level/main.go)
|
||||
- [Translations & Custom Errors](https://github.com/go-playground/validator/blob/master/_examples/translations/main.go)
|
||||
- [Gin upgrade and/or override validator](https://github.com/go-playground/validator/tree/v9/_examples/gin-upgrading-overriding)
|
||||
- [wash - an example application putting it all together](https://github.com/bluesuncorp/wash)
|
||||
|
||||
Baked-in Validations
|
||||
------
|
||||
|
||||
### Fields:
|
||||
|
||||
| Tag | Description |
|
||||
| - | - |
|
||||
| eqcsfield | Field Equals Another Field (relative)|
|
||||
| eqfield | Field Equals Another Field |
|
||||
| fieldcontains | NOT DOCUMENTED IN doc.go |
|
||||
| fieldexcludes | NOT DOCUMENTED IN doc.go |
|
||||
| gtcsfield | Field Greater Than Another Relative Field |
|
||||
| gtecsfield | Field Greater Than or Equal To Another Relative Field |
|
||||
| gtefield | Field Greater Than or Equal To Another Field |
|
||||
| gtfield | Field Greater Than Another Field |
|
||||
| ltcsfield | Less Than Another Relative Field |
|
||||
| ltecsfield | Less Than or Equal To Another Relative Field |
|
||||
| ltefield | Less Than or Equal To Another Field |
|
||||
| ltfield | Less Than Another Field |
|
||||
| necsfield | Field Does Not Equal Another Field (relative) |
|
||||
| nefield | Field Does Not Equal Another Field |
|
||||
|
||||
### Network:
|
||||
|
||||
| Tag | Description |
|
||||
| - | - |
|
||||
| cidr | Classless Inter-Domain Routing CIDR |
|
||||
| cidrv4 | Classless Inter-Domain Routing CIDRv4 |
|
||||
| cidrv6 | Classless Inter-Domain Routing CIDRv6 |
|
||||
| datauri | Data URL |
|
||||
| fqdn | Full Qualified Domain Name (FQDN) |
|
||||
| hostname | Hostname RFC 952 |
|
||||
| hostname_port | HostPort |
|
||||
| hostname_rfc1123 | Hostname RFC 1123 |
|
||||
| ip | Internet Protocol Address IP |
|
||||
| ip4_addr | Internet Protocol Address IPv4 |
|
||||
| ip6_addr | Internet Protocol Address IPv6 |
|
||||
| ip_addr | Internet Protocol Address IP |
|
||||
| ipv4 | Internet Protocol Address IPv4 |
|
||||
| ipv6 | Internet Protocol Address IPv6 |
|
||||
| mac | Media Access Control Address MAC |
|
||||
| tcp4_addr | Transmission Control Protocol Address TCPv4 |
|
||||
| tcp6_addr | Transmission Control Protocol Address TCPv6 |
|
||||
| tcp_addr | Transmission Control Protocol Address TCP |
|
||||
| udp4_addr | User Datagram Protocol Address UDPv4 |
|
||||
| udp6_addr | User Datagram Protocol Address UDPv6 |
|
||||
| udp_addr | User Datagram Protocol Address UDP |
|
||||
| unix_addr | Unix domain socket end point Address |
|
||||
| uri | URI String |
|
||||
| url | URL String |
|
||||
| url_encoded | URL Encoded |
|
||||
| urn_rfc2141 | Urn RFC 2141 String |
|
||||
|
||||
### Strings:
|
||||
|
||||
| Tag | Description |
|
||||
| - | - |
|
||||
| alpha | Alpha Only |
|
||||
| alphanum | Alphanumeric |
|
||||
| alphanumunicode | Alphanumeric Unicode |
|
||||
| alphaunicode | Alpha Unicode |
|
||||
| ascii | ASCII |
|
||||
| boolean | Boolean |
|
||||
| contains | Contains |
|
||||
| containsany | Contains Any |
|
||||
| containsrune | Contains Rune |
|
||||
| endsnotwith | Ends Not With |
|
||||
| endswith | Ends With |
|
||||
| excludes | Excludes |
|
||||
| excludesall | Excludes All |
|
||||
| excludesrune | Excludes Rune |
|
||||
| lowercase | Lowercase |
|
||||
| multibyte | Multi-Byte Characters |
|
||||
| number | NOT DOCUMENTED IN doc.go |
|
||||
| numeric | Numeric |
|
||||
| printascii | Printable ASCII |
|
||||
| startsnotwith | Starts Not With |
|
||||
| startswith | Starts With |
|
||||
| uppercase | Uppercase |
|
||||
|
||||
### Format:
|
||||
| Tag | Description |
|
||||
| - | - |
|
||||
| base64 | Base64 String |
|
||||
| base64url | Base64URL String |
|
||||
| bic | Business Identifier Code (ISO 9362) |
|
||||
| bcp47_language_tag | Language tag (BCP 47) |
|
||||
| btc_addr | Bitcoin Address |
|
||||
| btc_addr_bech32 | Bitcoin Bech32 Address (segwit) |
|
||||
| credit_card | Credit Card Number |
|
||||
| datetime | Datetime |
|
||||
| e164 | e164 formatted phone number |
|
||||
| email | E-mail String
|
||||
| eth_addr | Ethereum Address |
|
||||
| hexadecimal | Hexadecimal String |
|
||||
| hexcolor | Hexcolor String |
|
||||
| hsl | HSL String |
|
||||
| hsla | HSLA String |
|
||||
| html | HTML Tags |
|
||||
| html_encoded | HTML Encoded |
|
||||
| isbn | International Standard Book Number |
|
||||
| isbn10 | International Standard Book Number 10 |
|
||||
| isbn13 | International Standard Book Number 13 |
|
||||
| iso3166_1_alpha2 | Two-letter country code (ISO 3166-1 alpha-2) |
|
||||
| iso3166_1_alpha3 | Three-letter country code (ISO 3166-1 alpha-3) |
|
||||
| iso3166_1_alpha_numeric | Numeric country code (ISO 3166-1 numeric) |
|
||||
| iso3166_2 | Country subdivision code (ISO 3166-2) |
|
||||
| iso4217 | Currency code (ISO 4217) |
|
||||
| json | JSON |
|
||||
| jwt | JSON Web Token (JWT) |
|
||||
| latitude | Latitude |
|
||||
| longitude | Longitude |
|
||||
| postcode_iso3166_alpha2 | Postcode |
|
||||
| postcode_iso3166_alpha2_field | Postcode |
|
||||
| rgb | RGB String |
|
||||
| rgba | RGBA String |
|
||||
| ssn | Social Security Number SSN |
|
||||
| timezone | Timezone |
|
||||
| uuid | Universally Unique Identifier UUID |
|
||||
| uuid3 | Universally Unique Identifier UUID v3 |
|
||||
| uuid3_rfc4122 | Universally Unique Identifier UUID v3 RFC4122 |
|
||||
| uuid4 | Universally Unique Identifier UUID v4 |
|
||||
| uuid4_rfc4122 | Universally Unique Identifier UUID v4 RFC4122 |
|
||||
| uuid5 | Universally Unique Identifier UUID v5 |
|
||||
| uuid5_rfc4122 | Universally Unique Identifier UUID v5 RFC4122 |
|
||||
| uuid_rfc4122 | Universally Unique Identifier UUID RFC4122 |
|
||||
| md4 | MD4 hash |
|
||||
| md5 | MD5 hash |
|
||||
| sha256 | SHA256 hash |
|
||||
| sha384 | SHA384 hash |
|
||||
| sha512 | SHA512 hash |
|
||||
| ripemd128 | RIPEMD-128 hash |
|
||||
| ripemd128 | RIPEMD-160 hash |
|
||||
| tiger128 | TIGER128 hash |
|
||||
| tiger160 | TIGER160 hash |
|
||||
| tiger192 | TIGER192 hash |
|
||||
| semver | Semantic Versioning 2.0.0 |
|
||||
| ulid | Universally Unique Lexicographically Sortable Identifier ULID |
|
||||
|
||||
### Comparisons:
|
||||
| Tag | Description |
|
||||
| - | - |
|
||||
| eq | Equals |
|
||||
| gt | Greater than|
|
||||
| gte | Greater than or equal |
|
||||
| lt | Less Than |
|
||||
| lte | Less Than or Equal |
|
||||
| ne | Not Equal |
|
||||
|
||||
### Other:
|
||||
| Tag | Description |
|
||||
| - | - |
|
||||
| dir | Directory |
|
||||
| file | File path |
|
||||
| isdefault | Is Default |
|
||||
| len | Length |
|
||||
| max | Maximum |
|
||||
| min | Minimum |
|
||||
| oneof | One Of |
|
||||
| required | Required |
|
||||
| required_if | Required If |
|
||||
| required_unless | Required Unless |
|
||||
| required_with | Required With |
|
||||
| required_with_all | Required With All |
|
||||
| required_without | Required Without |
|
||||
| required_without_all | Required Without All |
|
||||
| excluded_if | Excluded If |
|
||||
| excluded_unless | Excluded Unless |
|
||||
| excluded_with | Excluded With |
|
||||
| excluded_with_all | Excluded With All |
|
||||
| excluded_without | Excluded Without |
|
||||
| excluded_without_all | Excluded Without All |
|
||||
| unique | Unique |
|
||||
|
||||
#### Aliases:
|
||||
| Tag | Description |
|
||||
| - | - |
|
||||
| iscolor | hexcolor\|rgb\|rgba\|hsl\|hsla |
|
||||
| country_code | iso3166_1_alpha2\|iso3166_1_alpha3\|iso3166_1_alpha_numeric |
|
||||
|
||||
Benchmarks
|
||||
------
|
||||
###### Run on MacBook Pro (15-inch, 2017) go version go1.10.2 darwin/amd64
|
||||
```go
|
||||
goos: darwin
|
||||
goarch: amd64
|
||||
pkg: github.com/go-playground/validator
|
||||
BenchmarkFieldSuccess-8 20000000 83.6 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkFieldSuccessParallel-8 50000000 26.8 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkFieldFailure-8 5000000 291 ns/op 208 B/op 4 allocs/op
|
||||
BenchmarkFieldFailureParallel-8 20000000 107 ns/op 208 B/op 4 allocs/op
|
||||
BenchmarkFieldArrayDiveSuccess-8 2000000 623 ns/op 201 B/op 11 allocs/op
|
||||
BenchmarkFieldArrayDiveSuccessParallel-8 10000000 237 ns/op 201 B/op 11 allocs/op
|
||||
BenchmarkFieldArrayDiveFailure-8 2000000 859 ns/op 412 B/op 16 allocs/op
|
||||
BenchmarkFieldArrayDiveFailureParallel-8 5000000 335 ns/op 413 B/op 16 allocs/op
|
||||
BenchmarkFieldMapDiveSuccess-8 1000000 1292 ns/op 432 B/op 18 allocs/op
|
||||
BenchmarkFieldMapDiveSuccessParallel-8 3000000 467 ns/op 432 B/op 18 allocs/op
|
||||
BenchmarkFieldMapDiveFailure-8 1000000 1082 ns/op 512 B/op 16 allocs/op
|
||||
BenchmarkFieldMapDiveFailureParallel-8 5000000 425 ns/op 512 B/op 16 allocs/op
|
||||
BenchmarkFieldMapDiveWithKeysSuccess-8 1000000 1539 ns/op 480 B/op 21 allocs/op
|
||||
BenchmarkFieldMapDiveWithKeysSuccessParallel-8 3000000 613 ns/op 480 B/op 21 allocs/op
|
||||
BenchmarkFieldMapDiveWithKeysFailure-8 1000000 1413 ns/op 721 B/op 21 allocs/op
|
||||
BenchmarkFieldMapDiveWithKeysFailureParallel-8 3000000 575 ns/op 721 B/op 21 allocs/op
|
||||
BenchmarkFieldCustomTypeSuccess-8 10000000 216 ns/op 32 B/op 2 allocs/op
|
||||
BenchmarkFieldCustomTypeSuccessParallel-8 20000000 82.2 ns/op 32 B/op 2 allocs/op
|
||||
BenchmarkFieldCustomTypeFailure-8 5000000 274 ns/op 208 B/op 4 allocs/op
|
||||
BenchmarkFieldCustomTypeFailureParallel-8 20000000 116 ns/op 208 B/op 4 allocs/op
|
||||
BenchmarkFieldOrTagSuccess-8 2000000 740 ns/op 16 B/op 1 allocs/op
|
||||
BenchmarkFieldOrTagSuccessParallel-8 3000000 474 ns/op 16 B/op 1 allocs/op
|
||||
BenchmarkFieldOrTagFailure-8 3000000 471 ns/op 224 B/op 5 allocs/op
|
||||
BenchmarkFieldOrTagFailureParallel-8 3000000 414 ns/op 224 B/op 5 allocs/op
|
||||
BenchmarkStructLevelValidationSuccess-8 10000000 213 ns/op 32 B/op 2 allocs/op
|
||||
BenchmarkStructLevelValidationSuccessParallel-8 20000000 91.8 ns/op 32 B/op 2 allocs/op
|
||||
BenchmarkStructLevelValidationFailure-8 3000000 473 ns/op 304 B/op 8 allocs/op
|
||||
BenchmarkStructLevelValidationFailureParallel-8 10000000 234 ns/op 304 B/op 8 allocs/op
|
||||
BenchmarkStructSimpleCustomTypeSuccess-8 5000000 385 ns/op 32 B/op 2 allocs/op
|
||||
BenchmarkStructSimpleCustomTypeSuccessParallel-8 10000000 161 ns/op 32 B/op 2 allocs/op
|
||||
BenchmarkStructSimpleCustomTypeFailure-8 2000000 640 ns/op 424 B/op 9 allocs/op
|
||||
BenchmarkStructSimpleCustomTypeFailureParallel-8 5000000 318 ns/op 440 B/op 10 allocs/op
|
||||
BenchmarkStructFilteredSuccess-8 2000000 597 ns/op 288 B/op 9 allocs/op
|
||||
BenchmarkStructFilteredSuccessParallel-8 10000000 266 ns/op 288 B/op 9 allocs/op
|
||||
BenchmarkStructFilteredFailure-8 3000000 454 ns/op 256 B/op 7 allocs/op
|
||||
BenchmarkStructFilteredFailureParallel-8 10000000 214 ns/op 256 B/op 7 allocs/op
|
||||
BenchmarkStructPartialSuccess-8 3000000 502 ns/op 256 B/op 6 allocs/op
|
||||
BenchmarkStructPartialSuccessParallel-8 10000000 225 ns/op 256 B/op 6 allocs/op
|
||||
BenchmarkStructPartialFailure-8 2000000 702 ns/op 480 B/op 11 allocs/op
|
||||
BenchmarkStructPartialFailureParallel-8 5000000 329 ns/op 480 B/op 11 allocs/op
|
||||
BenchmarkStructExceptSuccess-8 2000000 793 ns/op 496 B/op 12 allocs/op
|
||||
BenchmarkStructExceptSuccessParallel-8 10000000 193 ns/op 240 B/op 5 allocs/op
|
||||
BenchmarkStructExceptFailure-8 2000000 639 ns/op 464 B/op 10 allocs/op
|
||||
BenchmarkStructExceptFailureParallel-8 5000000 300 ns/op 464 B/op 10 allocs/op
|
||||
BenchmarkStructSimpleCrossFieldSuccess-8 3000000 417 ns/op 72 B/op 3 allocs/op
|
||||
BenchmarkStructSimpleCrossFieldSuccessParallel-8 10000000 163 ns/op 72 B/op 3 allocs/op
|
||||
BenchmarkStructSimpleCrossFieldFailure-8 2000000 645 ns/op 304 B/op 8 allocs/op
|
||||
BenchmarkStructSimpleCrossFieldFailureParallel-8 5000000 285 ns/op 304 B/op 8 allocs/op
|
||||
BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 3000000 588 ns/op 80 B/op 4 allocs/op
|
||||
BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 10000000 221 ns/op 80 B/op 4 allocs/op
|
||||
BenchmarkStructSimpleCrossStructCrossFieldFailure-8 2000000 868 ns/op 320 B/op 9 allocs/op
|
||||
BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 5000000 337 ns/op 320 B/op 9 allocs/op
|
||||
BenchmarkStructSimpleSuccess-8 5000000 260 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkStructSimpleSuccessParallel-8 20000000 90.6 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkStructSimpleFailure-8 2000000 619 ns/op 424 B/op 9 allocs/op
|
||||
BenchmarkStructSimpleFailureParallel-8 5000000 296 ns/op 424 B/op 9 allocs/op
|
||||
BenchmarkStructComplexSuccess-8 1000000 1454 ns/op 128 B/op 8 allocs/op
|
||||
BenchmarkStructComplexSuccessParallel-8 3000000 579 ns/op 128 B/op 8 allocs/op
|
||||
BenchmarkStructComplexFailure-8 300000 4140 ns/op 3041 B/op 53 allocs/op
|
||||
BenchmarkStructComplexFailureParallel-8 1000000 2127 ns/op 3041 B/op 53 allocs/op
|
||||
BenchmarkOneof-8 10000000 140 ns/op 0 B/op 0 allocs/op
|
||||
BenchmarkOneofParallel-8 20000000 70.1 ns/op 0 B/op 0 allocs/op
|
||||
```
|
||||
|
||||
Complementary Software
|
||||
----------------------
|
||||
|
||||
Here is a list of software that complements using this library either pre or post validation.
|
||||
|
||||
* [form](https://github.com/go-playground/form) - Decodes url.Values into Go value(s) and Encodes Go value(s) into url.Values. Dual Array and Full map support.
|
||||
* [mold](https://github.com/go-playground/mold) - A general library to help modify or set data within data structures and other objects
|
||||
|
||||
How to Contribute
|
||||
------
|
||||
|
||||
Make a pull request...
|
||||
|
||||
License
|
||||
-------
|
||||
Distributed under MIT License, please see license file within the code for more details.
|
||||
|
||||
Maintainers
|
||||
-----------
|
||||
This project has grown large enough that more than one person is required to properly support the community.
|
||||
If you are interested in becoming a maintainer please reach out to me https://github.com/deankarn
|
2526
vendor/github.com/go-playground/validator/v10/baked_in.go
generated
vendored
Normal file
2526
vendor/github.com/go-playground/validator/v10/baked_in.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
327
vendor/github.com/go-playground/validator/v10/cache.go
generated
vendored
Normal file
327
vendor/github.com/go-playground/validator/v10/cache.go
generated
vendored
Normal file
@ -0,0 +1,327 @@
|
||||
package validator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
type tagType uint8
|
||||
|
||||
const (
|
||||
typeDefault tagType = iota
|
||||
typeOmitEmpty
|
||||
typeIsDefault
|
||||
typeNoStructLevel
|
||||
typeStructOnly
|
||||
typeDive
|
||||
typeOr
|
||||
typeKeys
|
||||
typeEndKeys
|
||||
)
|
||||
|
||||
const (
|
||||
invalidValidation = "Invalid validation tag on field '%s'"
|
||||
undefinedValidation = "Undefined validation function '%s' on field '%s'"
|
||||
keysTagNotDefined = "'" + endKeysTag + "' tag encountered without a corresponding '" + keysTag + "' tag"
|
||||
)
|
||||
|
||||
type structCache struct {
|
||||
lock sync.Mutex
|
||||
m atomic.Value // map[reflect.Type]*cStruct
|
||||
}
|
||||
|
||||
func (sc *structCache) Get(key reflect.Type) (c *cStruct, found bool) {
|
||||
c, found = sc.m.Load().(map[reflect.Type]*cStruct)[key]
|
||||
return
|
||||
}
|
||||
|
||||
func (sc *structCache) Set(key reflect.Type, value *cStruct) {
|
||||
m := sc.m.Load().(map[reflect.Type]*cStruct)
|
||||
nm := make(map[reflect.Type]*cStruct, len(m)+1)
|
||||
for k, v := range m {
|
||||
nm[k] = v
|
||||
}
|
||||
nm[key] = value
|
||||
sc.m.Store(nm)
|
||||
}
|
||||
|
||||
type tagCache struct {
|
||||
lock sync.Mutex
|
||||
m atomic.Value // map[string]*cTag
|
||||
}
|
||||
|
||||
func (tc *tagCache) Get(key string) (c *cTag, found bool) {
|
||||
c, found = tc.m.Load().(map[string]*cTag)[key]
|
||||
return
|
||||
}
|
||||
|
||||
func (tc *tagCache) Set(key string, value *cTag) {
|
||||
m := tc.m.Load().(map[string]*cTag)
|
||||
nm := make(map[string]*cTag, len(m)+1)
|
||||
for k, v := range m {
|
||||
nm[k] = v
|
||||
}
|
||||
nm[key] = value
|
||||
tc.m.Store(nm)
|
||||
}
|
||||
|
||||
type cStruct struct {
|
||||
name string
|
||||
fields []*cField
|
||||
fn StructLevelFuncCtx
|
||||
}
|
||||
|
||||
type cField struct {
|
||||
idx int
|
||||
name string
|
||||
altName string
|
||||
namesEqual bool
|
||||
cTags *cTag
|
||||
}
|
||||
|
||||
type cTag struct {
|
||||
tag string
|
||||
aliasTag string
|
||||
actualAliasTag string
|
||||
param string
|
||||
keys *cTag // only populated when using tag's 'keys' and 'endkeys' for map key validation
|
||||
next *cTag
|
||||
fn FuncCtx
|
||||
typeof tagType
|
||||
hasTag bool
|
||||
hasAlias bool
|
||||
hasParam bool // true if parameter used eg. eq= where the equal sign has been set
|
||||
isBlockEnd bool // indicates the current tag represents the last validation in the block
|
||||
runValidationWhenNil bool
|
||||
}
|
||||
|
||||
func (v *Validate) extractStructCache(current reflect.Value, sName string) *cStruct {
|
||||
v.structCache.lock.Lock()
|
||||
defer v.structCache.lock.Unlock() // leave as defer! because if inner panics, it will never get unlocked otherwise!
|
||||
|
||||
typ := current.Type()
|
||||
|
||||
// could have been multiple trying to access, but once first is done this ensures struct
|
||||
// isn't parsed again.
|
||||
cs, ok := v.structCache.Get(typ)
|
||||
if ok {
|
||||
return cs
|
||||
}
|
||||
|
||||
cs = &cStruct{name: sName, fields: make([]*cField, 0), fn: v.structLevelFuncs[typ]}
|
||||
|
||||
numFields := current.NumField()
|
||||
rules := v.rules[typ]
|
||||
|
||||
var ctag *cTag
|
||||
var fld reflect.StructField
|
||||
var tag string
|
||||
var customName string
|
||||
|
||||
for i := 0; i < numFields; i++ {
|
||||
|
||||
fld = typ.Field(i)
|
||||
|
||||
if !fld.Anonymous && len(fld.PkgPath) > 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if rtag, ok := rules[fld.Name]; ok {
|
||||
tag = rtag
|
||||
} else {
|
||||
tag = fld.Tag.Get(v.tagName)
|
||||
}
|
||||
|
||||
if tag == skipValidationTag {
|
||||
continue
|
||||
}
|
||||
|
||||
customName = fld.Name
|
||||
|
||||
if v.hasTagNameFunc {
|
||||
name := v.tagNameFunc(fld)
|
||||
if len(name) > 0 {
|
||||
customName = name
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: cannot use shared tag cache, because tags may be equal, but things like alias may be different
|
||||
// and so only struct level caching can be used instead of combined with Field tag caching
|
||||
|
||||
if len(tag) > 0 {
|
||||
ctag, _ = v.parseFieldTagsRecursive(tag, fld.Name, "", false)
|
||||
} else {
|
||||
// even if field doesn't have validations need cTag for traversing to potential inner/nested
|
||||
// elements of the field.
|
||||
ctag = new(cTag)
|
||||
}
|
||||
|
||||
cs.fields = append(cs.fields, &cField{
|
||||
idx: i,
|
||||
name: fld.Name,
|
||||
altName: customName,
|
||||
cTags: ctag,
|
||||
namesEqual: fld.Name == customName,
|
||||
})
|
||||
}
|
||||
v.structCache.Set(typ, cs)
|
||||
return cs
|
||||
}
|
||||
|
||||
func (v *Validate) parseFieldTagsRecursive(tag string, fieldName string, alias string, hasAlias bool) (firstCtag *cTag, current *cTag) {
|
||||
var t string
|
||||
noAlias := len(alias) == 0
|
||||
tags := strings.Split(tag, tagSeparator)
|
||||
|
||||
for i := 0; i < len(tags); i++ {
|
||||
t = tags[i]
|
||||
if noAlias {
|
||||
alias = t
|
||||
}
|
||||
|
||||
// check map for alias and process new tags, otherwise process as usual
|
||||
if tagsVal, found := v.aliases[t]; found {
|
||||
if i == 0 {
|
||||
firstCtag, current = v.parseFieldTagsRecursive(tagsVal, fieldName, t, true)
|
||||
} else {
|
||||
next, curr := v.parseFieldTagsRecursive(tagsVal, fieldName, t, true)
|
||||
current.next, current = next, curr
|
||||
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
var prevTag tagType
|
||||
|
||||
if i == 0 {
|
||||
current = &cTag{aliasTag: alias, hasAlias: hasAlias, hasTag: true, typeof: typeDefault}
|
||||
firstCtag = current
|
||||
} else {
|
||||
prevTag = current.typeof
|
||||
current.next = &cTag{aliasTag: alias, hasAlias: hasAlias, hasTag: true}
|
||||
current = current.next
|
||||
}
|
||||
|
||||
switch t {
|
||||
case diveTag:
|
||||
current.typeof = typeDive
|
||||
continue
|
||||
|
||||
case keysTag:
|
||||
current.typeof = typeKeys
|
||||
|
||||
if i == 0 || prevTag != typeDive {
|
||||
panic(fmt.Sprintf("'%s' tag must be immediately preceded by the '%s' tag", keysTag, diveTag))
|
||||
}
|
||||
|
||||
current.typeof = typeKeys
|
||||
|
||||
// need to pass along only keys tag
|
||||
// need to increment i to skip over the keys tags
|
||||
b := make([]byte, 0, 64)
|
||||
|
||||
i++
|
||||
|
||||
for ; i < len(tags); i++ {
|
||||
|
||||
b = append(b, tags[i]...)
|
||||
b = append(b, ',')
|
||||
|
||||
if tags[i] == endKeysTag {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
current.keys, _ = v.parseFieldTagsRecursive(string(b[:len(b)-1]), fieldName, "", false)
|
||||
continue
|
||||
|
||||
case endKeysTag:
|
||||
current.typeof = typeEndKeys
|
||||
|
||||
// if there are more in tags then there was no keysTag defined
|
||||
// and an error should be thrown
|
||||
if i != len(tags)-1 {
|
||||
panic(keysTagNotDefined)
|
||||
}
|
||||
return
|
||||
|
||||
case omitempty:
|
||||
current.typeof = typeOmitEmpty
|
||||
continue
|
||||
|
||||
case structOnlyTag:
|
||||
current.typeof = typeStructOnly
|
||||
continue
|
||||
|
||||
case noStructLevelTag:
|
||||
current.typeof = typeNoStructLevel
|
||||
continue
|
||||
|
||||
default:
|
||||
if t == isdefault {
|
||||
current.typeof = typeIsDefault
|
||||
}
|
||||
// if a pipe character is needed within the param you must use the utf8Pipe representation "0x7C"
|
||||
orVals := strings.Split(t, orSeparator)
|
||||
|
||||
for j := 0; j < len(orVals); j++ {
|
||||
vals := strings.SplitN(orVals[j], tagKeySeparator, 2)
|
||||
if noAlias {
|
||||
alias = vals[0]
|
||||
current.aliasTag = alias
|
||||
} else {
|
||||
current.actualAliasTag = t
|
||||
}
|
||||
|
||||
if j > 0 {
|
||||
current.next = &cTag{aliasTag: alias, actualAliasTag: current.actualAliasTag, hasAlias: hasAlias, hasTag: true}
|
||||
current = current.next
|
||||
}
|
||||
current.hasParam = len(vals) > 1
|
||||
|
||||
current.tag = vals[0]
|
||||
if len(current.tag) == 0 {
|
||||
panic(strings.TrimSpace(fmt.Sprintf(invalidValidation, fieldName)))
|
||||
}
|
||||
|
||||
if wrapper, ok := v.validations[current.tag]; ok {
|
||||
current.fn = wrapper.fn
|
||||
current.runValidationWhenNil = wrapper.runValidatinOnNil
|
||||
} else {
|
||||
panic(strings.TrimSpace(fmt.Sprintf(undefinedValidation, current.tag, fieldName)))
|
||||
}
|
||||
|
||||
if len(orVals) > 1 {
|
||||
current.typeof = typeOr
|
||||
}
|
||||
|
||||
if len(vals) > 1 {
|
||||
current.param = strings.Replace(strings.Replace(vals[1], utf8HexComma, ",", -1), utf8Pipe, "|", -1)
|
||||
}
|
||||
}
|
||||
current.isBlockEnd = true
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (v *Validate) fetchCacheTag(tag string) *cTag {
|
||||
// find cached tag
|
||||
ctag, found := v.tagCache.Get(tag)
|
||||
if !found {
|
||||
v.tagCache.lock.Lock()
|
||||
defer v.tagCache.lock.Unlock()
|
||||
|
||||
// could have been multiple trying to access, but once first is done this ensures tag
|
||||
// isn't parsed again.
|
||||
ctag, found = v.tagCache.Get(tag)
|
||||
if !found {
|
||||
ctag, _ = v.parseFieldTagsRecursive(tag, "", "", false)
|
||||
v.tagCache.Set(tag, ctag)
|
||||
}
|
||||
}
|
||||
return ctag
|
||||
}
|
1132
vendor/github.com/go-playground/validator/v10/country_codes.go
generated
vendored
Normal file
1132
vendor/github.com/go-playground/validator/v10/country_codes.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
79
vendor/github.com/go-playground/validator/v10/currency_codes.go
generated
vendored
Normal file
79
vendor/github.com/go-playground/validator/v10/currency_codes.go
generated
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
package validator
|
||||
|
||||
var iso4217 = map[string]bool{
|
||||
"AFN": true, "EUR": true, "ALL": true, "DZD": true, "USD": true,
|
||||
"AOA": true, "XCD": true, "ARS": true, "AMD": true, "AWG": true,
|
||||
"AUD": true, "AZN": true, "BSD": true, "BHD": true, "BDT": true,
|
||||
"BBD": true, "BYN": true, "BZD": true, "XOF": true, "BMD": true,
|
||||
"INR": true, "BTN": true, "BOB": true, "BOV": true, "BAM": true,
|
||||
"BWP": true, "NOK": true, "BRL": true, "BND": true, "BGN": true,
|
||||
"BIF": true, "CVE": true, "KHR": true, "XAF": true, "CAD": true,
|
||||
"KYD": true, "CLP": true, "CLF": true, "CNY": true, "COP": true,
|
||||
"COU": true, "KMF": true, "CDF": true, "NZD": true, "CRC": true,
|
||||
"HRK": true, "CUP": true, "CUC": true, "ANG": true, "CZK": true,
|
||||
"DKK": true, "DJF": true, "DOP": true, "EGP": true, "SVC": true,
|
||||
"ERN": true, "SZL": true, "ETB": true, "FKP": true, "FJD": true,
|
||||
"XPF": true, "GMD": true, "GEL": true, "GHS": true, "GIP": true,
|
||||
"GTQ": true, "GBP": true, "GNF": true, "GYD": true, "HTG": true,
|
||||
"HNL": true, "HKD": true, "HUF": true, "ISK": true, "IDR": true,
|
||||
"XDR": true, "IRR": true, "IQD": true, "ILS": true, "JMD": true,
|
||||
"JPY": true, "JOD": true, "KZT": true, "KES": true, "KPW": true,
|
||||
"KRW": true, "KWD": true, "KGS": true, "LAK": true, "LBP": true,
|
||||
"LSL": true, "ZAR": true, "LRD": true, "LYD": true, "CHF": true,
|
||||
"MOP": true, "MKD": true, "MGA": true, "MWK": true, "MYR": true,
|
||||
"MVR": true, "MRU": true, "MUR": true, "XUA": true, "MXN": true,
|
||||
"MXV": true, "MDL": true, "MNT": true, "MAD": true, "MZN": true,
|
||||
"MMK": true, "NAD": true, "NPR": true, "NIO": true, "NGN": true,
|
||||
"OMR": true, "PKR": true, "PAB": true, "PGK": true, "PYG": true,
|
||||
"PEN": true, "PHP": true, "PLN": true, "QAR": true, "RON": true,
|
||||
"RUB": true, "RWF": true, "SHP": true, "WST": true, "STN": true,
|
||||
"SAR": true, "RSD": true, "SCR": true, "SLL": true, "SGD": true,
|
||||
"XSU": true, "SBD": true, "SOS": true, "SSP": true, "LKR": true,
|
||||
"SDG": true, "SRD": true, "SEK": true, "CHE": true, "CHW": true,
|
||||
"SYP": true, "TWD": true, "TJS": true, "TZS": true, "THB": true,
|
||||
"TOP": true, "TTD": true, "TND": true, "TRY": true, "TMT": true,
|
||||
"UGX": true, "UAH": true, "AED": true, "USN": true, "UYU": true,
|
||||
"UYI": true, "UYW": true, "UZS": true, "VUV": true, "VES": true,
|
||||
"VND": true, "YER": true, "ZMW": true, "ZWL": true, "XBA": true,
|
||||
"XBB": true, "XBC": true, "XBD": true, "XTS": true, "XXX": true,
|
||||
"XAU": true, "XPD": true, "XPT": true, "XAG": true,
|
||||
}
|
||||
|
||||
var iso4217_numeric = map[int]bool{
|
||||
8: true, 12: true, 32: true, 36: true, 44: true,
|
||||
48: true, 50: true, 51: true, 52: true, 60: true,
|
||||
64: true, 68: true, 72: true, 84: true, 90: true,
|
||||
96: true, 104: true, 108: true, 116: true, 124: true,
|
||||
132: true, 136: true, 144: true, 152: true, 156: true,
|
||||
170: true, 174: true, 188: true, 191: true, 192: true,
|
||||
203: true, 208: true, 214: true, 222: true, 230: true,
|
||||
232: true, 238: true, 242: true, 262: true, 270: true,
|
||||
292: true, 320: true, 324: true, 328: true, 332: true,
|
||||
340: true, 344: true, 348: true, 352: true, 356: true,
|
||||
360: true, 364: true, 368: true, 376: true, 388: true,
|
||||
392: true, 398: true, 400: true, 404: true, 408: true,
|
||||
410: true, 414: true, 417: true, 418: true, 422: true,
|
||||
426: true, 430: true, 434: true, 446: true, 454: true,
|
||||
458: true, 462: true, 480: true, 484: true, 496: true,
|
||||
498: true, 504: true, 512: true, 516: true, 524: true,
|
||||
532: true, 533: true, 548: true, 554: true, 558: true,
|
||||
566: true, 578: true, 586: true, 590: true, 598: true,
|
||||
600: true, 604: true, 608: true, 634: true, 643: true,
|
||||
646: true, 654: true, 682: true, 690: true, 694: true,
|
||||
702: true, 704: true, 706: true, 710: true, 728: true,
|
||||
748: true, 752: true, 756: true, 760: true, 764: true,
|
||||
776: true, 780: true, 784: true, 788: true, 800: true,
|
||||
807: true, 818: true, 826: true, 834: true, 840: true,
|
||||
858: true, 860: true, 882: true, 886: true, 901: true,
|
||||
927: true, 928: true, 929: true, 930: true, 931: true,
|
||||
932: true, 933: true, 934: true, 936: true, 938: true,
|
||||
940: true, 941: true, 943: true, 944: true, 946: true,
|
||||
947: true, 948: true, 949: true, 950: true, 951: true,
|
||||
952: true, 953: true, 955: true, 956: true, 957: true,
|
||||
958: true, 959: true, 960: true, 961: true, 962: true,
|
||||
963: true, 964: true, 965: true, 967: true, 968: true,
|
||||
969: true, 970: true, 971: true, 972: true, 973: true,
|
||||
975: true, 976: true, 977: true, 978: true, 979: true,
|
||||
980: true, 981: true, 984: true, 985: true, 986: true,
|
||||
990: true, 994: true, 997: true, 999: true,
|
||||
}
|
1401
vendor/github.com/go-playground/validator/v10/doc.go
generated
vendored
Normal file
1401
vendor/github.com/go-playground/validator/v10/doc.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
275
vendor/github.com/go-playground/validator/v10/errors.go
generated
vendored
Normal file
275
vendor/github.com/go-playground/validator/v10/errors.go
generated
vendored
Normal file
@ -0,0 +1,275 @@
|
||||
package validator
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
ut "github.com/go-playground/universal-translator"
|
||||
)
|
||||
|
||||
const (
|
||||
fieldErrMsg = "Key: '%s' Error:Field validation for '%s' failed on the '%s' tag"
|
||||
)
|
||||
|
||||
// ValidationErrorsTranslations is the translation return type
|
||||
type ValidationErrorsTranslations map[string]string
|
||||
|
||||
// InvalidValidationError describes an invalid argument passed to
|
||||
// `Struct`, `StructExcept`, StructPartial` or `Field`
|
||||
type InvalidValidationError struct {
|
||||
Type reflect.Type
|
||||
}
|
||||
|
||||
// Error returns InvalidValidationError message
|
||||
func (e *InvalidValidationError) Error() string {
|
||||
|
||||
if e.Type == nil {
|
||||
return "validator: (nil)"
|
||||
}
|
||||
|
||||
return "validator: (nil " + e.Type.String() + ")"
|
||||
}
|
||||
|
||||
// ValidationErrors is an array of FieldError's
|
||||
// for use in custom error messages post validation.
|
||||
type ValidationErrors []FieldError
|
||||
|
||||
// Error is intended for use in development + debugging and not intended to be a production error message.
|
||||
// It allows ValidationErrors to subscribe to the Error interface.
|
||||
// All information to create an error message specific to your application is contained within
|
||||
// the FieldError found within the ValidationErrors array
|
||||
func (ve ValidationErrors) Error() string {
|
||||
|
||||
buff := bytes.NewBufferString("")
|
||||
|
||||
var fe *fieldError
|
||||
|
||||
for i := 0; i < len(ve); i++ {
|
||||
|
||||
fe = ve[i].(*fieldError)
|
||||
buff.WriteString(fe.Error())
|
||||
buff.WriteString("\n")
|
||||
}
|
||||
|
||||
return strings.TrimSpace(buff.String())
|
||||
}
|
||||
|
||||
// Translate translates all of the ValidationErrors
|
||||
func (ve ValidationErrors) Translate(ut ut.Translator) ValidationErrorsTranslations {
|
||||
|
||||
trans := make(ValidationErrorsTranslations)
|
||||
|
||||
var fe *fieldError
|
||||
|
||||
for i := 0; i < len(ve); i++ {
|
||||
fe = ve[i].(*fieldError)
|
||||
|
||||
// // in case an Anonymous struct was used, ensure that the key
|
||||
// // would be 'Username' instead of ".Username"
|
||||
// if len(fe.ns) > 0 && fe.ns[:1] == "." {
|
||||
// trans[fe.ns[1:]] = fe.Translate(ut)
|
||||
// continue
|
||||
// }
|
||||
|
||||
trans[fe.ns] = fe.Translate(ut)
|
||||
}
|
||||
|
||||
return trans
|
||||
}
|
||||
|
||||
// FieldError contains all functions to get error details
|
||||
type FieldError interface {
|
||||
|
||||
// Tag returns the validation tag that failed. if the
|
||||
// validation was an alias, this will return the
|
||||
// alias name and not the underlying tag that failed.
|
||||
//
|
||||
// eg. alias "iscolor": "hexcolor|rgb|rgba|hsl|hsla"
|
||||
// will return "iscolor"
|
||||
Tag() string
|
||||
|
||||
// ActualTag returns the validation tag that failed, even if an
|
||||
// alias the actual tag within the alias will be returned.
|
||||
// If an 'or' validation fails the entire or will be returned.
|
||||
//
|
||||
// eg. alias "iscolor": "hexcolor|rgb|rgba|hsl|hsla"
|
||||
// will return "hexcolor|rgb|rgba|hsl|hsla"
|
||||
ActualTag() string
|
||||
|
||||
// Namespace returns the namespace for the field error, with the tag
|
||||
// name taking precedence over the field's actual name.
|
||||
//
|
||||
// eg. JSON name "User.fname"
|
||||
//
|
||||
// See StructNamespace() for a version that returns actual names.
|
||||
//
|
||||
// NOTE: this field can be blank when validating a single primitive field
|
||||
// using validate.Field(...) as there is no way to extract it's name
|
||||
Namespace() string
|
||||
|
||||
// StructNamespace returns the namespace for the field error, with the field's
|
||||
// actual name.
|
||||
//
|
||||
// eq. "User.FirstName" see Namespace for comparison
|
||||
//
|
||||
// NOTE: this field can be blank when validating a single primitive field
|
||||
// using validate.Field(...) as there is no way to extract its name
|
||||
StructNamespace() string
|
||||
|
||||
// Field returns the fields name with the tag name taking precedence over the
|
||||
// field's actual name.
|
||||
//
|
||||
// eq. JSON name "fname"
|
||||
// see StructField for comparison
|
||||
Field() string
|
||||
|
||||
// StructField returns the field's actual name from the struct, when able to determine.
|
||||
//
|
||||
// eq. "FirstName"
|
||||
// see Field for comparison
|
||||
StructField() string
|
||||
|
||||
// Value returns the actual field's value in case needed for creating the error
|
||||
// message
|
||||
Value() interface{}
|
||||
|
||||
// Param returns the param value, in string form for comparison; this will also
|
||||
// help with generating an error message
|
||||
Param() string
|
||||
|
||||
// Kind returns the Field's reflect Kind
|
||||
//
|
||||
// eg. time.Time's kind is a struct
|
||||
Kind() reflect.Kind
|
||||
|
||||
// Type returns the Field's reflect Type
|
||||
//
|
||||
// eg. time.Time's type is time.Time
|
||||
Type() reflect.Type
|
||||
|
||||
// Translate returns the FieldError's translated error
|
||||
// from the provided 'ut.Translator' and registered 'TranslationFunc'
|
||||
//
|
||||
// NOTE: if no registered translator can be found it returns the same as
|
||||
// calling fe.Error()
|
||||
Translate(ut ut.Translator) string
|
||||
|
||||
// Error returns the FieldError's message
|
||||
Error() string
|
||||
}
|
||||
|
||||
// compile time interface checks
|
||||
var _ FieldError = new(fieldError)
|
||||
var _ error = new(fieldError)
|
||||
|
||||
// fieldError contains a single field's validation error along
|
||||
// with other properties that may be needed for error message creation
|
||||
// it complies with the FieldError interface
|
||||
type fieldError struct {
|
||||
v *Validate
|
||||
tag string
|
||||
actualTag string
|
||||
ns string
|
||||
structNs string
|
||||
fieldLen uint8
|
||||
structfieldLen uint8
|
||||
value interface{}
|
||||
param string
|
||||
kind reflect.Kind
|
||||
typ reflect.Type
|
||||
}
|
||||
|
||||
// Tag returns the validation tag that failed.
|
||||
func (fe *fieldError) Tag() string {
|
||||
return fe.tag
|
||||
}
|
||||
|
||||
// ActualTag returns the validation tag that failed, even if an
|
||||
// alias the actual tag within the alias will be returned.
|
||||
func (fe *fieldError) ActualTag() string {
|
||||
return fe.actualTag
|
||||
}
|
||||
|
||||
// Namespace returns the namespace for the field error, with the tag
|
||||
// name taking precedence over the field's actual name.
|
||||
func (fe *fieldError) Namespace() string {
|
||||
return fe.ns
|
||||
}
|
||||
|
||||
// StructNamespace returns the namespace for the field error, with the field's
|
||||
// actual name.
|
||||
func (fe *fieldError) StructNamespace() string {
|
||||
return fe.structNs
|
||||
}
|
||||
|
||||
// Field returns the field's name with the tag name taking precedence over the
|
||||
// field's actual name.
|
||||
func (fe *fieldError) Field() string {
|
||||
|
||||
return fe.ns[len(fe.ns)-int(fe.fieldLen):]
|
||||
// // return fe.field
|
||||
// fld := fe.ns[len(fe.ns)-int(fe.fieldLen):]
|
||||
|
||||
// log.Println("FLD:", fld)
|
||||
|
||||
// if len(fld) > 0 && fld[:1] == "." {
|
||||
// return fld[1:]
|
||||
// }
|
||||
|
||||
// return fld
|
||||
}
|
||||
|
||||
// StructField returns the field's actual name from the struct, when able to determine.
|
||||
func (fe *fieldError) StructField() string {
|
||||
// return fe.structField
|
||||
return fe.structNs[len(fe.structNs)-int(fe.structfieldLen):]
|
||||
}
|
||||
|
||||
// Value returns the actual field's value in case needed for creating the error
|
||||
// message
|
||||
func (fe *fieldError) Value() interface{} {
|
||||
return fe.value
|
||||
}
|
||||
|
||||
// Param returns the param value, in string form for comparison; this will
|
||||
// also help with generating an error message
|
||||
func (fe *fieldError) Param() string {
|
||||
return fe.param
|
||||
}
|
||||
|
||||
// Kind returns the Field's reflect Kind
|
||||
func (fe *fieldError) Kind() reflect.Kind {
|
||||
return fe.kind
|
||||
}
|
||||
|
||||
// Type returns the Field's reflect Type
|
||||
func (fe *fieldError) Type() reflect.Type {
|
||||
return fe.typ
|
||||
}
|
||||
|
||||
// Error returns the fieldError's error message
|
||||
func (fe *fieldError) Error() string {
|
||||
return fmt.Sprintf(fieldErrMsg, fe.ns, fe.Field(), fe.tag)
|
||||
}
|
||||
|
||||
// Translate returns the FieldError's translated error
|
||||
// from the provided 'ut.Translator' and registered 'TranslationFunc'
|
||||
//
|
||||
// NOTE: if no registered translation can be found, it returns the original
|
||||
// untranslated error message.
|
||||
func (fe *fieldError) Translate(ut ut.Translator) string {
|
||||
|
||||
m, ok := fe.v.transTagFunc[ut]
|
||||
if !ok {
|
||||
return fe.Error()
|
||||
}
|
||||
|
||||
fn, ok := m[fe.tag]
|
||||
if !ok {
|
||||
return fe.Error()
|
||||
}
|
||||
|
||||
return fn(ut, fe)
|
||||
}
|
120
vendor/github.com/go-playground/validator/v10/field_level.go
generated
vendored
Normal file
120
vendor/github.com/go-playground/validator/v10/field_level.go
generated
vendored
Normal file
@ -0,0 +1,120 @@
|
||||
package validator
|
||||
|
||||
import "reflect"
|
||||
|
||||
// FieldLevel contains all the information and helper functions
|
||||
// to validate a field
|
||||
type FieldLevel interface {
|
||||
|
||||
// Top returns the top level struct, if any
|
||||
Top() reflect.Value
|
||||
|
||||
// Parent returns the current fields parent struct, if any or
|
||||
// the comparison value if called 'VarWithValue'
|
||||
Parent() reflect.Value
|
||||
|
||||
// Field returns current field for validation
|
||||
Field() reflect.Value
|
||||
|
||||
// FieldName returns the field's name with the tag
|
||||
// name taking precedence over the fields actual name.
|
||||
FieldName() string
|
||||
|
||||
// StructFieldName returns the struct field's name
|
||||
StructFieldName() string
|
||||
|
||||
// Param returns param for validation against current field
|
||||
Param() string
|
||||
|
||||
// GetTag returns the current validations tag name
|
||||
GetTag() string
|
||||
|
||||
// ExtractType gets the actual underlying type of field value.
|
||||
// It will dive into pointers, customTypes and return you the
|
||||
// underlying value and it's kind.
|
||||
ExtractType(field reflect.Value) (value reflect.Value, kind reflect.Kind, nullable bool)
|
||||
|
||||
// GetStructFieldOK traverses the parent struct to retrieve a specific field denoted by the provided namespace
|
||||
// in the param and returns the field, field kind and whether is was successful in retrieving
|
||||
// the field at all.
|
||||
//
|
||||
// NOTE: when not successful ok will be false, this can happen when a nested struct is nil and so the field
|
||||
// could not be retrieved because it didn't exist.
|
||||
//
|
||||
// Deprecated: Use GetStructFieldOK2() instead which also return if the value is nullable.
|
||||
GetStructFieldOK() (reflect.Value, reflect.Kind, bool)
|
||||
|
||||
// GetStructFieldOKAdvanced is the same as GetStructFieldOK except that it accepts the parent struct to start looking for
|
||||
// the field and namespace allowing more extensibility for validators.
|
||||
//
|
||||
// Deprecated: Use GetStructFieldOKAdvanced2() instead which also return if the value is nullable.
|
||||
GetStructFieldOKAdvanced(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool)
|
||||
|
||||
// GetStructFieldOK2 traverses the parent struct to retrieve a specific field denoted by the provided namespace
|
||||
// in the param and returns the field, field kind, if it's a nullable type and whether is was successful in retrieving
|
||||
// the field at all.
|
||||
//
|
||||
// NOTE: when not successful ok will be false, this can happen when a nested struct is nil and so the field
|
||||
// could not be retrieved because it didn't exist.
|
||||
GetStructFieldOK2() (reflect.Value, reflect.Kind, bool, bool)
|
||||
|
||||
// GetStructFieldOKAdvanced2 is the same as GetStructFieldOK except that it accepts the parent struct to start looking for
|
||||
// the field and namespace allowing more extensibility for validators.
|
||||
GetStructFieldOKAdvanced2(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool, bool)
|
||||
}
|
||||
|
||||
var _ FieldLevel = new(validate)
|
||||
|
||||
// Field returns current field for validation
|
||||
func (v *validate) Field() reflect.Value {
|
||||
return v.flField
|
||||
}
|
||||
|
||||
// FieldName returns the field's name with the tag
|
||||
// name taking precedence over the fields actual name.
|
||||
func (v *validate) FieldName() string {
|
||||
return v.cf.altName
|
||||
}
|
||||
|
||||
// GetTag returns the current validations tag name
|
||||
func (v *validate) GetTag() string {
|
||||
return v.ct.tag
|
||||
}
|
||||
|
||||
// StructFieldName returns the struct field's name
|
||||
func (v *validate) StructFieldName() string {
|
||||
return v.cf.name
|
||||
}
|
||||
|
||||
// Param returns param for validation against current field
|
||||
func (v *validate) Param() string {
|
||||
return v.ct.param
|
||||
}
|
||||
|
||||
// GetStructFieldOK returns Param returns param for validation against current field
|
||||
//
|
||||
// Deprecated: Use GetStructFieldOK2() instead which also return if the value is nullable.
|
||||
func (v *validate) GetStructFieldOK() (reflect.Value, reflect.Kind, bool) {
|
||||
current, kind, _, found := v.getStructFieldOKInternal(v.slflParent, v.ct.param)
|
||||
return current, kind, found
|
||||
}
|
||||
|
||||
// GetStructFieldOKAdvanced is the same as GetStructFieldOK except that it accepts the parent struct to start looking for
|
||||
// the field and namespace allowing more extensibility for validators.
|
||||
//
|
||||
// Deprecated: Use GetStructFieldOKAdvanced2() instead which also return if the value is nullable.
|
||||
func (v *validate) GetStructFieldOKAdvanced(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool) {
|
||||
current, kind, _, found := v.GetStructFieldOKAdvanced2(val, namespace)
|
||||
return current, kind, found
|
||||
}
|
||||
|
||||
// GetStructFieldOK2 returns Param returns param for validation against current field
|
||||
func (v *validate) GetStructFieldOK2() (reflect.Value, reflect.Kind, bool, bool) {
|
||||
return v.getStructFieldOKInternal(v.slflParent, v.ct.param)
|
||||
}
|
||||
|
||||
// GetStructFieldOKAdvanced2 is the same as GetStructFieldOK except that it accepts the parent struct to start looking for
|
||||
// the field and namespace allowing more extensibility for validators.
|
||||
func (v *validate) GetStructFieldOKAdvanced2(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool, bool) {
|
||||
return v.getStructFieldOKInternal(val, namespace)
|
||||
}
|
BIN
vendor/github.com/go-playground/validator/v10/logo.png
generated
vendored
Normal file
BIN
vendor/github.com/go-playground/validator/v10/logo.png
generated
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
173
vendor/github.com/go-playground/validator/v10/postcode_regexes.go
generated
vendored
Normal file
173
vendor/github.com/go-playground/validator/v10/postcode_regexes.go
generated
vendored
Normal file
@ -0,0 +1,173 @@
|
||||
package validator
|
||||
|
||||
import "regexp"
|
||||
|
||||
var postCodePatternDict = map[string]string{
|
||||
"GB": `^GIR[ ]?0AA|((AB|AL|B|BA|BB|BD|BH|BL|BN|BR|BS|BT|CA|CB|CF|CH|CM|CO|CR|CT|CV|CW|DA|DD|DE|DG|DH|DL|DN|DT|DY|E|EC|EH|EN|EX|FK|FY|G|GL|GY|GU|HA|HD|HG|HP|HR|HS|HU|HX|IG|IM|IP|IV|JE|KA|KT|KW|KY|L|LA|LD|LE|LL|LN|LS|LU|M|ME|MK|ML|N|NE|NG|NN|NP|NR|NW|OL|OX|PA|PE|PH|PL|PO|PR|RG|RH|RM|S|SA|SE|SG|SK|SL|SM|SN|SO|SP|SR|SS|ST|SW|SY|TA|TD|TF|TN|TQ|TR|TS|TW|UB|W|WA|WC|WD|WF|WN|WR|WS|WV|YO|ZE)(\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}))|BFPO[ ]?\d{1,4}$`,
|
||||
"JE": `^JE\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}$`,
|
||||
"GG": `^GY\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}$`,
|
||||
"IM": `^IM\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}$`,
|
||||
"US": `^\d{5}([ \-]\d{4})?$`,
|
||||
"CA": `^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ ]?\d[ABCEGHJ-NPRSTV-Z]\d$`,
|
||||
"DE": `^\d{5}$`,
|
||||
"JP": `^\d{3}-\d{4}$`,
|
||||
"FR": `^\d{2}[ ]?\d{3}$`,
|
||||
"AU": `^\d{4}$`,
|
||||
"IT": `^\d{5}$`,
|
||||
"CH": `^\d{4}$`,
|
||||
"AT": `^\d{4}$`,
|
||||
"ES": `^\d{5}$`,
|
||||
"NL": `^\d{4}[ ]?[A-Z]{2}$`,
|
||||
"BE": `^\d{4}$`,
|
||||
"DK": `^\d{4}$`,
|
||||
"SE": `^\d{3}[ ]?\d{2}$`,
|
||||
"NO": `^\d{4}$`,
|
||||
"BR": `^\d{5}[\-]?\d{3}$`,
|
||||
"PT": `^\d{4}([\-]\d{3})?$`,
|
||||
"FI": `^\d{5}$`,
|
||||
"AX": `^22\d{3}$`,
|
||||
"KR": `^\d{3}[\-]\d{3}$`,
|
||||
"CN": `^\d{6}$`,
|
||||
"TW": `^\d{3}(\d{2})?$`,
|
||||
"SG": `^\d{6}$`,
|
||||
"DZ": `^\d{5}$`,
|
||||
"AD": `^AD\d{3}$`,
|
||||
"AR": `^([A-HJ-NP-Z])?\d{4}([A-Z]{3})?$`,
|
||||
"AM": `^(37)?\d{4}$`,
|
||||
"AZ": `^\d{4}$`,
|
||||
"BH": `^((1[0-2]|[2-9])\d{2})?$`,
|
||||
"BD": `^\d{4}$`,
|
||||
"BB": `^(BB\d{5})?$`,
|
||||
"BY": `^\d{6}$`,
|
||||
"BM": `^[A-Z]{2}[ ]?[A-Z0-9]{2}$`,
|
||||
"BA": `^\d{5}$`,
|
||||
"IO": `^BBND 1ZZ$`,
|
||||
"BN": `^[A-Z]{2}[ ]?\d{4}$`,
|
||||
"BG": `^\d{4}$`,
|
||||
"KH": `^\d{5}$`,
|
||||
"CV": `^\d{4}$`,
|
||||
"CL": `^\d{7}$`,
|
||||
"CR": `^\d{4,5}|\d{3}-\d{4}$`,
|
||||
"HR": `^\d{5}$`,
|
||||
"CY": `^\d{4}$`,
|
||||
"CZ": `^\d{3}[ ]?\d{2}$`,
|
||||
"DO": `^\d{5}$`,
|
||||
"EC": `^([A-Z]\d{4}[A-Z]|(?:[A-Z]{2})?\d{6})?$`,
|
||||
"EG": `^\d{5}$`,
|
||||
"EE": `^\d{5}$`,
|
||||
"FO": `^\d{3}$`,
|
||||
"GE": `^\d{4}$`,
|
||||
"GR": `^\d{3}[ ]?\d{2}$`,
|
||||
"GL": `^39\d{2}$`,
|
||||
"GT": `^\d{5}$`,
|
||||
"HT": `^\d{4}$`,
|
||||
"HN": `^(?:\d{5})?$`,
|
||||
"HU": `^\d{4}$`,
|
||||
"IS": `^\d{3}$`,
|
||||
"IN": `^\d{6}$`,
|
||||
"ID": `^\d{5}$`,
|
||||
"IL": `^\d{5}$`,
|
||||
"JO": `^\d{5}$`,
|
||||
"KZ": `^\d{6}$`,
|
||||
"KE": `^\d{5}$`,
|
||||
"KW": `^\d{5}$`,
|
||||
"LA": `^\d{5}$`,
|
||||
"LV": `^\d{4}$`,
|
||||
"LB": `^(\d{4}([ ]?\d{4})?)?$`,
|
||||
"LI": `^(948[5-9])|(949[0-7])$`,
|
||||
"LT": `^\d{5}$`,
|
||||
"LU": `^\d{4}$`,
|
||||
"MK": `^\d{4}$`,
|
||||
"MY": `^\d{5}$`,
|
||||
"MV": `^\d{5}$`,
|
||||
"MT": `^[A-Z]{3}[ ]?\d{2,4}$`,
|
||||
"MU": `^(\d{3}[A-Z]{2}\d{3})?$`,
|
||||
"MX": `^\d{5}$`,
|
||||
"MD": `^\d{4}$`,
|
||||
"MC": `^980\d{2}$`,
|
||||
"MA": `^\d{5}$`,
|
||||
"NP": `^\d{5}$`,
|
||||
"NZ": `^\d{4}$`,
|
||||
"NI": `^((\d{4}-)?\d{3}-\d{3}(-\d{1})?)?$`,
|
||||
"NG": `^(\d{6})?$`,
|
||||
"OM": `^(PC )?\d{3}$`,
|
||||
"PK": `^\d{5}$`,
|
||||
"PY": `^\d{4}$`,
|
||||
"PH": `^\d{4}$`,
|
||||
"PL": `^\d{2}-\d{3}$`,
|
||||
"PR": `^00[679]\d{2}([ \-]\d{4})?$`,
|
||||
"RO": `^\d{6}$`,
|
||||
"RU": `^\d{6}$`,
|
||||
"SM": `^4789\d$`,
|
||||
"SA": `^\d{5}$`,
|
||||
"SN": `^\d{5}$`,
|
||||
"SK": `^\d{3}[ ]?\d{2}$`,
|
||||
"SI": `^\d{4}$`,
|
||||
"ZA": `^\d{4}$`,
|
||||
"LK": `^\d{5}$`,
|
||||
"TJ": `^\d{6}$`,
|
||||
"TH": `^\d{5}$`,
|
||||
"TN": `^\d{4}$`,
|
||||
"TR": `^\d{5}$`,
|
||||
"TM": `^\d{6}$`,
|
||||
"UA": `^\d{5}$`,
|
||||
"UY": `^\d{5}$`,
|
||||
"UZ": `^\d{6}$`,
|
||||
"VA": `^00120$`,
|
||||
"VE": `^\d{4}$`,
|
||||
"ZM": `^\d{5}$`,
|
||||
"AS": `^96799$`,
|
||||
"CC": `^6799$`,
|
||||
"CK": `^\d{4}$`,
|
||||
"RS": `^\d{6}$`,
|
||||
"ME": `^8\d{4}$`,
|
||||
"CS": `^\d{5}$`,
|
||||
"YU": `^\d{5}$`,
|
||||
"CX": `^6798$`,
|
||||
"ET": `^\d{4}$`,
|
||||
"FK": `^FIQQ 1ZZ$`,
|
||||
"NF": `^2899$`,
|
||||
"FM": `^(9694[1-4])([ \-]\d{4})?$`,
|
||||
"GF": `^9[78]3\d{2}$`,
|
||||
"GN": `^\d{3}$`,
|
||||
"GP": `^9[78][01]\d{2}$`,
|
||||
"GS": `^SIQQ 1ZZ$`,
|
||||
"GU": `^969[123]\d([ \-]\d{4})?$`,
|
||||
"GW": `^\d{4}$`,
|
||||
"HM": `^\d{4}$`,
|
||||
"IQ": `^\d{5}$`,
|
||||
"KG": `^\d{6}$`,
|
||||
"LR": `^\d{4}$`,
|
||||
"LS": `^\d{3}$`,
|
||||
"MG": `^\d{3}$`,
|
||||
"MH": `^969[67]\d([ \-]\d{4})?$`,
|
||||
"MN": `^\d{6}$`,
|
||||
"MP": `^9695[012]([ \-]\d{4})?$`,
|
||||
"MQ": `^9[78]2\d{2}$`,
|
||||
"NC": `^988\d{2}$`,
|
||||
"NE": `^\d{4}$`,
|
||||
"VI": `^008(([0-4]\d)|(5[01]))([ \-]\d{4})?$`,
|
||||
"VN": `^[0-9]{1,6}$`,
|
||||
"PF": `^987\d{2}$`,
|
||||
"PG": `^\d{3}$`,
|
||||
"PM": `^9[78]5\d{2}$`,
|
||||
"PN": `^PCRN 1ZZ$`,
|
||||
"PW": `^96940$`,
|
||||
"RE": `^9[78]4\d{2}$`,
|
||||
"SH": `^(ASCN|STHL) 1ZZ$`,
|
||||
"SJ": `^\d{4}$`,
|
||||
"SO": `^\d{5}$`,
|
||||
"SZ": `^[HLMS]\d{3}$`,
|
||||
"TC": `^TKCA 1ZZ$`,
|
||||
"WF": `^986\d{2}$`,
|
||||
"XK": `^\d{5}$`,
|
||||
"YT": `^976\d{2}$`,
|
||||
}
|
||||
|
||||
var postCodeRegexDict = map[string]*regexp.Regexp{}
|
||||
|
||||
func init() {
|
||||
for countryCode, pattern := range postCodePatternDict {
|
||||
postCodeRegexDict[countryCode] = regexp.MustCompile(pattern)
|
||||
}
|
||||
}
|
131
vendor/github.com/go-playground/validator/v10/regexes.go
generated
vendored
Normal file
131
vendor/github.com/go-playground/validator/v10/regexes.go
generated
vendored
Normal file
@ -0,0 +1,131 @@
|
||||
package validator
|
||||
|
||||
import "regexp"
|
||||
|
||||
const (
|
||||
alphaRegexString = "^[a-zA-Z]+$"
|
||||
alphaNumericRegexString = "^[a-zA-Z0-9]+$"
|
||||
alphaUnicodeRegexString = "^[\\p{L}]+$"
|
||||
alphaUnicodeNumericRegexString = "^[\\p{L}\\p{N}]+$"
|
||||
numericRegexString = "^[-+]?[0-9]+(?:\\.[0-9]+)?$"
|
||||
numberRegexString = "^[0-9]+$"
|
||||
hexadecimalRegexString = "^(0[xX])?[0-9a-fA-F]+$"
|
||||
hexColorRegexString = "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
|
||||
rgbRegexString = "^rgb\\(\\s*(?:(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])|(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%)\\s*\\)$"
|
||||
rgbaRegexString = "^rgba\\(\\s*(?:(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])|(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%)\\s*,\\s*(?:(?:0.[1-9]*)|[01])\\s*\\)$"
|
||||
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*\\)$"
|
||||
hslaRegexString = "^hsla\\(\\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*,\\s*(?:(?:0.[1-9]*)|[01])\\s*\\)$"
|
||||
emailRegexString = "^(?:(?:(?:(?:[a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(?:\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|(?:(?:\\x22)(?:(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(?:\\x20|\\x09)+)?(?:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(\\x20|\\x09)+)?(?:\\x22))))@(?:(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$"
|
||||
e164RegexString = "^\\+[1-9]?[0-9]{7,14}$"
|
||||
base64RegexString = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$"
|
||||
base64URLRegexString = "^(?:[A-Za-z0-9-_]{4})*(?:[A-Za-z0-9-_]{2}==|[A-Za-z0-9-_]{3}=|[A-Za-z0-9-_]{4})$"
|
||||
iSBN10RegexString = "^(?:[0-9]{9}X|[0-9]{10})$"
|
||||
iSBN13RegexString = "^(?:(?:97(?:8|9))[0-9]{10})$"
|
||||
uUID3RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$"
|
||||
uUID4RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
|
||||
uUID5RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
|
||||
uUIDRegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
|
||||
uUID3RFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-3[0-9a-fA-F]{3}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
|
||||
uUID4RFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
|
||||
uUID5RFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-5[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
|
||||
uUIDRFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
|
||||
uLIDRegexString = "^[A-HJKMNP-TV-Z0-9]{26}$"
|
||||
md4RegexString = "^[0-9a-f]{32}$"
|
||||
md5RegexString = "^[0-9a-f]{32}$"
|
||||
sha256RegexString = "^[0-9a-f]{64}$"
|
||||
sha384RegexString = "^[0-9a-f]{96}$"
|
||||
sha512RegexString = "^[0-9a-f]{128}$"
|
||||
ripemd128RegexString = "^[0-9a-f]{32}$"
|
||||
ripemd160RegexString = "^[0-9a-f]{40}$"
|
||||
tiger128RegexString = "^[0-9a-f]{32}$"
|
||||
tiger160RegexString = "^[0-9a-f]{40}$"
|
||||
tiger192RegexString = "^[0-9a-f]{48}$"
|
||||
aSCIIRegexString = "^[\x00-\x7F]*$"
|
||||
printableASCIIRegexString = "^[\x20-\x7E]*$"
|
||||
multibyteRegexString = "[^\x00-\x7F]"
|
||||
dataURIRegexString = `^data:((?:\w+\/(?:([^;]|;[^;]).)+)?)`
|
||||
latitudeRegexString = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$"
|
||||
longitudeRegexString = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$"
|
||||
sSNRegexString = `^[0-9]{3}[ -]?(0[1-9]|[1-9][0-9])[ -]?([1-9][0-9]{3}|[0-9][1-9][0-9]{2}|[0-9]{2}[1-9][0-9]|[0-9]{3}[1-9])$`
|
||||
hostnameRegexStringRFC952 = `^[a-zA-Z]([a-zA-Z0-9\-]+[\.]?)*[a-zA-Z0-9]$` // https://tools.ietf.org/html/rfc952
|
||||
hostnameRegexStringRFC1123 = `^([a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62}){1}(\.[a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62})*?$` // accepts hostname starting with a digit https://tools.ietf.org/html/rfc1123
|
||||
fqdnRegexStringRFC1123 = `^([a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62})(\.[a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62})*?(\.[a-zA-Z]{1}[a-zA-Z0-9]{0,62})\.?$` // same as hostnameRegexStringRFC1123 but must contain a non numerical TLD (possibly ending with '.')
|
||||
btcAddressRegexString = `^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$` // bitcoin address
|
||||
btcAddressUpperRegexStringBech32 = `^BC1[02-9AC-HJ-NP-Z]{7,76}$` // bitcoin bech32 address https://en.bitcoin.it/wiki/Bech32
|
||||
btcAddressLowerRegexStringBech32 = `^bc1[02-9ac-hj-np-z]{7,76}$` // bitcoin bech32 address https://en.bitcoin.it/wiki/Bech32
|
||||
ethAddressRegexString = `^0x[0-9a-fA-F]{40}$`
|
||||
ethAddressUpperRegexString = `^0x[0-9A-F]{40}$`
|
||||
ethAddressLowerRegexString = `^0x[0-9a-f]{40}$`
|
||||
uRLEncodedRegexString = `^(?:[^%]|%[0-9A-Fa-f]{2})*$`
|
||||
hTMLEncodedRegexString = `&#[x]?([0-9a-fA-F]{2})|(>)|(<)|(")|(&)+[;]?`
|
||||
hTMLRegexString = `<[/]?([a-zA-Z]+).*?>`
|
||||
jWTRegexString = "^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$"
|
||||
splitParamsRegexString = `'[^']*'|\S+`
|
||||
bicRegexString = `^[A-Za-z]{6}[A-Za-z0-9]{2}([A-Za-z0-9]{3})?$`
|
||||
semverRegexString = `^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$` // numbered capture groups https://semver.org/
|
||||
dnsRegexStringRFC1035Label = "^[a-z]([-a-z0-9]*[a-z0-9]){0,62}$"
|
||||
)
|
||||
|
||||
var (
|
||||
alphaRegex = regexp.MustCompile(alphaRegexString)
|
||||
alphaNumericRegex = regexp.MustCompile(alphaNumericRegexString)
|
||||
alphaUnicodeRegex = regexp.MustCompile(alphaUnicodeRegexString)
|
||||
alphaUnicodeNumericRegex = regexp.MustCompile(alphaUnicodeNumericRegexString)
|
||||
numericRegex = regexp.MustCompile(numericRegexString)
|
||||
numberRegex = regexp.MustCompile(numberRegexString)
|
||||
hexadecimalRegex = regexp.MustCompile(hexadecimalRegexString)
|
||||
hexColorRegex = regexp.MustCompile(hexColorRegexString)
|
||||
rgbRegex = regexp.MustCompile(rgbRegexString)
|
||||
rgbaRegex = regexp.MustCompile(rgbaRegexString)
|
||||
hslRegex = regexp.MustCompile(hslRegexString)
|
||||
hslaRegex = regexp.MustCompile(hslaRegexString)
|
||||
e164Regex = regexp.MustCompile(e164RegexString)
|
||||
emailRegex = regexp.MustCompile(emailRegexString)
|
||||
base64Regex = regexp.MustCompile(base64RegexString)
|
||||
base64URLRegex = regexp.MustCompile(base64URLRegexString)
|
||||
iSBN10Regex = regexp.MustCompile(iSBN10RegexString)
|
||||
iSBN13Regex = regexp.MustCompile(iSBN13RegexString)
|
||||
uUID3Regex = regexp.MustCompile(uUID3RegexString)
|
||||
uUID4Regex = regexp.MustCompile(uUID4RegexString)
|
||||
uUID5Regex = regexp.MustCompile(uUID5RegexString)
|
||||
uUIDRegex = regexp.MustCompile(uUIDRegexString)
|
||||
uUID3RFC4122Regex = regexp.MustCompile(uUID3RFC4122RegexString)
|
||||
uUID4RFC4122Regex = regexp.MustCompile(uUID4RFC4122RegexString)
|
||||
uUID5RFC4122Regex = regexp.MustCompile(uUID5RFC4122RegexString)
|
||||
uUIDRFC4122Regex = regexp.MustCompile(uUIDRFC4122RegexString)
|
||||
uLIDRegex = regexp.MustCompile(uLIDRegexString)
|
||||
md4Regex = regexp.MustCompile(md4RegexString)
|
||||
md5Regex = regexp.MustCompile(md5RegexString)
|
||||
sha256Regex = regexp.MustCompile(sha256RegexString)
|
||||
sha384Regex = regexp.MustCompile(sha384RegexString)
|
||||
sha512Regex = regexp.MustCompile(sha512RegexString)
|
||||
ripemd128Regex = regexp.MustCompile(ripemd128RegexString)
|
||||
ripemd160Regex = regexp.MustCompile(ripemd160RegexString)
|
||||
tiger128Regex = regexp.MustCompile(tiger128RegexString)
|
||||
tiger160Regex = regexp.MustCompile(tiger160RegexString)
|
||||
tiger192Regex = regexp.MustCompile(tiger192RegexString)
|
||||
aSCIIRegex = regexp.MustCompile(aSCIIRegexString)
|
||||
printableASCIIRegex = regexp.MustCompile(printableASCIIRegexString)
|
||||
multibyteRegex = regexp.MustCompile(multibyteRegexString)
|
||||
dataURIRegex = regexp.MustCompile(dataURIRegexString)
|
||||
latitudeRegex = regexp.MustCompile(latitudeRegexString)
|
||||
longitudeRegex = regexp.MustCompile(longitudeRegexString)
|
||||
sSNRegex = regexp.MustCompile(sSNRegexString)
|
||||
hostnameRegexRFC952 = regexp.MustCompile(hostnameRegexStringRFC952)
|
||||
hostnameRegexRFC1123 = regexp.MustCompile(hostnameRegexStringRFC1123)
|
||||
fqdnRegexRFC1123 = regexp.MustCompile(fqdnRegexStringRFC1123)
|
||||
btcAddressRegex = regexp.MustCompile(btcAddressRegexString)
|
||||
btcUpperAddressRegexBech32 = regexp.MustCompile(btcAddressUpperRegexStringBech32)
|
||||
btcLowerAddressRegexBech32 = regexp.MustCompile(btcAddressLowerRegexStringBech32)
|
||||
ethAddressRegex = regexp.MustCompile(ethAddressRegexString)
|
||||
ethAddressRegexUpper = regexp.MustCompile(ethAddressUpperRegexString)
|
||||
ethAddressRegexLower = regexp.MustCompile(ethAddressLowerRegexString)
|
||||
uRLEncodedRegex = regexp.MustCompile(uRLEncodedRegexString)
|
||||
hTMLEncodedRegex = regexp.MustCompile(hTMLEncodedRegexString)
|
||||
hTMLRegex = regexp.MustCompile(hTMLRegexString)
|
||||
jWTRegex = regexp.MustCompile(jWTRegexString)
|
||||
splitParamsRegex = regexp.MustCompile(splitParamsRegexString)
|
||||
bicRegex = regexp.MustCompile(bicRegexString)
|
||||
semverRegex = regexp.MustCompile(semverRegexString)
|
||||
dnsRegexRFC1035Label = regexp.MustCompile(dnsRegexStringRFC1035Label)
|
||||
)
|
175
vendor/github.com/go-playground/validator/v10/struct_level.go
generated
vendored
Normal file
175
vendor/github.com/go-playground/validator/v10/struct_level.go
generated
vendored
Normal file
@ -0,0 +1,175 @@
|
||||
package validator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// StructLevelFunc accepts all values needed for struct level validation
|
||||
type StructLevelFunc func(sl StructLevel)
|
||||
|
||||
// StructLevelFuncCtx accepts all values needed for struct level validation
|
||||
// but also allows passing of contextual validation information via context.Context.
|
||||
type StructLevelFuncCtx func(ctx context.Context, sl StructLevel)
|
||||
|
||||
// wrapStructLevelFunc wraps normal StructLevelFunc makes it compatible with StructLevelFuncCtx
|
||||
func wrapStructLevelFunc(fn StructLevelFunc) StructLevelFuncCtx {
|
||||
return func(ctx context.Context, sl StructLevel) {
|
||||
fn(sl)
|
||||
}
|
||||
}
|
||||
|
||||
// StructLevel contains all the information and helper functions
|
||||
// to validate a struct
|
||||
type StructLevel interface {
|
||||
|
||||
// Validator returns the main validation object, in case one wants to call validations internally.
|
||||
// this is so you don't have to use anonymous functions to get access to the validate
|
||||
// instance.
|
||||
Validator() *Validate
|
||||
|
||||
// Top returns the top level struct, if any
|
||||
Top() reflect.Value
|
||||
|
||||
// Parent returns the current fields parent struct, if any
|
||||
Parent() reflect.Value
|
||||
|
||||
// Current returns the current struct.
|
||||
Current() reflect.Value
|
||||
|
||||
// ExtractType gets the actual underlying type of field value.
|
||||
// It will dive into pointers, customTypes and return you the
|
||||
// underlying value and its kind.
|
||||
ExtractType(field reflect.Value) (value reflect.Value, kind reflect.Kind, nullable bool)
|
||||
|
||||
// ReportError reports an error just by passing the field and tag information
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// fieldName and altName get appended to the existing namespace that
|
||||
// validator is on. e.g. pass 'FirstName' or 'Names[0]' depending
|
||||
// on the nesting
|
||||
//
|
||||
// tag can be an existing validation tag or just something you make up
|
||||
// and process on the flip side it's up to you.
|
||||
ReportError(field interface{}, fieldName, structFieldName string, tag, param string)
|
||||
|
||||
// ReportValidationErrors reports an error just by passing ValidationErrors
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// relativeNamespace and relativeActualNamespace get appended to the
|
||||
// existing namespace that validator is on.
|
||||
// e.g. pass 'User.FirstName' or 'Users[0].FirstName' depending
|
||||
// on the nesting. most of the time they will be blank, unless you validate
|
||||
// at a level lower the the current field depth
|
||||
ReportValidationErrors(relativeNamespace, relativeActualNamespace string, errs ValidationErrors)
|
||||
}
|
||||
|
||||
var _ StructLevel = new(validate)
|
||||
|
||||
// Top returns the top level struct
|
||||
//
|
||||
// NOTE: this can be the same as the current struct being validated
|
||||
// if not is a nested struct.
|
||||
//
|
||||
// this is only called when within Struct and Field Level validation and
|
||||
// should not be relied upon for an acurate value otherwise.
|
||||
func (v *validate) Top() reflect.Value {
|
||||
return v.top
|
||||
}
|
||||
|
||||
// Parent returns the current structs parent
|
||||
//
|
||||
// NOTE: this can be the same as the current struct being validated
|
||||
// if not is a nested struct.
|
||||
//
|
||||
// this is only called when within Struct and Field Level validation and
|
||||
// should not be relied upon for an acurate value otherwise.
|
||||
func (v *validate) Parent() reflect.Value {
|
||||
return v.slflParent
|
||||
}
|
||||
|
||||
// Current returns the current struct.
|
||||
func (v *validate) Current() reflect.Value {
|
||||
return v.slCurrent
|
||||
}
|
||||
|
||||
// Validator returns the main validation object, in case one want to call validations internally.
|
||||
func (v *validate) Validator() *Validate {
|
||||
return v.v
|
||||
}
|
||||
|
||||
// ExtractType gets the actual underlying type of field value.
|
||||
func (v *validate) ExtractType(field reflect.Value) (reflect.Value, reflect.Kind, bool) {
|
||||
return v.extractTypeInternal(field, false)
|
||||
}
|
||||
|
||||
// ReportError reports an error just by passing the field and tag information
|
||||
func (v *validate) ReportError(field interface{}, fieldName, structFieldName, tag, param string) {
|
||||
|
||||
fv, kind, _ := v.extractTypeInternal(reflect.ValueOf(field), false)
|
||||
|
||||
if len(structFieldName) == 0 {
|
||||
structFieldName = fieldName
|
||||
}
|
||||
|
||||
v.str1 = string(append(v.ns, fieldName...))
|
||||
|
||||
if v.v.hasTagNameFunc || fieldName != structFieldName {
|
||||
v.str2 = string(append(v.actualNs, structFieldName...))
|
||||
} else {
|
||||
v.str2 = v.str1
|
||||
}
|
||||
|
||||
if kind == reflect.Invalid {
|
||||
|
||||
v.errs = append(v.errs,
|
||||
&fieldError{
|
||||
v: v.v,
|
||||
tag: tag,
|
||||
actualTag: tag,
|
||||
ns: v.str1,
|
||||
structNs: v.str2,
|
||||
fieldLen: uint8(len(fieldName)),
|
||||
structfieldLen: uint8(len(structFieldName)),
|
||||
param: param,
|
||||
kind: kind,
|
||||
},
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
v.errs = append(v.errs,
|
||||
&fieldError{
|
||||
v: v.v,
|
||||
tag: tag,
|
||||
actualTag: tag,
|
||||
ns: v.str1,
|
||||
structNs: v.str2,
|
||||
fieldLen: uint8(len(fieldName)),
|
||||
structfieldLen: uint8(len(structFieldName)),
|
||||
value: fv.Interface(),
|
||||
param: param,
|
||||
kind: kind,
|
||||
typ: fv.Type(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// ReportValidationErrors reports ValidationErrors obtained from running validations within the Struct Level validation.
|
||||
//
|
||||
// NOTE: this function prepends the current namespace to the relative ones.
|
||||
func (v *validate) ReportValidationErrors(relativeNamespace, relativeStructNamespace string, errs ValidationErrors) {
|
||||
|
||||
var err *fieldError
|
||||
|
||||
for i := 0; i < len(errs); i++ {
|
||||
|
||||
err = errs[i].(*fieldError)
|
||||
err.ns = string(append(append(v.ns, relativeNamespace...), err.ns...))
|
||||
err.structNs = string(append(append(v.actualNs, relativeStructNamespace...), err.structNs...))
|
||||
|
||||
v.errs = append(v.errs, err)
|
||||
}
|
||||
}
|
11
vendor/github.com/go-playground/validator/v10/translations.go
generated
vendored
Normal file
11
vendor/github.com/go-playground/validator/v10/translations.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
package validator
|
||||
|
||||
import ut "github.com/go-playground/universal-translator"
|
||||
|
||||
// TranslationFunc is the function type used to register or override
|
||||
// custom translations
|
||||
type TranslationFunc func(ut ut.Translator, fe FieldError) string
|
||||
|
||||
// RegisterTranslationsFunc allows for registering of translations
|
||||
// for a 'ut.Translator' for use within the 'TranslationFunc'
|
||||
type RegisterTranslationsFunc func(ut ut.Translator) error
|
288
vendor/github.com/go-playground/validator/v10/util.go
generated
vendored
Normal file
288
vendor/github.com/go-playground/validator/v10/util.go
generated
vendored
Normal file
@ -0,0 +1,288 @@
|
||||
package validator
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// extractTypeInternal gets the actual underlying type of field value.
|
||||
// It will dive into pointers, customTypes and return you the
|
||||
// underlying value and it's kind.
|
||||
func (v *validate) extractTypeInternal(current reflect.Value, nullable bool) (reflect.Value, reflect.Kind, bool) {
|
||||
|
||||
BEGIN:
|
||||
switch current.Kind() {
|
||||
case reflect.Ptr:
|
||||
|
||||
nullable = true
|
||||
|
||||
if current.IsNil() {
|
||||
return current, reflect.Ptr, nullable
|
||||
}
|
||||
|
||||
current = current.Elem()
|
||||
goto BEGIN
|
||||
|
||||
case reflect.Interface:
|
||||
|
||||
nullable = true
|
||||
|
||||
if current.IsNil() {
|
||||
return current, reflect.Interface, nullable
|
||||
}
|
||||
|
||||
current = current.Elem()
|
||||
goto BEGIN
|
||||
|
||||
case reflect.Invalid:
|
||||
return current, reflect.Invalid, nullable
|
||||
|
||||
default:
|
||||
|
||||
if v.v.hasCustomFuncs {
|
||||
|
||||
if fn, ok := v.v.customFuncs[current.Type()]; ok {
|
||||
current = reflect.ValueOf(fn(current))
|
||||
goto BEGIN
|
||||
}
|
||||
}
|
||||
|
||||
return current, current.Kind(), nullable
|
||||
}
|
||||
}
|
||||
|
||||
// getStructFieldOKInternal traverses a struct to retrieve a specific field denoted by the provided namespace and
|
||||
// returns the field, field kind and whether is was successful in retrieving the field at all.
|
||||
//
|
||||
// NOTE: when not successful ok will be false, this can happen when a nested struct is nil and so the field
|
||||
// could not be retrieved because it didn't exist.
|
||||
func (v *validate) getStructFieldOKInternal(val reflect.Value, namespace string) (current reflect.Value, kind reflect.Kind, nullable bool, found bool) {
|
||||
|
||||
BEGIN:
|
||||
current, kind, nullable = v.ExtractType(val)
|
||||
if kind == reflect.Invalid {
|
||||
return
|
||||
}
|
||||
|
||||
if namespace == "" {
|
||||
found = true
|
||||
return
|
||||
}
|
||||
|
||||
switch kind {
|
||||
|
||||
case reflect.Ptr, reflect.Interface:
|
||||
return
|
||||
|
||||
case reflect.Struct:
|
||||
|
||||
typ := current.Type()
|
||||
fld := namespace
|
||||
var ns string
|
||||
|
||||
if !typ.ConvertibleTo(timeType) {
|
||||
|
||||
idx := strings.Index(namespace, namespaceSeparator)
|
||||
|
||||
if idx != -1 {
|
||||
fld = namespace[:idx]
|
||||
ns = namespace[idx+1:]
|
||||
} else {
|
||||
ns = ""
|
||||
}
|
||||
|
||||
bracketIdx := strings.Index(fld, leftBracket)
|
||||
if bracketIdx != -1 {
|
||||
fld = fld[:bracketIdx]
|
||||
|
||||
ns = namespace[bracketIdx:]
|
||||
}
|
||||
|
||||
val = current.FieldByName(fld)
|
||||
namespace = ns
|
||||
goto BEGIN
|
||||
}
|
||||
|
||||
case reflect.Array, reflect.Slice:
|
||||
idx := strings.Index(namespace, leftBracket)
|
||||
idx2 := strings.Index(namespace, rightBracket)
|
||||
|
||||
arrIdx, _ := strconv.Atoi(namespace[idx+1 : idx2])
|
||||
|
||||
if arrIdx >= current.Len() {
|
||||
return
|
||||
}
|
||||
|
||||
startIdx := idx2 + 1
|
||||
|
||||
if startIdx < len(namespace) {
|
||||
if namespace[startIdx:startIdx+1] == namespaceSeparator {
|
||||
startIdx++
|
||||
}
|
||||
}
|
||||
|
||||
val = current.Index(arrIdx)
|
||||
namespace = namespace[startIdx:]
|
||||
goto BEGIN
|
||||
|
||||
case reflect.Map:
|
||||
idx := strings.Index(namespace, leftBracket) + 1
|
||||
idx2 := strings.Index(namespace, rightBracket)
|
||||
|
||||
endIdx := idx2
|
||||
|
||||
if endIdx+1 < len(namespace) {
|
||||
if namespace[endIdx+1:endIdx+2] == namespaceSeparator {
|
||||
endIdx++
|
||||
}
|
||||
}
|
||||
|
||||
key := namespace[idx:idx2]
|
||||
|
||||
switch current.Type().Key().Kind() {
|
||||
case reflect.Int:
|
||||
i, _ := strconv.Atoi(key)
|
||||
val = current.MapIndex(reflect.ValueOf(i))
|
||||
namespace = namespace[endIdx+1:]
|
||||
|
||||
case reflect.Int8:
|
||||
i, _ := strconv.ParseInt(key, 10, 8)
|
||||
val = current.MapIndex(reflect.ValueOf(int8(i)))
|
||||
namespace = namespace[endIdx+1:]
|
||||
|
||||
case reflect.Int16:
|
||||
i, _ := strconv.ParseInt(key, 10, 16)
|
||||
val = current.MapIndex(reflect.ValueOf(int16(i)))
|
||||
namespace = namespace[endIdx+1:]
|
||||
|
||||
case reflect.Int32:
|
||||
i, _ := strconv.ParseInt(key, 10, 32)
|
||||
val = current.MapIndex(reflect.ValueOf(int32(i)))
|
||||
namespace = namespace[endIdx+1:]
|
||||
|
||||
case reflect.Int64:
|
||||
i, _ := strconv.ParseInt(key, 10, 64)
|
||||
val = current.MapIndex(reflect.ValueOf(i))
|
||||
namespace = namespace[endIdx+1:]
|
||||
|
||||
case reflect.Uint:
|
||||
i, _ := strconv.ParseUint(key, 10, 0)
|
||||
val = current.MapIndex(reflect.ValueOf(uint(i)))
|
||||
namespace = namespace[endIdx+1:]
|
||||
|
||||
case reflect.Uint8:
|
||||
i, _ := strconv.ParseUint(key, 10, 8)
|
||||
val = current.MapIndex(reflect.ValueOf(uint8(i)))
|
||||
namespace = namespace[endIdx+1:]
|
||||
|
||||
case reflect.Uint16:
|
||||
i, _ := strconv.ParseUint(key, 10, 16)
|
||||
val = current.MapIndex(reflect.ValueOf(uint16(i)))
|
||||
namespace = namespace[endIdx+1:]
|
||||
|
||||
case reflect.Uint32:
|
||||
i, _ := strconv.ParseUint(key, 10, 32)
|
||||
val = current.MapIndex(reflect.ValueOf(uint32(i)))
|
||||
namespace = namespace[endIdx+1:]
|
||||
|
||||
case reflect.Uint64:
|
||||
i, _ := strconv.ParseUint(key, 10, 64)
|
||||
val = current.MapIndex(reflect.ValueOf(i))
|
||||
namespace = namespace[endIdx+1:]
|
||||
|
||||
case reflect.Float32:
|
||||
f, _ := strconv.ParseFloat(key, 32)
|
||||
val = current.MapIndex(reflect.ValueOf(float32(f)))
|
||||
namespace = namespace[endIdx+1:]
|
||||
|
||||
case reflect.Float64:
|
||||
f, _ := strconv.ParseFloat(key, 64)
|
||||
val = current.MapIndex(reflect.ValueOf(f))
|
||||
namespace = namespace[endIdx+1:]
|
||||
|
||||
case reflect.Bool:
|
||||
b, _ := strconv.ParseBool(key)
|
||||
val = current.MapIndex(reflect.ValueOf(b))
|
||||
namespace = namespace[endIdx+1:]
|
||||
|
||||
// reflect.Type = string
|
||||
default:
|
||||
val = current.MapIndex(reflect.ValueOf(key))
|
||||
namespace = namespace[endIdx+1:]
|
||||
}
|
||||
|
||||
goto BEGIN
|
||||
}
|
||||
|
||||
// if got here there was more namespace, cannot go any deeper
|
||||
panic("Invalid field namespace")
|
||||
}
|
||||
|
||||
// asInt returns the parameter as a int64
|
||||
// or panics if it can't convert
|
||||
func asInt(param string) int64 {
|
||||
i, err := strconv.ParseInt(param, 0, 64)
|
||||
panicIf(err)
|
||||
|
||||
return i
|
||||
}
|
||||
|
||||
// asIntFromTimeDuration parses param as time.Duration and returns it as int64
|
||||
// or panics on error.
|
||||
func asIntFromTimeDuration(param string) int64 {
|
||||
d, err := time.ParseDuration(param)
|
||||
if err != nil {
|
||||
// attempt parsing as an an integer assuming nanosecond precision
|
||||
return asInt(param)
|
||||
}
|
||||
return int64(d)
|
||||
}
|
||||
|
||||
// asIntFromType calls the proper function to parse param as int64,
|
||||
// given a field's Type t.
|
||||
func asIntFromType(t reflect.Type, param string) int64 {
|
||||
switch t {
|
||||
case timeDurationType:
|
||||
return asIntFromTimeDuration(param)
|
||||
default:
|
||||
return asInt(param)
|
||||
}
|
||||
}
|
||||
|
||||
// asUint returns the parameter as a uint64
|
||||
// or panics if it can't convert
|
||||
func asUint(param string) uint64 {
|
||||
|
||||
i, err := strconv.ParseUint(param, 0, 64)
|
||||
panicIf(err)
|
||||
|
||||
return i
|
||||
}
|
||||
|
||||
// asFloat returns the parameter as a float64
|
||||
// or panics if it can't convert
|
||||
func asFloat(param string) float64 {
|
||||
|
||||
i, err := strconv.ParseFloat(param, 64)
|
||||
panicIf(err)
|
||||
|
||||
return i
|
||||
}
|
||||
|
||||
// asBool returns the parameter as a bool
|
||||
// or panics if it can't convert
|
||||
func asBool(param string) bool {
|
||||
|
||||
i, err := strconv.ParseBool(param)
|
||||
panicIf(err)
|
||||
|
||||
return i
|
||||
}
|
||||
|
||||
func panicIf(err error) {
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
}
|
486
vendor/github.com/go-playground/validator/v10/validator.go
generated
vendored
Normal file
486
vendor/github.com/go-playground/validator/v10/validator.go
generated
vendored
Normal file
@ -0,0 +1,486 @@
|
||||
package validator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// per validate construct
|
||||
type validate struct {
|
||||
v *Validate
|
||||
top reflect.Value
|
||||
ns []byte
|
||||
actualNs []byte
|
||||
errs ValidationErrors
|
||||
includeExclude map[string]struct{} // reset only if StructPartial or StructExcept are called, no need otherwise
|
||||
ffn FilterFunc
|
||||
slflParent reflect.Value // StructLevel & FieldLevel
|
||||
slCurrent reflect.Value // StructLevel & FieldLevel
|
||||
flField reflect.Value // StructLevel & FieldLevel
|
||||
cf *cField // StructLevel & FieldLevel
|
||||
ct *cTag // StructLevel & FieldLevel
|
||||
misc []byte // misc reusable
|
||||
str1 string // misc reusable
|
||||
str2 string // misc reusable
|
||||
fldIsPointer bool // StructLevel & FieldLevel
|
||||
isPartial bool
|
||||
hasExcludes bool
|
||||
}
|
||||
|
||||
// parent and current will be the same the first run of validateStruct
|
||||
func (v *validate) validateStruct(ctx context.Context, parent reflect.Value, current reflect.Value, typ reflect.Type, ns []byte, structNs []byte, ct *cTag) {
|
||||
|
||||
cs, ok := v.v.structCache.Get(typ)
|
||||
if !ok {
|
||||
cs = v.v.extractStructCache(current, typ.Name())
|
||||
}
|
||||
|
||||
if len(ns) == 0 && len(cs.name) != 0 {
|
||||
|
||||
ns = append(ns, cs.name...)
|
||||
ns = append(ns, '.')
|
||||
|
||||
structNs = append(structNs, cs.name...)
|
||||
structNs = append(structNs, '.')
|
||||
}
|
||||
|
||||
// ct is nil on top level struct, and structs as fields that have no tag info
|
||||
// so if nil or if not nil and the structonly tag isn't present
|
||||
if ct == nil || ct.typeof != typeStructOnly {
|
||||
|
||||
var f *cField
|
||||
|
||||
for i := 0; i < len(cs.fields); i++ {
|
||||
|
||||
f = cs.fields[i]
|
||||
|
||||
if v.isPartial {
|
||||
|
||||
if v.ffn != nil {
|
||||
// used with StructFiltered
|
||||
if v.ffn(append(structNs, f.name...)) {
|
||||
continue
|
||||
}
|
||||
|
||||
} else {
|
||||
// used with StructPartial & StructExcept
|
||||
_, ok = v.includeExclude[string(append(structNs, f.name...))]
|
||||
|
||||
if (ok && v.hasExcludes) || (!ok && !v.hasExcludes) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
v.traverseField(ctx, current, current.Field(f.idx), ns, structNs, f, f.cTags)
|
||||
}
|
||||
}
|
||||
|
||||
// check if any struct level validations, after all field validations already checked.
|
||||
// first iteration will have no info about nostructlevel tag, and is checked prior to
|
||||
// calling the next iteration of validateStruct called from traverseField.
|
||||
if cs.fn != nil {
|
||||
|
||||
v.slflParent = parent
|
||||
v.slCurrent = current
|
||||
v.ns = ns
|
||||
v.actualNs = structNs
|
||||
|
||||
cs.fn(ctx, v)
|
||||
}
|
||||
}
|
||||
|
||||
// traverseField validates any field, be it a struct or single field, ensures it's validity and passes it along to be validated via it's tag options
|
||||
func (v *validate) traverseField(ctx context.Context, parent reflect.Value, current reflect.Value, ns []byte, structNs []byte, cf *cField, ct *cTag) {
|
||||
var typ reflect.Type
|
||||
var kind reflect.Kind
|
||||
|
||||
current, kind, v.fldIsPointer = v.extractTypeInternal(current, false)
|
||||
|
||||
switch kind {
|
||||
case reflect.Ptr, reflect.Interface, reflect.Invalid:
|
||||
|
||||
if ct == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if ct.typeof == typeOmitEmpty || ct.typeof == typeIsDefault {
|
||||
return
|
||||
}
|
||||
|
||||
if ct.hasTag {
|
||||
if kind == reflect.Invalid {
|
||||
v.str1 = string(append(ns, cf.altName...))
|
||||
if v.v.hasTagNameFunc {
|
||||
v.str2 = string(append(structNs, cf.name...))
|
||||
} else {
|
||||
v.str2 = v.str1
|
||||
}
|
||||
v.errs = append(v.errs,
|
||||
&fieldError{
|
||||
v: v.v,
|
||||
tag: ct.aliasTag,
|
||||
actualTag: ct.tag,
|
||||
ns: v.str1,
|
||||
structNs: v.str2,
|
||||
fieldLen: uint8(len(cf.altName)),
|
||||
structfieldLen: uint8(len(cf.name)),
|
||||
param: ct.param,
|
||||
kind: kind,
|
||||
},
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
v.str1 = string(append(ns, cf.altName...))
|
||||
if v.v.hasTagNameFunc {
|
||||
v.str2 = string(append(structNs, cf.name...))
|
||||
} else {
|
||||
v.str2 = v.str1
|
||||
}
|
||||
if !ct.runValidationWhenNil {
|
||||
v.errs = append(v.errs,
|
||||
&fieldError{
|
||||
v: v.v,
|
||||
tag: ct.aliasTag,
|
||||
actualTag: ct.tag,
|
||||
ns: v.str1,
|
||||
structNs: v.str2,
|
||||
fieldLen: uint8(len(cf.altName)),
|
||||
structfieldLen: uint8(len(cf.name)),
|
||||
value: current.Interface(),
|
||||
param: ct.param,
|
||||
kind: kind,
|
||||
typ: current.Type(),
|
||||
},
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.Struct:
|
||||
|
||||
typ = current.Type()
|
||||
|
||||
if !typ.ConvertibleTo(timeType) {
|
||||
|
||||
if ct != nil {
|
||||
|
||||
if ct.typeof == typeStructOnly {
|
||||
goto CONTINUE
|
||||
} else if ct.typeof == typeIsDefault {
|
||||
// set Field Level fields
|
||||
v.slflParent = parent
|
||||
v.flField = current
|
||||
v.cf = cf
|
||||
v.ct = ct
|
||||
|
||||
if !ct.fn(ctx, v) {
|
||||
v.str1 = string(append(ns, cf.altName...))
|
||||
|
||||
if v.v.hasTagNameFunc {
|
||||
v.str2 = string(append(structNs, cf.name...))
|
||||
} else {
|
||||
v.str2 = v.str1
|
||||
}
|
||||
|
||||
v.errs = append(v.errs,
|
||||
&fieldError{
|
||||
v: v.v,
|
||||
tag: ct.aliasTag,
|
||||
actualTag: ct.tag,
|
||||
ns: v.str1,
|
||||
structNs: v.str2,
|
||||
fieldLen: uint8(len(cf.altName)),
|
||||
structfieldLen: uint8(len(cf.name)),
|
||||
value: current.Interface(),
|
||||
param: ct.param,
|
||||
kind: kind,
|
||||
typ: typ,
|
||||
},
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ct = ct.next
|
||||
}
|
||||
|
||||
if ct != nil && ct.typeof == typeNoStructLevel {
|
||||
return
|
||||
}
|
||||
|
||||
CONTINUE:
|
||||
// if len == 0 then validating using 'Var' or 'VarWithValue'
|
||||
// Var - doesn't make much sense to do it that way, should call 'Struct', but no harm...
|
||||
// VarWithField - this allows for validating against each field within the struct against a specific value
|
||||
// pretty handy in certain situations
|
||||
if len(cf.name) > 0 {
|
||||
ns = append(append(ns, cf.altName...), '.')
|
||||
structNs = append(append(structNs, cf.name...), '.')
|
||||
}
|
||||
|
||||
v.validateStruct(ctx, parent, current, typ, ns, structNs, ct)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if ct == nil || !ct.hasTag {
|
||||
return
|
||||
}
|
||||
|
||||
typ = current.Type()
|
||||
|
||||
OUTER:
|
||||
for {
|
||||
if ct == nil {
|
||||
return
|
||||
}
|
||||
|
||||
switch ct.typeof {
|
||||
|
||||
case typeOmitEmpty:
|
||||
|
||||
// set Field Level fields
|
||||
v.slflParent = parent
|
||||
v.flField = current
|
||||
v.cf = cf
|
||||
v.ct = ct
|
||||
|
||||
if !hasValue(v) {
|
||||
return
|
||||
}
|
||||
|
||||
ct = ct.next
|
||||
continue
|
||||
|
||||
case typeEndKeys:
|
||||
return
|
||||
|
||||
case typeDive:
|
||||
|
||||
ct = ct.next
|
||||
|
||||
// traverse slice or map here
|
||||
// or panic ;)
|
||||
switch kind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
|
||||
var i64 int64
|
||||
reusableCF := &cField{}
|
||||
|
||||
for i := 0; i < current.Len(); i++ {
|
||||
|
||||
i64 = int64(i)
|
||||
|
||||
v.misc = append(v.misc[0:0], cf.name...)
|
||||
v.misc = append(v.misc, '[')
|
||||
v.misc = strconv.AppendInt(v.misc, i64, 10)
|
||||
v.misc = append(v.misc, ']')
|
||||
|
||||
reusableCF.name = string(v.misc)
|
||||
|
||||
if cf.namesEqual {
|
||||
reusableCF.altName = reusableCF.name
|
||||
} else {
|
||||
|
||||
v.misc = append(v.misc[0:0], cf.altName...)
|
||||
v.misc = append(v.misc, '[')
|
||||
v.misc = strconv.AppendInt(v.misc, i64, 10)
|
||||
v.misc = append(v.misc, ']')
|
||||
|
||||
reusableCF.altName = string(v.misc)
|
||||
}
|
||||
v.traverseField(ctx, parent, current.Index(i), ns, structNs, reusableCF, ct)
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
|
||||
var pv string
|
||||
reusableCF := &cField{}
|
||||
|
||||
for _, key := range current.MapKeys() {
|
||||
|
||||
pv = fmt.Sprintf("%v", key.Interface())
|
||||
|
||||
v.misc = append(v.misc[0:0], cf.name...)
|
||||
v.misc = append(v.misc, '[')
|
||||
v.misc = append(v.misc, pv...)
|
||||
v.misc = append(v.misc, ']')
|
||||
|
||||
reusableCF.name = string(v.misc)
|
||||
|
||||
if cf.namesEqual {
|
||||
reusableCF.altName = reusableCF.name
|
||||
} else {
|
||||
v.misc = append(v.misc[0:0], cf.altName...)
|
||||
v.misc = append(v.misc, '[')
|
||||
v.misc = append(v.misc, pv...)
|
||||
v.misc = append(v.misc, ']')
|
||||
|
||||
reusableCF.altName = string(v.misc)
|
||||
}
|
||||
|
||||
if ct != nil && ct.typeof == typeKeys && ct.keys != nil {
|
||||
v.traverseField(ctx, parent, key, ns, structNs, reusableCF, ct.keys)
|
||||
// can be nil when just keys being validated
|
||||
if ct.next != nil {
|
||||
v.traverseField(ctx, parent, current.MapIndex(key), ns, structNs, reusableCF, ct.next)
|
||||
}
|
||||
} else {
|
||||
v.traverseField(ctx, parent, current.MapIndex(key), ns, structNs, reusableCF, ct)
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
// throw error, if not a slice or map then should not have gotten here
|
||||
// bad dive tag
|
||||
panic("dive error! can't dive on a non slice or map")
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
case typeOr:
|
||||
|
||||
v.misc = v.misc[0:0]
|
||||
|
||||
for {
|
||||
|
||||
// set Field Level fields
|
||||
v.slflParent = parent
|
||||
v.flField = current
|
||||
v.cf = cf
|
||||
v.ct = ct
|
||||
|
||||
if ct.fn(ctx, v) {
|
||||
if ct.isBlockEnd {
|
||||
ct = ct.next
|
||||
continue OUTER
|
||||
}
|
||||
|
||||
// drain rest of the 'or' values, then continue or leave
|
||||
for {
|
||||
|
||||
ct = ct.next
|
||||
|
||||
if ct == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if ct.typeof != typeOr {
|
||||
continue OUTER
|
||||
}
|
||||
|
||||
if ct.isBlockEnd {
|
||||
ct = ct.next
|
||||
continue OUTER
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
v.misc = append(v.misc, '|')
|
||||
v.misc = append(v.misc, ct.tag...)
|
||||
|
||||
if ct.hasParam {
|
||||
v.misc = append(v.misc, '=')
|
||||
v.misc = append(v.misc, ct.param...)
|
||||
}
|
||||
|
||||
if ct.isBlockEnd || ct.next == nil {
|
||||
// if we get here, no valid 'or' value and no more tags
|
||||
v.str1 = string(append(ns, cf.altName...))
|
||||
|
||||
if v.v.hasTagNameFunc {
|
||||
v.str2 = string(append(structNs, cf.name...))
|
||||
} else {
|
||||
v.str2 = v.str1
|
||||
}
|
||||
|
||||
if ct.hasAlias {
|
||||
|
||||
v.errs = append(v.errs,
|
||||
&fieldError{
|
||||
v: v.v,
|
||||
tag: ct.aliasTag,
|
||||
actualTag: ct.actualAliasTag,
|
||||
ns: v.str1,
|
||||
structNs: v.str2,
|
||||
fieldLen: uint8(len(cf.altName)),
|
||||
structfieldLen: uint8(len(cf.name)),
|
||||
value: current.Interface(),
|
||||
param: ct.param,
|
||||
kind: kind,
|
||||
typ: typ,
|
||||
},
|
||||
)
|
||||
|
||||
} else {
|
||||
|
||||
tVal := string(v.misc)[1:]
|
||||
|
||||
v.errs = append(v.errs,
|
||||
&fieldError{
|
||||
v: v.v,
|
||||
tag: tVal,
|
||||
actualTag: tVal,
|
||||
ns: v.str1,
|
||||
structNs: v.str2,
|
||||
fieldLen: uint8(len(cf.altName)),
|
||||
structfieldLen: uint8(len(cf.name)),
|
||||
value: current.Interface(),
|
||||
param: ct.param,
|
||||
kind: kind,
|
||||
typ: typ,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
ct = ct.next
|
||||
}
|
||||
|
||||
default:
|
||||
|
||||
// set Field Level fields
|
||||
v.slflParent = parent
|
||||
v.flField = current
|
||||
v.cf = cf
|
||||
v.ct = ct
|
||||
|
||||
if !ct.fn(ctx, v) {
|
||||
|
||||
v.str1 = string(append(ns, cf.altName...))
|
||||
|
||||
if v.v.hasTagNameFunc {
|
||||
v.str2 = string(append(structNs, cf.name...))
|
||||
} else {
|
||||
v.str2 = v.str1
|
||||
}
|
||||
|
||||
v.errs = append(v.errs,
|
||||
&fieldError{
|
||||
v: v.v,
|
||||
tag: ct.aliasTag,
|
||||
actualTag: ct.tag,
|
||||
ns: v.str1,
|
||||
structNs: v.str2,
|
||||
fieldLen: uint8(len(cf.altName)),
|
||||
structfieldLen: uint8(len(cf.name)),
|
||||
value: current.Interface(),
|
||||
param: ct.param,
|
||||
kind: kind,
|
||||
typ: typ,
|
||||
},
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
ct = ct.next
|
||||
}
|
||||
}
|
||||
|
||||
}
|
699
vendor/github.com/go-playground/validator/v10/validator_instance.go
generated
vendored
Normal file
699
vendor/github.com/go-playground/validator/v10/validator_instance.go
generated
vendored
Normal file
@ -0,0 +1,699 @@
|
||||
package validator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
ut "github.com/go-playground/universal-translator"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultTagName = "validate"
|
||||
utf8HexComma = "0x2C"
|
||||
utf8Pipe = "0x7C"
|
||||
tagSeparator = ","
|
||||
orSeparator = "|"
|
||||
tagKeySeparator = "="
|
||||
structOnlyTag = "structonly"
|
||||
noStructLevelTag = "nostructlevel"
|
||||
omitempty = "omitempty"
|
||||
isdefault = "isdefault"
|
||||
requiredWithoutAllTag = "required_without_all"
|
||||
requiredWithoutTag = "required_without"
|
||||
requiredWithTag = "required_with"
|
||||
requiredWithAllTag = "required_with_all"
|
||||
requiredIfTag = "required_if"
|
||||
requiredUnlessTag = "required_unless"
|
||||
excludedWithoutAllTag = "excluded_without_all"
|
||||
excludedWithoutTag = "excluded_without"
|
||||
excludedWithTag = "excluded_with"
|
||||
excludedWithAllTag = "excluded_with_all"
|
||||
excludedIfTag = "excluded_if"
|
||||
excludedUnlessTag = "excluded_unless"
|
||||
skipValidationTag = "-"
|
||||
diveTag = "dive"
|
||||
keysTag = "keys"
|
||||
endKeysTag = "endkeys"
|
||||
requiredTag = "required"
|
||||
namespaceSeparator = "."
|
||||
leftBracket = "["
|
||||
rightBracket = "]"
|
||||
restrictedTagChars = ".[],|=+()`~!@#$%^&*\\\"/?<>{}"
|
||||
restrictedAliasErr = "Alias '%s' either contains restricted characters or is the same as a restricted tag needed for normal operation"
|
||||
restrictedTagErr = "Tag '%s' either contains restricted characters or is the same as a restricted tag needed for normal operation"
|
||||
)
|
||||
|
||||
var (
|
||||
timeDurationType = reflect.TypeOf(time.Duration(0))
|
||||
timeType = reflect.TypeOf(time.Time{})
|
||||
|
||||
defaultCField = &cField{namesEqual: true}
|
||||
)
|
||||
|
||||
// FilterFunc is the type used to filter fields using
|
||||
// StructFiltered(...) function.
|
||||
// returning true results in the field being filtered/skiped from
|
||||
// validation
|
||||
type FilterFunc func(ns []byte) bool
|
||||
|
||||
// CustomTypeFunc allows for overriding or adding custom field type handler functions
|
||||
// field = field value of the type to return a value to be validated
|
||||
// example Valuer from sql drive see https://golang.org/src/database/sql/driver/types.go?s=1210:1293#L29
|
||||
type CustomTypeFunc func(field reflect.Value) interface{}
|
||||
|
||||
// TagNameFunc allows for adding of a custom tag name parser
|
||||
type TagNameFunc func(field reflect.StructField) string
|
||||
|
||||
type internalValidationFuncWrapper struct {
|
||||
fn FuncCtx
|
||||
runValidatinOnNil bool
|
||||
}
|
||||
|
||||
// Validate contains the validator settings and cache
|
||||
type Validate struct {
|
||||
tagName string
|
||||
pool *sync.Pool
|
||||
hasCustomFuncs bool
|
||||
hasTagNameFunc bool
|
||||
tagNameFunc TagNameFunc
|
||||
structLevelFuncs map[reflect.Type]StructLevelFuncCtx
|
||||
customFuncs map[reflect.Type]CustomTypeFunc
|
||||
aliases map[string]string
|
||||
validations map[string]internalValidationFuncWrapper
|
||||
transTagFunc map[ut.Translator]map[string]TranslationFunc // map[<locale>]map[<tag>]TranslationFunc
|
||||
rules map[reflect.Type]map[string]string
|
||||
tagCache *tagCache
|
||||
structCache *structCache
|
||||
}
|
||||
|
||||
// New returns a new instance of 'validate' with sane defaults.
|
||||
// Validate is designed to be thread-safe and used as a singleton instance.
|
||||
// It caches information about your struct and validations,
|
||||
// in essence only parsing your validation tags once per struct type.
|
||||
// Using multiple instances neglects the benefit of caching.
|
||||
func New() *Validate {
|
||||
|
||||
tc := new(tagCache)
|
||||
tc.m.Store(make(map[string]*cTag))
|
||||
|
||||
sc := new(structCache)
|
||||
sc.m.Store(make(map[reflect.Type]*cStruct))
|
||||
|
||||
v := &Validate{
|
||||
tagName: defaultTagName,
|
||||
aliases: make(map[string]string, len(bakedInAliases)),
|
||||
validations: make(map[string]internalValidationFuncWrapper, len(bakedInValidators)),
|
||||
tagCache: tc,
|
||||
structCache: sc,
|
||||
}
|
||||
|
||||
// must copy alias validators for separate validations to be used in each validator instance
|
||||
for k, val := range bakedInAliases {
|
||||
v.RegisterAlias(k, val)
|
||||
}
|
||||
|
||||
// must copy validators for separate validations to be used in each instance
|
||||
for k, val := range bakedInValidators {
|
||||
|
||||
switch k {
|
||||
// these require that even if the value is nil that the validation should run, omitempty still overrides this behaviour
|
||||
case requiredIfTag, requiredUnlessTag, requiredWithTag, requiredWithAllTag, requiredWithoutTag, requiredWithoutAllTag,
|
||||
excludedIfTag, excludedUnlessTag, excludedWithTag, excludedWithAllTag, excludedWithoutTag, excludedWithoutAllTag:
|
||||
_ = v.registerValidation(k, wrapFunc(val), true, true)
|
||||
default:
|
||||
// no need to error check here, baked in will always be valid
|
||||
_ = v.registerValidation(k, wrapFunc(val), true, false)
|
||||
}
|
||||
}
|
||||
|
||||
v.pool = &sync.Pool{
|
||||
New: func() interface{} {
|
||||
return &validate{
|
||||
v: v,
|
||||
ns: make([]byte, 0, 64),
|
||||
actualNs: make([]byte, 0, 64),
|
||||
misc: make([]byte, 32),
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// SetTagName allows for changing of the default tag name of 'validate'
|
||||
func (v *Validate) SetTagName(name string) {
|
||||
v.tagName = name
|
||||
}
|
||||
|
||||
// ValidateMapCtx validates a map using a map of validation rules and allows passing of contextual
|
||||
// validation validation information via context.Context.
|
||||
func (v Validate) ValidateMapCtx(ctx context.Context, data map[string]interface{}, rules map[string]interface{}) map[string]interface{} {
|
||||
errs := make(map[string]interface{})
|
||||
for field, rule := range rules {
|
||||
if ruleObj, ok := rule.(map[string]interface{}); ok {
|
||||
if dataObj, ok := data[field].(map[string]interface{}); ok {
|
||||
err := v.ValidateMapCtx(ctx, dataObj, ruleObj)
|
||||
if len(err) > 0 {
|
||||
errs[field] = err
|
||||
}
|
||||
} else if dataObjs, ok := data[field].([]map[string]interface{}); ok {
|
||||
for _, obj := range dataObjs {
|
||||
err := v.ValidateMapCtx(ctx, obj, ruleObj)
|
||||
if len(err) > 0 {
|
||||
errs[field] = err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
errs[field] = errors.New("The field: '" + field + "' is not a map to dive")
|
||||
}
|
||||
} else if ruleStr, ok := rule.(string); ok {
|
||||
err := v.VarCtx(ctx, data[field], ruleStr)
|
||||
if err != nil {
|
||||
errs[field] = err
|
||||
}
|
||||
}
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
// ValidateMap validates map data from a map of tags
|
||||
func (v *Validate) ValidateMap(data map[string]interface{}, rules map[string]interface{}) map[string]interface{} {
|
||||
return v.ValidateMapCtx(context.Background(), data, rules)
|
||||
}
|
||||
|
||||
// RegisterTagNameFunc registers a function to get alternate names for StructFields.
|
||||
//
|
||||
// eg. to use the names which have been specified for JSON representations of structs, rather than normal Go field names:
|
||||
//
|
||||
// validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
|
||||
// name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
|
||||
// // skip if tag key says it should be ignored
|
||||
// if name == "-" {
|
||||
// return ""
|
||||
// }
|
||||
// return name
|
||||
// })
|
||||
func (v *Validate) RegisterTagNameFunc(fn TagNameFunc) {
|
||||
v.tagNameFunc = fn
|
||||
v.hasTagNameFunc = true
|
||||
}
|
||||
|
||||
// RegisterValidation adds a validation with the given tag
|
||||
//
|
||||
// NOTES:
|
||||
// - if the key already exists, the previous validation function will be replaced.
|
||||
// - this method is not thread-safe it is intended that these all be registered prior to any validation
|
||||
func (v *Validate) RegisterValidation(tag string, fn Func, callValidationEvenIfNull ...bool) error {
|
||||
return v.RegisterValidationCtx(tag, wrapFunc(fn), callValidationEvenIfNull...)
|
||||
}
|
||||
|
||||
// RegisterValidationCtx does the same as RegisterValidation on accepts a FuncCtx validation
|
||||
// allowing context.Context validation support.
|
||||
func (v *Validate) RegisterValidationCtx(tag string, fn FuncCtx, callValidationEvenIfNull ...bool) error {
|
||||
var nilCheckable bool
|
||||
if len(callValidationEvenIfNull) > 0 {
|
||||
nilCheckable = callValidationEvenIfNull[0]
|
||||
}
|
||||
return v.registerValidation(tag, fn, false, nilCheckable)
|
||||
}
|
||||
|
||||
func (v *Validate) registerValidation(tag string, fn FuncCtx, bakedIn bool, nilCheckable bool) error {
|
||||
if len(tag) == 0 {
|
||||
return errors.New("function Key cannot be empty")
|
||||
}
|
||||
|
||||
if fn == nil {
|
||||
return errors.New("function cannot be empty")
|
||||
}
|
||||
|
||||
_, ok := restrictedTags[tag]
|
||||
if !bakedIn && (ok || strings.ContainsAny(tag, restrictedTagChars)) {
|
||||
panic(fmt.Sprintf(restrictedTagErr, tag))
|
||||
}
|
||||
v.validations[tag] = internalValidationFuncWrapper{fn: fn, runValidatinOnNil: nilCheckable}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterAlias registers a mapping of a single validation tag that
|
||||
// defines a common or complex set of validation(s) to simplify adding validation
|
||||
// to structs.
|
||||
//
|
||||
// NOTE: this function is not thread-safe it is intended that these all be registered prior to any validation
|
||||
func (v *Validate) RegisterAlias(alias, tags string) {
|
||||
|
||||
_, ok := restrictedTags[alias]
|
||||
|
||||
if ok || strings.ContainsAny(alias, restrictedTagChars) {
|
||||
panic(fmt.Sprintf(restrictedAliasErr, alias))
|
||||
}
|
||||
|
||||
v.aliases[alias] = tags
|
||||
}
|
||||
|
||||
// RegisterStructValidation registers a StructLevelFunc against a number of types.
|
||||
//
|
||||
// NOTE:
|
||||
// - this method is not thread-safe it is intended that these all be registered prior to any validation
|
||||
func (v *Validate) RegisterStructValidation(fn StructLevelFunc, types ...interface{}) {
|
||||
v.RegisterStructValidationCtx(wrapStructLevelFunc(fn), types...)
|
||||
}
|
||||
|
||||
// RegisterStructValidationCtx registers a StructLevelFuncCtx against a number of types and allows passing
|
||||
// of contextual validation information via context.Context.
|
||||
//
|
||||
// NOTE:
|
||||
// - this method is not thread-safe it is intended that these all be registered prior to any validation
|
||||
func (v *Validate) RegisterStructValidationCtx(fn StructLevelFuncCtx, types ...interface{}) {
|
||||
|
||||
if v.structLevelFuncs == nil {
|
||||
v.structLevelFuncs = make(map[reflect.Type]StructLevelFuncCtx)
|
||||
}
|
||||
|
||||
for _, t := range types {
|
||||
tv := reflect.ValueOf(t)
|
||||
if tv.Kind() == reflect.Ptr {
|
||||
t = reflect.Indirect(tv).Interface()
|
||||
}
|
||||
|
||||
v.structLevelFuncs[reflect.TypeOf(t)] = fn
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterStructValidationMapRules registers validate map rules.
|
||||
// Be aware that map validation rules supersede those defined on a/the struct if present.
|
||||
//
|
||||
// NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation
|
||||
func (v *Validate) RegisterStructValidationMapRules(rules map[string]string, types ...interface{}) {
|
||||
if v.rules == nil {
|
||||
v.rules = make(map[reflect.Type]map[string]string)
|
||||
}
|
||||
|
||||
deepCopyRules := make(map[string]string)
|
||||
for i, rule := range rules {
|
||||
deepCopyRules[i] = rule
|
||||
}
|
||||
|
||||
for _, t := range types {
|
||||
typ := reflect.TypeOf(t)
|
||||
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
typ = typ.Elem()
|
||||
}
|
||||
|
||||
if typ.Kind() != reflect.Struct {
|
||||
continue
|
||||
}
|
||||
v.rules[typ] = deepCopyRules
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterCustomTypeFunc registers a CustomTypeFunc against a number of types
|
||||
//
|
||||
// NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation
|
||||
func (v *Validate) RegisterCustomTypeFunc(fn CustomTypeFunc, types ...interface{}) {
|
||||
|
||||
if v.customFuncs == nil {
|
||||
v.customFuncs = make(map[reflect.Type]CustomTypeFunc)
|
||||
}
|
||||
|
||||
for _, t := range types {
|
||||
v.customFuncs[reflect.TypeOf(t)] = fn
|
||||
}
|
||||
|
||||
v.hasCustomFuncs = true
|
||||
}
|
||||
|
||||
// RegisterTranslation registers translations against the provided tag.
|
||||
func (v *Validate) RegisterTranslation(tag string, trans ut.Translator, registerFn RegisterTranslationsFunc, translationFn TranslationFunc) (err error) {
|
||||
|
||||
if v.transTagFunc == nil {
|
||||
v.transTagFunc = make(map[ut.Translator]map[string]TranslationFunc)
|
||||
}
|
||||
|
||||
if err = registerFn(trans); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
m, ok := v.transTagFunc[trans]
|
||||
if !ok {
|
||||
m = make(map[string]TranslationFunc)
|
||||
v.transTagFunc[trans] = m
|
||||
}
|
||||
|
||||
m[tag] = translationFn
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Struct validates a structs exposed fields, and automatically validates nested structs, unless otherwise specified.
|
||||
//
|
||||
// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
|
||||
// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
|
||||
func (v *Validate) Struct(s interface{}) error {
|
||||
return v.StructCtx(context.Background(), s)
|
||||
}
|
||||
|
||||
// StructCtx validates a structs exposed fields, and automatically validates nested structs, unless otherwise specified
|
||||
// and also allows passing of context.Context for contextual validation information.
|
||||
//
|
||||
// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
|
||||
// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
|
||||
func (v *Validate) StructCtx(ctx context.Context, s interface{}) (err error) {
|
||||
|
||||
val := reflect.ValueOf(s)
|
||||
top := val
|
||||
|
||||
if val.Kind() == reflect.Ptr && !val.IsNil() {
|
||||
val = val.Elem()
|
||||
}
|
||||
|
||||
if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) {
|
||||
return &InvalidValidationError{Type: reflect.TypeOf(s)}
|
||||
}
|
||||
|
||||
// good to validate
|
||||
vd := v.pool.Get().(*validate)
|
||||
vd.top = top
|
||||
vd.isPartial = false
|
||||
// vd.hasExcludes = false // only need to reset in StructPartial and StructExcept
|
||||
|
||||
vd.validateStruct(ctx, top, val, val.Type(), vd.ns[0:0], vd.actualNs[0:0], nil)
|
||||
|
||||
if len(vd.errs) > 0 {
|
||||
err = vd.errs
|
||||
vd.errs = nil
|
||||
}
|
||||
|
||||
v.pool.Put(vd)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// StructFiltered validates a structs exposed fields, that pass the FilterFunc check and automatically validates
|
||||
// nested structs, unless otherwise specified.
|
||||
//
|
||||
// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
|
||||
// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
|
||||
func (v *Validate) StructFiltered(s interface{}, fn FilterFunc) error {
|
||||
return v.StructFilteredCtx(context.Background(), s, fn)
|
||||
}
|
||||
|
||||
// StructFilteredCtx validates a structs exposed fields, that pass the FilterFunc check and automatically validates
|
||||
// nested structs, unless otherwise specified and also allows passing of contextual validation information via
|
||||
// context.Context
|
||||
//
|
||||
// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
|
||||
// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
|
||||
func (v *Validate) StructFilteredCtx(ctx context.Context, s interface{}, fn FilterFunc) (err error) {
|
||||
val := reflect.ValueOf(s)
|
||||
top := val
|
||||
|
||||
if val.Kind() == reflect.Ptr && !val.IsNil() {
|
||||
val = val.Elem()
|
||||
}
|
||||
|
||||
if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) {
|
||||
return &InvalidValidationError{Type: reflect.TypeOf(s)}
|
||||
}
|
||||
|
||||
// good to validate
|
||||
vd := v.pool.Get().(*validate)
|
||||
vd.top = top
|
||||
vd.isPartial = true
|
||||
vd.ffn = fn
|
||||
// vd.hasExcludes = false // only need to reset in StructPartial and StructExcept
|
||||
|
||||
vd.validateStruct(ctx, top, val, val.Type(), vd.ns[0:0], vd.actualNs[0:0], nil)
|
||||
|
||||
if len(vd.errs) > 0 {
|
||||
err = vd.errs
|
||||
vd.errs = nil
|
||||
}
|
||||
|
||||
v.pool.Put(vd)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// StructPartial validates the fields passed in only, ignoring all others.
|
||||
// Fields may be provided in a namespaced fashion relative to the struct provided
|
||||
// eg. NestedStruct.Field or NestedArrayField[0].Struct.Name
|
||||
//
|
||||
// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
|
||||
// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
|
||||
func (v *Validate) StructPartial(s interface{}, fields ...string) error {
|
||||
return v.StructPartialCtx(context.Background(), s, fields...)
|
||||
}
|
||||
|
||||
// StructPartialCtx validates the fields passed in only, ignoring all others and allows passing of contextual
|
||||
// validation validation information via context.Context
|
||||
// Fields may be provided in a namespaced fashion relative to the struct provided
|
||||
// eg. NestedStruct.Field or NestedArrayField[0].Struct.Name
|
||||
//
|
||||
// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
|
||||
// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
|
||||
func (v *Validate) StructPartialCtx(ctx context.Context, s interface{}, fields ...string) (err error) {
|
||||
val := reflect.ValueOf(s)
|
||||
top := val
|
||||
|
||||
if val.Kind() == reflect.Ptr && !val.IsNil() {
|
||||
val = val.Elem()
|
||||
}
|
||||
|
||||
if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) {
|
||||
return &InvalidValidationError{Type: reflect.TypeOf(s)}
|
||||
}
|
||||
|
||||
// good to validate
|
||||
vd := v.pool.Get().(*validate)
|
||||
vd.top = top
|
||||
vd.isPartial = true
|
||||
vd.ffn = nil
|
||||
vd.hasExcludes = false
|
||||
vd.includeExclude = make(map[string]struct{})
|
||||
|
||||
typ := val.Type()
|
||||
name := typ.Name()
|
||||
|
||||
for _, k := range fields {
|
||||
|
||||
flds := strings.Split(k, namespaceSeparator)
|
||||
if len(flds) > 0 {
|
||||
|
||||
vd.misc = append(vd.misc[0:0], name...)
|
||||
// Don't append empty name for unnamed structs
|
||||
if len(vd.misc) != 0 {
|
||||
vd.misc = append(vd.misc, '.')
|
||||
}
|
||||
|
||||
for _, s := range flds {
|
||||
|
||||
idx := strings.Index(s, leftBracket)
|
||||
|
||||
if idx != -1 {
|
||||
for idx != -1 {
|
||||
vd.misc = append(vd.misc, s[:idx]...)
|
||||
vd.includeExclude[string(vd.misc)] = struct{}{}
|
||||
|
||||
idx2 := strings.Index(s, rightBracket)
|
||||
idx2++
|
||||
vd.misc = append(vd.misc, s[idx:idx2]...)
|
||||
vd.includeExclude[string(vd.misc)] = struct{}{}
|
||||
s = s[idx2:]
|
||||
idx = strings.Index(s, leftBracket)
|
||||
}
|
||||
} else {
|
||||
|
||||
vd.misc = append(vd.misc, s...)
|
||||
vd.includeExclude[string(vd.misc)] = struct{}{}
|
||||
}
|
||||
|
||||
vd.misc = append(vd.misc, '.')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vd.validateStruct(ctx, top, val, typ, vd.ns[0:0], vd.actualNs[0:0], nil)
|
||||
|
||||
if len(vd.errs) > 0 {
|
||||
err = vd.errs
|
||||
vd.errs = nil
|
||||
}
|
||||
|
||||
v.pool.Put(vd)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// StructExcept validates all fields except the ones passed in.
|
||||
// Fields may be provided in a namespaced fashion relative to the struct provided
|
||||
// i.e. NestedStruct.Field or NestedArrayField[0].Struct.Name
|
||||
//
|
||||
// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
|
||||
// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
|
||||
func (v *Validate) StructExcept(s interface{}, fields ...string) error {
|
||||
return v.StructExceptCtx(context.Background(), s, fields...)
|
||||
}
|
||||
|
||||
// StructExceptCtx validates all fields except the ones passed in and allows passing of contextual
|
||||
// validation validation information via context.Context
|
||||
// Fields may be provided in a namespaced fashion relative to the struct provided
|
||||
// i.e. NestedStruct.Field or NestedArrayField[0].Struct.Name
|
||||
//
|
||||
// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
|
||||
// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
|
||||
func (v *Validate) StructExceptCtx(ctx context.Context, s interface{}, fields ...string) (err error) {
|
||||
val := reflect.ValueOf(s)
|
||||
top := val
|
||||
|
||||
if val.Kind() == reflect.Ptr && !val.IsNil() {
|
||||
val = val.Elem()
|
||||
}
|
||||
|
||||
if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) {
|
||||
return &InvalidValidationError{Type: reflect.TypeOf(s)}
|
||||
}
|
||||
|
||||
// good to validate
|
||||
vd := v.pool.Get().(*validate)
|
||||
vd.top = top
|
||||
vd.isPartial = true
|
||||
vd.ffn = nil
|
||||
vd.hasExcludes = true
|
||||
vd.includeExclude = make(map[string]struct{})
|
||||
|
||||
typ := val.Type()
|
||||
name := typ.Name()
|
||||
|
||||
for _, key := range fields {
|
||||
|
||||
vd.misc = vd.misc[0:0]
|
||||
|
||||
if len(name) > 0 {
|
||||
vd.misc = append(vd.misc, name...)
|
||||
vd.misc = append(vd.misc, '.')
|
||||
}
|
||||
|
||||
vd.misc = append(vd.misc, key...)
|
||||
vd.includeExclude[string(vd.misc)] = struct{}{}
|
||||
}
|
||||
|
||||
vd.validateStruct(ctx, top, val, typ, vd.ns[0:0], vd.actualNs[0:0], nil)
|
||||
|
||||
if len(vd.errs) > 0 {
|
||||
err = vd.errs
|
||||
vd.errs = nil
|
||||
}
|
||||
|
||||
v.pool.Put(vd)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Var validates a single variable using tag style validation.
|
||||
// eg.
|
||||
// var i int
|
||||
// validate.Var(i, "gt=1,lt=10")
|
||||
//
|
||||
// WARNING: a struct can be passed for validation eg. time.Time is a struct or
|
||||
// if you have a custom type and have registered a custom type handler, so must
|
||||
// allow it; however unforeseen validations will occur if trying to validate a
|
||||
// struct that is meant to be passed to 'validate.Struct'
|
||||
//
|
||||
// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
|
||||
// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
|
||||
// validate Array, Slice and maps fields which may contain more than one error
|
||||
func (v *Validate) Var(field interface{}, tag string) error {
|
||||
return v.VarCtx(context.Background(), field, tag)
|
||||
}
|
||||
|
||||
// VarCtx validates a single variable using tag style validation and allows passing of contextual
|
||||
// validation validation information via context.Context.
|
||||
// eg.
|
||||
// var i int
|
||||
// validate.Var(i, "gt=1,lt=10")
|
||||
//
|
||||
// WARNING: a struct can be passed for validation eg. time.Time is a struct or
|
||||
// if you have a custom type and have registered a custom type handler, so must
|
||||
// allow it; however unforeseen validations will occur if trying to validate a
|
||||
// struct that is meant to be passed to 'validate.Struct'
|
||||
//
|
||||
// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
|
||||
// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
|
||||
// validate Array, Slice and maps fields which may contain more than one error
|
||||
func (v *Validate) VarCtx(ctx context.Context, field interface{}, tag string) (err error) {
|
||||
if len(tag) == 0 || tag == skipValidationTag {
|
||||
return nil
|
||||
}
|
||||
|
||||
ctag := v.fetchCacheTag(tag)
|
||||
val := reflect.ValueOf(field)
|
||||
vd := v.pool.Get().(*validate)
|
||||
vd.top = val
|
||||
vd.isPartial = false
|
||||
vd.traverseField(ctx, val, val, vd.ns[0:0], vd.actualNs[0:0], defaultCField, ctag)
|
||||
|
||||
if len(vd.errs) > 0 {
|
||||
err = vd.errs
|
||||
vd.errs = nil
|
||||
}
|
||||
v.pool.Put(vd)
|
||||
return
|
||||
}
|
||||
|
||||
// VarWithValue validates a single variable, against another variable/field's value using tag style validation
|
||||
// eg.
|
||||
// s1 := "abcd"
|
||||
// s2 := "abcd"
|
||||
// validate.VarWithValue(s1, s2, "eqcsfield") // returns true
|
||||
//
|
||||
// WARNING: a struct can be passed for validation eg. time.Time is a struct or
|
||||
// if you have a custom type and have registered a custom type handler, so must
|
||||
// allow it; however unforeseen validations will occur if trying to validate a
|
||||
// struct that is meant to be passed to 'validate.Struct'
|
||||
//
|
||||
// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
|
||||
// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
|
||||
// validate Array, Slice and maps fields which may contain more than one error
|
||||
func (v *Validate) VarWithValue(field interface{}, other interface{}, tag string) error {
|
||||
return v.VarWithValueCtx(context.Background(), field, other, tag)
|
||||
}
|
||||
|
||||
// VarWithValueCtx validates a single variable, against another variable/field's value using tag style validation and
|
||||
// allows passing of contextual validation validation information via context.Context.
|
||||
// eg.
|
||||
// s1 := "abcd"
|
||||
// s2 := "abcd"
|
||||
// validate.VarWithValue(s1, s2, "eqcsfield") // returns true
|
||||
//
|
||||
// WARNING: a struct can be passed for validation eg. time.Time is a struct or
|
||||
// if you have a custom type and have registered a custom type handler, so must
|
||||
// allow it; however unforeseen validations will occur if trying to validate a
|
||||
// struct that is meant to be passed to 'validate.Struct'
|
||||
//
|
||||
// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
|
||||
// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
|
||||
// validate Array, Slice and maps fields which may contain more than one error
|
||||
func (v *Validate) VarWithValueCtx(ctx context.Context, field interface{}, other interface{}, tag string) (err error) {
|
||||
if len(tag) == 0 || tag == skipValidationTag {
|
||||
return nil
|
||||
}
|
||||
ctag := v.fetchCacheTag(tag)
|
||||
otherVal := reflect.ValueOf(other)
|
||||
vd := v.pool.Get().(*validate)
|
||||
vd.top = otherVal
|
||||
vd.isPartial = false
|
||||
vd.traverseField(ctx, otherVal, reflect.ValueOf(field), vd.ns[0:0], vd.actualNs[0:0], defaultCField, ctag)
|
||||
|
||||
if len(vd.errs) > 0 {
|
||||
err = vd.errs
|
||||
vd.errs = nil
|
||||
}
|
||||
v.pool.Put(vd)
|
||||
return
|
||||
}
|
Reference in New Issue
Block a user