-
Notifications
You must be signed in to change notification settings - Fork 6
/
groupIterator.go
77 lines (64 loc) · 1.32 KB
/
groupIterator.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
package rrule
import (
"fmt"
"time"
)
type groupIterator struct {
currentMin *int
iters []Iterator
}
func groupIteratorFromRRules(rrules []RRule) *groupIterator {
gi := &groupIterator{}
for _, rr := range rrules {
iter := rr.Iterator()
if iter == nil {
panic(fmt.Sprintf("rrule %q produced a nil iterator", rr))
}
if iter.(*iterator).next == nil {
panic(fmt.Sprintf("rrule %q produced a faulty iterator", rr))
}
gi.iters = append(gi.iters, iter)
}
return gi
}
func (gi *groupIterator) Peek() *time.Time {
if gi.currentMin != nil {
return gi.iters[*gi.currentMin].Peek()
}
var min *time.Time
minIdx := -1
for i, iter := range gi.iters {
t := iter.Peek()
if t != nil {
if min == nil {
min = t
minIdx = i
} else {
if t.Before(*min) {
min = t
minIdx = i
} else if t.Truncate(time.Second).Equal(min.Truncate(time.Second)) {
// we equal the current minimum. we can safely
// skip this
iter.Next()
}
}
}
}
if minIdx >= 0 {
gi.currentMin = &minIdx
}
return min
}
func (gi *groupIterator) Next() *time.Time {
if gi.currentMin == nil {
gi.Peek()
}
if gi.currentMin == nil {
// still don't have a min time, so the iterators must all have ended
return nil
}
idx := *gi.currentMin
gi.currentMin = nil
return gi.iters[idx].Next()
}