$darkmode
message.hpp
1 #pragma once
2 
3 #include "picojson.h"
4 #include "lrdb/optional.hpp"
5 
6 namespace lrdb {
7 namespace json {
8 using namespace ::picojson;
9 }
10 
11 namespace message {
12 
14  request_message() {}
15  request_message(std::string id, std::string method,
16  json::value params = json::value())
17  : id(std::move(id)),
18  method(std::move(method)),
19  params(std::move(params)) {}
20  request_message(int id, std::string method,
21  json::value params = json::value())
22  : id(double(id)), method(std::move(method)), params(std::move(params)) {}
23  json::value id;
24  std::string method;
25  json::value params;
26 };
27 
29  int code;
30  std::string message;
31  json::value data;
32 
33  response_error(int code, std::string message)
34  : code(code), message(std::move(message)) {}
35 
36  enum error_code {
37  ParseError = -32700,
38  InvalidRequest = -32600,
39  MethodNotFound = -32601,
40  InvalidParams = -32602,
41  InternalError = -32603,
42  serverErrorStart = -32099,
43  serverErrorEnd = -32000,
44  ServerNotInitialized,
45  UnknownErrorCode = -32001
46  };
47 };
48 
50  response_message() {}
51  response_message(std::string id, json::value result = json::value())
52  : id(std::move(id)), result(std::move(result)) {}
53  response_message(int id, json::value result = json::value())
54  : id(double(id)), result(std::move(result)) {}
55  json::value id;
56  json::value result;
58 };
60  notify_message(std::string method, json::value params = json::value())
61  : method(std::move(method)), params(std::move(params)) {}
62  std::string method;
63  json::value params;
64 };
65 
66 inline bool is_notify(const json::value& msg) {
67  return msg.is<json::object>() && !msg.contains("id");
68 }
69 inline bool is_request(const json::value& msg) {
70  return msg.is<json::object>() && msg.contains("method") &&
71  msg.get("method").is<std::string>();
72 }
73 inline bool is_response(const json::value& msg) {
74  return msg.is<json::object>() && !msg.contains("method") &&
75  msg.contains("id");
76 }
77 
78 inline bool parse(const json::value& message, request_message& request) {
79  if (!is_request(message)) {
80  return false;
81  }
82  request.id = message.get("id");
83  request.method = message.get("method").get<std::string>();
84  if (message.contains("param")) {
85  request.params = message.get("param");
86  } else {
87  request.params = message.get("params");
88  }
89  return true;
90 }
91 
92 inline bool parse(const json::value& message, notify_message& notify) {
93  if (!is_notify(message)) {
94  return false;
95  }
96  notify.method = message.get("method").get<std::string>();
97  if (message.contains("param")) {
98  notify.params = message.get("param");
99  } else {
100  notify.params = message.get("params");
101  }
102  return true;
103 }
104 
105 inline bool parse(const json::value& message, response_message& response) {
106  if (!is_response(message)) {
107  return false;
108  }
109  response.id = message.get("id");
110  response.result = message.get("result");
111  return true;
112 }
113 
114 inline std::string serialize(const request_message& msg) {
115  json::object obj;
116  obj["jsonrpc"] = json::value("2.0");
117 
118  obj["method"] = json::value(msg.method);
119  if (!msg.params.is<json::null>()) {
120  obj["params"] = msg.params;
121  }
122  obj["id"] = msg.id;
123  return json::value(obj).serialize();
124 }
125 
126 inline std::string serialize(const response_message& msg) {
127  json::object obj;
128  obj["jsonrpc"] = json::value("2.0");
129 
130  obj["result"] = msg.result;
131 
132  if (msg.error) {
133  json::object error = {{"code", json::value(double(msg.error->code))},
134  {"message", json::value(msg.error->message)},
135  {"data", json::value(msg.error->data)}};
136  obj["error"] = json::value(error);
137  }
138 
139  obj["id"] = msg.id;
140  return json::value(obj).serialize();
141 }
142 
143 inline std::string serialize(const notify_message& msg) {
144  json::object obj;
145  obj["jsonrpc"] = json::value("2.0");
146 
147  obj["method"] = json::value(msg.method);
148  if (!msg.params.is<json::null>()) {
149  obj["params"] = msg.params;
150  }
151  return json::value(obj).serialize();
152 }
153 
154 inline const std::string& get_method(const json::value& msg) {
155  static std::string null;
156  if (!msg.is<json::object>() || !msg.contains("method")) {
157  return null;
158  }
159  const json::value& m = msg.get<json::object>().at("method");
160  if (!m.is<std::string>()) {
161  return null;
162  }
163  return m.get<std::string>();
164 }
165 inline const json::value& get_param(const json::value& msg) {
166  static json::value null;
167  if (!msg.is<json::object>() || !msg.contains("params")) {
168  return null;
169  }
170  return msg.get<json::object>().at("params");
171 }
172 inline const json::value& get_id(const json::value& msg) {
173  static json::value null;
174  if (!msg.is<json::object>() || !msg.contains("id")) {
175  return null;
176  }
177  return msg.get<json::object>().at("id");
178 }
179 namespace request {
180 inline std::string serialize(const json::value& id, const std::string& medhod,
181  const json::value& param = json::value()) {
182  json::object obj;
183  obj["method"] = json::value(medhod);
184  if (!param.is<json::null>()) {
185  obj["params"] = param;
186  }
187  obj["id"] = id;
188  return json::value(obj).serialize();
189 }
190 inline std::string serialize(const json::value& id, const std::string& medhod,
191  const std::string& param) {
192  return serialize(id, medhod, json::value(param));
193 }
194 inline std::string serialize(double id, const std::string& medhod,
195  const std::string& param) {
196  return serialize(json::value(id), medhod, json::value(param));
197 }
198 inline std::string serialize(double id, const std::string& medhod,
199  const json::value& param = json::value()) {
200  return serialize(json::value(id), medhod, json::value(param));
201 }
202 inline std::string serialize(const std::string& id, const std::string& medhod,
203  const std::string& param) {
204  return serialize(json::value(id), medhod, json::value(param));
205 }
206 inline std::string serialize(const std::string& id, const std::string& medhod,
207  const json::value& param = json::value()) {
208  return serialize(json::value(id), medhod, json::value(param));
209 }
210 }
211 namespace notify {
212 inline std::string serialize(const std::string& medhod,
213  const json::value& param = json::value()) {
214  json::object obj;
215  obj["method"] = json::value(medhod);
216  if (!param.is<json::null>()) {
217  obj["params"] = param;
218  }
219  return json::value(obj).serialize();
220 }
221 inline std::string serialize(const std::string& medhod,
222  const std::string& param) {
223  return serialize(medhod, json::value(param));
224 }
225 }
226 namespace responce {
227 inline std::string serialize(const json::value& id,
228  const json::value& result = json::value(),
229  bool error = false) {
230  json::object obj;
231  if (error) {
232  obj["error"] = result;
233  } else {
234  obj["result"] = result;
235  }
236  obj["id"] = id;
237  return json::value(obj).serialize();
238 }
239 inline std::string serialize(const json::value& id, const std::string& result,
240  bool error = false) {
241  return serialize(id, json::value(result), error);
242 }
243 }
244 }
245 using message::request_message;
246 using message::response_message;
247 using message::notify_message;
248 using message::response_error;
249 }
self implement for std::optional(C++17 feature).
Definition: optional.hpp:19
Definition: message.hpp:59
Definition: message.hpp:13
Definition: message.hpp:28
Definition: message.hpp:49