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

     1  package funcs
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  
     7  	"github.com/nevalang/neva/internal/runtime"
     8  )
     9  
    10  type intMod struct{}
    11  
    12  func (intMod) Create(io runtime.FuncIO, _ runtime.Msg) (func(ctx context.Context), error) {
    13  	dataIn, err := io.In.Port("data")
    14  	if err != nil {
    15  		return nil, err
    16  	}
    17  
    18  	caseIn, ok := io.In["case"]
    19  	if !ok {
    20  		return nil, errors.New("port 'case' is required")
    21  	}
    22  
    23  	caseOut, ok := io.Out["case"]
    24  	if !ok {
    25  		return nil, errors.New("port 'then' is required")
    26  	}
    27  
    28  	elseOut, err := io.Out.Port("else")
    29  	if err != nil {
    30  		return nil, err
    31  	}
    32  
    33  	if len(caseIn) != len(caseOut) {
    34  		return nil, errors.New("number of 'case' inports must match number of 'then' outports")
    35  	}
    36  
    37  	return func(ctx context.Context) {
    38  		var data runtime.Msg
    39  
    40  		for {
    41  			select {
    42  			case <-ctx.Done():
    43  				return
    44  			case data = <-dataIn:
    45  			}
    46  
    47  			cases := make([]runtime.Msg, len(caseIn))
    48  			for i, slot := range caseIn {
    49  				select {
    50  				case <-ctx.Done():
    51  					return
    52  				case caseMsg := <-slot:
    53  					cases[i] = caseMsg
    54  				}
    55  			}
    56  
    57  			matchIdx := -1
    58  			dataInt := data.Int()
    59  			for i, caseMsg := range cases {
    60  				if dataInt%caseMsg.Int() == 0 {
    61  					matchIdx = i
    62  					break
    63  				}
    64  			}
    65  
    66  			if matchIdx != -1 {
    67  				select {
    68  				case <-ctx.Done():
    69  					return
    70  				case caseOut[matchIdx] <- data:
    71  					continue
    72  				}
    73  			}
    74  
    75  			select {
    76  			case <-ctx.Done():
    77  				return
    78  			case elseOut <- data:
    79  			}
    80  		}
    81  	}, nil
    82  }