DockerCLI/vendor/github.com/docker/licensing/lib/go-validation/validation.go

142 lines
3.6 KiB
Go

package validation
import (
"fmt"
"reflect"
validator "github.com/asaskevich/govalidator"
)
// ErrorKind represents a validation error type
type ErrorKind int
// ErrorKind enumeration
const (
// ErrorGeneral represents a catchall validation error. That is,
// an error that does not match any ErrorKind.
ErrorGeneral ErrorKind = iota
// ErrorEmpty represents an empty field validation error.
ErrorEmpty
// ErrorInvalidEmail represents an invalid email validation error.
ErrorInvalidEmail
// ErrorInvalidURL represents an invalid url validation error.
ErrorInvalidURL
)
// Error represents a validation error
type Error struct {
FieldName string
FieldValue interface{}
kind ErrorKind
}
// Error returns the string representation of the error
func (e *Error) Error() string {
msg := e.MsgForCode()
return fmt.Sprintf("%v invalid: %v", e.FieldName, msg)
}
// MsgForCode returns a human readable message for the given ErrorKind.
// The message may optionally include the given field value in the message.
func (e *Error) MsgForCode() string {
switch e.kind {
case ErrorEmpty:
return "not provided"
case ErrorInvalidEmail:
return fmt.Sprintf("%v is an invalid email address", e.FieldValue)
case ErrorInvalidURL:
return fmt.Sprintf("%v is an invalid url", e.FieldValue)
}
return fmt.Sprintf("'%v' is not a valid value", e.FieldValue)
}
// Errors is a list of validation Errors
type Errors []*Error
// Validater has a single function Validate, which can be used to determine
// if the interface implementation is valid. Validate should return true if the implementation
// passes validation, false otherwise. If invalid, a list of one or more validation
// Errors should be returned.
type Validater interface {
Validate() (bool, Errors)
}
// IsEmpty returns true if the given interface is empty, false otherwise
func IsEmpty(s interface{}) bool {
v := reflect.ValueOf(s)
switch v.Kind() {
case reflect.String,
reflect.Array:
return v.Len() == 0
case reflect.Map,
reflect.Slice:
return v.Len() == 0 || v.IsNil()
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.Interface,
reflect.Ptr:
return v.IsNil()
}
return reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface())
}
// IsEmail returns true if the given email address is valid, false otherwise
func IsEmail(str string) bool {
return validator.IsEmail(str)
}
// IsURL returns true if the given url is valid, false otherwise
func IsURL(str string) bool {
return validator.IsURL(str)
}
// Matches returns true if the given string matches the given pattern, false otherwise
func Matches(str, pattern string) bool {
return validator.Matches(str, pattern)
}
// InvalidEmpty returns an empty validation Error for the given field name
func InvalidEmpty(fieldName string) *Error {
return &Error{
FieldName: fieldName,
kind: ErrorEmpty,
}
}
// InvalidEmail returns an invalid validation error for the given field name and value
func InvalidEmail(fieldName, fieldValue string) *Error {
return &Error{
FieldName: fieldName,
FieldValue: fieldValue,
kind: ErrorInvalidEmail,
}
}
// InvalidURL returns an invalid validation error for the given field name and value
func InvalidURL(fieldName, fieldValue string) *Error {
return &Error{
FieldName: fieldName,
FieldValue: fieldValue,
kind: ErrorInvalidURL,
}
}