iterresult.ts 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import { QueryMethodTypes, IterResultType } from './types'
  2. // =============================================================================
  3. // Results
  4. // =============================================================================
  5. export interface IterArgs {
  6. inc: boolean
  7. before: Date
  8. after: Date
  9. dt: Date
  10. _value: Date | Date[] | null
  11. }
  12. /**
  13. * This class helps us to emulate python's generators, sorta.
  14. */
  15. export default class IterResult<M extends QueryMethodTypes> {
  16. public readonly method: M
  17. public readonly args: Partial<IterArgs>
  18. public readonly minDate: Date | null = null
  19. public readonly maxDate: Date | null = null
  20. public _result: Date[] = []
  21. public total = 0
  22. constructor(method: M, args: Partial<IterArgs>) {
  23. this.method = method
  24. this.args = args
  25. if (method === 'between') {
  26. this.maxDate = args.inc
  27. ? args.before
  28. : new Date(args.before.getTime() - 1)
  29. this.minDate = args.inc ? args.after : new Date(args.after.getTime() + 1)
  30. } else if (method === 'before') {
  31. this.maxDate = args.inc ? args.dt : new Date(args.dt.getTime() - 1)
  32. } else if (method === 'after') {
  33. this.minDate = args.inc ? args.dt : new Date(args.dt.getTime() + 1)
  34. }
  35. }
  36. /**
  37. * Possibly adds a date into the result.
  38. *
  39. * @param {Date} date - the date isn't necessarly added to the result
  40. * list (if it is too late/too early)
  41. * @return {Boolean} true if it makes sense to continue the iteration
  42. * false if we're done.
  43. */
  44. accept(date: Date) {
  45. ++this.total
  46. const tooEarly = this.minDate && date < this.minDate
  47. const tooLate = this.maxDate && date > this.maxDate
  48. if (this.method === 'between') {
  49. if (tooEarly) return true
  50. if (tooLate) return false
  51. } else if (this.method === 'before') {
  52. if (tooLate) return false
  53. } else if (this.method === 'after') {
  54. if (tooEarly) return true
  55. this.add(date)
  56. return false
  57. }
  58. return this.add(date)
  59. }
  60. /**
  61. *
  62. * @param {Date} date that is part of the result.
  63. * @return {Boolean} whether we are interested in more values.
  64. */
  65. add(date: Date) {
  66. this._result.push(date)
  67. return true
  68. }
  69. /**
  70. * 'before' and 'after' return only one date, whereas 'all'
  71. * and 'between' an array.
  72. *
  73. * @return {Date,Array?}
  74. */
  75. getValue(): IterResultType<M> {
  76. const res = this._result
  77. switch (this.method) {
  78. case 'all':
  79. case 'between':
  80. return res as IterResultType<M>
  81. case 'before':
  82. case 'after':
  83. default:
  84. return (res.length ? res[res.length - 1] : null) as IterResultType<M>
  85. }
  86. }
  87. clone() {
  88. return new IterResult(this.method, this.args)
  89. }
  90. }