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 }