-
Notifications
You must be signed in to change notification settings - Fork 1
/
chain.go
45 lines (39 loc) · 1.33 KB
/
chain.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
package itertools
import (
optionext "github.com/go-playground/pkg/v5/values/option"
)
// Chain creates a new `chainIterator[T]` for use.
func Chain[T any, FI Iterator[T], SI Iterator[T]](first FI, second SI) *chainIterator[T, FI, SI, struct{}] {
return ChainWithMap[T, FI, SI, struct{}](first, second)
}
// ChainWithMap creates a new `chainIterator[T]` for use and parameter to specify a Map type for the `Iterate.Map` helper
// function.
func ChainWithMap[T any, FI Iterator[T], SI Iterator[T], MAP any](first FI, second SI) *chainIterator[T, FI, SI, MAP] {
return &chainIterator[T, FI, SI, MAP]{
current: first,
next: second,
}
}
// chainIterator takes two iterators and creates a new iterator over both in sequence.
type chainIterator[T any, FI Iterator[T], SI Iterator[T], MAP any] struct {
current FI
next SI
flipped bool
}
// Next returns the next value from the first iterator until exhausted and then the second.
func (i *chainIterator[T, FI, SI, MAP]) Next() optionext.Option[T] {
for {
if i.flipped {
return i.next.Next()
}
v := i.current.Next()
if v.IsSome() {
return v
}
i.flipped = true
}
}
// Iter is a convenience function that converts the chainIterator iterator into an `*Iterate[T]`.
func (i *chainIterator[T, FI, SI, MAP]) Iter() Iterate[T, Iterator[T], MAP] {
return IterMap[T, Iterator[T], MAP](i)
}