@@ -43,7 +43,9 @@ class JRPC_Message(msg, kind, json_table)
4343 # Parse the JSON-RPC message and set the kind of the message
4444 method parse_json(s)
4545 msg := s
46- if json_table := jtou(s) then {
46+ json_table := &null
47+
48+ if json_table := jtous(s) then {
4749 guess_kind()
4850 return self
4951 } else
@@ -52,11 +54,10 @@ class JRPC_Message(msg, kind, json_table)
5254
5355 # Guess the kind of the message based on the JSON-RPC message
5456 method guess_kind()
55- #if we have a method, the msg is a request
56- if \json_table["method"] then
57- kind := if \json_table["id"] then "request" else "notification"
58- else if \json_table["error"] then
57+ if \json_table["error"] then
5958 kind := "error"
59+ else if \json_table["method"] then
60+ kind := if \json_table["id"] then "request" else "notification"
6061 else if \json_table["result"] then
6162 kind := "response"
6263 else
@@ -100,38 +101,54 @@ class JRPC_Message(msg, kind, json_table)
100101 return msg
101102 end
102103
104+ method to_json()
105+ if msg := tojson(json_table) then
106+ return msg
107+ end
108+
103109 # Initialize the JSON RPC message
104110 method init_msg()
105111 /json_table := ["jsonrpc" : "2.0"]
106112 end
107113
108114 # Set the result of the JSON RPC message
109115 method set_result(result)
116+ init_msg()
110117 json_table["result"] := result
111118 end
112119 # Set the id of the JSON RPC message
113120 method set_id(id)
121+ init_msg()
114122 return json_table["id"] := id
115123 end
116124 # Set the method of the JSON RPC message
117125 method set_method(meth)
118- return json_table["method"] := meth
126+ init_msg()
127+ json_table["method"] := meth
128+ guess_kind()
129+ return meth
119130 end
120131 # Set the params of the JSON RPC message
121132 method set_params(params)
122- return json_table["params"] := params
133+ init_msg()
134+ json_table["params"] := params
135+ return params
123136 end
124137
125138 # Make a result response JSON RPC message
126139 method make_result_response(result)
140+ init_msg()
127141 delete(json_table, "method", "params", "error")
128- json_table["result"] := \result | ""
142+ # JSON-RPC 2.0: result can be null, so preserve null
143+ json_table["result"] := result
144+ guess_kind()
129145 if msg := tojson(json_table) then
130146 return self
131147 end
132148
133149 # Make a request JSON RPC message
134150 method make_request(id, meth, params)
151+ init_msg()
135152 if /json_table then
136153 json_table := [
137154 "id" : id;
@@ -144,6 +161,24 @@ class JRPC_Message(msg, kind, json_table)
144161 json_table["method"] := meth
145162 json_table["params"] := params
146163 }
164+ guess_kind()
165+ if msg := tojson(json_table) then
166+ return self
167+ end
168+
169+ method make_notification(meth, params)
170+ init_msg()
171+ if /json_table then
172+ json_table := [
173+ "method" : meth;
174+ "params" : params
175+ ]
176+ else {
177+ delete(json_table, "id", "result", "error")
178+ json_table["method"] := meth
179+ json_table["params"] := params
180+ }
181+ guess_kind()
147182 if msg := tojson(json_table) then
148183 return self
149184 end
@@ -198,12 +233,24 @@ class JRPC_Message(msg, kind, json_table)
198233
199234 # Make an error response JSON RPC message
200235 method make_error_response(err_code, err_msg, err_data)
201- delete(json_table, "method", "params", "result")
202- json_table["error"] := [
203- "code" : err_code;
204- "message" : err_msg;
205- "data" : \err_data | ""
206- ]
236+ init_msg()
237+ if /json_table then
238+ json_table := [
239+ "error" : [
240+ "code" : err_code;
241+ "message" : err_msg;
242+ "data" : \err_data | ""
243+ ]
244+ ]
245+ else {
246+ delete(json_table, "method", "params", "result")
247+ json_table["error"] := [
248+ "code" : err_code;
249+ "message" : err_msg;
250+ "data" : \err_data | ""
251+ ]
252+ }
253+ guess_kind()
207254 if msg := tojson(json_table) then
208255 return self
209256 end
@@ -229,7 +276,7 @@ class JRPC_HTTPSocket(sock)
229276 # Wait for a message to arrive, read the header
230277 # assume the min header size is 22, because the shortest jrpc
231278 # msgs will be at least 2 digits, I.e header size >=22
232- *select(sock, timeout) > 0 | fail
279+ *select(\ sock, timeout) > 0 | fail
233280 data ||:= ready(sock, size-*data)
234281 data ~== "" | fail
235282 if *data < size then next
0 commit comments