123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- 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())
- }
|