github.com/haraldrudell/parl@v0.4.176/iters/simple.go (about) 1 /* 2 © 2023–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 package iters 7 8 import ( 9 "github.com/haraldrudell/parl/internal/cyclebreaker" 10 ) 11 12 // Converter traverses another iterator and returns converted values 13 type Simple[K any, V any] struct { 14 // keyIterator provides the key values converterFunction uses to 15 // return values 16 keyIterator Iterator[K] 17 simpleConverter func(key K) (value V) 18 // BaseIterator implements Cancel and the DelegateAction[T] function required by 19 // Delegator[T] 20 // - receives invokeConverterFunction function 21 // - provides delegateAction function 22 BaseIterator[V] 23 } 24 25 // NewConverterIterator returns a converting iterator. 26 // - converterFunction receives cancel and can return error 27 // - ConverterIterator is thread-safe and re-entrant. 28 // - stores self-referencing pointers 29 func NewSimpleConverterIterator[K any, V any]( 30 keyIterator Iterator[K], 31 simpleConverter SimpleConverter[K, V], 32 asyncCancel ...func(), 33 ) (iterator Iterator[V]) { 34 if simpleConverter == nil { 35 panic(cyclebreaker.NilError("simpleConverter")) 36 } else if keyIterator == nil { 37 panic(cyclebreaker.NilError("keyIterator")) 38 } 39 40 c := Simple[K, V]{ 41 keyIterator: keyIterator, 42 simpleConverter: simpleConverter, 43 } 44 c.BaseIterator = *NewBaseIterator(c.iteratorAction, asyncCancel...) 45 46 return &c 47 } 48 49 // Init implements the right-hand side of a short variable declaration in 50 // the init statement for a Go “for” clause 51 // 52 // Usage: 53 // 54 // for i, iterator := NewSlicePointerIterator(someSlice).Init(); iterator.Cond(&i); { 55 // // i is pointer to slice element 56 func (i *Simple[K, T]) Init() (iterationVariable T, iterator Iterator[T]) { 57 iterator = i 58 return 59 } 60 61 // iteratorAction invokes converterFunction recovering a possible panic 62 // - if cancelState == notCanceled, a new value is requested. 63 // Otherwise, iteration cancel is requested 64 // - if err is nil, value is valid and isPanic false. 65 // Otherwise, err is non-nil and isPanic may be set. 66 // value is zero-value 67 func (i *Simple[K, T]) iteratorAction(isCancel bool) (value T, err error) { 68 if isCancel { 69 return 70 } 71 // get next key from keyIterator 72 var key K 73 var hasKey bool 74 if key, hasKey = i.keyIterator.Next(); !hasKey { 75 err = cyclebreaker.ErrEndCallbacks 76 return 77 } 78 value = i.simpleConverter(key) 79 80 return 81 }