length.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Copyright 2016 Qiang Xue. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package validation
  5. import (
  6. "errors"
  7. "fmt"
  8. "unicode/utf8"
  9. )
  10. // Length returns a validation rule that checks if a value's length is within the specified range.
  11. // If max is 0, it means there is no upper bound for the length.
  12. // This rule should only be used for validating strings, slices, maps, and arrays.
  13. // An empty value is considered valid. Use the Required rule to make sure a value is not empty.
  14. func Length(min, max int) *LengthRule {
  15. message := "the value must be empty"
  16. if min == 0 && max > 0 {
  17. message = fmt.Sprintf("the length must be no more than %v", max)
  18. } else if min > 0 && max == 0 {
  19. message = fmt.Sprintf("the length must be no less than %v", min)
  20. } else if min > 0 && max > 0 {
  21. if min == max {
  22. message = fmt.Sprintf("the length must be exactly %v", min)
  23. } else {
  24. message = fmt.Sprintf("the length must be between %v and %v", min, max)
  25. }
  26. }
  27. return &LengthRule{
  28. min: min,
  29. max: max,
  30. message: message,
  31. }
  32. }
  33. // RuneLength returns a validation rule that checks if a string's rune length is within the specified range.
  34. // If max is 0, it means there is no upper bound for the length.
  35. // This rule should only be used for validating strings, slices, maps, and arrays.
  36. // An empty value is considered valid. Use the Required rule to make sure a value is not empty.
  37. // If the value being validated is not a string, the rule works the same as Length.
  38. func RuneLength(min, max int) *LengthRule {
  39. r := Length(min, max)
  40. r.rune = true
  41. return r
  42. }
  43. type LengthRule struct {
  44. min, max int
  45. message string
  46. rune bool
  47. }
  48. // Validate checks if the given value is valid or not.
  49. func (v *LengthRule) Validate(value interface{}) error {
  50. value, isNil := Indirect(value)
  51. if isNil || IsEmpty(value) {
  52. return nil
  53. }
  54. var (
  55. l int
  56. err error
  57. )
  58. if s, ok := value.(string); ok && v.rune {
  59. l = utf8.RuneCountInString(s)
  60. } else if l, err = LengthOfValue(value); err != nil {
  61. return err
  62. }
  63. if v.min > 0 && l < v.min || v.max > 0 && l > v.max {
  64. return errors.New(v.message)
  65. }
  66. return nil
  67. }
  68. // Error sets the error message for the rule.
  69. func (v *LengthRule) Error(message string) *LengthRule {
  70. v.message = message
  71. return v
  72. }