Update heketi dependencies to sha@558b29266ce0a873991ecfb3edc41a668a998514.
Fixes # https://github.com/kubernetes/kubernetes/issues/70802 Signed-off-by: Humble Chirammal <hchiramm@redhat.com>
This commit is contained in:
25
vendor/github.com/go-ozzo/ozzo-validation/.gitignore
generated
vendored
Normal file
25
vendor/github.com/go-ozzo/ozzo-validation/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
.DS_Store
|
16
vendor/github.com/go-ozzo/ozzo-validation/.travis.yml
generated
vendored
Normal file
16
vendor/github.com/go-ozzo/ozzo-validation/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.8
|
||||
- 1.9
|
||||
- tip
|
||||
|
||||
install:
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
- go get github.com/mattn/goveralls
|
||||
- go list -f '{{range .Imports}}{{.}} {{end}}' ./... | xargs go get -v
|
||||
- go list -f '{{range .TestImports}}{{.}} {{end}}' ./... | xargs go get -v
|
||||
|
||||
script:
|
||||
- go test -v -covermode=count -coverprofile=coverage.out
|
||||
- $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci
|
41
vendor/github.com/go-ozzo/ozzo-validation/BUILD
generated
vendored
Normal file
41
vendor/github.com/go-ozzo/ozzo-validation/BUILD
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"date.go",
|
||||
"error.go",
|
||||
"in.go",
|
||||
"length.go",
|
||||
"match.go",
|
||||
"minmax.go",
|
||||
"multipleof.go",
|
||||
"not_in.go",
|
||||
"not_nil.go",
|
||||
"required.go",
|
||||
"string.go",
|
||||
"struct.go",
|
||||
"util.go",
|
||||
"validation.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/github.com/go-ozzo/ozzo-validation",
|
||||
importpath = "github.com/go-ozzo/ozzo-validation",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//vendor/github.com/go-ozzo/ozzo-validation/is:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
17
vendor/github.com/go-ozzo/ozzo-validation/LICENSE
generated
vendored
Normal file
17
vendor/github.com/go-ozzo/ozzo-validation/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2016, Qiang Xue
|
||||
|
||||
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.
|
534
vendor/github.com/go-ozzo/ozzo-validation/README.md
generated
vendored
Normal file
534
vendor/github.com/go-ozzo/ozzo-validation/README.md
generated
vendored
Normal file
@@ -0,0 +1,534 @@
|
||||
# ozzo-validation
|
||||
|
||||
[](http://godoc.org/github.com/go-ozzo/ozzo-validation)
|
||||
[](https://travis-ci.org/go-ozzo/ozzo-validation)
|
||||
[](https://coveralls.io/github/go-ozzo/ozzo-validation?branch=master)
|
||||
[](https://goreportcard.com/report/github.com/go-ozzo/ozzo-validation)
|
||||
|
||||
## Description
|
||||
|
||||
ozzo-validation is a Go package that provides configurable and extensible data validation capabilities.
|
||||
It has the following features:
|
||||
|
||||
* use normal programming constructs rather than error-prone struct tags to specify how data should be validated.
|
||||
* can validate data of different types, e.g., structs, strings, byte slices, slices, maps, arrays.
|
||||
* can validate custom data types as long as they implement the `Validatable` interface.
|
||||
* can validate data types that implement the `sql.Valuer` interface (e.g. `sql.NullString`).
|
||||
* customizable and well-formatted validation errors.
|
||||
* provide a rich set of validation rules right out of box.
|
||||
* extremely easy to create and use custom validation rules.
|
||||
|
||||
|
||||
## Requirements
|
||||
|
||||
Go 1.8 or above.
|
||||
|
||||
|
||||
## Getting Started
|
||||
|
||||
The ozzo-validation package mainly includes a set of validation rules and two validation methods. You use
|
||||
validation rules to describe how a value should be considered valid, and you call either `validation.Validate()`
|
||||
or `validation.ValidateStruct()` to validate the value.
|
||||
|
||||
|
||||
### Installation
|
||||
|
||||
Run the following command to install the package:
|
||||
|
||||
```
|
||||
go get github.com/go-ozzo/ozzo-validation
|
||||
go get github.com/go-ozzo/ozzo-validation/is
|
||||
```
|
||||
|
||||
### Validating a Simple Value
|
||||
|
||||
For a simple value, such as a string or an integer, you may use `validation.Validate()` to validate it. For example,
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-ozzo/ozzo-validation"
|
||||
"github.com/go-ozzo/ozzo-validation/is"
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := "example"
|
||||
err := validation.Validate(data,
|
||||
validation.Required, // not empty
|
||||
validation.Length(5, 100), // length between 5 and 100
|
||||
is.URL, // is a valid URL
|
||||
)
|
||||
fmt.Println(err)
|
||||
// Output:
|
||||
// must be a valid URL
|
||||
}
|
||||
```
|
||||
|
||||
The method `validation.Validate()` will run through the rules in the order that they are listed. If a rule fails
|
||||
the validation, the method will return the corresponding error and skip the rest of the rules. The method will
|
||||
return nil if the value passes all validation rules.
|
||||
|
||||
|
||||
### Validating a Struct
|
||||
|
||||
For a struct value, you usually want to check if its fields are valid. For example, in a RESTful application, you
|
||||
may unmarshal the request payload into a struct and then validate the struct fields. If one or multiple fields
|
||||
are invalid, you may want to get an error describing which fields are invalid. You can use `validation.ValidateStruct()`
|
||||
to achieve this purpose. A single struct can have rules for multiple fields, and a field can be associated with multiple
|
||||
rules. For example,
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/go-ozzo/ozzo-validation"
|
||||
"github.com/go-ozzo/ozzo-validation/is"
|
||||
)
|
||||
|
||||
type Address struct {
|
||||
Street string
|
||||
City string
|
||||
State string
|
||||
Zip string
|
||||
}
|
||||
|
||||
func (a Address) Validate() error {
|
||||
return validation.ValidateStruct(&a,
|
||||
// Street cannot be empty, and the length must between 5 and 50
|
||||
validation.Field(&a.Street, validation.Required, validation.Length(5, 50)),
|
||||
// City cannot be empty, and the length must between 5 and 50
|
||||
validation.Field(&a.City, validation.Required, validation.Length(5, 50)),
|
||||
// State cannot be empty, and must be a string consisting of two letters in upper case
|
||||
validation.Field(&a.State, validation.Required, validation.Match(regexp.MustCompile("^[A-Z]{2}$"))),
|
||||
// State cannot be empty, and must be a string consisting of five digits
|
||||
validation.Field(&a.Zip, validation.Required, validation.Match(regexp.MustCompile("^[0-9]{5}$"))),
|
||||
)
|
||||
}
|
||||
|
||||
func main() {
|
||||
a := Address{
|
||||
Street: "123",
|
||||
City: "Unknown",
|
||||
State: "Virginia",
|
||||
Zip: "12345",
|
||||
}
|
||||
|
||||
err := a.Validate()
|
||||
fmt.Println(err)
|
||||
// Output:
|
||||
// Street: the length must be between 5 and 50; State: must be in a valid format.
|
||||
}
|
||||
```
|
||||
|
||||
Note that when calling `validation.ValidateStruct` to validate a struct, you should pass to the method a pointer
|
||||
to the struct instead of the struct itself. Similarly, when calling `validation.Field` to specify the rules
|
||||
for a struct field, you should use a pointer to the struct field.
|
||||
|
||||
When the struct validation is performed, the fields are validated in the order they are specified in `ValidateStruct`.
|
||||
And when each field is validated, its rules are also evaluated in the order they are associated with the field.
|
||||
If a rule fails, an error is recorded for that field, and the validation will continue with the next field.
|
||||
|
||||
|
||||
### Validation Errors
|
||||
|
||||
The `validation.ValidateStruct` method returns validation errors found in struct fields in terms of `validation.Errors`
|
||||
which is a map of fields and their corresponding errors. Nil is returned if validation passes.
|
||||
|
||||
By default, `validation.Errors` uses the struct tags named `json` to determine what names should be used to
|
||||
represent the invalid fields. The type also implements the `json.Marshaler` interface so that it can be marshaled
|
||||
into a proper JSON object. For example,
|
||||
|
||||
```go
|
||||
type Address struct {
|
||||
Street string `json:"street"`
|
||||
City string `json:"city"`
|
||||
State string `json:"state"`
|
||||
Zip string `json:"zip"`
|
||||
}
|
||||
|
||||
// ...perform validation here...
|
||||
|
||||
err := a.Validate()
|
||||
b, _ := json.Marshal(err)
|
||||
fmt.Println(string(b))
|
||||
// Output:
|
||||
// {"street":"the length must be between 5 and 50","state":"must be in a valid format"}
|
||||
```
|
||||
|
||||
You may modify `validation.ErrorTag` to use a different struct tag name.
|
||||
|
||||
If you do not like the magic that `ValidateStruct` determines error keys based on struct field names or corresponding
|
||||
tag values, you may use the following alternative approach:
|
||||
|
||||
```go
|
||||
c := Customer{
|
||||
Name: "Qiang Xue",
|
||||
Email: "q",
|
||||
Address: Address{
|
||||
State: "Virginia",
|
||||
},
|
||||
}
|
||||
|
||||
err := validation.Errors{
|
||||
"name": validation.Validate(c.Name, validation.Required, validation.Length(5, 20)),
|
||||
"email": validation.Validate(c.Name, validation.Required, is.Email),
|
||||
"zip": validation.Validate(c.Address.Zip, validation.Required, validation.Match(regexp.MustCompile("^[0-9]{5}$"))),
|
||||
}.Filter()
|
||||
fmt.Println(err)
|
||||
// Output:
|
||||
// email: must be a valid email address; zip: cannot be blank.
|
||||
```
|
||||
|
||||
In the above example, we build a `validation.Errors` by a list of names and the corresponding validation results.
|
||||
At the end we call `Errors.Filter()` to remove from `Errors` all nils which correspond to those successful validation
|
||||
results. The method will return nil if `Errors` is empty.
|
||||
|
||||
The above approach is very flexible as it allows you to freely build up your validation error structure. You can use
|
||||
it to validate both struct and non-struct values. Compared to using `ValidateStruct` to validate a struct,
|
||||
it has the drawback that you have to redundantly specify the error keys while `ValidateStruct` can automatically
|
||||
find them out.
|
||||
|
||||
|
||||
### Internal Errors
|
||||
|
||||
Internal errors are different from validation errors in that internal errors are caused by malfunctioning code (e.g.
|
||||
a validator making a remote call to validate some data when the remote service is down) rather
|
||||
than the data being validated. When an internal error happens during data validation, you may allow the user to resubmit
|
||||
the same data to perform validation again, hoping the program resumes functioning. On the other hand, if data validation
|
||||
fails due to data error, the user should generally not resubmit the same data again.
|
||||
|
||||
To differentiate internal errors from validation errors, when an internal error occurs in a validator, wrap it
|
||||
into `validation.InternalError` by calling `validation.NewInternalError()`. The user of the validator can then check
|
||||
if a returned error is an internal error or not. For example,
|
||||
|
||||
```go
|
||||
if err := a.Validate(); err != nil {
|
||||
if e, ok := err.(validation.InternalError); ok {
|
||||
// an internal error happened
|
||||
fmt.Println(e.InternalError())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Validatable Types
|
||||
|
||||
A type is validatable if it implements the `validation.Validatable` interface.
|
||||
|
||||
When `validation.Validate` is used to validate a validatable value, if it does not find any error with the
|
||||
given validation rules, it will further call the value's `Validate()` method.
|
||||
|
||||
Similarly, when `validation.ValidateStruct` is validating a struct field whose type is validatable, it will call
|
||||
the field's `Validate` method after it passes the listed rules.
|
||||
|
||||
In the following example, the `Address` field of `Customer` is validatable because `Address` implements
|
||||
`validation.Validatable`. Therefore, when validating a `Customer` struct with `validation.ValidateStruct`,
|
||||
validation will "dive" into the `Address` field.
|
||||
|
||||
```go
|
||||
type Customer struct {
|
||||
Name string
|
||||
Gender string
|
||||
Email string
|
||||
Address Address
|
||||
}
|
||||
|
||||
func (c Customer) Validate() error {
|
||||
return validation.ValidateStruct(&c,
|
||||
// Name cannot be empty, and the length must be between 5 and 20.
|
||||
validation.Field(&c.Name, validation.Required, validation.Length(5, 20)),
|
||||
// Gender is optional, and should be either "Female" or "Male".
|
||||
validation.Field(&c.Gender, validation.In("Female", "Male")),
|
||||
// Email cannot be empty and should be in a valid email format.
|
||||
validation.Field(&c.Email, validation.Required, is.Email),
|
||||
// Validate Address using its own validation rules
|
||||
validation.Field(&c.Address),
|
||||
)
|
||||
}
|
||||
|
||||
c := Customer{
|
||||
Name: "Qiang Xue",
|
||||
Email: "q",
|
||||
Address: Address{
|
||||
Street: "123 Main Street",
|
||||
City: "Unknown",
|
||||
State: "Virginia",
|
||||
Zip: "12345",
|
||||
},
|
||||
}
|
||||
|
||||
err := c.Validate()
|
||||
fmt.Println(err)
|
||||
// Output:
|
||||
// Address: (State: must be in a valid format.); Email: must be a valid email address.
|
||||
```
|
||||
|
||||
Sometimes, you may want to skip the invocation of a type's `Validate` method. To do so, simply associate
|
||||
a `validation.Skip` rule with the value being validated.
|
||||
|
||||
|
||||
### Maps/Slices/Arrays of Validatables
|
||||
|
||||
When validating a map, slice, or array, whose element type implements the `validation.Validatable` interface,
|
||||
the `validation.Validate` method will call the `Validate` method of every non-nil element.
|
||||
The validation errors of the elements will be returned as `validation.Errors` which maps the keys of the
|
||||
invalid elements to their corresponding validation errors. For example,
|
||||
|
||||
```go
|
||||
addresses := []Address{
|
||||
Address{State: "MD", Zip: "12345"},
|
||||
Address{Street: "123 Main St", City: "Vienna", State: "VA", Zip: "12345"},
|
||||
Address{City: "Unknown", State: "NC", Zip: "123"},
|
||||
}
|
||||
err := validation.Validate(addresses)
|
||||
fmt.Println(err)
|
||||
// Output:
|
||||
// 0: (City: cannot be blank; Street: cannot be blank.); 2: (Street: cannot be blank; Zip: must be in a valid format.).
|
||||
```
|
||||
|
||||
When using `validation.ValidateStruct` to validate a struct, the above validation procedure also applies to those struct
|
||||
fields which are map/slices/arrays of validatables.
|
||||
|
||||
|
||||
### Pointers
|
||||
|
||||
When a value being validated is a pointer, most validation rules will validate the actual value pointed to by the pointer.
|
||||
If the pointer is nil, these rules will skip the validation.
|
||||
|
||||
An exception is the `validation.Required` and `validation.NotNil` rules. When a pointer is nil, they
|
||||
will report a validation error.
|
||||
|
||||
|
||||
### Types Implementing `sql.Valuer`
|
||||
|
||||
If a data type implements the `sql.Valuer` interface (e.g. `sql.NullString`), the built-in validation rules will handle
|
||||
it properly. In particular, when a rule is validating such data, it will call the `Value()` method and validate
|
||||
the returned value instead.
|
||||
|
||||
|
||||
### Required vs. Not Nil
|
||||
|
||||
When validating input values, there are two different scenarios about checking if input values are provided or not.
|
||||
|
||||
In the first scenario, an input value is considered missing if it is not entered or it is entered as a zero value
|
||||
(e.g. an empty string, a zero integer). You can use the `validation.Required` rule in this case.
|
||||
|
||||
In the second scenario, an input value is considered missing only if it is not entered. A pointer field is usually
|
||||
used in this case so that you can detect if a value is entered or not by checking if the pointer is nil or not.
|
||||
You can use the `validation.NotNil` rule to ensure a value is entered (even if it is a zero value).
|
||||
|
||||
|
||||
### Embedded Structs
|
||||
|
||||
The `validation.ValidateStruct` method will properly validate a struct that contains embedded structs. In particular,
|
||||
the fields of an embedded struct are treated as if they belong directly to the containing struct. For example,
|
||||
|
||||
```go
|
||||
type Employee struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func ()
|
||||
|
||||
type Manager struct {
|
||||
Employee
|
||||
Level int
|
||||
}
|
||||
|
||||
m := Manager{}
|
||||
err := validation.ValidateStruct(&m,
|
||||
validation.Field(&m.Name, validation.Required),
|
||||
validation.Field(&m.Level, validation.Required),
|
||||
)
|
||||
fmt.Println(err)
|
||||
// Output:
|
||||
// Level: cannot be blank; Name: cannot be blank.
|
||||
```
|
||||
|
||||
In the above code, we use `&m.Name` to specify the validation of the `Name` field of the embedded struct `Employee`.
|
||||
And the validation error uses `Name` as the key for the error associated with the `Name` field as if `Name` a field
|
||||
directly belonging to `Manager`.
|
||||
|
||||
If `Employee` implements the `validation.Validatable` interface, we can also use the following code to validate
|
||||
`Manager`, which generates the same validation result:
|
||||
|
||||
```go
|
||||
func (e Employee) Validate() error {
|
||||
return validation.ValidateStruct(&e,
|
||||
validation.Field(&e.Name, validation.Required),
|
||||
)
|
||||
}
|
||||
|
||||
err := validation.ValidateStruct(&m,
|
||||
validation.Field(&m.Employee),
|
||||
validation.Field(&m.Level, validation.Required),
|
||||
)
|
||||
fmt.Println(err)
|
||||
// Output:
|
||||
// Level: cannot be blank; Name: cannot be blank.
|
||||
```
|
||||
|
||||
|
||||
## Built-in Validation Rules
|
||||
|
||||
The following rules are provided in the `validation` package:
|
||||
|
||||
* `In(...interface{})`: checks if a value can be found in the given list of values.
|
||||
* `Length(min, max int)`: checks if the length of a value is within the specified range.
|
||||
This rule should only be used for validating strings, slices, maps, and arrays.
|
||||
* `RuneLength(min, max int)`: checks if the length of a string is within the specified range.
|
||||
This rule is similar as `Length` except that when the value being validated is a string, it checks
|
||||
its rune length instead of byte length.
|
||||
* `Min(min interface{})` and `Max(max interface{})`: checks if a value is within the specified range.
|
||||
These two rules should only be used for validating int, uint, float and time.Time types.
|
||||
* `Match(*regexp.Regexp)`: checks if a value matches the specified regular expression.
|
||||
This rule should only be used for strings and byte slices.
|
||||
* `Date(layout string)`: checks if a string value is a date whose format is specified by the layout.
|
||||
By calling `Min()` and/or `Max()`, you can check additionally if the date is within the specified range.
|
||||
* `Required`: checks if a value is not empty (neither nil nor zero).
|
||||
* `NotNil`: checks if a pointer value is not nil. Non-pointer values are considered valid.
|
||||
* `NilOrNotEmpty`: checks if a value is a nil pointer or a non-empty value. This differs from `Required` in that it treats a nil pointer as valid.
|
||||
* `Skip`: this is a special rule used to indicate that all rules following it should be skipped (including the nested ones).
|
||||
* `MultipleOf`: checks if the value is a multiple of the specified range.
|
||||
|
||||
The `is` sub-package provides a list of commonly used string validation rules that can be used to check if the format
|
||||
of a value satisfies certain requirements. Note that these rules only handle strings and byte slices and if a string
|
||||
or byte slice is empty, it is considered valid. You may use a `Required` rule to ensure a value is not empty.
|
||||
Below is the whole list of the rules provided by the `is` package:
|
||||
|
||||
* `Email`: validates if a string is an email or not
|
||||
* `URL`: validates if a string is a valid URL
|
||||
* `RequestURL`: validates if a string is a valid request URL
|
||||
* `RequestURI`: validates if a string is a valid request URI
|
||||
* `Alpha`: validates if a string contains English letters only (a-zA-Z)
|
||||
* `Digit`: validates if a string contains digits only (0-9)
|
||||
* `Alphanumeric`: validates if a string contains English letters and digits only (a-zA-Z0-9)
|
||||
* `UTFLetter`: validates if a string contains unicode letters only
|
||||
* `UTFDigit`: validates if a string contains unicode decimal digits only
|
||||
* `UTFLetterNumeric`: validates if a string contains unicode letters and numbers only
|
||||
* `UTFNumeric`: validates if a string contains unicode number characters (category N) only
|
||||
* `LowerCase`: validates if a string contains lower case unicode letters only
|
||||
* `UpperCase`: validates if a string contains upper case unicode letters only
|
||||
* `Hexadecimal`: validates if a string is a valid hexadecimal number
|
||||
* `HexColor`: validates if a string is a valid hexadecimal color code
|
||||
* `RGBColor`: validates if a string is a valid RGB color in the form of rgb(R, G, B)
|
||||
* `Int`: validates if a string is a valid integer number
|
||||
* `Float`: validates if a string is a floating point number
|
||||
* `UUIDv3`: validates if a string is a valid version 3 UUID
|
||||
* `UUIDv4`: validates if a string is a valid version 4 UUID
|
||||
* `UUIDv5`: validates if a string is a valid version 5 UUID
|
||||
* `UUID`: validates if a string is a valid UUID
|
||||
* `CreditCard`: validates if a string is a valid credit card number
|
||||
* `ISBN10`: validates if a string is an ISBN version 10
|
||||
* `ISBN13`: validates if a string is an ISBN version 13
|
||||
* `ISBN`: validates if a string is an ISBN (either version 10 or 13)
|
||||
* `JSON`: validates if a string is in valid JSON format
|
||||
* `ASCII`: validates if a string contains ASCII characters only
|
||||
* `PrintableASCII`: validates if a string contains printable ASCII characters only
|
||||
* `Multibyte`: validates if a string contains multibyte characters
|
||||
* `FullWidth`: validates if a string contains full-width characters
|
||||
* `HalfWidth`: validates if a string contains half-width characters
|
||||
* `VariableWidth`: validates if a string contains both full-width and half-width characters
|
||||
* `Base64`: validates if a string is encoded in Base64
|
||||
* `DataURI`: validates if a string is a valid base64-encoded data URI
|
||||
* `E164`: validates if a string is a valid E164 phone number (+19251232233)
|
||||
* `CountryCode2`: validates if a string is a valid ISO3166 Alpha 2 country code
|
||||
* `CountryCode3`: validates if a string is a valid ISO3166 Alpha 3 country code
|
||||
* `DialString`: validates if a string is a valid dial string that can be passed to Dial()
|
||||
* `MAC`: validates if a string is a MAC address
|
||||
* `IP`: validates if a string is a valid IP address (either version 4 or 6)
|
||||
* `IPv4`: validates if a string is a valid version 4 IP address
|
||||
* `IPv6`: validates if a string is a valid version 6 IP address
|
||||
* `Subdomain`: validates if a string is valid subdomain
|
||||
* `Domain`: validates if a string is valid domain
|
||||
* `DNSName`: validates if a string is valid DNS name
|
||||
* `Host`: validates if a string is a valid IP (both v4 and v6) or a valid DNS name
|
||||
* `Port`: validates if a string is a valid port number
|
||||
* `MongoID`: validates if a string is a valid Mongo ID
|
||||
* `Latitude`: validates if a string is a valid latitude
|
||||
* `Longitude`: validates if a string is a valid longitude
|
||||
* `SSN`: validates if a string is a social security number (SSN)
|
||||
* `Semver`: validates if a string is a valid semantic version
|
||||
|
||||
### Customizing Error Messages
|
||||
|
||||
All built-in validation rules allow you to customize error messages. To do so, simply call the `Error()` method
|
||||
of the rules. For example,
|
||||
|
||||
```go
|
||||
data := "2123"
|
||||
err := validation.Validate(data,
|
||||
validation.Required.Error("is required"),
|
||||
validation.Match(regexp.MustCompile("^[0-9]{5}$")).Error("must be a string with five digits"),
|
||||
)
|
||||
fmt.Println(err)
|
||||
// Output:
|
||||
// must be a string with five digits
|
||||
```
|
||||
|
||||
|
||||
## Creating Custom Rules
|
||||
|
||||
Creating a custom rule is as simple as implementing the `validation.Rule` interface. The interface contains a single
|
||||
method as shown below, which should validate the value and return the validation error, if any:
|
||||
|
||||
```go
|
||||
// Validate validates a value and returns an error if validation fails.
|
||||
Validate(value interface{}) error
|
||||
```
|
||||
|
||||
If you already have a function with the same signature as shown above, you can call `validation.By()` to turn
|
||||
it into a validation rule. For example,
|
||||
|
||||
```go
|
||||
func checkAbc(value interface{}) error {
|
||||
s, _ := value.(string)
|
||||
if s != "abc" {
|
||||
return errors.New("must be abc")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
err := validation.Validate("xyz", validation.By(checkAbc))
|
||||
fmt.Println(err)
|
||||
// Output: must be abc
|
||||
```
|
||||
|
||||
|
||||
### Rule Groups
|
||||
|
||||
When a combination of several rules are used in multiple places, you may use the following trick to create a
|
||||
rule group so that your code is more maintainable.
|
||||
|
||||
```go
|
||||
var NameRule = []validation.Rule{
|
||||
validation.Required,
|
||||
validation.Length(5, 20),
|
||||
}
|
||||
|
||||
type User struct {
|
||||
FirstName string
|
||||
LastName string
|
||||
}
|
||||
|
||||
func (u User) Validate() error {
|
||||
return validation.ValidateStruct(&u,
|
||||
validation.Field(&u.FirstName, NameRule...),
|
||||
validation.Field(&u.LastName, NameRule...),
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
In the above example, we create a rule group `NameRule` which consists of two validation rules. We then use this rule
|
||||
group to validate both `FirstName` and `LastName`.
|
||||
|
||||
|
||||
## Credits
|
||||
|
||||
The `is` sub-package wraps the excellent validators provided by the [govalidator](https://github.com/asaskevich/govalidator) package.
|
46
vendor/github.com/go-ozzo/ozzo-validation/UPGRADE.md
generated
vendored
Normal file
46
vendor/github.com/go-ozzo/ozzo-validation/UPGRADE.md
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
# Upgrade Instructions
|
||||
|
||||
## Upgrade from 2.x to 3.x
|
||||
|
||||
* Instead of using `StructRules` to define struct validation rules, use `ValidateStruct()` to declare and perform
|
||||
struct validation. The following code snippet shows how to modify your code:
|
||||
```go
|
||||
// 2.x usage
|
||||
err := validation.StructRules{}.
|
||||
Add("Street", validation.Required, validation.Length(5, 50)).
|
||||
Add("City", validation.Required, validation.Length(5, 50)).
|
||||
Add("State", validation.Required, validation.Match(regexp.MustCompile("^[A-Z]{2}$"))).
|
||||
Add("Zip", validation.Required, validation.Match(regexp.MustCompile("^[0-9]{5}$"))).
|
||||
Validate(a)
|
||||
|
||||
// 3.x usage
|
||||
err := validation.ValidateStruct(&a,
|
||||
validation.Field(&a.Street, validation.Required, validation.Length(5, 50)),
|
||||
validation.Field(&a.City, validation.Required, validation.Length(5, 50)),
|
||||
validation.Field(&a.State, validation.Required, validation.Match(regexp.MustCompile("^[A-Z]{2}$"))),
|
||||
validation.Field(&a.Zip, validation.Required, validation.Match(regexp.MustCompile("^[0-9]{5}$"))),
|
||||
)
|
||||
```
|
||||
|
||||
* Instead of using `Rules` to declare a rule list and use it to validate a value, call `Validate()` with the rules directly.
|
||||
```go
|
||||
data := "example"
|
||||
|
||||
// 2.x usage
|
||||
rules := validation.Rules{
|
||||
validation.Required,
|
||||
validation.Length(5, 100),
|
||||
is.URL,
|
||||
}
|
||||
err := rules.Validate(data)
|
||||
|
||||
// 3.x usage
|
||||
err := validation.Validate(data,
|
||||
validation.Required,
|
||||
validation.Length(5, 100),
|
||||
is.URL,
|
||||
)
|
||||
```
|
||||
|
||||
* The default struct tags used for determining error keys is changed from `validation` to `json`. You may modify
|
||||
`validation.ErrorTag` to change it back.
|
84
vendor/github.com/go-ozzo/ozzo-validation/date.go
generated
vendored
Normal file
84
vendor/github.com/go-ozzo/ozzo-validation/date.go
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright 2016 Qiang Xue. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
type DateRule struct {
|
||||
layout string
|
||||
min, max time.Time
|
||||
message string
|
||||
rangeMessage string
|
||||
}
|
||||
|
||||
// Date returns a validation rule that checks if a string value is in a format that can be parsed into a date.
|
||||
// The format of the date should be specified as the layout parameter which accepts the same value as that for time.Parse.
|
||||
// For example,
|
||||
// validation.Date(time.ANSIC)
|
||||
// validation.Date("02 Jan 06 15:04 MST")
|
||||
// validation.Date("2006-01-02")
|
||||
//
|
||||
// By calling Min() and/or Max(), you can let the Date rule to check if a parsed date value is within
|
||||
// the specified date range.
|
||||
//
|
||||
// An empty value is considered valid. Use the Required rule to make sure a value is not empty.
|
||||
func Date(layout string) *DateRule {
|
||||
return &DateRule{
|
||||
layout: layout,
|
||||
message: "must be a valid date",
|
||||
rangeMessage: "the data is out of range",
|
||||
}
|
||||
}
|
||||
|
||||
// Error sets the error message that is used when the value being validated is not a valid date.
|
||||
func (r *DateRule) Error(message string) *DateRule {
|
||||
r.message = message
|
||||
return r
|
||||
}
|
||||
|
||||
// RangeError sets the error message that is used when the value being validated is out of the specified Min/Max date range.
|
||||
func (r *DateRule) RangeError(message string) *DateRule {
|
||||
r.rangeMessage = message
|
||||
return r
|
||||
}
|
||||
|
||||
// Min sets the minimum date range. A zero value means skipping the minimum range validation.
|
||||
func (r *DateRule) Min(min time.Time) *DateRule {
|
||||
r.min = min
|
||||
return r
|
||||
}
|
||||
|
||||
// Max sets the maximum date range. A zero value means skipping the maximum range validation.
|
||||
func (r *DateRule) Max(max time.Time) *DateRule {
|
||||
r.max = max
|
||||
return r
|
||||
}
|
||||
|
||||
// Validate checks if the given value is a valid date.
|
||||
func (r *DateRule) Validate(value interface{}) error {
|
||||
value, isNil := Indirect(value)
|
||||
if isNil || IsEmpty(value) {
|
||||
return nil
|
||||
}
|
||||
|
||||
str, err := EnsureString(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
date, err := time.Parse(r.layout, str)
|
||||
if err != nil {
|
||||
return errors.New(r.message)
|
||||
}
|
||||
|
||||
if !r.min.IsZero() && r.min.After(date) || !r.max.IsZero() && date.After(r.max) {
|
||||
return errors.New(r.rangeMessage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
89
vendor/github.com/go-ozzo/ozzo-validation/error.go
generated
vendored
Normal file
89
vendor/github.com/go-ozzo/ozzo-validation/error.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
// Copyright 2016 Qiang Xue. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type (
|
||||
// Errors represents the validation errors that are indexed by struct field names, map or slice keys.
|
||||
Errors map[string]error
|
||||
|
||||
// InternalError represents an error that should NOT be treated as a validation error.
|
||||
InternalError interface {
|
||||
error
|
||||
InternalError() error
|
||||
}
|
||||
|
||||
internalError struct {
|
||||
error
|
||||
}
|
||||
)
|
||||
|
||||
// NewInternalError wraps a given error into an InternalError.
|
||||
func NewInternalError(err error) InternalError {
|
||||
return &internalError{error: err}
|
||||
}
|
||||
|
||||
// InternalError returns the actual error that it wraps around.
|
||||
func (e *internalError) InternalError() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
// Error returns the error string of Errors.
|
||||
func (es Errors) Error() string {
|
||||
if len(es) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
keys := []string{}
|
||||
for key := range es {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
s := ""
|
||||
for i, key := range keys {
|
||||
if i > 0 {
|
||||
s += "; "
|
||||
}
|
||||
if errs, ok := es[key].(Errors); ok {
|
||||
s += fmt.Sprintf("%v: (%v)", key, errs)
|
||||
} else {
|
||||
s += fmt.Sprintf("%v: %v", key, es[key].Error())
|
||||
}
|
||||
}
|
||||
return s + "."
|
||||
}
|
||||
|
||||
// MarshalJSON converts the Errors into a valid JSON.
|
||||
func (es Errors) MarshalJSON() ([]byte, error) {
|
||||
errs := map[string]interface{}{}
|
||||
for key, err := range es {
|
||||
if ms, ok := err.(json.Marshaler); ok {
|
||||
errs[key] = ms
|
||||
} else {
|
||||
errs[key] = err.Error()
|
||||
}
|
||||
}
|
||||
return json.Marshal(errs)
|
||||
}
|
||||
|
||||
// Filter removes all nils from Errors and returns back the updated Errors as an error.
|
||||
// If the length of Errors becomes 0, it will return nil.
|
||||
func (es Errors) Filter() error {
|
||||
for key, value := range es {
|
||||
if value == nil {
|
||||
delete(es, key)
|
||||
}
|
||||
}
|
||||
if len(es) == 0 {
|
||||
return nil
|
||||
}
|
||||
return es
|
||||
}
|
43
vendor/github.com/go-ozzo/ozzo-validation/in.go
generated
vendored
Normal file
43
vendor/github.com/go-ozzo/ozzo-validation/in.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright 2016 Qiang Xue. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package validation
|
||||
|
||||
import "errors"
|
||||
|
||||
// In returns a validation rule that checks if a value can be found in the given list of values.
|
||||
// Note that the value being checked and the possible range of values must be of the same type.
|
||||
// An empty value is considered valid. Use the Required rule to make sure a value is not empty.
|
||||
func In(values ...interface{}) *InRule {
|
||||
return &InRule{
|
||||
elements: values,
|
||||
message: "must be a valid value",
|
||||
}
|
||||
}
|
||||
|
||||
type InRule struct {
|
||||
elements []interface{}
|
||||
message string
|
||||
}
|
||||
|
||||
// Validate checks if the given value is valid or not.
|
||||
func (r *InRule) Validate(value interface{}) error {
|
||||
value, isNil := Indirect(value)
|
||||
if isNil || IsEmpty(value) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, e := range r.elements {
|
||||
if e == value {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return errors.New(r.message)
|
||||
}
|
||||
|
||||
// Error sets the error message for the rule.
|
||||
func (r *InRule) Error(message string) *InRule {
|
||||
r.message = message
|
||||
return r
|
||||
}
|
27
vendor/github.com/go-ozzo/ozzo-validation/is/BUILD
generated
vendored
Normal file
27
vendor/github.com/go-ozzo/ozzo-validation/is/BUILD
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["rules.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/github.com/go-ozzo/ozzo-validation/is",
|
||||
importpath = "github.com/go-ozzo/ozzo-validation/is",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/asaskevich/govalidator:go_default_library",
|
||||
"//vendor/github.com/go-ozzo/ozzo-validation:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
171
vendor/github.com/go-ozzo/ozzo-validation/is/rules.go
generated
vendored
Normal file
171
vendor/github.com/go-ozzo/ozzo-validation/is/rules.go
generated
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
// Copyright 2016 Qiang Xue. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package is provides a list of commonly used string validation rules.
|
||||
package is
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"unicode"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/go-ozzo/ozzo-validation"
|
||||
)
|
||||
|
||||
var (
|
||||
// Email validates if a string is an email or not.
|
||||
Email = validation.NewStringRule(govalidator.IsEmail, "must be a valid email address")
|
||||
// URL validates if a string is a valid URL
|
||||
URL = validation.NewStringRule(govalidator.IsURL, "must be a valid URL")
|
||||
// RequestURL validates if a string is a valid request URL
|
||||
RequestURL = validation.NewStringRule(govalidator.IsRequestURL, "must be a valid request URL")
|
||||
// RequestURI validates if a string is a valid request URI
|
||||
RequestURI = validation.NewStringRule(govalidator.IsRequestURI, "must be a valid request URI")
|
||||
// Alpha validates if a string contains English letters only (a-zA-Z)
|
||||
Alpha = validation.NewStringRule(govalidator.IsAlpha, "must contain English letters only")
|
||||
// Digit validates if a string contains digits only (0-9)
|
||||
Digit = validation.NewStringRule(isDigit, "must contain digits only")
|
||||
// Alphanumeric validates if a string contains English letters and digits only (a-zA-Z0-9)
|
||||
Alphanumeric = validation.NewStringRule(govalidator.IsAlphanumeric, "must contain English letters and digits only")
|
||||
// UTFLetter validates if a string contains unicode letters only
|
||||
UTFLetter = validation.NewStringRule(govalidator.IsUTFLetter, "must contain unicode letter characters only")
|
||||
// UTFDigit validates if a string contains unicode decimal digits only
|
||||
UTFDigit = validation.NewStringRule(govalidator.IsUTFDigit, "must contain unicode decimal digits only")
|
||||
// UTFLetterNumeric validates if a string contains unicode letters and numbers only
|
||||
UTFLetterNumeric = validation.NewStringRule(govalidator.IsUTFLetterNumeric, "must contain unicode letters and numbers only")
|
||||
// UTFNumeric validates if a string contains unicode number characters (category N) only
|
||||
UTFNumeric = validation.NewStringRule(isUTFNumeric, "must contain unicode number characters only")
|
||||
// LowerCase validates if a string contains lower case unicode letters only
|
||||
LowerCase = validation.NewStringRule(govalidator.IsLowerCase, "must be in lower case")
|
||||
// UpperCase validates if a string contains upper case unicode letters only
|
||||
UpperCase = validation.NewStringRule(govalidator.IsUpperCase, "must be in upper case")
|
||||
// Hexadecimal validates if a string is a valid hexadecimal number
|
||||
Hexadecimal = validation.NewStringRule(govalidator.IsHexadecimal, "must be a valid hexadecimal number")
|
||||
// HexColor validates if a string is a valid hexadecimal color code
|
||||
HexColor = validation.NewStringRule(govalidator.IsHexcolor, "must be a valid hexadecimal color code")
|
||||
// RGBColor validates if a string is a valid RGB color in the form of rgb(R, G, B)
|
||||
RGBColor = validation.NewStringRule(govalidator.IsRGBcolor, "must be a valid RGB color code")
|
||||
// Int validates if a string is a valid integer number
|
||||
Int = validation.NewStringRule(govalidator.IsInt, "must be an integer number")
|
||||
// Float validates if a string is a floating point number
|
||||
Float = validation.NewStringRule(govalidator.IsFloat, "must be a floating point number")
|
||||
// UUIDv3 validates if a string is a valid version 3 UUID
|
||||
UUIDv3 = validation.NewStringRule(govalidator.IsUUIDv3, "must be a valid UUID v3")
|
||||
// UUIDv4 validates if a string is a valid version 4 UUID
|
||||
UUIDv4 = validation.NewStringRule(govalidator.IsUUIDv4, "must be a valid UUID v4")
|
||||
// UUIDv5 validates if a string is a valid version 5 UUID
|
||||
UUIDv5 = validation.NewStringRule(govalidator.IsUUIDv5, "must be a valid UUID v5")
|
||||
// UUID validates if a string is a valid UUID
|
||||
UUID = validation.NewStringRule(govalidator.IsUUID, "must be a valid UUID")
|
||||
// CreditCard validates if a string is a valid credit card number
|
||||
CreditCard = validation.NewStringRule(govalidator.IsCreditCard, "must be a valid credit card number")
|
||||
// ISBN10 validates if a string is an ISBN version 10
|
||||
ISBN10 = validation.NewStringRule(govalidator.IsISBN10, "must be a valid ISBN-10")
|
||||
// ISBN13 validates if a string is an ISBN version 13
|
||||
ISBN13 = validation.NewStringRule(govalidator.IsISBN13, "must be a valid ISBN-13")
|
||||
// ISBN validates if a string is an ISBN (either version 10 or 13)
|
||||
ISBN = validation.NewStringRule(isISBN, "must be a valid ISBN")
|
||||
// JSON validates if a string is in valid JSON format
|
||||
JSON = validation.NewStringRule(govalidator.IsJSON, "must be in valid JSON format")
|
||||
// ASCII validates if a string contains ASCII characters only
|
||||
ASCII = validation.NewStringRule(govalidator.IsASCII, "must contain ASCII characters only")
|
||||
// PrintableASCII validates if a string contains printable ASCII characters only
|
||||
PrintableASCII = validation.NewStringRule(govalidator.IsPrintableASCII, "must contain printable ASCII characters only")
|
||||
// Multibyte validates if a string contains multibyte characters
|
||||
Multibyte = validation.NewStringRule(govalidator.IsMultibyte, "must contain multibyte characters")
|
||||
// FullWidth validates if a string contains full-width characters
|
||||
FullWidth = validation.NewStringRule(govalidator.IsFullWidth, "must contain full-width characters")
|
||||
// HalfWidth validates if a string contains half-width characters
|
||||
HalfWidth = validation.NewStringRule(govalidator.IsHalfWidth, "must contain half-width characters")
|
||||
// VariableWidth validates if a string contains both full-width and half-width characters
|
||||
VariableWidth = validation.NewStringRule(govalidator.IsVariableWidth, "must contain both full-width and half-width characters")
|
||||
// Base64 validates if a string is encoded in Base64
|
||||
Base64 = validation.NewStringRule(govalidator.IsBase64, "must be encoded in Base64")
|
||||
// DataURI validates if a string is a valid base64-encoded data URI
|
||||
DataURI = validation.NewStringRule(govalidator.IsDataURI, "must be a Base64-encoded data URI")
|
||||
// E164 validates if a string is a valid ISO3166 Alpha 2 country code
|
||||
E164 = validation.NewStringRule(isE164Number, "must be a valid E164 number")
|
||||
// CountryCode2 validates if a string is a valid ISO3166 Alpha 2 country code
|
||||
CountryCode2 = validation.NewStringRule(govalidator.IsISO3166Alpha2, "must be a valid two-letter country code")
|
||||
// CountryCode3 validates if a string is a valid ISO3166 Alpha 3 country code
|
||||
CountryCode3 = validation.NewStringRule(govalidator.IsISO3166Alpha3, "must be a valid three-letter country code")
|
||||
// DialString validates if a string is a valid dial string that can be passed to Dial()
|
||||
DialString = validation.NewStringRule(govalidator.IsDialString, "must be a valid dial string")
|
||||
// MAC validates if a string is a MAC address
|
||||
MAC = validation.NewStringRule(govalidator.IsMAC, "must be a valid MAC address")
|
||||
// IP validates if a string is a valid IP address (either version 4 or 6)
|
||||
IP = validation.NewStringRule(govalidator.IsIP, "must be a valid IP address")
|
||||
// IPv4 validates if a string is a valid version 4 IP address
|
||||
IPv4 = validation.NewStringRule(govalidator.IsIPv4, "must be a valid IPv4 address")
|
||||
// IPv6 validates if a string is a valid version 6 IP address
|
||||
IPv6 = validation.NewStringRule(govalidator.IsIPv6, "must be a valid IPv6 address")
|
||||
// Subdomain validates if a string is valid subdomain
|
||||
Subdomain = validation.NewStringRule(isSubdomain, "must be a valid subdomain")
|
||||
// Domain validates if a string is valid domain
|
||||
Domain = validation.NewStringRule(isDomain, "must be a valid domain")
|
||||
// DNSName validates if a string is valid DNS name
|
||||
DNSName = validation.NewStringRule(govalidator.IsDNSName, "must be a valid DNS name")
|
||||
// Host validates if a string is a valid IP (both v4 and v6) or a valid DNS name
|
||||
Host = validation.NewStringRule(govalidator.IsHost, "must be a valid IP address or DNS name")
|
||||
// Port validates if a string is a valid port number
|
||||
Port = validation.NewStringRule(govalidator.IsPort, "must be a valid port number")
|
||||
// MongoID validates if a string is a valid Mongo ID
|
||||
MongoID = validation.NewStringRule(govalidator.IsMongoID, "must be a valid hex-encoded MongoDB ObjectId")
|
||||
// Latitude validates if a string is a valid latitude
|
||||
Latitude = validation.NewStringRule(govalidator.IsLatitude, "must be a valid latitude")
|
||||
// Longitude validates if a string is a valid longitude
|
||||
Longitude = validation.NewStringRule(govalidator.IsLongitude, "must be a valid longitude")
|
||||
// SSN validates if a string is a social security number (SSN)
|
||||
SSN = validation.NewStringRule(govalidator.IsSSN, "must be a valid social security number")
|
||||
// Semver validates if a string is a valid semantic version
|
||||
Semver = validation.NewStringRule(govalidator.IsSemver, "must be a valid semantic version")
|
||||
)
|
||||
|
||||
var (
|
||||
reDigit = regexp.MustCompile("^[0-9]+$")
|
||||
// Subdomain regex source: https://stackoverflow.com/a/7933253
|
||||
reSubdomain = regexp.MustCompile(`^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$`)
|
||||
)
|
||||
|
||||
func isISBN(value string) bool {
|
||||
return govalidator.IsISBN(value, 10) || govalidator.IsISBN(value, 13)
|
||||
}
|
||||
|
||||
func isDigit(value string) bool {
|
||||
return reDigit.MatchString(value)
|
||||
}
|
||||
|
||||
func isE164Number(value string) bool {
|
||||
// E164 regex source: https://stackoverflow.com/a/23299989
|
||||
reE164 := regexp.MustCompile(`^\+?[1-9]\d{1,14}$`)
|
||||
return reE164.MatchString(value)
|
||||
}
|
||||
|
||||
func isSubdomain(value string) bool {
|
||||
// Subdomain regex source: https://stackoverflow.com/a/7933253
|
||||
reSubdomain := regexp.MustCompile(`^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$`)
|
||||
return reSubdomain.MatchString(value)
|
||||
}
|
||||
|
||||
func isDomain(value string) bool {
|
||||
if len(value) > 255 {
|
||||
return false
|
||||
}
|
||||
|
||||
// Domain regex source: https://stackoverflow.com/a/7933253
|
||||
// Slightly modified: Removed 255 max length validation since Go regex does not
|
||||
// support lookarounds. More info: https://stackoverflow.com/a/38935027
|
||||
reDomain := regexp.MustCompile(`^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+(?:[a-z]{1,63}| xn--[a-z0-9]{1,59})$`)
|
||||
|
||||
return reDomain.MatchString(value)
|
||||
}
|
||||
|
||||
func isUTFNumeric(value string) bool {
|
||||
for _, c := range value {
|
||||
if unicode.IsNumber(c) == false {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
81
vendor/github.com/go-ozzo/ozzo-validation/length.go
generated
vendored
Normal file
81
vendor/github.com/go-ozzo/ozzo-validation/length.go
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
// Copyright 2016 Qiang Xue. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// Length returns a validation rule that checks if a value's length is within the specified range.
|
||||
// If max is 0, it means there is no upper bound for the length.
|
||||
// This rule should only be used for validating strings, slices, maps, and arrays.
|
||||
// An empty value is considered valid. Use the Required rule to make sure a value is not empty.
|
||||
func Length(min, max int) *LengthRule {
|
||||
message := "the value must be empty"
|
||||
if min == 0 && max > 0 {
|
||||
message = fmt.Sprintf("the length must be no more than %v", max)
|
||||
} else if min > 0 && max == 0 {
|
||||
message = fmt.Sprintf("the length must be no less than %v", min)
|
||||
} else if min > 0 && max > 0 {
|
||||
if min == max {
|
||||
message = fmt.Sprintf("the length must be exactly %v", min)
|
||||
} else {
|
||||
message = fmt.Sprintf("the length must be between %v and %v", min, max)
|
||||
}
|
||||
}
|
||||
return &LengthRule{
|
||||
min: min,
|
||||
max: max,
|
||||
message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// RuneLength returns a validation rule that checks if a string's rune length is within the specified range.
|
||||
// If max is 0, it means there is no upper bound for the length.
|
||||
// This rule should only be used for validating strings, slices, maps, and arrays.
|
||||
// An empty value is considered valid. Use the Required rule to make sure a value is not empty.
|
||||
// If the value being validated is not a string, the rule works the same as Length.
|
||||
func RuneLength(min, max int) *LengthRule {
|
||||
r := Length(min, max)
|
||||
r.rune = true
|
||||
return r
|
||||
}
|
||||
|
||||
type LengthRule struct {
|
||||
min, max int
|
||||
message string
|
||||
rune bool
|
||||
}
|
||||
|
||||
// Validate checks if the given value is valid or not.
|
||||
func (v *LengthRule) Validate(value interface{}) error {
|
||||
value, isNil := Indirect(value)
|
||||
if isNil || IsEmpty(value) {
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
l int
|
||||
err error
|
||||
)
|
||||
if s, ok := value.(string); ok && v.rune {
|
||||
l = utf8.RuneCountInString(s)
|
||||
} else if l, err = LengthOfValue(value); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if v.min > 0 && l < v.min || v.max > 0 && l > v.max {
|
||||
return errors.New(v.message)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Error sets the error message for the rule.
|
||||
func (v *LengthRule) Error(message string) *LengthRule {
|
||||
v.message = message
|
||||
return v
|
||||
}
|
47
vendor/github.com/go-ozzo/ozzo-validation/match.go
generated
vendored
Normal file
47
vendor/github.com/go-ozzo/ozzo-validation/match.go
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright 2016 Qiang Xue. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// Match returns a validation rule that checks if a value matches the specified regular expression.
|
||||
// This rule should only be used for validating strings and byte slices, or a validation error will be reported.
|
||||
// An empty value is considered valid. Use the Required rule to make sure a value is not empty.
|
||||
func Match(re *regexp.Regexp) *MatchRule {
|
||||
return &MatchRule{
|
||||
re: re,
|
||||
message: "must be in a valid format",
|
||||
}
|
||||
}
|
||||
|
||||
type MatchRule struct {
|
||||
re *regexp.Regexp
|
||||
message string
|
||||
}
|
||||
|
||||
// Validate checks if the given value is valid or not.
|
||||
func (v *MatchRule) Validate(value interface{}) error {
|
||||
value, isNil := Indirect(value)
|
||||
if isNil {
|
||||
return nil
|
||||
}
|
||||
|
||||
isString, str, isBytes, bs := StringOrBytes(value)
|
||||
if isString && (str == "" || v.re.MatchString(str)) {
|
||||
return nil
|
||||
} else if isBytes && (len(bs) == 0 || v.re.Match(bs)) {
|
||||
return nil
|
||||
}
|
||||
return errors.New(v.message)
|
||||
}
|
||||
|
||||
// Error sets the error message for the rule.
|
||||
func (v *MatchRule) Error(message string) *MatchRule {
|
||||
v.message = message
|
||||
return v
|
||||
}
|
177
vendor/github.com/go-ozzo/ozzo-validation/minmax.go
generated
vendored
Normal file
177
vendor/github.com/go-ozzo/ozzo-validation/minmax.go
generated
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
// Copyright 2016 Qiang Xue. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ThresholdRule struct {
|
||||
threshold interface{}
|
||||
operator int
|
||||
message string
|
||||
}
|
||||
|
||||
const (
|
||||
greaterThan = iota
|
||||
greaterEqualThan
|
||||
lessThan
|
||||
lessEqualThan
|
||||
)
|
||||
|
||||
// Min is a validation rule that checks if a value is greater or equal than the specified value.
|
||||
// By calling Exclusive, the rule will check if the value is strictly greater than the specified value.
|
||||
// Note that the value being checked and the threshold value must be of the same type.
|
||||
// Only int, uint, float and time.Time types are supported.
|
||||
// An empty value is considered valid. Please use the Required rule to make sure a value is not empty.
|
||||
func Min(min interface{}) *ThresholdRule {
|
||||
return &ThresholdRule{
|
||||
threshold: min,
|
||||
operator: greaterEqualThan,
|
||||
message: fmt.Sprintf("must be no less than %v", min),
|
||||
}
|
||||
}
|
||||
|
||||
// Max is a validation rule that checks if a value is less or equal than the specified value.
|
||||
// By calling Exclusive, the rule will check if the value is strictly less than the specified value.
|
||||
// Note that the value being checked and the threshold value must be of the same type.
|
||||
// Only int, uint, float and time.Time types are supported.
|
||||
// An empty value is considered valid. Please use the Required rule to make sure a value is not empty.
|
||||
func Max(max interface{}) *ThresholdRule {
|
||||
return &ThresholdRule{
|
||||
threshold: max,
|
||||
operator: lessEqualThan,
|
||||
message: fmt.Sprintf("must be no greater than %v", max),
|
||||
}
|
||||
}
|
||||
|
||||
// Exclusive sets the comparison to exclude the boundary value.
|
||||
func (r *ThresholdRule) Exclusive() *ThresholdRule {
|
||||
if r.operator == greaterEqualThan {
|
||||
r.operator = greaterThan
|
||||
r.message = fmt.Sprintf("must be greater than %v", r.threshold)
|
||||
} else if r.operator == lessEqualThan {
|
||||
r.operator = lessThan
|
||||
r.message = fmt.Sprintf("must be less than %v", r.threshold)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// Validate checks if the given value is valid or not.
|
||||
func (r *ThresholdRule) Validate(value interface{}) error {
|
||||
value, isNil := Indirect(value)
|
||||
if isNil || IsEmpty(value) {
|
||||
return nil
|
||||
}
|
||||
|
||||
rv := reflect.ValueOf(r.threshold)
|
||||
switch rv.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
v, err := ToInt(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if r.compareInt(rv.Int(), v) {
|
||||
return nil
|
||||
}
|
||||
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
v, err := ToUint(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if r.compareUint(rv.Uint(), v) {
|
||||
return nil
|
||||
}
|
||||
|
||||
case reflect.Float32, reflect.Float64:
|
||||
v, err := ToFloat(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if r.compareFloat(rv.Float(), v) {
|
||||
return nil
|
||||
}
|
||||
|
||||
case reflect.Struct:
|
||||
t, ok := r.threshold.(time.Time)
|
||||
if !ok {
|
||||
return fmt.Errorf("type not supported: %v", rv.Type())
|
||||
}
|
||||
v, ok := value.(time.Time)
|
||||
if !ok {
|
||||
return fmt.Errorf("cannot convert %v to time.Time", reflect.TypeOf(value))
|
||||
}
|
||||
if v.IsZero() || r.compareTime(t, v) {
|
||||
return nil
|
||||
}
|
||||
|
||||
default:
|
||||
return fmt.Errorf("type not supported: %v", rv.Type())
|
||||
}
|
||||
|
||||
return errors.New(r.message)
|
||||
}
|
||||
|
||||
// Error sets the error message for the rule.
|
||||
func (r *ThresholdRule) Error(message string) *ThresholdRule {
|
||||
r.message = message
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *ThresholdRule) compareInt(threshold, value int64) bool {
|
||||
switch r.operator {
|
||||
case greaterThan:
|
||||
return value > threshold
|
||||
case greaterEqualThan:
|
||||
return value >= threshold
|
||||
case lessThan:
|
||||
return value < threshold
|
||||
default:
|
||||
return value <= threshold
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ThresholdRule) compareUint(threshold, value uint64) bool {
|
||||
switch r.operator {
|
||||
case greaterThan:
|
||||
return value > threshold
|
||||
case greaterEqualThan:
|
||||
return value >= threshold
|
||||
case lessThan:
|
||||
return value < threshold
|
||||
default:
|
||||
return value <= threshold
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ThresholdRule) compareFloat(threshold, value float64) bool {
|
||||
switch r.operator {
|
||||
case greaterThan:
|
||||
return value > threshold
|
||||
case greaterEqualThan:
|
||||
return value >= threshold
|
||||
case lessThan:
|
||||
return value < threshold
|
||||
default:
|
||||
return value <= threshold
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ThresholdRule) compareTime(threshold, value time.Time) bool {
|
||||
switch r.operator {
|
||||
case greaterThan:
|
||||
return value.After(threshold)
|
||||
case greaterEqualThan:
|
||||
return value.After(threshold) || value.Equal(threshold)
|
||||
case lessThan:
|
||||
return value.Before(threshold)
|
||||
default:
|
||||
return value.Before(threshold) || value.Equal(threshold)
|
||||
}
|
||||
}
|
55
vendor/github.com/go-ozzo/ozzo-validation/multipleof.go
generated
vendored
Normal file
55
vendor/github.com/go-ozzo/ozzo-validation/multipleof.go
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func MultipleOf(threshold interface{}) *multipleOfRule {
|
||||
return &multipleOfRule{
|
||||
threshold,
|
||||
fmt.Sprintf("must be multiple of %v", threshold),
|
||||
}
|
||||
}
|
||||
|
||||
type multipleOfRule struct {
|
||||
threshold interface{}
|
||||
message string
|
||||
}
|
||||
|
||||
// Error sets the error message for the rule.
|
||||
func (r *multipleOfRule) Error(message string) *multipleOfRule {
|
||||
r.message = message
|
||||
return r
|
||||
}
|
||||
|
||||
|
||||
func (r *multipleOfRule) Validate(value interface{}) error {
|
||||
|
||||
rv := reflect.ValueOf(r.threshold)
|
||||
switch rv.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
v, err := ToInt(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if v%rv.Int() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
v, err := ToUint(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if v%rv.Uint() == 0 {
|
||||
return nil
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("type not supported: %v", rv.Type())
|
||||
}
|
||||
|
||||
return errors.New(r.message)
|
||||
}
|
45
vendor/github.com/go-ozzo/ozzo-validation/not_in.go
generated
vendored
Normal file
45
vendor/github.com/go-ozzo/ozzo-validation/not_in.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2018 Qiang Xue, Google LLC. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
// NotIn returns a validation rule that checks if a value os absent from, the given list of values.
|
||||
// Note that the value being checked and the possible range of values must be of the same type.
|
||||
// An empty value is considered valid. Use the Required rule to make sure a value is not empty.
|
||||
func NotIn(values ...interface{}) *NotInRule {
|
||||
return &NotInRule{
|
||||
elements: values,
|
||||
message: "must not be in list",
|
||||
}
|
||||
}
|
||||
|
||||
type NotInRule struct {
|
||||
elements []interface{}
|
||||
message string
|
||||
}
|
||||
|
||||
// Validate checks if the given value is valid or not.
|
||||
func (r *NotInRule) Validate(value interface{}) error {
|
||||
value, isNil := Indirect(value)
|
||||
if isNil || IsEmpty(value) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, e := range r.elements {
|
||||
if e == value {
|
||||
return errors.New(r.message)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Error sets the error message for the rule.
|
||||
func (r *NotInRule) Error(message string) *NotInRule {
|
||||
r.message = message
|
||||
return r
|
||||
}
|
32
vendor/github.com/go-ozzo/ozzo-validation/not_nil.go
generated
vendored
Normal file
32
vendor/github.com/go-ozzo/ozzo-validation/not_nil.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright 2016 Qiang Xue. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package validation
|
||||
|
||||
import "errors"
|
||||
|
||||
// NotNil is a validation rule that checks if a value is not nil.
|
||||
// NotNil only handles types including interface, pointer, slice, and map.
|
||||
// All other types are considered valid.
|
||||
var NotNil = ¬NilRule{message: "is required"}
|
||||
|
||||
type notNilRule struct {
|
||||
message string
|
||||
}
|
||||
|
||||
// Validate checks if the given value is valid or not.
|
||||
func (r *notNilRule) Validate(value interface{}) error {
|
||||
_, isNil := Indirect(value)
|
||||
if isNil {
|
||||
return errors.New(r.message)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Error sets the error message for the rule.
|
||||
func (r *notNilRule) Error(message string) *notNilRule {
|
||||
return ¬NilRule{
|
||||
message: message,
|
||||
}
|
||||
}
|
42
vendor/github.com/go-ozzo/ozzo-validation/required.go
generated
vendored
Normal file
42
vendor/github.com/go-ozzo/ozzo-validation/required.go
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright 2016 Qiang Xue. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package validation
|
||||
|
||||
import "errors"
|
||||
|
||||
// Required is a validation rule that checks if a value is not empty.
|
||||
// A value is considered not empty if
|
||||
// - integer, float: not zero
|
||||
// - bool: true
|
||||
// - string, array, slice, map: len() > 0
|
||||
// - interface, pointer: not nil and the referenced value is not empty
|
||||
// - any other types
|
||||
var Required = &requiredRule{message: "cannot be blank", skipNil: false}
|
||||
|
||||
// NilOrNotEmpty checks if a value is a nil pointer or a value that is not empty.
|
||||
// NilOrNotEmpty differs from Required in that it treats a nil pointer as valid.
|
||||
var NilOrNotEmpty = &requiredRule{message: "cannot be blank", skipNil: true}
|
||||
|
||||
type requiredRule struct {
|
||||
message string
|
||||
skipNil bool
|
||||
}
|
||||
|
||||
// Validate checks if the given value is valid or not.
|
||||
func (v *requiredRule) Validate(value interface{}) error {
|
||||
value, isNil := Indirect(value)
|
||||
if v.skipNil && !isNil && IsEmpty(value) || !v.skipNil && (isNil || IsEmpty(value)) {
|
||||
return errors.New(v.message)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Error sets the error message for the rule.
|
||||
func (v *requiredRule) Error(message string) *requiredRule {
|
||||
return &requiredRule{
|
||||
message: message,
|
||||
skipNil: v.skipNil,
|
||||
}
|
||||
}
|
48
vendor/github.com/go-ozzo/ozzo-validation/string.go
generated
vendored
Normal file
48
vendor/github.com/go-ozzo/ozzo-validation/string.go
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright 2016 Qiang Xue. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package validation
|
||||
|
||||
import "errors"
|
||||
|
||||
type stringValidator func(string) bool
|
||||
|
||||
// StringRule is a rule that checks a string variable using a specified stringValidator.
|
||||
type StringRule struct {
|
||||
validate stringValidator
|
||||
message string
|
||||
}
|
||||
|
||||
// NewStringRule creates a new validation rule using a function that takes a string value and returns a bool.
|
||||
// The rule returned will use the function to check if a given string or byte slice is valid or not.
|
||||
// An empty value is considered to be valid. Please use the Required rule to make sure a value is not empty.
|
||||
func NewStringRule(validator stringValidator, message string) *StringRule {
|
||||
return &StringRule{
|
||||
validate: validator,
|
||||
message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// Error sets the error message for the rule.
|
||||
func (v *StringRule) Error(message string) *StringRule {
|
||||
return NewStringRule(v.validate, message)
|
||||
}
|
||||
|
||||
// Validate checks if the given value is valid or not.
|
||||
func (v *StringRule) Validate(value interface{}) error {
|
||||
value, isNil := Indirect(value)
|
||||
if isNil || IsEmpty(value) {
|
||||
return nil
|
||||
}
|
||||
|
||||
str, err := EnsureString(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if v.validate(str) {
|
||||
return nil
|
||||
}
|
||||
return errors.New(v.message)
|
||||
}
|
154
vendor/github.com/go-ozzo/ozzo-validation/struct.go
generated
vendored
Normal file
154
vendor/github.com/go-ozzo/ozzo-validation/struct.go
generated
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
// Copyright 2016 Qiang Xue. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrStructPointer is the error that a struct being validated is not specified as a pointer.
|
||||
ErrStructPointer = errors.New("only a pointer to a struct can be validated")
|
||||
)
|
||||
|
||||
type (
|
||||
// ErrFieldPointer is the error that a field is not specified as a pointer.
|
||||
ErrFieldPointer int
|
||||
|
||||
// ErrFieldNotFound is the error that a field cannot be found in the struct.
|
||||
ErrFieldNotFound int
|
||||
|
||||
// FieldRules represents a rule set associated with a struct field.
|
||||
FieldRules struct {
|
||||
fieldPtr interface{}
|
||||
rules []Rule
|
||||
}
|
||||
)
|
||||
|
||||
// Error returns the error string of ErrFieldPointer.
|
||||
func (e ErrFieldPointer) Error() string {
|
||||
return fmt.Sprintf("field #%v must be specified as a pointer", int(e))
|
||||
}
|
||||
|
||||
// Error returns the error string of ErrFieldNotFound.
|
||||
func (e ErrFieldNotFound) Error() string {
|
||||
return fmt.Sprintf("field #%v cannot be found in the struct", int(e))
|
||||
}
|
||||
|
||||
// ValidateStruct validates a struct by checking the specified struct fields against the corresponding validation rules.
|
||||
// Note that the struct being validated must be specified as a pointer to it. If the pointer is nil, it is considered valid.
|
||||
// Use Field() to specify struct fields that need to be validated. Each Field() call specifies a single field which
|
||||
// should be specified as a pointer to the field. A field can be associated with multiple rules.
|
||||
// For example,
|
||||
//
|
||||
// value := struct {
|
||||
// Name string
|
||||
// Value string
|
||||
// }{"name", "demo"}
|
||||
// err := validation.ValidateStruct(&value,
|
||||
// validation.Field(&a.Name, validation.Required),
|
||||
// validation.Field(&a.Value, validation.Required, validation.Length(5, 10)),
|
||||
// )
|
||||
// fmt.Println(err)
|
||||
// // Value: the length must be between 5 and 10.
|
||||
//
|
||||
// An error will be returned if validation fails.
|
||||
func ValidateStruct(structPtr interface{}, fields ...*FieldRules) error {
|
||||
value := reflect.ValueOf(structPtr)
|
||||
if value.Kind() != reflect.Ptr || !value.IsNil() && value.Elem().Kind() != reflect.Struct {
|
||||
// must be a pointer to a struct
|
||||
return NewInternalError(ErrStructPointer)
|
||||
}
|
||||
if value.IsNil() {
|
||||
// treat a nil struct pointer as valid
|
||||
return nil
|
||||
}
|
||||
value = value.Elem()
|
||||
|
||||
errs := Errors{}
|
||||
|
||||
for i, fr := range fields {
|
||||
fv := reflect.ValueOf(fr.fieldPtr)
|
||||
if fv.Kind() != reflect.Ptr {
|
||||
return NewInternalError(ErrFieldPointer(i))
|
||||
}
|
||||
ft := findStructField(value, fv)
|
||||
if ft == nil {
|
||||
return NewInternalError(ErrFieldNotFound(i))
|
||||
}
|
||||
if err := Validate(fv.Elem().Interface(), fr.rules...); err != nil {
|
||||
if ie, ok := err.(InternalError); ok && ie.InternalError() != nil {
|
||||
return err
|
||||
}
|
||||
if ft.Anonymous {
|
||||
// merge errors from anonymous struct field
|
||||
if es, ok := err.(Errors); ok {
|
||||
for name, value := range es {
|
||||
errs[name] = value
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
errs[getErrorFieldName(ft)] = err
|
||||
}
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Field specifies a struct field and the corresponding validation rules.
|
||||
// The struct field must be specified as a pointer to it.
|
||||
func Field(fieldPtr interface{}, rules ...Rule) *FieldRules {
|
||||
return &FieldRules{
|
||||
fieldPtr: fieldPtr,
|
||||
rules: rules,
|
||||
}
|
||||
}
|
||||
|
||||
// findStructField looks for a field in the given struct.
|
||||
// The field being looked for should be a pointer to the actual struct field.
|
||||
// If found, the field info will be returned. Otherwise, nil will be returned.
|
||||
func findStructField(structValue reflect.Value, fieldValue reflect.Value) *reflect.StructField {
|
||||
ptr := fieldValue.Pointer()
|
||||
for i := structValue.NumField() - 1; i >= 0; i-- {
|
||||
sf := structValue.Type().Field(i)
|
||||
if ptr == structValue.Field(i).UnsafeAddr() {
|
||||
// do additional type comparison because it's possible that the address of
|
||||
// an embedded struct is the same as the first field of the embedded struct
|
||||
if sf.Type == fieldValue.Elem().Type() {
|
||||
return &sf
|
||||
}
|
||||
}
|
||||
if sf.Anonymous {
|
||||
// delve into anonymous struct to look for the field
|
||||
fi := structValue.Field(i)
|
||||
if sf.Type.Kind() == reflect.Ptr {
|
||||
fi = fi.Elem()
|
||||
}
|
||||
if fi.Kind() == reflect.Struct {
|
||||
if f := findStructField(fi, fieldValue); f != nil {
|
||||
return f
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getErrorFieldName returns the name that should be used to represent the validation error of a struct field.
|
||||
func getErrorFieldName(f *reflect.StructField) string {
|
||||
if tag := f.Tag.Get(ErrorTag); tag != "" {
|
||||
if cps := strings.SplitN(tag, ",", 2); cps[0] != "" {
|
||||
return cps[0]
|
||||
}
|
||||
}
|
||||
return f.Name
|
||||
}
|
163
vendor/github.com/go-ozzo/ozzo-validation/util.go
generated
vendored
Normal file
163
vendor/github.com/go-ozzo/ozzo-validation/util.go
generated
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
// Copyright 2016 Qiang Xue. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
bytesType = reflect.TypeOf([]byte(nil))
|
||||
valuerType = reflect.TypeOf((*driver.Valuer)(nil)).Elem()
|
||||
)
|
||||
|
||||
// EnsureString ensures the given value is a string.
|
||||
// If the value is a byte slice, it will be typecast into a string.
|
||||
// An error is returned otherwise.
|
||||
func EnsureString(value interface{}) (string, error) {
|
||||
v := reflect.ValueOf(value)
|
||||
if v.Kind() == reflect.String {
|
||||
return v.String(), nil
|
||||
}
|
||||
if v.Type() == bytesType {
|
||||
return string(v.Interface().([]byte)), nil
|
||||
}
|
||||
return "", errors.New("must be either a string or byte slice")
|
||||
}
|
||||
|
||||
// StringOrBytes typecasts a value into a string or byte slice.
|
||||
// Boolean flags are returned to indicate if the typecasting succeeds or not.
|
||||
func StringOrBytes(value interface{}) (isString bool, str string, isBytes bool, bs []byte) {
|
||||
v := reflect.ValueOf(value)
|
||||
if v.Kind() == reflect.String {
|
||||
str = v.String()
|
||||
isString = true
|
||||
} else if v.Kind() == reflect.Slice && v.Type() == bytesType {
|
||||
bs = v.Interface().([]byte)
|
||||
isBytes = true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// LengthOfValue returns the length of a value that is a string, slice, map, or array.
|
||||
// An error is returned for all other types.
|
||||
func LengthOfValue(value interface{}) (int, error) {
|
||||
v := reflect.ValueOf(value)
|
||||
switch v.Kind() {
|
||||
case reflect.String, reflect.Slice, reflect.Map, reflect.Array:
|
||||
return v.Len(), nil
|
||||
}
|
||||
return 0, fmt.Errorf("cannot get the length of %v", v.Kind())
|
||||
}
|
||||
|
||||
// ToInt converts the given value to an int64.
|
||||
// An error is returned for all incompatible types.
|
||||
func ToInt(value interface{}) (int64, error) {
|
||||
v := reflect.ValueOf(value)
|
||||
switch v.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return v.Int(), nil
|
||||
}
|
||||
return 0, fmt.Errorf("cannot convert %v to int64", v.Kind())
|
||||
}
|
||||
|
||||
// ToUint converts the given value to an uint64.
|
||||
// An error is returned for all incompatible types.
|
||||
func ToUint(value interface{}) (uint64, error) {
|
||||
v := reflect.ValueOf(value)
|
||||
switch v.Kind() {
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return v.Uint(), nil
|
||||
}
|
||||
return 0, fmt.Errorf("cannot convert %v to uint64", v.Kind())
|
||||
}
|
||||
|
||||
// ToFloat converts the given value to a float64.
|
||||
// An error is returned for all incompatible types.
|
||||
func ToFloat(value interface{}) (float64, error) {
|
||||
v := reflect.ValueOf(value)
|
||||
switch v.Kind() {
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v.Float(), nil
|
||||
}
|
||||
return 0, fmt.Errorf("cannot convert %v to float64", v.Kind())
|
||||
}
|
||||
|
||||
// IsEmpty checks if a value is empty or not.
|
||||
// A value is considered empty if
|
||||
// - integer, float: zero
|
||||
// - bool: false
|
||||
// - string, array: len() == 0
|
||||
// - slice, map: nil or len() == 0
|
||||
// - interface, pointer: nil or the referenced value is empty
|
||||
func IsEmpty(value interface{}) bool {
|
||||
v := reflect.ValueOf(value)
|
||||
switch v.Kind() {
|
||||
case reflect.String, reflect.Array, reflect.Map, reflect.Slice:
|
||||
return v.Len() == 0
|
||||
case reflect.Bool:
|
||||
return !v.Bool()
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return v.Int() == 0
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return v.Uint() == 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v.Float() == 0
|
||||
case reflect.Invalid:
|
||||
return true
|
||||
case reflect.Interface, reflect.Ptr:
|
||||
if v.IsNil() {
|
||||
return true
|
||||
}
|
||||
return IsEmpty(v.Elem().Interface())
|
||||
case reflect.Struct:
|
||||
v, ok := value.(time.Time)
|
||||
if ok && v.IsZero() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Indirect returns the value that the given interface or pointer references to.
|
||||
// If the value implements driver.Valuer, it will deal with the value returned by
|
||||
// the Value() method instead. A boolean value is also returned to indicate if
|
||||
// the value is nil or not (only applicable to interface, pointer, map, and slice).
|
||||
// If the value is neither an interface nor a pointer, it will be returned back.
|
||||
func Indirect(value interface{}) (interface{}, bool) {
|
||||
rv := reflect.ValueOf(value)
|
||||
kind := rv.Kind()
|
||||
switch kind {
|
||||
case reflect.Invalid:
|
||||
return nil, true
|
||||
case reflect.Ptr, reflect.Interface:
|
||||
if rv.IsNil() {
|
||||
return nil, true
|
||||
}
|
||||
return Indirect(rv.Elem().Interface())
|
||||
case reflect.Slice, reflect.Map, reflect.Func, reflect.Chan:
|
||||
if rv.IsNil() {
|
||||
return nil, true
|
||||
}
|
||||
}
|
||||
|
||||
if rv.Type().Implements(valuerType) {
|
||||
return indirectValuer(value.(driver.Valuer))
|
||||
}
|
||||
|
||||
return value, false
|
||||
}
|
||||
|
||||
func indirectValuer(valuer driver.Valuer) (interface{}, bool) {
|
||||
if value, err := valuer.Value(); value != nil && err == nil {
|
||||
return Indirect(value)
|
||||
}
|
||||
return nil, true
|
||||
}
|
133
vendor/github.com/go-ozzo/ozzo-validation/validation.go
generated
vendored
Normal file
133
vendor/github.com/go-ozzo/ozzo-validation/validation.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// Copyright 2016 Qiang Xue. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package validation provides configurable and extensible rules for validating data of various types.
|
||||
package validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type (
|
||||
// Validatable is the interface indicating the type implementing it supports data validation.
|
||||
Validatable interface {
|
||||
// Validate validates the data and returns an error if validation fails.
|
||||
Validate() error
|
||||
}
|
||||
|
||||
// Rule represents a validation rule.
|
||||
Rule interface {
|
||||
// Validate validates a value and returns a value if validation fails.
|
||||
Validate(value interface{}) error
|
||||
}
|
||||
|
||||
// RuleFunc represents a validator function.
|
||||
// You may wrap it as a Rule by calling By().
|
||||
RuleFunc func(value interface{}) error
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrorTag is the struct tag name used to customize the error field name for a struct field.
|
||||
ErrorTag = "json"
|
||||
|
||||
// Skip is a special validation rule that indicates all rules following it should be skipped.
|
||||
Skip = &skipRule{}
|
||||
|
||||
validatableType = reflect.TypeOf((*Validatable)(nil)).Elem()
|
||||
)
|
||||
|
||||
// Validate validates the given value and returns the validation error, if any.
|
||||
//
|
||||
// Validate performs validation using the following steps:
|
||||
// - validate the value against the rules passed in as parameters
|
||||
// - if the value is a map and the map values implement `Validatable`, call `Validate` of every map value
|
||||
// - if the value is a slice or array whose values implement `Validatable`, call `Validate` of every element
|
||||
func Validate(value interface{}, rules ...Rule) error {
|
||||
for _, rule := range rules {
|
||||
if _, ok := rule.(*skipRule); ok {
|
||||
return nil
|
||||
}
|
||||
if err := rule.Validate(value); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
rv := reflect.ValueOf(value)
|
||||
if (rv.Kind() == reflect.Ptr || rv.Kind() == reflect.Interface) && rv.IsNil() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if v, ok := value.(Validatable); ok {
|
||||
return v.Validate()
|
||||
}
|
||||
|
||||
switch rv.Kind() {
|
||||
case reflect.Map:
|
||||
if rv.Type().Elem().Implements(validatableType) {
|
||||
return validateMap(rv)
|
||||
}
|
||||
case reflect.Slice, reflect.Array:
|
||||
if rv.Type().Elem().Implements(validatableType) {
|
||||
return validateSlice(rv)
|
||||
}
|
||||
case reflect.Ptr, reflect.Interface:
|
||||
return Validate(rv.Elem().Interface())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateMap validates a map of validatable elements
|
||||
func validateMap(rv reflect.Value) error {
|
||||
errs := Errors{}
|
||||
for _, key := range rv.MapKeys() {
|
||||
if mv := rv.MapIndex(key).Interface(); mv != nil {
|
||||
if err := mv.(Validatable).Validate(); err != nil {
|
||||
errs[fmt.Sprintf("%v", key.Interface())] = err
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateMap validates a slice/array of validatable elements
|
||||
func validateSlice(rv reflect.Value) error {
|
||||
errs := Errors{}
|
||||
l := rv.Len()
|
||||
for i := 0; i < l; i++ {
|
||||
if ev := rv.Index(i).Interface(); ev != nil {
|
||||
if err := ev.(Validatable).Validate(); err != nil {
|
||||
errs[strconv.Itoa(i)] = err
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type skipRule struct{}
|
||||
|
||||
func (r *skipRule) Validate(interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type inlineRule struct {
|
||||
f RuleFunc
|
||||
}
|
||||
|
||||
func (r *inlineRule) Validate(value interface{}) error {
|
||||
return r.f(value)
|
||||
}
|
||||
|
||||
// By wraps a RuleFunc into a Rule.
|
||||
func By(f RuleFunc) Rule {
|
||||
return &inlineRule{f}
|
||||
}
|
Reference in New Issue
Block a user