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 }