github.com/nevalang/neva@v0.23.1-0.20240507185603-7696a9bb8dda/internal/runtime/msg.go (about) 1 package runtime 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strconv" 7 "strings" 8 ) 9 10 // Msg methods don't return errors because they can be used not only at startup. 11 // If runtime functions need to validate message at startup, they must do it by themselves. 12 type Msg interface { 13 fmt.Stringer 14 Type() MsgType 15 Bool() bool 16 Int() int64 17 Float() float64 18 Str() string 19 List() []Msg 20 Map() map[string]Msg 21 } 22 23 type MsgType uint8 24 25 const ( 26 UnknownMsgType MsgType = 0 27 BoolMsgType MsgType = 1 28 IntMsgType MsgType = 2 29 FloatMsgType MsgType = 3 30 StrMsgType MsgType = 4 31 ListMsgType MsgType = 5 32 MapMsgType MsgType = 6 33 ) 34 35 // Empty 36 37 type emptyMsg struct{} 38 39 func (emptyMsg) String() string { return "<empty>" } 40 func (emptyMsg) Type() MsgType { return UnknownMsgType } 41 func (emptyMsg) Bool() bool { return false } 42 func (emptyMsg) Int() int64 { return 0 } 43 func (emptyMsg) Float() float64 { return 0 } 44 func (emptyMsg) Str() string { return "" } 45 func (emptyMsg) List() []Msg { return nil } 46 func (emptyMsg) Map() map[string]Msg { return nil } 47 48 // Int 49 50 type IntMsg struct { 51 emptyMsg 52 v int64 53 } 54 55 func (msg IntMsg) Type() MsgType { return IntMsgType } 56 func (msg IntMsg) Int() int64 { return msg.v } 57 func (msg IntMsg) String() string { return strconv.Itoa(int(msg.v)) } 58 func (msg IntMsg) MarshalJSON() ([]byte, error) { return []byte(msg.String()), nil } 59 60 func NewIntMsg(n int64) IntMsg { 61 return IntMsg{ 62 emptyMsg: emptyMsg{}, 63 v: n, 64 } 65 } 66 67 // Float 68 69 type FloatMsg struct { 70 emptyMsg 71 v float64 72 } 73 74 func (msg FloatMsg) Type() MsgType { return FloatMsgType } 75 func (msg FloatMsg) Float() float64 { return msg.v } 76 func (msg FloatMsg) String() string { return fmt.Sprint(msg.v) } 77 func (msg FloatMsg) MarshalJSON() ([]byte, error) { return []byte(msg.String()), nil } 78 79 func NewFloatMsg(n float64) FloatMsg { 80 return FloatMsg{ 81 emptyMsg: emptyMsg{}, 82 v: n, 83 } 84 } 85 86 // Str 87 88 type StrMsg struct { 89 emptyMsg 90 v string 91 } 92 93 func (msg StrMsg) Type() MsgType { return StrMsgType } 94 func (msg StrMsg) Str() string { return msg.v } 95 func (msg StrMsg) String() string { return msg.v } 96 func (msg StrMsg) MarshalJSON() ([]byte, error) { 97 // Escape special characters in the string before marshaling 98 jsonString, err := json.Marshal(msg.String()) 99 if err != nil { 100 return nil, err 101 } 102 return jsonString, nil 103 } 104 105 func NewStrMsg(s string) StrMsg { 106 return StrMsg{ 107 emptyMsg: emptyMsg{}, 108 v: s, 109 } 110 } 111 112 // Bool 113 114 type BoolMsg struct { 115 emptyMsg 116 v bool 117 } 118 119 func (msg BoolMsg) Type() MsgType { return BoolMsgType } 120 func (msg BoolMsg) Bool() bool { return msg.v } 121 func (msg BoolMsg) String() string { return strconv.FormatBool(msg.v) } 122 func (msg BoolMsg) MarshalJSON() ([]byte, error) { return []byte(msg.String()), nil } 123 124 func NewBoolMsg(b bool) BoolMsg { 125 return BoolMsg{ 126 emptyMsg: emptyMsg{}, 127 v: b, 128 } 129 } 130 131 // List 132 type ListMsg struct { 133 emptyMsg 134 v []Msg 135 } 136 137 func (msg ListMsg) Type() MsgType { return ListMsgType } 138 func (msg ListMsg) List() []Msg { return msg.v } 139 func (msg ListMsg) String() string { 140 bb, err := msg.MarshalJSON() 141 if err != nil { 142 panic(err) 143 } 144 return string(bb) 145 } 146 func (msg ListMsg) MarshalJSON() ([]byte, error) { return json.Marshal(msg.v) } 147 148 func NewListMsg(v ...Msg) ListMsg { 149 return ListMsg{ 150 emptyMsg: emptyMsg{}, 151 v: v, 152 } 153 } 154 155 // Map 156 type MapMsg struct { 157 emptyMsg 158 v map[string]Msg 159 } 160 161 func (msg MapMsg) Type() MsgType { return MapMsgType } 162 func (msg MapMsg) Map() map[string]Msg { return msg.v } 163 func (msg MapMsg) MarshalJSON() ([]byte, error) { 164 jsonData, err := json.Marshal(msg.v) 165 if err != nil { 166 panic(err) 167 } 168 169 jsonString := string(jsonData) 170 jsonString = strings.ReplaceAll(jsonString, ":", ": ") 171 jsonString = strings.ReplaceAll(jsonString, ",", ", ") 172 173 return []byte(jsonString), nil 174 } 175 func (msg MapMsg) String() string { 176 b, err := msg.MarshalJSON() 177 if err != nil { 178 panic(err) 179 } 180 return string(b) 181 } 182 183 func NewMapMsg(m map[string]Msg) MapMsg { 184 return MapMsg{ 185 emptyMsg: emptyMsg{}, 186 v: m, 187 } 188 }