every n days recurrer
This commit is contained in:
parent
bbf594f37d
commit
03252488cf
|
@ -25,20 +25,13 @@ func NewRecurrer(recurStr string) Recurrer {
|
||||||
|
|
||||||
terms = terms[1:]
|
terms = terms[1:]
|
||||||
|
|
||||||
if recur, ok := ParseDaily(start, terms); ok {
|
for _, parseFunc := range []func(Date, []string) (Recurrer, bool){
|
||||||
|
ParseDaily, ParseEveryNDays, ParseWeekly, ParseBiweekly,
|
||||||
|
ParseEveryNWeeks, ParseEveryNMonths,
|
||||||
|
} {
|
||||||
|
if recur, ok := parseFunc(start, terms); ok {
|
||||||
return recur
|
return recur
|
||||||
}
|
}
|
||||||
if recur, ok := ParseWeekly(start, terms); ok {
|
|
||||||
return recur
|
|
||||||
}
|
|
||||||
if recur, ok := ParseBiweekly(start, terms); ok {
|
|
||||||
return recur
|
|
||||||
}
|
|
||||||
if recur, ok := ParseEveryNWeeks(start, terms); ok {
|
|
||||||
return recur
|
|
||||||
}
|
|
||||||
if recur, ok := ParseEveryNMonths(start, terms); ok {
|
|
||||||
return recur
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -48,6 +41,7 @@ type Daily struct {
|
||||||
Start Date
|
Start Date
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// yyyy-mm-dd, daily
|
||||||
func ParseDaily(start Date, terms []string) (Recurrer, bool) {
|
func ParseDaily(start Date, terms []string) (Recurrer, bool) {
|
||||||
if len(terms) < 1 {
|
if len(terms) < 1 {
|
||||||
return nil, false
|
return nil, false
|
||||||
|
@ -70,6 +64,55 @@ func (d Daily) String() string {
|
||||||
return fmt.Sprintf("%s, daily", d.Start.String())
|
return fmt.Sprintf("%s, daily", d.Start.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EveryNDays struct {
|
||||||
|
Start Date
|
||||||
|
N int
|
||||||
|
}
|
||||||
|
|
||||||
|
// yyyy-mm-dd, every 3 days
|
||||||
|
func ParseEveryNDays(start Date, terms []string) (Recurrer, bool) {
|
||||||
|
if len(terms) != 1 {
|
||||||
|
return EveryNDays{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
terms = strings.Split(terms[0], " ")
|
||||||
|
if len(terms) != 3 || terms[0] != "every" || terms[2] != "days" {
|
||||||
|
return EveryNDays{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
n, err := strconv.Atoi(terms[1])
|
||||||
|
if err != nil {
|
||||||
|
return EveryNDays{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return EveryNDays{
|
||||||
|
Start: start,
|
||||||
|
N: n,
|
||||||
|
}, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nd EveryNDays) RecursOn(date Date) bool {
|
||||||
|
if nd.Start.After(date) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
testDate := nd.Start
|
||||||
|
for {
|
||||||
|
switch {
|
||||||
|
case testDate.Equal(date):
|
||||||
|
return true
|
||||||
|
case testDate.After(date):
|
||||||
|
return false
|
||||||
|
default:
|
||||||
|
testDate = testDate.Add(nd.N)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (nd EveryNDays) String() string {
|
||||||
|
return fmt.Sprintf("%s, every %d days", nd.Start.String(), nd.N)
|
||||||
|
}
|
||||||
|
|
||||||
type Weekly struct {
|
type Weekly struct {
|
||||||
Start Date
|
Start Date
|
||||||
Weekdays Weekdays
|
Weekdays Weekdays
|
||||||
|
|
|
@ -50,6 +50,53 @@ func TestDaily(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEveryNDays(t *testing.T) {
|
||||||
|
every := task.EveryNDays{
|
||||||
|
Start: task.NewDate(2022, 6, 8),
|
||||||
|
N: 5,
|
||||||
|
}
|
||||||
|
everyStr := "2022-06-08 (wednesday), every 5 days"
|
||||||
|
|
||||||
|
t.Run("parse", func(t *testing.T) {
|
||||||
|
test.Equals(t, every, task.NewRecurrer(everyStr))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("string", func(t *testing.T) {
|
||||||
|
test.Equals(t, everyStr, every.String())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("recurs on", func(t *testing.T) {
|
||||||
|
for _, tc := range []struct {
|
||||||
|
name string
|
||||||
|
date task.Date
|
||||||
|
exp bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "before",
|
||||||
|
date: task.NewDate(2022, 1, 1),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "start",
|
||||||
|
date: every.Start,
|
||||||
|
exp: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "after true",
|
||||||
|
date: every.Start.Add(15),
|
||||||
|
exp: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "after false",
|
||||||
|
date: every.Start.Add(16),
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
test.Equals(t, tc.exp, every.RecursOn(tc.date))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestParseWeekly(t *testing.T) {
|
func TestParseWeekly(t *testing.T) {
|
||||||
start := task.NewDate(2021, 2, 7)
|
start := task.NewDate(2021, 2, 7)
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
|
|
Loading…
Reference in New Issue