model.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. package dara
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "reflect"
  7. "regexp"
  8. "strconv"
  9. "strings"
  10. )
  11. type Model interface {
  12. Validate() error
  13. ToMap() map[string]interface{}
  14. copyWithouStream() Model
  15. }
  16. func Validate(params interface{}) error {
  17. if params == nil {
  18. return nil
  19. }
  20. requestValue := reflect.ValueOf(params)
  21. if requestValue.IsNil() {
  22. return nil
  23. }
  24. err := validate(requestValue.Elem())
  25. return err
  26. }
  27. // Verify whether the parameters meet the requirements
  28. func validate(dataValue reflect.Value) error {
  29. if strings.HasPrefix(dataValue.Type().String(), "*") { // Determines whether the input is a structure object or a pointer object
  30. if dataValue.IsNil() {
  31. return nil
  32. }
  33. dataValue = dataValue.Elem()
  34. }
  35. dataType := dataValue.Type()
  36. for i := 0; i < dataType.NumField(); i++ {
  37. field := dataType.Field(i)
  38. valueField := dataValue.Field(i)
  39. for _, value := range validateParams {
  40. err := validateParam(field, valueField, value)
  41. if err != nil {
  42. return err
  43. }
  44. }
  45. }
  46. return nil
  47. }
  48. func validateParam(field reflect.StructField, valueField reflect.Value, tagName string) error {
  49. tag, containsTag := field.Tag.Lookup(tagName) // Take out the checked regular expression
  50. if containsTag && tagName == "require" {
  51. err := checkRequire(field, valueField)
  52. if err != nil {
  53. return err
  54. }
  55. }
  56. if strings.HasPrefix(field.Type.String(), "[]") { // Verify the parameters of the array type
  57. err := validateSlice(field, valueField, containsTag, tag, tagName)
  58. if err != nil {
  59. return err
  60. }
  61. } else if valueField.Kind() == reflect.Ptr { // Determines whether it is a pointer object
  62. err := validatePtr(field, valueField, containsTag, tag, tagName)
  63. if err != nil {
  64. return err
  65. }
  66. }
  67. return nil
  68. }
  69. func validateSlice(field reflect.StructField, valueField reflect.Value, containsregexpTag bool, tag, tagName string) error {
  70. if valueField.IsValid() && !valueField.IsNil() { // Determines whether the parameter has a value
  71. if containsregexpTag {
  72. if tagName == "maxItems" {
  73. err := checkMaxItems(field, valueField, tag)
  74. if err != nil {
  75. return err
  76. }
  77. }
  78. if tagName == "minItems" {
  79. err := checkMinItems(field, valueField, tag)
  80. if err != nil {
  81. return err
  82. }
  83. }
  84. }
  85. for m := 0; m < valueField.Len(); m++ {
  86. elementValue := valueField.Index(m)
  87. if elementValue.Type().Kind() == reflect.Ptr { // Determines whether the child elements of an array are of a basic type
  88. err := validatePtr(field, elementValue, containsregexpTag, tag, tagName)
  89. if err != nil {
  90. return err
  91. }
  92. }
  93. }
  94. }
  95. return nil
  96. }
  97. func validatePtr(field reflect.StructField, elementValue reflect.Value, containsregexpTag bool, tag, tagName string) error {
  98. if elementValue.IsNil() {
  99. return nil
  100. }
  101. if isFilterType(elementValue.Elem().Type().String(), basicTypes) {
  102. if containsregexpTag {
  103. if tagName == "pattern" {
  104. err := checkPattern(field, elementValue.Elem(), tag)
  105. if err != nil {
  106. return err
  107. }
  108. }
  109. if tagName == "maxLength" {
  110. err := checkMaxLength(field, elementValue.Elem(), tag)
  111. if err != nil {
  112. return err
  113. }
  114. }
  115. if tagName == "minLength" {
  116. err := checkMinLength(field, elementValue.Elem(), tag)
  117. if err != nil {
  118. return err
  119. }
  120. }
  121. if tagName == "maximum" {
  122. err := checkMaximum(field, elementValue.Elem(), tag)
  123. if err != nil {
  124. return err
  125. }
  126. }
  127. if tagName == "minimum" {
  128. err := checkMinimum(field, elementValue.Elem(), tag)
  129. if err != nil {
  130. return err
  131. }
  132. }
  133. }
  134. } else {
  135. err := validate(elementValue)
  136. if err != nil {
  137. return err
  138. }
  139. }
  140. return nil
  141. }
  142. func checkRequire(field reflect.StructField, valueField reflect.Value) error {
  143. name, _ := field.Tag.Lookup("json")
  144. strs := strings.Split(name, ",")
  145. name = strs[0]
  146. if !valueField.IsNil() && valueField.IsValid() {
  147. return nil
  148. }
  149. return errors.New(name + " should be setted")
  150. }
  151. func checkPattern(field reflect.StructField, valueField reflect.Value, tag string) error {
  152. if valueField.IsValid() && valueField.String() != "" {
  153. value := valueField.String()
  154. r, _ := regexp.Compile("^" + tag + "$")
  155. if match := r.MatchString(value); !match { // Determines whether the parameter value satisfies the regular expression or not, and throws an error
  156. return errors.New(value + " is not matched " + tag)
  157. }
  158. }
  159. return nil
  160. }
  161. func checkMaxItems(field reflect.StructField, valueField reflect.Value, tag string) error {
  162. if valueField.IsValid() && valueField.String() != "" {
  163. maxItems, err := strconv.Atoi(tag)
  164. if err != nil {
  165. return err
  166. }
  167. length := valueField.Len()
  168. if maxItems < length {
  169. errMsg := fmt.Sprintf("The length of %s is %d which is more than %d", field.Name, length, maxItems)
  170. return errors.New(errMsg)
  171. }
  172. }
  173. return nil
  174. }
  175. func checkMinItems(field reflect.StructField, valueField reflect.Value, tag string) error {
  176. if valueField.IsValid() {
  177. minItems, err := strconv.Atoi(tag)
  178. if err != nil {
  179. return err
  180. }
  181. length := valueField.Len()
  182. if minItems > length {
  183. errMsg := fmt.Sprintf("The length of %s is %d which is less than %d", field.Name, length, minItems)
  184. return errors.New(errMsg)
  185. }
  186. }
  187. return nil
  188. }
  189. func checkMaxLength(field reflect.StructField, valueField reflect.Value, tag string) error {
  190. if valueField.IsValid() && valueField.String() != "" {
  191. maxLength, err := strconv.Atoi(tag)
  192. if err != nil {
  193. return err
  194. }
  195. length := valueField.Len()
  196. if valueField.Kind().String() == "string" {
  197. length = strings.Count(valueField.String(), "") - 1
  198. }
  199. if maxLength < length {
  200. errMsg := fmt.Sprintf("The length of %s is %d which is more than %d", field.Name, length, maxLength)
  201. return errors.New(errMsg)
  202. }
  203. }
  204. return nil
  205. }
  206. func checkMinLength(field reflect.StructField, valueField reflect.Value, tag string) error {
  207. if valueField.IsValid() {
  208. minLength, err := strconv.Atoi(tag)
  209. if err != nil {
  210. return err
  211. }
  212. length := valueField.Len()
  213. if valueField.Kind().String() == "string" {
  214. length = strings.Count(valueField.String(), "") - 1
  215. }
  216. if minLength > length {
  217. errMsg := fmt.Sprintf("The length of %s is %d which is less than %d", field.Name, length, minLength)
  218. return errors.New(errMsg)
  219. }
  220. }
  221. return nil
  222. }
  223. func checkMaximum(field reflect.StructField, valueField reflect.Value, tag string) error {
  224. if valueField.IsValid() && valueField.String() != "" {
  225. maximum, err := strconv.ParseFloat(tag, 64)
  226. if err != nil {
  227. return err
  228. }
  229. byt, _ := json.Marshal(valueField.Interface())
  230. num, err := strconv.ParseFloat(string(byt), 64)
  231. if err != nil {
  232. return err
  233. }
  234. if maximum < num {
  235. errMsg := fmt.Sprintf("The size of %s is %f which is greater than %f", field.Name, num, maximum)
  236. return errors.New(errMsg)
  237. }
  238. }
  239. return nil
  240. }
  241. func checkMinimum(field reflect.StructField, valueField reflect.Value, tag string) error {
  242. if valueField.IsValid() && valueField.String() != "" {
  243. minimum, err := strconv.ParseFloat(tag, 64)
  244. if err != nil {
  245. return err
  246. }
  247. byt, _ := json.Marshal(valueField.Interface())
  248. num, err := strconv.ParseFloat(string(byt), 64)
  249. if err != nil {
  250. return err
  251. }
  252. if minimum > num {
  253. errMsg := fmt.Sprintf("The size of %s is %f which is less than %f", field.Name, num, minimum)
  254. return errors.New(errMsg)
  255. }
  256. }
  257. return nil
  258. }