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

     1  package funcs
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  
     7  	"github.com/nevalang/neva/internal/runtime"
     8  )
     9  
    10  type structBuilder struct{}
    11  
    12  func (s structBuilder) Create(io runtime.FuncIO, _ runtime.Msg) (func(ctx context.Context), error) {
    13  	if len(io.In) == 0 {
    14  		return nil, errors.New("cannot create struct builder without inports")
    15  	}
    16  
    17  	inports := make(map[string]chan runtime.Msg, len(io.In))
    18  	for inportName, inportSlots := range io.In {
    19  		if len(inportSlots) != 1 {
    20  			return nil, errors.New("non-single port found: " + inportName)
    21  		}
    22  		inports[inportName] = inportSlots[0]
    23  	}
    24  
    25  	outport, err := io.Out.Port("msg")
    26  	if err != nil {
    27  		return nil, err
    28  	}
    29  
    30  	return s.Handle(inports, outport), nil
    31  }
    32  
    33  func (structBuilder) Handle(
    34  	inports map[string]chan runtime.Msg,
    35  	outport chan runtime.Msg,
    36  ) func(ctx context.Context) {
    37  	return func(ctx context.Context) {
    38  		var structure = make(map[string]runtime.Msg, len(inports))
    39  
    40  		for {
    41  			for inportName, inportChan := range inports {
    42  				select {
    43  				case <-ctx.Done():
    44  					return
    45  				case msg := <-inportChan:
    46  					structure[inportName] = msg
    47  				}
    48  			}
    49  
    50  			select {
    51  			case <-ctx.Done():
    52  				return
    53  			case outport <- runtime.NewMapMsg(structure):
    54  			}
    55  		}
    56  	}
    57  }