github.com/MontFerret/ferret@v0.18.0/pkg/runtime/collections/helpers.go (about) 1 package collections 2 3 import ( 4 "context" 5 6 "github.com/MontFerret/ferret/pkg/runtime/core" 7 ) 8 9 type ( 10 IterableFn struct { 11 fn func(ctx context.Context, scope *core.Scope) (Iterator, error) 12 } 13 14 IteratorFn struct { 15 fn func(ctx context.Context, scope *core.Scope) (*core.Scope, error) 16 } 17 ) 18 19 func AsIterable(fn func(ctx context.Context, scope *core.Scope) (Iterator, error)) Iterable { 20 return &IterableFn{fn} 21 } 22 23 func (i *IterableFn) Iterate(ctx context.Context, scope *core.Scope) (Iterator, error) { 24 return i.fn(ctx, scope) 25 } 26 27 func AsIterator(fn func(ctx context.Context, scope *core.Scope) (*core.Scope, error)) Iterator { 28 return &IteratorFn{fn} 29 } 30 31 func (i *IteratorFn) Next(ctx context.Context, scope *core.Scope) (*core.Scope, error) { 32 return i.fn(ctx, scope) 33 } 34 35 func ToSlice(ctx context.Context, scope *core.Scope, iterator Iterator) ([]*core.Scope, error) { 36 res := make([]*core.Scope, 0, 10) 37 38 for { 39 nextScope, err := iterator.Next(ctx, scope.Fork()) 40 41 if err != nil { 42 if core.IsNoMoreData(err) { 43 return res, nil 44 } 45 46 return nil, err 47 } 48 49 res = append(res, nextScope) 50 } 51 } 52 53 func ForEach(ctx context.Context, scope *core.Scope, iter Iterator, predicate func(ctx context.Context, scope *core.Scope) bool) error { 54 for { 55 nextScope, err := iter.Next(ctx, scope) 56 57 if err != nil { 58 if core.IsNoMoreData(err) { 59 return nil 60 } 61 62 return err 63 } 64 65 if !predicate(ctx, nextScope) { 66 return nil 67 } 68 } 69 }