github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/rpcclient/nns/iterators.go (about)

     1  package nns
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/google/uuid"
     8  	"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
     9  	"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
    10  )
    11  
    12  // RecordIterator is used for iterating over GetAllRecords results.
    13  type RecordIterator struct {
    14  	client   Invoker
    15  	session  uuid.UUID
    16  	iterator result.Iterator
    17  }
    18  
    19  // RootIterator is used for iterating over Roots results.
    20  type RootIterator struct {
    21  	client   Invoker
    22  	session  uuid.UUID
    23  	iterator result.Iterator
    24  }
    25  
    26  func itemsToRecords(arr []stackitem.Item) ([]RecordState, error) {
    27  	res := make([]RecordState, len(arr))
    28  	for i := range arr {
    29  		err := res[i].FromStackItem(arr[i])
    30  		if err != nil {
    31  			return nil, fmt.Errorf("item #%d: %w", i, err)
    32  		}
    33  	}
    34  	return res, nil
    35  }
    36  
    37  func itemsToRoots(arr []stackitem.Item) ([]string, error) {
    38  	res := make([]string, len(arr))
    39  	for i := range arr {
    40  		rs, ok := arr[i].Value().([]stackitem.Item)
    41  		if !ok {
    42  			return nil, errors.New("wrong number of elements")
    43  		}
    44  		myval, _ := rs[0].TryBytes()
    45  		res[i] = string(myval)
    46  	}
    47  	return res, nil
    48  }
    49  
    50  // Next returns the next set of elements from the iterator (up to num of them).
    51  // It can return less than num elements in case iterator doesn't have that many
    52  // or zero elements if the iterator has no more elements or the session is
    53  // expired.
    54  func (r *RecordIterator) Next(num int) ([]RecordState, error) {
    55  	items, err := r.client.TraverseIterator(r.session, &r.iterator, num)
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  	return itemsToRecords(items)
    60  }
    61  
    62  // Next returns the next set of elements from the iterator (up to num of them).
    63  // It can return less than num elements in case iterator doesn't have that many
    64  // or zero elements if the iterator has no more elements or the session is
    65  // expired.
    66  func (r *RootIterator) Next(num int) ([]string, error) {
    67  	items, err := r.client.TraverseIterator(r.session, &r.iterator, num)
    68  	if err != nil {
    69  		return nil, err
    70  	}
    71  	return itemsToRoots(items)
    72  }
    73  
    74  // Terminate closes the iterator session used by RecordIterator (if it's
    75  // session-based).
    76  func (r *RecordIterator) Terminate() error {
    77  	if r.iterator.ID == nil {
    78  		return nil
    79  	}
    80  	return r.client.TerminateSession(r.session)
    81  }
    82  
    83  // Terminate closes the iterator session used by RootIterator (if it's
    84  // session-based).
    85  func (r *RootIterator) Terminate() error {
    86  	if r.iterator.ID == nil {
    87  		return nil
    88  	}
    89  	return r.client.TerminateSession(r.session)
    90  }