validate.go 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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. // if the value passed in is the zero value of the appropriate type
  10. if isZero(reflect.ValueOf(val)) {
  11. return errors.New("Value is required")
  12. }
  13. return nil
  14. }
  15. // MaxLength requires that the string is no longer than the specified value
  16. func MaxLength(length int) Validator {
  17. // return a validator that checks the length of the string
  18. return func(val interface{}) error {
  19. if str, ok := val.(string); ok {
  20. // if the string is longer than the given value
  21. if len(str) > length {
  22. // yell loudly
  23. return fmt.Errorf("value is too long. Max length is %v", length)
  24. }
  25. } else {
  26. // otherwise we cannot convert the value into a string and cannot enforce length
  27. return fmt.Errorf("cannot enforce length on response of type %v", reflect.TypeOf(val).Name())
  28. }
  29. // the input is fine
  30. return nil
  31. }
  32. }
  33. // MinLength requires that the string is longer or equal in length to the specified value
  34. func MinLength(length int) Validator {
  35. // return a validator that checks the length of the string
  36. return func(val interface{}) error {
  37. if str, ok := val.(string); ok {
  38. // if the string is shorter than the given value
  39. if len(str) < length {
  40. // yell loudly
  41. return fmt.Errorf("value is too short. Min length is %v", length)
  42. }
  43. } else {
  44. // otherwise we cannot convert the value into a string and cannot enforce length
  45. return fmt.Errorf("cannot enforce length on response of type %v", reflect.TypeOf(val).Name())
  46. }
  47. // the input is fine
  48. return nil
  49. }
  50. }
  51. // ComposeValidators is a variadic function used to create one validator from many.
  52. func ComposeValidators(validators ...Validator) Validator {
  53. // return a validator that calls each one sequentially
  54. return func(val interface{}) error {
  55. // execute each validator
  56. for _, validator := range validators {
  57. // if the answer's value is not valid
  58. if err := validator(val); err != nil {
  59. // return the error
  60. return err
  61. }
  62. }
  63. // we passed all validators, the answer is valid
  64. return nil
  65. }
  66. }
  67. // isZero returns true if the passed value is the zero object
  68. func isZero(v reflect.Value) bool {
  69. switch v.Kind() {
  70. case reflect.Slice, reflect.Map:
  71. return v.Len() == 0
  72. // fixes:
  73. // if confirm and `Validate: survey.Required` is used
  74. // and answer is "No" (== false)
  75. // then it shows "Sorry, your reply was invalid: Value is required"
  76. // and it stucks there.
  77. // This happens because 'false' is the zero value of a "bool" type.
  78. case reflect.Bool:
  79. return false
  80. }
  81. // compare the types directly with more general coverage
  82. return reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface())
  83. }