github.com/MontFerret/ferret@v0.18.0/pkg/runtime/collections/indexed.go (about)

     1  package collections
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/MontFerret/ferret/pkg/runtime/core"
     7  	"github.com/MontFerret/ferret/pkg/runtime/values"
     8  )
     9  
    10  const (
    11  	DefaultValueVar = "value"
    12  	DefaultKeyVar   = "key"
    13  )
    14  
    15  type IndexedIterator struct {
    16  	valVar string
    17  	keyVar string
    18  	values IndexedCollection
    19  	pos    int
    20  }
    21  
    22  func NewIndexedIterator(
    23  	valVar,
    24  	keyVar string,
    25  	values IndexedCollection,
    26  ) (Iterator, error) {
    27  	if valVar == "" {
    28  		return nil, core.Error(core.ErrMissedArgument, "value variable")
    29  	}
    30  
    31  	if values == nil {
    32  		return nil, core.Error(core.ErrMissedArgument, "result")
    33  	}
    34  
    35  	return &IndexedIterator{valVar, keyVar, values, 0}, nil
    36  }
    37  
    38  func NewDefaultIndexedIterator(
    39  	values IndexedCollection,
    40  ) (Iterator, error) {
    41  	return NewIndexedIterator(DefaultValueVar, DefaultKeyVar, values)
    42  }
    43  
    44  func (iterator *IndexedIterator) Next(_ context.Context, scope *core.Scope) (*core.Scope, error) {
    45  	if int(iterator.values.Length()) > iterator.pos {
    46  		idx := values.NewInt(iterator.pos)
    47  		val := iterator.values.Get(idx)
    48  
    49  		iterator.pos++
    50  
    51  		nextScope := scope.Fork()
    52  
    53  		if err := nextScope.SetVariable(iterator.valVar, val); err != nil {
    54  			return nil, err
    55  		}
    56  
    57  		if iterator.keyVar != "" {
    58  			if err := nextScope.SetVariable(iterator.keyVar, idx); err != nil {
    59  				return nil, err
    60  			}
    61  		}
    62  
    63  		return nextScope, nil
    64  	}
    65  
    66  	return nil, core.ErrNoMoreData
    67  }