github.com/nevalang/neva@v0.23.1-0.20240507185603-7696a9bb8dda/internal/runtime/funcs/index.go (about)

     1  package funcs
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/nevalang/neva/internal/runtime"
     7  )
     8  
     9  type index struct{}
    10  
    11  func (p index) Create(io runtime.FuncIO, _ runtime.Msg) (func(ctx context.Context), error) {
    12  	listIn, err := io.In.Port("data")
    13  	if err != nil {
    14  		return nil, err
    15  	}
    16  
    17  	indexIn, err := io.In.Port("idx")
    18  	if err != nil {
    19  		return nil, err
    20  	}
    21  
    22  	resOut, err := io.Out.Port("res")
    23  	if err != nil {
    24  		return nil, err
    25  	}
    26  
    27  	errOut, err := io.Out.Port("err")
    28  	if err != nil {
    29  		return nil, err
    30  	}
    31  
    32  	return func(ctx context.Context) {
    33  		var listMsg, idxMsg runtime.Msg
    34  
    35  		for {
    36  			select {
    37  			case <-ctx.Done():
    38  				return
    39  			case listMsg = <-listIn:
    40  			}
    41  
    42  			select {
    43  			case <-ctx.Done():
    44  				return
    45  			case idxMsg = <-indexIn:
    46  			}
    47  
    48  			idx := idxMsg.Int()
    49  			list := listMsg.List()
    50  
    51  			if idx < 0 || idx >= int64(len(list)) {
    52  				select {
    53  				case <-ctx.Done():
    54  					return
    55  				case errOut <- runtime.NewStrMsg("Index out of bounds"):
    56  					continue
    57  				}
    58  			}
    59  
    60  			select {
    61  			case <-ctx.Done():
    62  				return
    63  			case resOut <- list[idx]:
    64  			}
    65  		}
    66  	}, nil
    67  }