88 lines
2.5 KiB
Go
88 lines
2.5 KiB
Go
|
package survey
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"reflect"
|
||
|
)
|
||
|
|
||
|
// Required does not allow an empty value
|
||
|
func Required(val interface{}) error {
|
||
|
// the reflect value of the result
|
||
|
value := reflect.ValueOf(val)
|
||
|
|
||
|
// if the value passed in is the zero value of the appropriate type
|
||
|
if isZero(value) && value.Kind() != reflect.Bool {
|
||
|
return errors.New("Value is required")
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// MaxLength requires that the string is no longer than the specified value
|
||
|
func MaxLength(length int) Validator {
|
||
|
// return a validator that checks the length of the string
|
||
|
return func(val interface{}) error {
|
||
|
if str, ok := val.(string); ok {
|
||
|
// if the string is longer than the given value
|
||
|
if len([]rune(str)) > length {
|
||
|
// yell loudly
|
||
|
return fmt.Errorf("value is too long. Max length is %v", length)
|
||
|
}
|
||
|
} else {
|
||
|
// otherwise we cannot convert the value into a string and cannot enforce length
|
||
|
return fmt.Errorf("cannot enforce length on response of type %v", reflect.TypeOf(val).Name())
|
||
|
}
|
||
|
|
||
|
// the input is fine
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// MinLength requires that the string is longer or equal in length to the specified value
|
||
|
func MinLength(length int) Validator {
|
||
|
// return a validator that checks the length of the string
|
||
|
return func(val interface{}) error {
|
||
|
if str, ok := val.(string); ok {
|
||
|
// if the string is shorter than the given value
|
||
|
if len([]rune(str)) < length {
|
||
|
// yell loudly
|
||
|
return fmt.Errorf("value is too short. Min length is %v", length)
|
||
|
}
|
||
|
} else {
|
||
|
// otherwise we cannot convert the value into a string and cannot enforce length
|
||
|
return fmt.Errorf("cannot enforce length on response of type %v", reflect.TypeOf(val).Name())
|
||
|
}
|
||
|
|
||
|
// the input is fine
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ComposeValidators is a variadic function used to create one validator from many.
|
||
|
func ComposeValidators(validators ...Validator) Validator {
|
||
|
// return a validator that calls each one sequentially
|
||
|
return func(val interface{}) error {
|
||
|
// execute each validator
|
||
|
for _, validator := range validators {
|
||
|
// if the answer's value is not valid
|
||
|
if err := validator(val); err != nil {
|
||
|
// return the error
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
// we passed all validators, the answer is valid
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// isZero returns true if the passed value is the zero object
|
||
|
func isZero(v reflect.Value) bool {
|
||
|
switch v.Kind() {
|
||
|
case reflect.Slice, reflect.Map:
|
||
|
return v.Len() == 0
|
||
|
}
|
||
|
|
||
|
// compare the types directly with more general coverage
|
||
|
return reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface())
|
||
|
}
|