github.com/nevalang/neva@v0.23.1-0.20240507185603-7696a9bb8dda/internal/runtime/program.go (about) 1 package runtime 2 3 import ( 4 "errors" 5 "fmt" 6 ) 7 8 type Program struct { 9 Ports Ports 10 Connections []Connection 11 Funcs []FuncCall 12 } 13 14 type PortAddr struct { 15 Path string // Path is needed to distinguish ports with the same name 16 Port string // Separate port field is needed for functions 17 Idx uint8 18 } 19 20 func (p PortAddr) String() string { 21 return fmt.Sprintf("%v:%v[%v]", p.Path, p.Port, p.Idx) 22 } 23 24 type Ports map[PortAddr]chan Msg 25 26 type Connection struct { 27 Sender chan Msg 28 Receivers []chan Msg 29 Meta ConnectionMeta 30 } 31 32 type ConnectionMeta struct { 33 SenderPortAddr PortAddr 34 ReceiverPortAddrs []PortAddr 35 } 36 37 type FuncCall struct { 38 Ref string 39 IO FuncIO 40 ConfigMsg Msg 41 } 42 43 type FuncIO struct { 44 In, Out FuncPorts 45 } 46 47 // FuncPorts is data structure that runtime functions must use at startup to get needed ports. 48 // Its methods can return error because it's okay to fail at startup. Keys are port names and values are slots. 49 type FuncPorts map[string][]chan Msg 50 51 var ErrSinglePortCount = errors.New("number of ports found by name not equals to one") 52 53 // Port returns first slot of port found by the given name. 54 // It returns error if port is not found or if it's not a single port. 55 func (f FuncPorts) Port(name string) (chan Msg, error) { 56 slots, ok := f[name] 57 if !ok { 58 return nil, fmt.Errorf("port '%v' not found", name) 59 } 60 61 if len(slots) != 1 { 62 return nil, fmt.Errorf("%w: %v", ErrSinglePortCount, len(f[name])) 63 } 64 65 return slots[0], nil 66 }