PageRenderTime 70ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/gopkg.in/bluesuncorp/validator.v5/baked_in.go

https://gitlab.com/sheket/server
Go | 999 lines | 646 code | 333 blank | 20 comment | 158 complexity | 8510c7293adab43355ec15f96a2318e5 MD5 | raw file
  1. package validator
  2. import (
  3. "fmt"
  4. "net/url"
  5. "reflect"
  6. "strconv"
  7. "strings"
  8. "time"
  9. "unicode/utf8"
  10. )
  11. // BakedInValidators is the default map of ValidationFunc
  12. // you can add, remove or even replace items to suite your needs,
  13. // or even disregard and use your own map if so desired.
  14. var BakedInValidators = map[string]Func{
  15. "required": hasValue,
  16. "len": hasLengthOf,
  17. "min": hasMinOf,
  18. "max": hasMaxOf,
  19. "eq": isEq,
  20. "ne": isNe,
  21. "lt": isLt,
  22. "lte": isLte,
  23. "gt": isGt,
  24. "gte": isGte,
  25. "eqfield": isEqField,
  26. "nefield": isNeField,
  27. "gtefield": isGteField,
  28. "gtfield": isGtField,
  29. "ltefield": isLteField,
  30. "ltfield": isLtField,
  31. "alpha": isAlpha,
  32. "alphanum": isAlphanum,
  33. "numeric": isNumeric,
  34. "number": isNumber,
  35. "hexadecimal": isHexadecimal,
  36. "hexcolor": isHexcolor,
  37. "rgb": isRgb,
  38. "rgba": isRgba,
  39. "hsl": isHsl,
  40. "hsla": isHsla,
  41. "email": isEmail,
  42. "url": isURL,
  43. "uri": isURI,
  44. "base64": isBase64,
  45. "contains": contains,
  46. "containsany": containsAny,
  47. "containsrune": containsRune,
  48. "excludes": excludes,
  49. "excludesall": excludesAll,
  50. "excludesrune": excludesRune,
  51. "isbn": isISBN,
  52. "isbn10": isISBN10,
  53. "isbn13": isISBN13,
  54. "uuid": isUUID,
  55. "uuid3": isUUID3,
  56. "uuid4": isUUID4,
  57. "uuid5": isUUID5,
  58. "ascii": isASCII,
  59. "printascii": isPrintableASCII,
  60. "multibyte": hasMultiByteCharacter,
  61. "datauri": isDataURI,
  62. "latitude": isLatitude,
  63. "longitude": isLongitude,
  64. "ssn": isSSN,
  65. }
  66. func isSSN(top interface{}, current interface{}, field interface{}, param string) bool {
  67. if len(field.(string)) != 11 {
  68. return false
  69. }
  70. return matchesRegex(sSNRegex, field)
  71. }
  72. func isLongitude(top interface{}, current interface{}, field interface{}, param string) bool {
  73. return matchesRegex(longitudeRegex, field)
  74. }
  75. func isLatitude(top interface{}, current interface{}, field interface{}, param string) bool {
  76. return matchesRegex(latitudeRegex, field)
  77. }
  78. func isDataURI(top interface{}, current interface{}, field interface{}, param string) bool {
  79. uri := strings.SplitN(field.(string), ",", 2)
  80. if len(uri) != 2 {
  81. return false
  82. }
  83. if !matchesRegex(dataURIRegex, uri[0]) {
  84. return false
  85. }
  86. return isBase64(top, current, uri[1], param)
  87. }
  88. func hasMultiByteCharacter(top interface{}, current interface{}, field interface{}, param string) bool {
  89. if len(field.(string)) == 0 {
  90. return true
  91. }
  92. return matchesRegex(multibyteRegex, field)
  93. }
  94. func isPrintableASCII(top interface{}, current interface{}, field interface{}, param string) bool {
  95. return matchesRegex(printableASCIIRegex, field)
  96. }
  97. func isASCII(top interface{}, current interface{}, field interface{}, param string) bool {
  98. return matchesRegex(aSCIIRegex, field)
  99. }
  100. func isUUID5(top interface{}, current interface{}, field interface{}, param string) bool {
  101. return matchesRegex(uUID5Regex, field)
  102. }
  103. func isUUID4(top interface{}, current interface{}, field interface{}, param string) bool {
  104. return matchesRegex(uUID4Regex, field)
  105. }
  106. func isUUID3(top interface{}, current interface{}, field interface{}, param string) bool {
  107. return matchesRegex(uUID3Regex, field)
  108. }
  109. func isUUID(top interface{}, current interface{}, field interface{}, param string) bool {
  110. return matchesRegex(uUIDRegex, field)
  111. }
  112. func isISBN(top interface{}, current interface{}, field interface{}, param string) bool {
  113. return isISBN10(top, current, field, param) || isISBN13(top, current, field, param)
  114. }
  115. func isISBN13(top interface{}, current interface{}, field interface{}, param string) bool {
  116. s := strings.Replace(strings.Replace(field.(string), "-", "", 4), " ", "", 4)
  117. if !matchesRegex(iSBN13Regex, s) {
  118. return false
  119. }
  120. var checksum int32
  121. var i int32
  122. factor := []int32{1, 3}
  123. for i = 0; i < 12; i++ {
  124. checksum += factor[i%2] * int32(s[i]-'0')
  125. }
  126. if (int32(s[12]-'0'))-((10-(checksum%10))%10) == 0 {
  127. return true
  128. }
  129. return false
  130. }
  131. func isISBN10(top interface{}, current interface{}, field interface{}, param string) bool {
  132. s := strings.Replace(strings.Replace(field.(string), "-", "", 3), " ", "", 3)
  133. if !matchesRegex(iSBN10Regex, s) {
  134. return false
  135. }
  136. var checksum int32
  137. var i int32
  138. for i = 0; i < 9; i++ {
  139. checksum += (i + 1) * int32(s[i]-'0')
  140. }
  141. if s[9] == 'X' {
  142. checksum += 10 * 10
  143. } else {
  144. checksum += 10 * int32(s[9]-'0')
  145. }
  146. if checksum%11 == 0 {
  147. return true
  148. }
  149. return false
  150. }
  151. func excludesRune(top interface{}, current interface{}, field interface{}, param string) bool {
  152. return !containsRune(top, current, field, param)
  153. }
  154. func excludesAll(top interface{}, current interface{}, field interface{}, param string) bool {
  155. return !containsAny(top, current, field, param)
  156. }
  157. func excludes(top interface{}, current interface{}, field interface{}, param string) bool {
  158. return !contains(top, current, field, param)
  159. }
  160. func containsRune(top interface{}, current interface{}, field interface{}, param string) bool {
  161. r, _ := utf8.DecodeRuneInString(param)
  162. return strings.ContainsRune(field.(string), r)
  163. }
  164. func containsAny(top interface{}, current interface{}, field interface{}, param string) bool {
  165. return strings.ContainsAny(field.(string), param)
  166. }
  167. func contains(top interface{}, current interface{}, field interface{}, param string) bool {
  168. return strings.Contains(field.(string), param)
  169. }
  170. func isNeField(top interface{}, current interface{}, field interface{}, param string) bool {
  171. return !isEqField(top, current, field, param)
  172. }
  173. func isNe(top interface{}, current interface{}, field interface{}, param string) bool {
  174. return !isEq(top, current, field, param)
  175. }
  176. func isEqField(top interface{}, current interface{}, field interface{}, param string) bool {
  177. if current == nil {
  178. panic("struct not passed for cross validation")
  179. }
  180. currentVal := reflect.ValueOf(current)
  181. if currentVal.Kind() == reflect.Ptr && !currentVal.IsNil() {
  182. currentVal = reflect.ValueOf(currentVal.Elem().Interface())
  183. }
  184. var currentFielVal reflect.Value
  185. switch currentVal.Kind() {
  186. case reflect.Struct:
  187. if currentVal.Type() == reflect.TypeOf(time.Time{}) {
  188. currentFielVal = currentVal
  189. break
  190. }
  191. f := currentVal.FieldByName(param)
  192. if f.Kind() == reflect.Invalid {
  193. panic(fmt.Sprintf("Field \"%s\" not found in struct", param))
  194. }
  195. currentFielVal = f
  196. default:
  197. currentFielVal = currentVal
  198. }
  199. if currentFielVal.Kind() == reflect.Ptr && !currentFielVal.IsNil() {
  200. currentFielVal = reflect.ValueOf(currentFielVal.Elem().Interface())
  201. }
  202. fv := reflect.ValueOf(field)
  203. switch fv.Kind() {
  204. case reflect.String:
  205. return fv.String() == currentFielVal.String()
  206. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  207. return fv.Int() == currentFielVal.Int()
  208. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  209. return fv.Uint() == currentFielVal.Uint()
  210. case reflect.Float32, reflect.Float64:
  211. return fv.Float() == currentFielVal.Float()
  212. case reflect.Slice, reflect.Map, reflect.Array:
  213. return int64(fv.Len()) == int64(currentFielVal.Len())
  214. case reflect.Struct:
  215. if fv.Type() == reflect.TypeOf(time.Time{}) {
  216. if currentFielVal.Type() != reflect.TypeOf(time.Time{}) {
  217. panic("Bad Top Level field type")
  218. }
  219. t := currentFielVal.Interface().(time.Time)
  220. fieldTime := field.(time.Time)
  221. return fieldTime.Equal(t)
  222. }
  223. }
  224. panic(fmt.Sprintf("Bad field type %T", field))
  225. }
  226. func isEq(top interface{}, current interface{}, field interface{}, param string) bool {
  227. st := reflect.ValueOf(field)
  228. switch st.Kind() {
  229. case reflect.String:
  230. return st.String() == param
  231. case reflect.Slice, reflect.Map, reflect.Array:
  232. p := asInt(param)
  233. return int64(st.Len()) == p
  234. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  235. p := asInt(param)
  236. return st.Int() == p
  237. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  238. p := asUint(param)
  239. return st.Uint() == p
  240. case reflect.Float32, reflect.Float64:
  241. p := asFloat(param)
  242. return st.Float() == p
  243. }
  244. panic(fmt.Sprintf("Bad field type %T", field))
  245. }
  246. func isBase64(top interface{}, current interface{}, field interface{}, param string) bool {
  247. return matchesRegex(base64Regex, field)
  248. }
  249. func isURI(top interface{}, current interface{}, field interface{}, param string) bool {
  250. st := reflect.ValueOf(field)
  251. switch st.Kind() {
  252. case reflect.String:
  253. _, err := url.ParseRequestURI(field.(string))
  254. return err == nil
  255. }
  256. panic(fmt.Sprintf("Bad field type %T", field))
  257. }
  258. func isURL(top interface{}, current interface{}, field interface{}, param string) bool {
  259. st := reflect.ValueOf(field)
  260. switch st.Kind() {
  261. case reflect.String:
  262. url, err := url.ParseRequestURI(field.(string))
  263. if err != nil {
  264. return false
  265. }
  266. if len(url.Scheme) == 0 {
  267. return false
  268. }
  269. return err == nil
  270. }
  271. panic(fmt.Sprintf("Bad field type %T", field))
  272. }
  273. func isEmail(top interface{}, current interface{}, field interface{}, param string) bool {
  274. return matchesRegex(emailRegex, field)
  275. }
  276. func isHsla(top interface{}, current interface{}, field interface{}, param string) bool {
  277. return matchesRegex(hslaRegex, field)
  278. }
  279. func isHsl(top interface{}, current interface{}, field interface{}, param string) bool {
  280. return matchesRegex(hslRegex, field)
  281. }
  282. func isRgba(top interface{}, current interface{}, field interface{}, param string) bool {
  283. return matchesRegex(rgbaRegex, field)
  284. }
  285. func isRgb(top interface{}, current interface{}, field interface{}, param string) bool {
  286. return matchesRegex(rgbRegex, field)
  287. }
  288. func isHexcolor(top interface{}, current interface{}, field interface{}, param string) bool {
  289. return matchesRegex(hexcolorRegex, field)
  290. }
  291. func isHexadecimal(top interface{}, current interface{}, field interface{}, param string) bool {
  292. return matchesRegex(hexadecimalRegex, field)
  293. }
  294. func isNumber(top interface{}, current interface{}, field interface{}, param string) bool {
  295. return matchesRegex(numberRegex, field)
  296. }
  297. func isNumeric(top interface{}, current interface{}, field interface{}, param string) bool {
  298. return matchesRegex(numericRegex, field)
  299. }
  300. func isAlphanum(top interface{}, current interface{}, field interface{}, param string) bool {
  301. return matchesRegex(alphaNumericRegex, field)
  302. }
  303. func isAlpha(top interface{}, current interface{}, field interface{}, param string) bool {
  304. return matchesRegex(alphaRegex, field)
  305. }
  306. func hasValue(top interface{}, current interface{}, field interface{}, param string) bool {
  307. st := reflect.ValueOf(field)
  308. switch st.Kind() {
  309. case reflect.Slice, reflect.Map, reflect.Array:
  310. return field != nil && int64(st.Len()) > 0
  311. default:
  312. return field != nil && field != reflect.Zero(reflect.TypeOf(field)).Interface()
  313. }
  314. }
  315. func isGteField(top interface{}, current interface{}, field interface{}, param string) bool {
  316. if current == nil {
  317. panic("struct not passed for cross validation")
  318. }
  319. currentVal := reflect.ValueOf(current)
  320. if currentVal.Kind() == reflect.Ptr && !currentVal.IsNil() {
  321. currentVal = reflect.ValueOf(currentVal.Elem().Interface())
  322. }
  323. var currentFielVal reflect.Value
  324. switch currentVal.Kind() {
  325. case reflect.Struct:
  326. if currentVal.Type() == reflect.TypeOf(time.Time{}) {
  327. currentFielVal = currentVal
  328. break
  329. }
  330. f := currentVal.FieldByName(param)
  331. if f.Kind() == reflect.Invalid {
  332. panic(fmt.Sprintf("Field \"%s\" not found in struct", param))
  333. }
  334. currentFielVal = f
  335. default:
  336. currentFielVal = currentVal
  337. }
  338. if currentFielVal.Kind() == reflect.Ptr && !currentFielVal.IsNil() {
  339. currentFielVal = reflect.ValueOf(currentFielVal.Elem().Interface())
  340. }
  341. fv := reflect.ValueOf(field)
  342. switch fv.Kind() {
  343. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  344. return fv.Int() >= currentFielVal.Int()
  345. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  346. return fv.Uint() >= currentFielVal.Uint()
  347. case reflect.Float32, reflect.Float64:
  348. return fv.Float() >= currentFielVal.Float()
  349. case reflect.Struct:
  350. if fv.Type() == reflect.TypeOf(time.Time{}) {
  351. if currentFielVal.Type() != reflect.TypeOf(time.Time{}) {
  352. panic("Bad Top Level field type")
  353. }
  354. t := currentFielVal.Interface().(time.Time)
  355. fieldTime := field.(time.Time)
  356. return fieldTime.After(t) || fieldTime.Equal(t)
  357. }
  358. }
  359. panic(fmt.Sprintf("Bad field type %T", field))
  360. }
  361. func isGtField(top interface{}, current interface{}, field interface{}, param string) bool {
  362. if current == nil {
  363. panic("struct not passed for cross validation")
  364. }
  365. currentVal := reflect.ValueOf(current)
  366. if currentVal.Kind() == reflect.Ptr && !currentVal.IsNil() {
  367. currentVal = reflect.ValueOf(currentVal.Elem().Interface())
  368. }
  369. var currentFielVal reflect.Value
  370. switch currentVal.Kind() {
  371. case reflect.Struct:
  372. if currentVal.Type() == reflect.TypeOf(time.Time{}) {
  373. currentFielVal = currentVal
  374. break
  375. }
  376. f := currentVal.FieldByName(param)
  377. if f.Kind() == reflect.Invalid {
  378. panic(fmt.Sprintf("Field \"%s\" not found in struct", param))
  379. }
  380. currentFielVal = f
  381. default:
  382. currentFielVal = currentVal
  383. }
  384. if currentFielVal.Kind() == reflect.Ptr && !currentFielVal.IsNil() {
  385. currentFielVal = reflect.ValueOf(currentFielVal.Elem().Interface())
  386. }
  387. fv := reflect.ValueOf(field)
  388. switch fv.Kind() {
  389. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  390. return fv.Int() > currentFielVal.Int()
  391. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  392. return fv.Uint() > currentFielVal.Uint()
  393. case reflect.Float32, reflect.Float64:
  394. return fv.Float() > currentFielVal.Float()
  395. case reflect.Struct:
  396. if fv.Type() == reflect.TypeOf(time.Time{}) {
  397. if currentFielVal.Type() != reflect.TypeOf(time.Time{}) {
  398. panic("Bad Top Level field type")
  399. }
  400. t := currentFielVal.Interface().(time.Time)
  401. fieldTime := field.(time.Time)
  402. return fieldTime.After(t)
  403. }
  404. }
  405. panic(fmt.Sprintf("Bad field type %T", field))
  406. }
  407. func isGte(top interface{}, current interface{}, field interface{}, param string) bool {
  408. st := reflect.ValueOf(field)
  409. switch st.Kind() {
  410. case reflect.String:
  411. p := asInt(param)
  412. return int64(len(st.String())) >= p
  413. case reflect.Slice, reflect.Map, reflect.Array:
  414. p := asInt(param)
  415. return int64(st.Len()) >= p
  416. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  417. p := asInt(param)
  418. return st.Int() >= p
  419. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  420. p := asUint(param)
  421. return st.Uint() >= p
  422. case reflect.Float32, reflect.Float64:
  423. p := asFloat(param)
  424. return st.Float() >= p
  425. case reflect.Struct:
  426. if st.Type() == reflect.TypeOf(time.Time{}) {
  427. now := time.Now().UTC()
  428. t := field.(time.Time)
  429. return t.After(now) || t.Equal(now)
  430. }
  431. }
  432. panic(fmt.Sprintf("Bad field type %T", field))
  433. }
  434. func isGt(top interface{}, current interface{}, field interface{}, param string) bool {
  435. st := reflect.ValueOf(field)
  436. switch st.Kind() {
  437. case reflect.String:
  438. p := asInt(param)
  439. return int64(len(st.String())) > p
  440. case reflect.Slice, reflect.Map, reflect.Array:
  441. p := asInt(param)
  442. return int64(st.Len()) > p
  443. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  444. p := asInt(param)
  445. return st.Int() > p
  446. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  447. p := asUint(param)
  448. return st.Uint() > p
  449. case reflect.Float32, reflect.Float64:
  450. p := asFloat(param)
  451. return st.Float() > p
  452. case reflect.Struct:
  453. if st.Type() == reflect.TypeOf(time.Time{}) {
  454. return field.(time.Time).After(time.Now().UTC())
  455. }
  456. }
  457. panic(fmt.Sprintf("Bad field type %T", field))
  458. }
  459. // length tests whether a variable's length is equal to a given
  460. // value. For strings it tests the number of characters whereas
  461. // for maps and slices it tests the number of items.
  462. func hasLengthOf(top interface{}, current interface{}, field interface{}, param string) bool {
  463. st := reflect.ValueOf(field)
  464. switch st.Kind() {
  465. case reflect.String:
  466. p := asInt(param)
  467. return int64(len(st.String())) == p
  468. case reflect.Slice, reflect.Map, reflect.Array:
  469. p := asInt(param)
  470. return int64(st.Len()) == p
  471. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  472. p := asInt(param)
  473. return st.Int() == p
  474. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  475. p := asUint(param)
  476. return st.Uint() == p
  477. case reflect.Float32, reflect.Float64:
  478. p := asFloat(param)
  479. return st.Float() == p
  480. }
  481. panic(fmt.Sprintf("Bad field type %T", field))
  482. }
  483. // min tests whether a variable value is larger or equal to a given
  484. // number. For number types, it's a simple lesser-than test; for
  485. // strings it tests the number of characters whereas for maps
  486. // and slices it tests the number of items.
  487. func hasMinOf(top interface{}, current interface{}, field interface{}, param string) bool {
  488. return isGte(top, current, field, param)
  489. }
  490. func isLteField(top interface{}, current interface{}, field interface{}, param string) bool {
  491. if current == nil {
  492. panic("struct not passed for cross validation")
  493. }
  494. currentVal := reflect.ValueOf(current)
  495. if currentVal.Kind() == reflect.Ptr && !currentVal.IsNil() {
  496. currentVal = reflect.ValueOf(currentVal.Elem().Interface())
  497. }
  498. var currentFielVal reflect.Value
  499. switch currentVal.Kind() {
  500. case reflect.Struct:
  501. if currentVal.Type() == reflect.TypeOf(time.Time{}) {
  502. currentFielVal = currentVal
  503. break
  504. }
  505. f := currentVal.FieldByName(param)
  506. if f.Kind() == reflect.Invalid {
  507. panic(fmt.Sprintf("Field \"%s\" not found in struct", param))
  508. }
  509. currentFielVal = f
  510. default:
  511. currentFielVal = currentVal
  512. }
  513. if currentFielVal.Kind() == reflect.Ptr && !currentFielVal.IsNil() {
  514. currentFielVal = reflect.ValueOf(currentFielVal.Elem().Interface())
  515. }
  516. fv := reflect.ValueOf(field)
  517. switch fv.Kind() {
  518. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  519. return fv.Int() <= currentFielVal.Int()
  520. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  521. return fv.Uint() <= currentFielVal.Uint()
  522. case reflect.Float32, reflect.Float64:
  523. return fv.Float() <= currentFielVal.Float()
  524. case reflect.Struct:
  525. if fv.Type() == reflect.TypeOf(time.Time{}) {
  526. if currentFielVal.Type() != reflect.TypeOf(time.Time{}) {
  527. panic("Bad Top Level field type")
  528. }
  529. t := currentFielVal.Interface().(time.Time)
  530. fieldTime := field.(time.Time)
  531. return fieldTime.Before(t) || fieldTime.Equal(t)
  532. }
  533. }
  534. panic(fmt.Sprintf("Bad field type %T", field))
  535. }
  536. func isLtField(top interface{}, current interface{}, field interface{}, param string) bool {
  537. if current == nil {
  538. panic("struct not passed for cross validation")
  539. }
  540. currentVal := reflect.ValueOf(current)
  541. if currentVal.Kind() == reflect.Ptr && !currentVal.IsNil() {
  542. currentVal = reflect.ValueOf(currentVal.Elem().Interface())
  543. }
  544. var currentFielVal reflect.Value
  545. switch currentVal.Kind() {
  546. case reflect.Struct:
  547. if currentVal.Type() == reflect.TypeOf(time.Time{}) {
  548. currentFielVal = currentVal
  549. break
  550. }
  551. f := currentVal.FieldByName(param)
  552. if f.Kind() == reflect.Invalid {
  553. panic(fmt.Sprintf("Field \"%s\" not found in struct", param))
  554. }
  555. currentFielVal = f
  556. default:
  557. currentFielVal = currentVal
  558. }
  559. if currentFielVal.Kind() == reflect.Ptr && !currentFielVal.IsNil() {
  560. currentFielVal = reflect.ValueOf(currentFielVal.Elem().Interface())
  561. }
  562. fv := reflect.ValueOf(field)
  563. switch fv.Kind() {
  564. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  565. return fv.Int() < currentFielVal.Int()
  566. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  567. return fv.Uint() < currentFielVal.Uint()
  568. case reflect.Float32, reflect.Float64:
  569. return fv.Float() < currentFielVal.Float()
  570. case reflect.Struct:
  571. if fv.Type() == reflect.TypeOf(time.Time{}) {
  572. if currentFielVal.Type() != reflect.TypeOf(time.Time{}) {
  573. panic("Bad Top Level field type")
  574. }
  575. t := currentFielVal.Interface().(time.Time)
  576. fieldTime := field.(time.Time)
  577. return fieldTime.Before(t)
  578. }
  579. }
  580. panic(fmt.Sprintf("Bad field type %T", field))
  581. }
  582. func isLte(top interface{}, current interface{}, field interface{}, param string) bool {
  583. st := reflect.ValueOf(field)
  584. switch st.Kind() {
  585. case reflect.String:
  586. p := asInt(param)
  587. return int64(len(st.String())) <= p
  588. case reflect.Slice, reflect.Map, reflect.Array:
  589. p := asInt(param)
  590. return int64(st.Len()) <= p
  591. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  592. p := asInt(param)
  593. return st.Int() <= p
  594. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  595. p := asUint(param)
  596. return st.Uint() <= p
  597. case reflect.Float32, reflect.Float64:
  598. p := asFloat(param)
  599. return st.Float() <= p
  600. case reflect.Struct:
  601. if st.Type() == reflect.TypeOf(time.Time{}) {
  602. now := time.Now().UTC()
  603. t := field.(time.Time)
  604. return t.Before(now) || t.Equal(now)
  605. }
  606. }
  607. panic(fmt.Sprintf("Bad field type %T", field))
  608. }
  609. func isLt(top interface{}, current interface{}, field interface{}, param string) bool {
  610. st := reflect.ValueOf(field)
  611. switch st.Kind() {
  612. case reflect.String:
  613. p := asInt(param)
  614. return int64(len(st.String())) < p
  615. case reflect.Slice, reflect.Map, reflect.Array:
  616. p := asInt(param)
  617. return int64(st.Len()) < p
  618. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  619. p := asInt(param)
  620. return st.Int() < p
  621. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  622. p := asUint(param)
  623. return st.Uint() < p
  624. case reflect.Float32, reflect.Float64:
  625. p := asFloat(param)
  626. return st.Float() < p
  627. case reflect.Struct:
  628. if st.Type() == reflect.TypeOf(time.Time{}) {
  629. return field.(time.Time).Before(time.Now().UTC())
  630. }
  631. }
  632. panic(fmt.Sprintf("Bad field type %T", field))
  633. }
  634. // max tests whether a variable value is lesser than a given
  635. // value. For numbers, it's a simple lesser-than test; for
  636. // strings it tests the number of characters whereas for maps
  637. // and slices it tests the number of items.
  638. func hasMaxOf(top interface{}, current interface{}, field interface{}, param string) bool {
  639. return isLte(top, current, field, param)
  640. }
  641. // asInt retuns the parameter as a int64
  642. // or panics if it can't convert
  643. func asInt(param string) int64 {
  644. i, err := strconv.ParseInt(param, 0, 64)
  645. panicIf(err)
  646. return i
  647. }
  648. // asUint returns the parameter as a uint64
  649. // or panics if it can't convert
  650. func asUint(param string) uint64 {
  651. i, err := strconv.ParseUint(param, 0, 64)
  652. panicIf(err)
  653. return i
  654. }
  655. // asFloat returns the parameter as a float64
  656. // or panics if it can't convert
  657. func asFloat(param string) float64 {
  658. i, err := strconv.ParseFloat(param, 64)
  659. panicIf(err)
  660. return i
  661. }
  662. func panicIf(err error) {
  663. if err != nil {
  664. panic(err.Error())
  665. }
  666. }