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

     1  package funcs
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  
     7  	"github.com/nevalang/neva/internal/runtime"
     8  )
     9  
    10  type readStructField struct{}
    11  
    12  func (s readStructField) Create(io runtime.FuncIO, fieldPathMsg runtime.Msg) (func(ctx context.Context), error) {
    13  	fieldPath := fieldPathMsg.List()
    14  	if len(fieldPath) == 0 {
    15  		return nil, errors.New("field path cannot be empty")
    16  	}
    17  
    18  	pathStrings := make([]string, 0, len(fieldPath))
    19  	for _, el := range fieldPath {
    20  		pathStrings = append(pathStrings, el.Str())
    21  	}
    22  
    23  	msgIn, err := io.In.Port("msg")
    24  	if err != nil {
    25  		return nil, err
    26  	}
    27  
    28  	msgOut, err := io.Out.Port("msg")
    29  	if err != nil {
    30  		return nil, err
    31  	}
    32  
    33  	return func(ctx context.Context) {
    34  		var msg runtime.Msg
    35  
    36  		for {
    37  			select {
    38  			case <-ctx.Done():
    39  				return
    40  			case msg = <-msgIn:
    41  			}
    42  
    43  			select {
    44  			case <-ctx.Done():
    45  				return
    46  			case msgOut <- s.mapLookup(msg, pathStrings):
    47  			}
    48  		}
    49  	}, nil
    50  }
    51  
    52  func (readStructField) mapLookup(m runtime.Msg, path []string) runtime.Msg {
    53  	for len(path) > 0 {
    54  		m = m.Map()[path[0]]
    55  		path = path[1:]
    56  	}
    57  	return m
    58  }