github.com/nevalang/neva@v0.23.1-0.20240507185603-7696a9bb8dda/internal/runtime/funcs/regexp_submatch.go (about) 1 package funcs 2 3 import ( 4 "context" 5 "regexp" 6 7 "github.com/nevalang/neva/internal/runtime" 8 ) 9 10 type regexpSubmatch struct{} 11 12 func (r regexpSubmatch) Create(io runtime.FuncIO, cfgMsg runtime.Msg) (func(ctx context.Context), error) { 13 regexpIn, err := io.In.Port("regexp") 14 if err != nil { 15 return nil, err 16 } 17 18 dataIn, err := io.In.Port("data") 19 if err != nil { 20 return nil, err 21 } 22 23 resOut, err := io.Out.Port("res") 24 if err != nil { 25 return nil, err 26 } 27 28 errOut, err := io.Out.Port("err") 29 if err != nil { 30 return nil, err 31 } 32 33 return func(ctx context.Context) { 34 var ( 35 regexpMsg runtime.Msg 36 dataMsg runtime.Msg 37 ) 38 39 for { 40 select { 41 case <-ctx.Done(): 42 return 43 case regexpMsg = <-regexpIn: 44 } 45 46 regex, err := regexp.Compile(regexpMsg.Str()) 47 if err != nil { 48 select { 49 case <-ctx.Done(): 50 return 51 case errOut <- runtime.NewStrMsg(err.Error()): 52 continue 53 } 54 } 55 56 select { 57 case <-ctx.Done(): 58 return 59 case dataMsg = <-dataIn: 60 } 61 62 res := regex.FindStringSubmatch(dataMsg.String()) 63 64 select { 65 case <-ctx.Done(): 66 case resOut <- wrap(res): 67 } 68 } 69 }, nil 70 } 71 72 func wrap(ss []string) runtime.Msg { 73 msgs := make([]runtime.Msg, 0, len(ss)) 74 for _, s := range ss { 75 msgs = append(msgs, runtime.NewStrMsg(s)) 76 } 77 return runtime.NewListMsg(msgs...) 78 }