vendor: add github.com/Azure/go-autorest/autorest/validation
This commit is contained in:
parent
b6d6582acc
commit
bdaf9d6ba9
373
vendor/github.com/Azure/go-autorest/autorest/validation/validation.go
generated
vendored
Normal file
373
vendor/github.com/Azure/go-autorest/autorest/validation/validation.go
generated
vendored
Normal file
|
@ -0,0 +1,373 @@
|
||||||
|
/*
|
||||||
|
Package validation provides methods for validating parameter value using reflection.
|
||||||
|
*/
|
||||||
|
package validation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Constraint stores constraint name, target field name
|
||||||
|
// Rule and chain validations.
|
||||||
|
type Constraint struct {
|
||||||
|
|
||||||
|
// Target field name for validation.
|
||||||
|
Target string
|
||||||
|
|
||||||
|
// Constraint name e.g. minLength, MaxLength, Pattern, etc.
|
||||||
|
Name string
|
||||||
|
|
||||||
|
// Rule for constraint e.g. greater than 10, less than 5 etc.
|
||||||
|
Rule interface{}
|
||||||
|
|
||||||
|
// Chain Validations for struct type
|
||||||
|
Chain []Constraint
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validation stores parameter-wise validation.
|
||||||
|
type Validation struct {
|
||||||
|
TargetValue interface{}
|
||||||
|
Constraints []Constraint
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constraint list
|
||||||
|
const (
|
||||||
|
Empty = "Empty"
|
||||||
|
Null = "Null"
|
||||||
|
ReadOnly = "ReadOnly"
|
||||||
|
Pattern = "Pattern"
|
||||||
|
MaxLength = "MaxLength"
|
||||||
|
MinLength = "MinLength"
|
||||||
|
MaxItems = "MaxItems"
|
||||||
|
MinItems = "MinItems"
|
||||||
|
MultipleOf = "MultipleOf"
|
||||||
|
UniqueItems = "UniqueItems"
|
||||||
|
InclusiveMaximum = "InclusiveMaximum"
|
||||||
|
ExclusiveMaximum = "ExclusiveMaximum"
|
||||||
|
ExclusiveMinimum = "ExclusiveMinimum"
|
||||||
|
InclusiveMinimum = "InclusiveMinimum"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Validate method validates constraints on parameter
|
||||||
|
// passed in validation array.
|
||||||
|
func Validate(m []Validation) error {
|
||||||
|
for _, item := range m {
|
||||||
|
v := reflect.ValueOf(item.TargetValue)
|
||||||
|
for _, constraint := range item.Constraints {
|
||||||
|
var err error
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
|
err = validatePtr(v, constraint)
|
||||||
|
case reflect.String:
|
||||||
|
err = validateString(v, constraint)
|
||||||
|
case reflect.Struct:
|
||||||
|
err = validateStruct(v, constraint)
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
err = validateInt(v, constraint)
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
err = validateFloat(v, constraint)
|
||||||
|
case reflect.Array, reflect.Slice, reflect.Map:
|
||||||
|
err = validateArrayMap(v, constraint)
|
||||||
|
default:
|
||||||
|
err = createError(v, constraint, fmt.Sprintf("unknown type %v", v.Kind()))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateStruct(x reflect.Value, v Constraint, name ...string) error {
|
||||||
|
//Get field name from target name which is in format a.b.c
|
||||||
|
s := strings.Split(v.Target, ".")
|
||||||
|
f := x.FieldByName(s[len(s)-1])
|
||||||
|
if isZero(f) {
|
||||||
|
return createError(x, v, fmt.Sprintf("field %q doesn't exist", v.Target))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := Validate([]Validation{
|
||||||
|
{
|
||||||
|
TargetValue: getInterfaceValue(f),
|
||||||
|
Constraints: []Constraint{v},
|
||||||
|
},
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validatePtr(x reflect.Value, v Constraint) error {
|
||||||
|
if v.Name == ReadOnly {
|
||||||
|
if !x.IsNil() {
|
||||||
|
return createError(x.Elem(), v, "readonly parameter; must send as nil or empty in request")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if x.IsNil() {
|
||||||
|
return checkNil(x, v)
|
||||||
|
}
|
||||||
|
if v.Chain != nil {
|
||||||
|
return Validate([]Validation{
|
||||||
|
{
|
||||||
|
TargetValue: getInterfaceValue(x.Elem()),
|
||||||
|
Constraints: v.Chain,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateInt(x reflect.Value, v Constraint) error {
|
||||||
|
i := x.Int()
|
||||||
|
r, ok := v.Rule.(int)
|
||||||
|
if !ok {
|
||||||
|
return createError(x, v, fmt.Sprintf("rule must be integer value for %v constraint; got: %v", v.Name, v.Rule))
|
||||||
|
}
|
||||||
|
switch v.Name {
|
||||||
|
case MultipleOf:
|
||||||
|
if i%int64(r) != 0 {
|
||||||
|
return createError(x, v, fmt.Sprintf("value must be a multiple of %v", r))
|
||||||
|
}
|
||||||
|
case ExclusiveMinimum:
|
||||||
|
if i <= int64(r) {
|
||||||
|
return createError(x, v, fmt.Sprintf("value must be greater than %v", r))
|
||||||
|
}
|
||||||
|
case ExclusiveMaximum:
|
||||||
|
if i >= int64(r) {
|
||||||
|
return createError(x, v, fmt.Sprintf("value must be less than %v", r))
|
||||||
|
}
|
||||||
|
case InclusiveMinimum:
|
||||||
|
if i < int64(r) {
|
||||||
|
return createError(x, v, fmt.Sprintf("value must be greater than or equal to %v", r))
|
||||||
|
}
|
||||||
|
case InclusiveMaximum:
|
||||||
|
if i > int64(r) {
|
||||||
|
return createError(x, v, fmt.Sprintf("value must be less than or equal to %v", r))
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return createError(x, v, fmt.Sprintf("constraint %v is not applicable for type integer", v.Name))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateFloat(x reflect.Value, v Constraint) error {
|
||||||
|
f := x.Float()
|
||||||
|
r, ok := v.Rule.(float64)
|
||||||
|
if !ok {
|
||||||
|
return createError(x, v, fmt.Sprintf("rule must be float value for %v constraint; got: %v", v.Name, v.Rule))
|
||||||
|
}
|
||||||
|
switch v.Name {
|
||||||
|
case ExclusiveMinimum:
|
||||||
|
if f <= r {
|
||||||
|
return createError(x, v, fmt.Sprintf("value must be greater than %v", r))
|
||||||
|
}
|
||||||
|
case ExclusiveMaximum:
|
||||||
|
if f >= r {
|
||||||
|
return createError(x, v, fmt.Sprintf("value must be less than %v", r))
|
||||||
|
}
|
||||||
|
case InclusiveMinimum:
|
||||||
|
if f < r {
|
||||||
|
return createError(x, v, fmt.Sprintf("value must be greater than or equal to %v", r))
|
||||||
|
}
|
||||||
|
case InclusiveMaximum:
|
||||||
|
if f > r {
|
||||||
|
return createError(x, v, fmt.Sprintf("value must be less than or equal to %v", r))
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return createError(x, v, fmt.Sprintf("constraint %s is not applicable for type float", v.Name))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateString(x reflect.Value, v Constraint) error {
|
||||||
|
s := x.String()
|
||||||
|
switch v.Name {
|
||||||
|
case Empty:
|
||||||
|
if len(s) == 0 {
|
||||||
|
return checkEmpty(x, v)
|
||||||
|
}
|
||||||
|
case Pattern:
|
||||||
|
reg, err := regexp.Compile(v.Rule.(string))
|
||||||
|
if err != nil {
|
||||||
|
return createError(x, v, err.Error())
|
||||||
|
}
|
||||||
|
if !reg.MatchString(s) {
|
||||||
|
return createError(x, v, fmt.Sprintf("value doesn't match pattern %v", v.Rule))
|
||||||
|
}
|
||||||
|
case MaxLength:
|
||||||
|
if _, ok := v.Rule.(int); !ok {
|
||||||
|
return createError(x, v, fmt.Sprintf("rule must be integer value for %v constraint; got: %v", v.Name, v.Rule))
|
||||||
|
}
|
||||||
|
if len(s) > v.Rule.(int) {
|
||||||
|
return createError(x, v, fmt.Sprintf("value length must be less than %v", v.Rule))
|
||||||
|
}
|
||||||
|
case MinLength:
|
||||||
|
if _, ok := v.Rule.(int); !ok {
|
||||||
|
return createError(x, v, fmt.Sprintf("rule must be integer value for %v constraint; got: %v", v.Name, v.Rule))
|
||||||
|
}
|
||||||
|
if len(s) < v.Rule.(int) {
|
||||||
|
return createError(x, v, fmt.Sprintf("value length must be greater than %v", v.Rule))
|
||||||
|
}
|
||||||
|
case ReadOnly:
|
||||||
|
if len(s) > 0 {
|
||||||
|
return createError(reflect.ValueOf(s), v, "readonly parameter; must send as nil or empty in request")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return createError(x, v, fmt.Sprintf("constraint %s is not applicable to string type", v.Name))
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.Chain != nil {
|
||||||
|
return Validate([]Validation{
|
||||||
|
{
|
||||||
|
TargetValue: getInterfaceValue(x),
|
||||||
|
Constraints: v.Chain,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateArrayMap(x reflect.Value, v Constraint) error {
|
||||||
|
switch v.Name {
|
||||||
|
case Null:
|
||||||
|
if x.IsNil() {
|
||||||
|
return checkNil(x, v)
|
||||||
|
}
|
||||||
|
case Empty:
|
||||||
|
if x.IsNil() || x.Len() == 0 {
|
||||||
|
return checkEmpty(x, v)
|
||||||
|
}
|
||||||
|
case MaxItems:
|
||||||
|
if _, ok := v.Rule.(int); !ok {
|
||||||
|
return createError(x, v, fmt.Sprintf("rule must be integer for %v constraint; got: %v", v.Name, v.Rule))
|
||||||
|
}
|
||||||
|
if x.Len() > v.Rule.(int) {
|
||||||
|
return createError(x, v, fmt.Sprintf("maximum item limit is %v; got: %v", v.Rule, x.Len()))
|
||||||
|
}
|
||||||
|
case MinItems:
|
||||||
|
if _, ok := v.Rule.(int); !ok {
|
||||||
|
return createError(x, v, fmt.Sprintf("rule must be integer for %v constraint; got: %v", v.Name, v.Rule))
|
||||||
|
}
|
||||||
|
if x.Len() < v.Rule.(int) {
|
||||||
|
return createError(x, v, fmt.Sprintf("minimum item limit is %v; got: %v", v.Rule, x.Len()))
|
||||||
|
}
|
||||||
|
case UniqueItems:
|
||||||
|
if x.Kind() == reflect.Array || x.Kind() == reflect.Slice {
|
||||||
|
if !checkForUniqueInArray(x) {
|
||||||
|
return createError(x, v, fmt.Sprintf("all items in parameter %q must be unique; got:%v", v.Target, x))
|
||||||
|
}
|
||||||
|
} else if x.Kind() == reflect.Map {
|
||||||
|
if !checkForUniqueInMap(x) {
|
||||||
|
return createError(x, v, fmt.Sprintf("all items in parameter %q must be unique; got:%v", v.Target, x))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return createError(x, v, fmt.Sprintf("type must be array, slice or map for constraint %v; got: %v", v.Name, x.Kind()))
|
||||||
|
}
|
||||||
|
case ReadOnly:
|
||||||
|
if x.Len() != 0 {
|
||||||
|
return createError(x, v, "readonly parameter; must send as nil or empty in request")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return createError(x, v, fmt.Sprintf("constraint %v is not applicable to array, slice and map type", v.Name))
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.Chain != nil {
|
||||||
|
return Validate([]Validation{
|
||||||
|
{
|
||||||
|
TargetValue: getInterfaceValue(x),
|
||||||
|
Constraints: v.Chain,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkNil(x reflect.Value, v Constraint) error {
|
||||||
|
if _, ok := v.Rule.(bool); !ok {
|
||||||
|
return createError(x, v, fmt.Sprintf("rule must be bool value for %v constraint; got: %v", v.Name, v.Rule))
|
||||||
|
}
|
||||||
|
if v.Rule.(bool) {
|
||||||
|
return createError(x, v, "value can not be null; required parameter")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkEmpty(x reflect.Value, v Constraint) error {
|
||||||
|
if _, ok := v.Rule.(bool); !ok {
|
||||||
|
return createError(x, v, fmt.Sprintf("rule must be bool value for %v constraint; got: %v", v.Name, v.Rule))
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.Rule.(bool) {
|
||||||
|
return createError(x, v, "value can not be null or empty; required parameter")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkForUniqueInArray(x reflect.Value) bool {
|
||||||
|
if x == reflect.Zero(reflect.TypeOf(x)) || x.Len() == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
arrOfInterface := make([]interface{}, x.Len())
|
||||||
|
|
||||||
|
for i := 0; i < x.Len(); i++ {
|
||||||
|
arrOfInterface[i] = x.Index(i).Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
m := make(map[interface{}]bool)
|
||||||
|
for _, val := range arrOfInterface {
|
||||||
|
if m[val] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
m[val] = true
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkForUniqueInMap(x reflect.Value) bool {
|
||||||
|
if x == reflect.Zero(reflect.TypeOf(x)) || x.Len() == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
mapOfInterface := make(map[interface{}]interface{}, x.Len())
|
||||||
|
|
||||||
|
keys := x.MapKeys()
|
||||||
|
for _, k := range keys {
|
||||||
|
mapOfInterface[k.Interface()] = x.MapIndex(k).Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
m := make(map[interface{}]bool)
|
||||||
|
for _, val := range mapOfInterface {
|
||||||
|
if m[val] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
m[val] = true
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func getInterfaceValue(x reflect.Value) interface{} {
|
||||||
|
if x.Kind() == reflect.Invalid {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return x.Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
func isZero(x interface{}) bool {
|
||||||
|
return x == reflect.Zero(reflect.TypeOf(x)).Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
func createError(x reflect.Value, v Constraint, err string) error {
|
||||||
|
return fmt.Errorf("autorest/validation: validation failed: parameter=%s constraint=%s value=%#v details: %s",
|
||||||
|
v.Target, v.Name, getInterfaceValue(x), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewErrorWithValidationError appends package type and method name in
|
||||||
|
// validation error.
|
||||||
|
func NewErrorWithValidationError(err error, packageType, method string) error {
|
||||||
|
return fmt.Errorf("%s#%s: Invalid input: %v", packageType, method, err)
|
||||||
|
}
|
|
@ -46,6 +46,12 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "Ev8qCsbFjDlMlX0N2tYAhYQFpUc=",
|
"checksumSHA1": "Ev8qCsbFjDlMlX0N2tYAhYQFpUc=",
|
||||||
|
"checksumSHA1": "oBixceM+55gdk47iff8DSEIh3po=",
|
||||||
|
"path": "github.com/Azure/go-autorest/autorest/validation",
|
||||||
|
"revision": "c2571aa487482a987546c123fef9334582786335",
|
||||||
|
"revisionTime": "2017-04-20T22:41:48Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
"checksumSHA1": "JhyS/zIicgtrSasHSZ6WtXGWJVk=",
|
"checksumSHA1": "JhyS/zIicgtrSasHSZ6WtXGWJVk=",
|
||||||
"path": "github.com/DataDog/datadog-go/statsd",
|
"path": "github.com/DataDog/datadog-go/statsd",
|
||||||
"revision": "cc2f4770f4d61871e19bfee967bc767fe730b0d9",
|
"revision": "cc2f4770f4d61871e19bfee967bc767fe730b0d9",
|
||||||
|
|
Loading…
Reference in New Issue