github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/core/interop/iterator/interop.go (about)

     1  package iterator
     2  
     3  import (
     4  	"github.com/nspcc-dev/neo-go/pkg/core/interop"
     5  	"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
     6  )
     7  
     8  type iterator interface {
     9  	Next() bool
    10  	Value() stackitem.Item
    11  }
    12  
    13  // Next advances the iterator, pushes true on success and false otherwise.
    14  func Next(ic *interop.Context) error {
    15  	iop := ic.VM.Estack().Pop().Interop()
    16  	arr := iop.Value().(iterator)
    17  	ic.VM.Estack().PushItem(stackitem.Bool(arr.Next()))
    18  
    19  	return nil
    20  }
    21  
    22  // Value returns current iterator value and depends on iterator type:
    23  // For slices the result is just value.
    24  // For maps the result is key-value pair packed in a struct.
    25  func Value(ic *interop.Context) error {
    26  	iop := ic.VM.Estack().Pop().Interop()
    27  	arr := iop.Value().(iterator)
    28  	ic.VM.Estack().PushItem(arr.Value())
    29  
    30  	return nil
    31  }
    32  
    33  // IsIterator returns whether stackitem implements iterator interface.
    34  func IsIterator(item stackitem.Item) bool {
    35  	_, ok := item.Value().(iterator)
    36  	return ok
    37  }
    38  
    39  // ValuesTruncated returns an array of up to `max` iterator values. The second
    40  // return parameter denotes whether iterator is truncated, i.e. has more values.
    41  // The provided iterator CAN NOT be reused in the subsequent calls to Values and
    42  // to ValuesTruncated.
    43  func ValuesTruncated(item stackitem.Item, max int) ([]stackitem.Item, bool) {
    44  	result := Values(item, max)
    45  	arr := item.Value().(iterator)
    46  	return result, arr.Next()
    47  }
    48  
    49  // Values returns an array of up to `max` iterator values. The provided
    50  // iterator can safely be reused to retrieve the rest of its values in the
    51  // subsequent calls to Values and to ValuesTruncated.
    52  func Values(item stackitem.Item, max int) []stackitem.Item {
    53  	var result []stackitem.Item
    54  	arr := item.Value().(iterator)
    55  	for max > 0 && arr.Next() {
    56  		result = append(result, arr.Value())
    57  		max--
    58  	}
    59  	return result
    60  }