github.com/MontFerret/ferret@v0.18.0/pkg/runtime/expressions/for_in.go (about) 1 package expressions 2 3 import ( 4 "context" 5 6 "github.com/MontFerret/ferret/pkg/runtime/collections" 7 "github.com/MontFerret/ferret/pkg/runtime/core" 8 "github.com/MontFerret/ferret/pkg/runtime/values/types" 9 ) 10 11 type ForInIterableExpression struct { 12 src core.SourceMap 13 valVariable string 14 keyVariable string 15 exp core.Expression 16 } 17 18 func NewForInIterableExpression( 19 src core.SourceMap, 20 valVariable, 21 keyVariable string, 22 exp core.Expression, 23 ) (collections.Iterable, error) { 24 if exp == nil { 25 return nil, core.Error(core.ErrMissedArgument, "expression") 26 } 27 28 return &ForInIterableExpression{ 29 src, 30 valVariable, 31 keyVariable, 32 exp, 33 }, nil 34 } 35 36 func (iterable *ForInIterableExpression) Iterate(ctx context.Context, scope *core.Scope) (collections.Iterator, error) { 37 select { 38 case <-ctx.Done(): 39 return nil, core.ErrTerminated 40 default: 41 data, err := iterable.exp.Exec(ctx, scope) 42 43 if err != nil { 44 return nil, core.SourceError(iterable.src, err) 45 } 46 47 switch data.Type() { 48 case types.Array: 49 return collections.NewIndexedIterator(iterable.valVariable, iterable.keyVariable, data.(collections.IndexedCollection)) 50 case types.Object: 51 return collections.NewKeyedIterator(iterable.valVariable, iterable.keyVariable, data.(collections.KeyedCollection)) 52 default: 53 // fallback to user defined types 54 switch collection := data.(type) { 55 case core.Iterable: 56 iterator, err := collection.Iterate(ctx) 57 58 if err != nil { 59 return nil, err 60 } 61 62 return collections.FromCoreIterator(iterable.valVariable, iterable.keyVariable, iterator) 63 case collections.KeyedCollection: 64 return collections.NewKeyedIterator(iterable.valVariable, iterable.keyVariable, collection) 65 case collections.IndexedCollection: 66 return collections.NewIndexedIterator(iterable.valVariable, iterable.keyVariable, collection) 67 default: 68 return nil, core.TypeError( 69 data.Type(), 70 types.Array, 71 types.Object, 72 core.NewType("Iterable"), 73 ) 74 } 75 } 76 } 77 }