validate.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package survey
  2. import (
  3. "errors"
  4. "fmt"
  5. "reflect"
  6. )
  7. // Required does not allow an empty value
  8. func Required(val interface{}) error {
  9. // the reflect value of the result
  10. value := reflect.ValueOf(val)
  11. // if the value passed in is the zero value of the appropriate type
  12. if isZero(value) && value.Kind() != reflect.Bool {
  13. return errors.New("Value is required")
  14. }
  15. return nil
  16. }
  17. // MaxLength requires that the string is no longer than the specified value
  18. func MaxLength(length int) Validator {
  19. // return a validator that checks the length of the string
  20. return func(val interface{}) error {
  21. if str, ok := val.(string); ok {
  22. // if the string is longer than the given value
  23. if len([]rune(str)) > length {
  24. // yell loudly
  25. return fmt.Errorf("value is too long. Max length is %v", length)
  26. }
  27. } else {
  28. // otherwise we cannot convert the value into a string and cannot enforce length
  29. return fmt.Errorf("cannot enforce length on response of type %v", reflect.TypeOf(val).Name())
  30. }
  31. // the input is fine
  32. return nil
  33. }
  34. }
  35. // MinLength requires that the string is longer or equal in length to the specified value
  36. func MinLength(length int) Validator {
  37. // return a validator that checks the length of the string
  38. return func(val interface{}) error {
  39. if str, ok := val.(string); ok {
  40. // if the string is shorter than the given value
  41. if len([]rune(str)) < length {
  42. // yell loudly
  43. return fmt.Errorf("value is too short. Min length is %v", length)
  44. }
  45. } else {
  46. // otherwise we cannot convert the value into a string and cannot enforce length
  47. return fmt.Errorf("cannot enforce length on response of type %v", reflect.TypeOf(val).Name())
  48. }
  49. // the input is fine
  50. return nil
  51. }
  52. }
  53. // ComposeValidators is a variadic function used to create one validator from many.
  54. func ComposeValidators(validators ...Validator) Validator {
  55. // return a validator that calls each one sequentially
  56. return func(val interface{}) error {
  57. // execute each validator
  58. for _, validator := range validators {
  59. // if the answer's value is not valid
  60. if err := validator(val); err != nil {
  61. // return the error
  62. return err
  63. }
  64. }
  65. // we passed all validators, the answer is valid
  66. return nil
  67. }
  68. }
  69. // isZero returns true if the passed value is the zero object
  70. func isZero(v reflect.Value) bool {
  71. switch v.Kind() {
  72. case reflect.Slice, reflect.Map:
  73. return v.Len() == 0
  74. }
  75. // compare the types directly with more general coverage
  76. return reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface())
  77. }