| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- package iter
- import (
- "sync"
- "github.com/anacrolix/missinggo/v2"
- )
- type Iterable interface {
- Iter(Callback)
- }
- type iterator struct {
- it Iterable
- ch chan interface{}
- value interface{}
- ok bool
- mu sync.Mutex
- stopped missinggo.Event
- }
- func NewIterator(it Iterable) (ret *iterator) {
- ret = &iterator{
- it: it,
- ch: make(chan interface{}),
- }
- go func() {
- // Have to do this in a goroutine, because the interface is synchronous.
- it.Iter(func(value interface{}) bool {
- select {
- case ret.ch <- value:
- return true
- case <-ret.stopped.LockedChan(&ret.mu):
- return false
- }
- })
- close(ret.ch)
- ret.mu.Lock()
- ret.stopped.Set()
- ret.mu.Unlock()
- }()
- return
- }
- func (me *iterator) Value() interface{} {
- if !me.ok {
- panic("no value")
- }
- return me.value
- }
- func (me *iterator) Next() bool {
- me.value, me.ok = <-me.ch
- return me.ok
- }
- func (me *iterator) Stop() {
- me.mu.Lock()
- me.stopped.Set()
- me.mu.Unlock()
- }
- func IterableAsSlice(it Iterable) (ret []interface{}) {
- it.Iter(func(value interface{}) bool {
- ret = append(ret, value)
- return true
- })
- return
- }
|