-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbetween_expression.go
141 lines (121 loc) · 3.8 KB
/
between_expression.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package schedule
import "time"
// BetweenExpression is the struct used to create cron between expressions.
type BetweenExpression struct {
x int
y int
step int
}
// Between is an expression that generates integers between the provided parameters (*inclusive*).
func Between(x int, y int) *BetweenExpression {
if x > y {
panic("schedule: invalid BetweenExpression expression")
}
return &BetweenExpression{
x: x,
y: y,
step: 1,
}
}
// BetweenMilliseconds uses the regular between logic, ensuring valid millisecond parameters.
func BetweenMilliseconds(x int, y int) *BetweenExpression {
validateMillisecond(x)
validateMillisecond(y)
return Between(x, y)
}
// BetweenSeconds uses the regular between logic, ensuring valid second parameters.
func BetweenSeconds(x int, y int) *BetweenExpression {
validateSecond(x)
validateSecond(y)
return Between(x, y)
}
// BetweenMinutes uses the regular between logic, ensuring valid minute parameters.
func BetweenMinutes(x int, y int) *BetweenExpression {
validateMinute(x)
validateMinute(y)
return Between(x, y)
}
// BetweenHours uses the regular between logic, ensuring valid hour parameters.
func BetweenHours(x int, y int) *BetweenExpression {
validateHour(x)
validateHour(y)
return Between(x, y)
}
// BetweenDays uses the regular between logic, ensuring valid day parameters.
func BetweenDays(x int, y int) *BetweenExpression {
validateDay(x)
validateDay(y)
return Between(x, y)
}
// BetweenWeekdays uses the regular between logic, ensuring valid time.Weekday parameters.
func BetweenWeekdays(x time.Weekday, y time.Weekday) *BetweenExpression {
xI := int(x)
yI := int(y)
validateWeekday(xI)
validateWeekday(yI)
return Between(xI, yI)
}
// BetweenMonths uses the regular between logic, ensuring valid time.Month parameters.
func BetweenMonths(x time.Month, y time.Month) *BetweenExpression {
xI := int(x)
yI := int(y)
validateMonth(xI)
validateMonth(yI)
return Between(xI, yI)
}
// BetweenYears uses the regular between logic, ensuring valid year parameters.
func BetweenYears(x int, y int) *BetweenExpression {
validateYear(x)
validateYear(y)
return Between(x, y)
}
// Every allows optional specification of the stepping used for the between logic.
// It's important to understand the behavior of the expression when step > 1. It may produce some unexpected values.
// Example: Between(0,10).Every(3)
// - Next(-1, true || false) = 0
// - Next(0, true) = 0
// - Next(0, false) = 3
// - Next(1, true || false) = 3
// - Next(3, false) = 6
// - Next(6, false) = 9
// - Next(9, false) = 10
// - Next(10, true || false) = 10
func (exp *BetweenExpression) Every(s int) *BetweenExpression {
if s < 1 {
panic("schedule: invalid step value")
}
exp.step = s
return exp
}
// Next allows retrieval of the next value from this expression.
// Expressions are stateless, the determination of their next value is based on input.
// Given a valid expression value, the parameter inc is used to specify if it should be included in the output.
// Given the last value of the expression or above, the inc parameter is ignored.
// It returns the next value according to provided parameters and a boolean indicating if it is the last value.
func (exp *BetweenExpression) Next(from int, inc bool) (int, bool) {
if from < exp.x || inc && from == exp.x {
return exp.x, false
}
if from >= exp.y {
return exp.y, true
}
diff := exp.step - (from-exp.x)%exp.step
if inc && diff == exp.step {
diff = 0
}
next := from + diff
if next >= exp.y {
return exp.y, true
}
return next, false
}
// Contains verifies if the provided value belongs to this expression.
func (exp *BetweenExpression) Contains(val int) bool {
if val < exp.x || val > exp.y {
return false
}
if val == exp.x || val == exp.y {
return true
}
return (exp.step - (val-exp.x)%exp.step) == exp.step
}