validators.go 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. package validation
  2. import (
  3. "fmt"
  4. "reflect"
  5. "regexp"
  6. "time"
  7. "unicode/utf8"
  8. )
  9. var MessageTmpls = map[string]string{
  10. "Required": "Can not be empty",
  11. "Min": "Minimum is %d",
  12. "Max": "Maximum is %d",
  13. "Range": "Range is %d to %d",
  14. "MinSize": "Minimum size is %d",
  15. "MaxSize": "Maximum size is %d",
  16. "Length": "Required length is %d",
  17. "Alpha": "Must be valid alpha characters",
  18. "Numeric": "Must be valid numeric characters",
  19. "AlphaNumeric": "Must be valid alpha or numeric characters",
  20. "Match": "Must match %s",
  21. "NoMatch": "Must not match %s",
  22. "AlphaDash": "Must be valid alpha or numeric or dash(-_) characters",
  23. "Email": "Must be a valid email address",
  24. "IP": "Must be a valid ip address",
  25. "Base64": "Must be valid base64 characters",
  26. "Mobile": "Must be valid mobile number",
  27. "Tel": "Must be valid telephone number",
  28. "Phone": "Must be valid telephone or mobile phone number",
  29. "ZipCode": "Must be valid zipcode",
  30. }
  31. type Validator interface {
  32. IsSatisfied(interface{}) bool
  33. DefaultMessage() string
  34. GetKey() string
  35. GetLimitValue() interface{}
  36. }
  37. type Required struct {
  38. Key string
  39. }
  40. func (r Required) IsSatisfied(obj interface{}) bool {
  41. if obj == nil {
  42. return false
  43. }
  44. if str, ok := obj.(string); ok {
  45. return len(str) > 0
  46. }
  47. if b, ok := obj.(bool); ok {
  48. return b
  49. }
  50. if i, ok := obj.(int); ok {
  51. return i != 0
  52. }
  53. if t, ok := obj.(time.Time); ok {
  54. return !t.IsZero()
  55. }
  56. v := reflect.ValueOf(obj)
  57. if v.Kind() == reflect.Slice {
  58. return v.Len() > 0
  59. }
  60. return true
  61. }
  62. func (r Required) DefaultMessage() string {
  63. return fmt.Sprint(MessageTmpls["Required"])
  64. }
  65. func (r Required) GetKey() string {
  66. return r.Key
  67. }
  68. func (r Required) GetLimitValue() interface{} {
  69. return nil
  70. }
  71. type Min struct {
  72. Min int
  73. Key string
  74. }
  75. func (m Min) IsSatisfied(obj interface{}) bool {
  76. num, ok := obj.(int)
  77. if ok {
  78. return num >= m.Min
  79. }
  80. return false
  81. }
  82. func (m Min) DefaultMessage() string {
  83. return fmt.Sprintf(MessageTmpls["Min"], m.Min)
  84. }
  85. func (m Min) GetKey() string {
  86. return m.Key
  87. }
  88. func (m Min) GetLimitValue() interface{} {
  89. return m.Min
  90. }
  91. type Max struct {
  92. Max int
  93. Key string
  94. }
  95. func (m Max) IsSatisfied(obj interface{}) bool {
  96. num, ok := obj.(int)
  97. if ok {
  98. return num <= m.Max
  99. }
  100. return false
  101. }
  102. func (m Max) DefaultMessage() string {
  103. return fmt.Sprintf(MessageTmpls["Max"], m.Max)
  104. }
  105. func (m Max) GetKey() string {
  106. return m.Key
  107. }
  108. func (m Max) GetLimitValue() interface{} {
  109. return m.Max
  110. }
  111. // Requires an integer to be within Min, Max inclusive.
  112. type Range struct {
  113. Min
  114. Max
  115. Key string
  116. }
  117. func (r Range) IsSatisfied(obj interface{}) bool {
  118. return r.Min.IsSatisfied(obj) && r.Max.IsSatisfied(obj)
  119. }
  120. func (r Range) DefaultMessage() string {
  121. return fmt.Sprintf(MessageTmpls["Range"], r.Min.Min, r.Max.Max)
  122. }
  123. func (r Range) GetKey() string {
  124. return r.Key
  125. }
  126. func (r Range) GetLimitValue() interface{} {
  127. return []int{r.Min.Min, r.Max.Max}
  128. }
  129. // Requires an array or string to be at least a given length.
  130. type MinSize struct {
  131. Min int
  132. Key string
  133. }
  134. func (m MinSize) IsSatisfied(obj interface{}) bool {
  135. if str, ok := obj.(string); ok {
  136. return utf8.RuneCountInString(str) >= m.Min
  137. }
  138. v := reflect.ValueOf(obj)
  139. if v.Kind() == reflect.Slice {
  140. return v.Len() >= m.Min
  141. }
  142. return false
  143. }
  144. func (m MinSize) DefaultMessage() string {
  145. return fmt.Sprintf(MessageTmpls["MinSize"], m.Min)
  146. }
  147. func (m MinSize) GetKey() string {
  148. return m.Key
  149. }
  150. func (m MinSize) GetLimitValue() interface{} {
  151. return m.Min
  152. }
  153. // Requires an array or string to be at most a given length.
  154. type MaxSize struct {
  155. Max int
  156. Key string
  157. }
  158. func (m MaxSize) IsSatisfied(obj interface{}) bool {
  159. if str, ok := obj.(string); ok {
  160. return utf8.RuneCountInString(str) <= m.Max
  161. }
  162. v := reflect.ValueOf(obj)
  163. if v.Kind() == reflect.Slice {
  164. return v.Len() <= m.Max
  165. }
  166. return false
  167. }
  168. func (m MaxSize) DefaultMessage() string {
  169. return fmt.Sprintf(MessageTmpls["MaxSize"], m.Max)
  170. }
  171. func (m MaxSize) GetKey() string {
  172. return m.Key
  173. }
  174. func (m MaxSize) GetLimitValue() interface{} {
  175. return m.Max
  176. }
  177. // Requires an array or string to be exactly a given length.
  178. type Length struct {
  179. N int
  180. Key string
  181. }
  182. func (l Length) IsSatisfied(obj interface{}) bool {
  183. if str, ok := obj.(string); ok {
  184. return utf8.RuneCountInString(str) == l.N
  185. }
  186. v := reflect.ValueOf(obj)
  187. if v.Kind() == reflect.Slice {
  188. return v.Len() == l.N
  189. }
  190. return false
  191. }
  192. func (l Length) DefaultMessage() string {
  193. return fmt.Sprintf(MessageTmpls["Length"], l.N)
  194. }
  195. func (l Length) GetKey() string {
  196. return l.Key
  197. }
  198. func (l Length) GetLimitValue() interface{} {
  199. return l.N
  200. }
  201. type Alpha struct {
  202. Key string
  203. }
  204. func (a Alpha) IsSatisfied(obj interface{}) bool {
  205. if str, ok := obj.(string); ok {
  206. for _, v := range str {
  207. if ('Z' < v || v < 'A') && ('z' < v || v < 'a') {
  208. return false
  209. }
  210. }
  211. return true
  212. }
  213. return false
  214. }
  215. func (a Alpha) DefaultMessage() string {
  216. return fmt.Sprint(MessageTmpls["Alpha"])
  217. }
  218. func (a Alpha) GetKey() string {
  219. return a.Key
  220. }
  221. func (a Alpha) GetLimitValue() interface{} {
  222. return nil
  223. }
  224. type Numeric struct {
  225. Key string
  226. }
  227. func (n Numeric) IsSatisfied(obj interface{}) bool {
  228. if str, ok := obj.(string); ok {
  229. for _, v := range str {
  230. if '9' < v || v < '0' {
  231. return false
  232. }
  233. }
  234. return true
  235. }
  236. return false
  237. }
  238. func (n Numeric) DefaultMessage() string {
  239. return fmt.Sprint(MessageTmpls["Numeric"])
  240. }
  241. func (n Numeric) GetKey() string {
  242. return n.Key
  243. }
  244. func (n Numeric) GetLimitValue() interface{} {
  245. return nil
  246. }
  247. type AlphaNumeric struct {
  248. Key string
  249. }
  250. func (a AlphaNumeric) IsSatisfied(obj interface{}) bool {
  251. if str, ok := obj.(string); ok {
  252. for _, v := range str {
  253. if ('Z' < v || v < 'A') && ('z' < v || v < 'a') && ('9' < v || v < '0') {
  254. return false
  255. }
  256. }
  257. return true
  258. }
  259. return false
  260. }
  261. func (a AlphaNumeric) DefaultMessage() string {
  262. return fmt.Sprint(MessageTmpls["AlphaNumeric"])
  263. }
  264. func (a AlphaNumeric) GetKey() string {
  265. return a.Key
  266. }
  267. func (a AlphaNumeric) GetLimitValue() interface{} {
  268. return nil
  269. }
  270. // Requires a string to match a given regex.
  271. type Match struct {
  272. Regexp *regexp.Regexp
  273. Key string
  274. }
  275. func (m Match) IsSatisfied(obj interface{}) bool {
  276. return m.Regexp.MatchString(fmt.Sprintf("%v", obj))
  277. }
  278. func (m Match) DefaultMessage() string {
  279. return fmt.Sprintf(MessageTmpls["Match"], m.Regexp.String())
  280. }
  281. func (m Match) GetKey() string {
  282. return m.Key
  283. }
  284. func (m Match) GetLimitValue() interface{} {
  285. return m.Regexp.String()
  286. }
  287. // Requires a string to not match a given regex.
  288. type NoMatch struct {
  289. Match
  290. Key string
  291. }
  292. func (n NoMatch) IsSatisfied(obj interface{}) bool {
  293. return !n.Match.IsSatisfied(obj)
  294. }
  295. func (n NoMatch) DefaultMessage() string {
  296. return fmt.Sprintf(MessageTmpls["NoMatch"], n.Regexp.String())
  297. }
  298. func (n NoMatch) GetKey() string {
  299. return n.Key
  300. }
  301. func (n NoMatch) GetLimitValue() interface{} {
  302. return n.Regexp.String()
  303. }
  304. var alphaDashPattern = regexp.MustCompile("[^\\d\\w-_]")
  305. type AlphaDash struct {
  306. NoMatch
  307. Key string
  308. }
  309. func (a AlphaDash) DefaultMessage() string {
  310. return fmt.Sprint(MessageTmpls["AlphaDash"])
  311. }
  312. func (a AlphaDash) GetKey() string {
  313. return a.Key
  314. }
  315. func (a AlphaDash) GetLimitValue() interface{} {
  316. return nil
  317. }
  318. var emailPattern = regexp.MustCompile("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[a-zA-Z0-9](?:[\\w-]*[\\w])?")
  319. type Email struct {
  320. Match
  321. Key string
  322. }
  323. func (e Email) DefaultMessage() string {
  324. return fmt.Sprint(MessageTmpls["Email"])
  325. }
  326. func (e Email) GetKey() string {
  327. return e.Key
  328. }
  329. func (e Email) GetLimitValue() interface{} {
  330. return nil
  331. }
  332. var ipPattern = regexp.MustCompile("^((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)$")
  333. type IP struct {
  334. Match
  335. Key string
  336. }
  337. func (i IP) DefaultMessage() string {
  338. return fmt.Sprint(MessageTmpls["IP"])
  339. }
  340. func (i IP) GetKey() string {
  341. return i.Key
  342. }
  343. func (i IP) GetLimitValue() interface{} {
  344. return nil
  345. }
  346. var base64Pattern = regexp.MustCompile("^(?:[A-Za-z0-99+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$")
  347. type Base64 struct {
  348. Match
  349. Key string
  350. }
  351. func (b Base64) DefaultMessage() string {
  352. return fmt.Sprint(MessageTmpls["Base64"])
  353. }
  354. func (b Base64) GetKey() string {
  355. return b.Key
  356. }
  357. func (b Base64) GetLimitValue() interface{} {
  358. return nil
  359. }
  360. // just for chinese mobile phone number
  361. var mobilePattern = regexp.MustCompile("^((\\+86)|(86))?(1(([35][0-9])|(47)|[8][012356789]))\\d{8}$")
  362. type Mobile struct {
  363. Match
  364. Key string
  365. }
  366. func (m Mobile) DefaultMessage() string {
  367. return fmt.Sprint(MessageTmpls["Mobile"])
  368. }
  369. func (m Mobile) GetKey() string {
  370. return m.Key
  371. }
  372. func (m Mobile) GetLimitValue() interface{} {
  373. return nil
  374. }
  375. // just for chinese telephone number
  376. var telPattern = regexp.MustCompile("^(0\\d{2,3}(\\-)?)?\\d{7,8}$")
  377. type Tel struct {
  378. Match
  379. Key string
  380. }
  381. func (t Tel) DefaultMessage() string {
  382. return fmt.Sprint(MessageTmpls["Tel"])
  383. }
  384. func (t Tel) GetKey() string {
  385. return t.Key
  386. }
  387. func (t Tel) GetLimitValue() interface{} {
  388. return nil
  389. }
  390. // just for chinese telephone or mobile phone number
  391. type Phone struct {
  392. Mobile
  393. Tel
  394. Key string
  395. }
  396. func (p Phone) IsSatisfied(obj interface{}) bool {
  397. return p.Mobile.IsSatisfied(obj) || p.Tel.IsSatisfied(obj)
  398. }
  399. func (p Phone) DefaultMessage() string {
  400. return fmt.Sprint(MessageTmpls["Phone"])
  401. }
  402. func (p Phone) GetKey() string {
  403. return p.Key
  404. }
  405. func (p Phone) GetLimitValue() interface{} {
  406. return nil
  407. }
  408. // just for chinese zipcode
  409. var zipCodePattern = regexp.MustCompile("^[1-9]\\d{5}$")
  410. type ZipCode struct {
  411. Match
  412. Key string
  413. }
  414. func (z ZipCode) DefaultMessage() string {
  415. return fmt.Sprint(MessageTmpls["ZipCode"])
  416. }
  417. func (z ZipCode) GetKey() string {
  418. return z.Key
  419. }
  420. func (z ZipCode) GetLimitValue() interface{} {
  421. return nil
  422. }