gvalid_error.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // Copyright 2018 gf Author(https://github.com/gogf/gf). All Rights Reserved.
  2. //
  3. // This Source Code Form is subject to the terms of the MIT License.
  4. // If a copy of the MIT was not distributed with this file,
  5. // You can obtain one at https://github.com/gogf/gf.
  6. package gvalid
  7. import (
  8. "errors"
  9. "github.com/gogf/gf/text/gregex"
  10. "strings"
  11. )
  12. // Error is the validation error for validation result.
  13. type Error struct {
  14. rules []string // Rules by sequence, which is used for keeping error sequence.
  15. errors ErrorMap // Error map.
  16. firstKey string // The first error rule key(nil in default).
  17. firstItem map[string]string // The first error rule value(nil in default).
  18. }
  19. // ErrorMap is the validation error map:
  20. // map[field]map[rule]message
  21. type ErrorMap map[string]map[string]string
  22. // newError creates and returns a validation error.
  23. func newError(rules []string, errors map[string]map[string]string) *Error {
  24. for field, m := range errors {
  25. for k, v := range m {
  26. v = strings.Replace(v, ":attribute", field, -1)
  27. m[k], _ = gregex.ReplaceString(`\s{2,}`, ` `, v)
  28. }
  29. errors[field] = m
  30. }
  31. return &Error{
  32. rules: rules,
  33. errors: errors,
  34. }
  35. }
  36. // newErrorStr creates and returns a validation error by string.
  37. func newErrorStr(key, err string) *Error {
  38. return newError(nil, map[string]map[string]string{
  39. "__gvalid__": {
  40. key: err,
  41. },
  42. })
  43. }
  44. // Map returns the first error message as map.
  45. func (e *Error) Map() map[string]string {
  46. if e == nil {
  47. return map[string]string{}
  48. }
  49. _, m := e.FirstItem()
  50. return m
  51. }
  52. // Maps returns all error messages as map.
  53. func (e *Error) Maps() ErrorMap {
  54. if e == nil {
  55. return nil
  56. }
  57. return e.errors
  58. }
  59. // FirstItem returns the field name and error messages for the first validation rule error.
  60. func (e *Error) FirstItem() (key string, messages map[string]string) {
  61. if e == nil {
  62. return "", map[string]string{}
  63. }
  64. if e.firstItem != nil {
  65. return e.firstKey, e.firstItem
  66. }
  67. // By sequence.
  68. if len(e.rules) > 0 {
  69. for _, v := range e.rules {
  70. name, _, _ := parseSequenceTag(v)
  71. if m, ok := e.errors[name]; ok {
  72. e.firstKey = name
  73. e.firstItem = m
  74. return name, m
  75. }
  76. }
  77. }
  78. // No sequence.
  79. for k, m := range e.errors {
  80. e.firstKey = k
  81. e.firstItem = m
  82. return k, m
  83. }
  84. return "", nil
  85. }
  86. // FirstRule returns the first error rule and message string.
  87. func (e *Error) FirstRule() (rule string, err string) {
  88. if e == nil {
  89. return "", ""
  90. }
  91. // By sequence.
  92. if len(e.rules) > 0 {
  93. for _, v := range e.rules {
  94. name, rule, _ := parseSequenceTag(v)
  95. if m, ok := e.errors[name]; ok {
  96. for _, rule := range strings.Split(rule, "|") {
  97. array := strings.Split(rule, ":")
  98. rule = strings.TrimSpace(array[0])
  99. if err, ok := m[rule]; ok {
  100. return rule, err
  101. }
  102. }
  103. }
  104. }
  105. }
  106. // No sequence.
  107. for _, m := range e.errors {
  108. for k, v := range m {
  109. return k, v
  110. }
  111. }
  112. return "", ""
  113. }
  114. // FirstString returns the first error message as string.
  115. // Note that the returned message might be different if it has no sequence.
  116. func (e *Error) FirstString() (err string) {
  117. if e == nil {
  118. return ""
  119. }
  120. _, err = e.FirstRule()
  121. return
  122. }
  123. // Current is alis of FirstString, which implements interface gerror.ApiCurrent.
  124. func (e *Error) Current() error {
  125. if e == nil {
  126. return nil
  127. }
  128. _, err := e.FirstRule()
  129. return errors.New(err)
  130. }
  131. // String returns all error messages as string, multiple error messages joined using char ';'.
  132. func (e *Error) String() string {
  133. if e == nil {
  134. return ""
  135. }
  136. return strings.Join(e.Strings(), "; ")
  137. }
  138. // Error implements interface of error.Error.
  139. func (e *Error) Error() string {
  140. if e == nil {
  141. return ""
  142. }
  143. return e.String()
  144. }
  145. // Strings returns all error messages as string array.
  146. func (e *Error) Strings() (errs []string) {
  147. if e == nil {
  148. return []string{}
  149. }
  150. errs = make([]string, 0)
  151. // By sequence.
  152. if len(e.rules) > 0 {
  153. for _, v := range e.rules {
  154. name, rule, _ := parseSequenceTag(v)
  155. if m, ok := e.errors[name]; ok {
  156. // validation error checks.
  157. for _, rule := range strings.Split(rule, "|") {
  158. rule = strings.TrimSpace(strings.Split(rule, ":")[0])
  159. if err, ok := m[rule]; ok {
  160. errs = append(errs, err)
  161. }
  162. }
  163. // internal error checks.
  164. for k, _ := range internalErrKeyMap {
  165. if err, ok := m[k]; ok {
  166. errs = append(errs, err)
  167. }
  168. }
  169. }
  170. }
  171. return errs
  172. }
  173. // No sequence.
  174. for _, m := range e.errors {
  175. for _, err := range m {
  176. errs = append(errs, err)
  177. }
  178. }
  179. return
  180. }