util.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. package valid
  2. import (
  3. "database/sql/driver"
  4. "errors"
  5. "fmt"
  6. "reflect"
  7. "strings"
  8. "time"
  9. )
  10. var (
  11. bytesType = reflect.TypeOf([]byte(nil))
  12. valuerType = reflect.TypeOf((*driver.Valuer)(nil)).Elem()
  13. // ErrEnsureString is the error that returns when a value is not a string or byte slice.
  14. ErrEnsureString = errors.New("must be either a string or byte slice")
  15. )
  16. // EnsureString ensures the given value is a string.
  17. // If the value is a byte slice, it will be typecast into a string.
  18. // An error is returned otherwise.
  19. func EnsureString(value interface{}) (string, error) {
  20. v := reflect.ValueOf(value)
  21. if v.Kind() == reflect.String {
  22. return v.String(), nil
  23. }
  24. if v.Type() == bytesType {
  25. return string(v.Interface().([]byte)), nil
  26. }
  27. return "", ErrEnsureString
  28. }
  29. // IsBlankString check the given value is a empty values or whitespace only values
  30. func IsBlankString(value string) bool {
  31. if value == "" {
  32. return true
  33. }
  34. if strings.TrimSpace(value) == "" {
  35. return true
  36. }
  37. return false
  38. }
  39. // StringOrBytes typecasts a value into a string or byte slice.
  40. // Boolean flags are returned to indicate if the typecasting succeeds or not.
  41. func StringOrBytes(value interface{}) (isString bool, str string, isBytes bool, bs []byte) {
  42. v := reflect.ValueOf(value)
  43. if v.Kind() == reflect.String {
  44. str = v.String()
  45. isString = true
  46. } else if v.Kind() == reflect.Slice && v.Type() == bytesType {
  47. bs = v.Interface().([]byte)
  48. isBytes = true
  49. }
  50. return
  51. }
  52. // LengthOfValue returns the length of a value that is a string, slice, map, or array.
  53. // An error is returned for all other types.
  54. func LengthOfValue(value interface{}) (int, error) {
  55. v := reflect.ValueOf(value)
  56. switch v.Kind() {
  57. case reflect.String, reflect.Slice, reflect.Map, reflect.Array:
  58. return v.Len(), nil
  59. }
  60. return 0, fmt.Errorf("cannot get the length of %v", v.Kind())
  61. }
  62. // ToInt converts the given value to an int64.
  63. // An error is returned for all incompatible types.
  64. func ToInt(value interface{}) (int64, error) {
  65. v := reflect.ValueOf(value)
  66. switch v.Kind() {
  67. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  68. return v.Int(), nil
  69. }
  70. return 0, fmt.Errorf("cannot convert %v to int64", v.Kind())
  71. }
  72. // ToUint converts the given value to an uint64.
  73. // An error is returned for all incompatible types.
  74. func ToUint(value interface{}) (uint64, error) {
  75. v := reflect.ValueOf(value)
  76. switch v.Kind() {
  77. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  78. return v.Uint(), nil
  79. }
  80. return 0, fmt.Errorf("cannot convert %v to uint64", v.Kind())
  81. }
  82. // ToFloat converts the given value to a float64.
  83. // An error is returned for all incompatible types.
  84. func ToFloat(value interface{}) (float64, error) {
  85. v := reflect.ValueOf(value)
  86. switch v.Kind() {
  87. case reflect.Float32, reflect.Float64:
  88. return v.Float(), nil
  89. }
  90. return 0, fmt.Errorf("cannot convert %v to float64", v.Kind())
  91. }
  92. // IsEmpty checks if a value is empty or not.
  93. // A value is considered empty if
  94. // - integer, float: zero
  95. // - bool: false
  96. // - string, array: len() == 0
  97. // - slice, map: nil or len() == 0
  98. // - interface, pointer: nil or the referenced value is empty
  99. func IsEmpty(value interface{}) bool {
  100. v := reflect.ValueOf(value)
  101. switch v.Kind() {
  102. case reflect.String, reflect.Array, reflect.Map, reflect.Slice:
  103. return v.Len() == 0
  104. case reflect.Bool:
  105. return !v.Bool()
  106. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  107. return v.Int() == 0
  108. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  109. return v.Uint() == 0
  110. case reflect.Float32, reflect.Float64:
  111. return v.Float() == 0
  112. case reflect.Invalid:
  113. return true
  114. case reflect.Interface, reflect.Ptr:
  115. if v.IsNil() {
  116. return true
  117. }
  118. return IsEmpty(v.Elem().Interface())
  119. case reflect.Struct:
  120. v, ok := value.(time.Time)
  121. if ok && v.IsZero() {
  122. return true
  123. }
  124. }
  125. return false
  126. }
  127. // Indirect returns the value that the given interface or pointer references to.
  128. // If the value implements driver.Valuer, it will deal with the value returned by
  129. // the Value() method instead. A boolean value is also returned to indicate if
  130. // the value is nil or not (only applicable to interface, pointer, map, and slice).
  131. // If the value is neither an interface nor a pointer, it will be returned back.
  132. func Indirect(value interface{}) (interface{}, bool) {
  133. rv := reflect.ValueOf(value)
  134. kind := rv.Kind()
  135. switch kind {
  136. case reflect.Invalid:
  137. return nil, true
  138. case reflect.Ptr, reflect.Interface:
  139. if rv.IsNil() {
  140. return nil, true
  141. }
  142. return Indirect(rv.Elem().Interface())
  143. case reflect.Slice, reflect.Map, reflect.Func, reflect.Chan:
  144. if rv.IsNil() {
  145. return nil, true
  146. }
  147. }
  148. if rv.Type().Implements(valuerType) {
  149. return indirectValuer(value.(driver.Valuer))
  150. }
  151. return value, false
  152. }
  153. func indirectValuer(valuer driver.Valuer) (interface{}, bool) {
  154. if value, err := valuer.Value(); value != nil && err == nil {
  155. return Indirect(value)
  156. }
  157. return nil, true
  158. }