1use serde::{de::DeserializeOwned, Deserialize, Serialize};
2
3pub type RequestId = lsp_types::NumberOrString;
4
5#[derive(Default, Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
6#[serde(rename_all = "camelCase")]
7pub struct Message {
8 pub jsonrpc: String,
9
10 #[serde(skip_serializing_if = "Option::is_none")]
11 pub method: Option<String>,
12 #[serde(skip_serializing_if = "Option::is_none")]
13 pub id: Option<RequestId>,
14 #[serde(skip_serializing_if = "Option::is_none")]
15 pub params: Option<serde_json::Value>,
16 #[serde(skip_serializing_if = "Option::is_none")]
17 pub result: Option<serde_json::Value>,
18 #[serde(skip_serializing_if = "Option::is_none")]
19 pub error: Option<Error>,
20}
21
22impl Message {
23 pub fn is_notification(&self) -> bool {
24 self.method.is_some() && self.id.is_none()
25 }
26
27 pub fn is_response(&self) -> bool {
28 self.method.is_none()
29 }
30
31 pub fn into_request(self) -> Request<serde_json::Value> {
32 Request {
33 jsonrpc: self.jsonrpc,
34 method: self.method.unwrap(),
35 id: self.id,
36 params: self.params,
37 }
38 }
39
40 pub fn into_response(self) -> Response<serde_json::Value> {
41 Response {
42 jsonrpc: self.jsonrpc,
43 id: self.id.unwrap(),
44 error: self.error,
45 result: self.result,
46 }
47 }
48}
49
50#[derive(Default, Debug, Eq, PartialEq, Serialize, Deserialize)]
51#[serde(rename_all = "camelCase")]
52pub struct Request<T = ()> {
53 pub jsonrpc: String,
54 pub method: String,
55
56 pub id: Option<RequestId>,
57 pub params: Option<T>,
58}
59
60impl<T: Serialize + DeserializeOwned> Request<T> {
61 pub fn new() -> Self {
62 Self {
63 jsonrpc: "2.0".into(),
64 method: "".into(),
65 id: None,
66 params: None,
67 }
68 }
69
70 pub fn with_method(self, method: &str) -> Self {
71 Self {
72 method: method.into(),
73 ..self
74 }
75 }
76
77 pub fn with_id(self, id: Option<RequestId>) -> Self {
78 Self { id, ..self }
79 }
80
81 pub fn with_params(self, params: Option<T>) -> Self {
82 Self { params, ..self }
83 }
84
85 pub fn into_message(self) -> Message {
86 Message {
87 jsonrpc: self.jsonrpc,
88 method: Some(self.method),
89 id: self.id,
90 params: self.params.map(|p| serde_json::to_value(p).unwrap()),
91 result: None,
92 error: None,
93 }
94 }
95}
96
97impl Request<serde_json::Value> {
98 pub fn into_params<P: DeserializeOwned>(self) -> Result<Request<P>, serde_json::Error> {
99 match self.params {
100 None => Ok(Request {
101 id: self.id,
102 jsonrpc: self.jsonrpc,
103 method: self.method,
104 params: None,
105 }),
106 Some(v) => match serde_json::from_value(v) {
107 Ok(params) => Ok(Request {
108 id: self.id,
109 jsonrpc: self.jsonrpc,
110 method: self.method,
111 params: Some(params),
112 }),
113 Err(e) => Err(e),
114 },
115 }
116 }
117}
118
119#[derive(Debug, Eq, PartialEq, Serialize, Deserialize)]
120pub struct Response<R = ()> {
121 pub jsonrpc: String,
122
123 pub id: RequestId,
124
125 #[serde(skip_serializing_if = "Option::is_none")]
126 pub result: Option<R>,
127
128 #[serde(skip_serializing_if = "Option::is_none")]
129 pub error: Option<Error>,
130}
131
132impl<R> Response<R> {
133 pub fn with_request_id(self, id: RequestId) -> Self {
134 Response { id, ..self }
135 }
136}
137
138impl<R: Serialize + DeserializeOwned> Response<R> {
139 pub fn success(data: R) -> Self {
140 Response {
141 jsonrpc: "2.0".into(),
142 id: lsp_types::NumberOrString::Number(0),
143 result: Some(data),
144 error: None,
145 }
146 }
147
148 pub fn into_result(self) -> Result<R, Error> {
149 if let Some(r) = self.result {
150 Ok(r)
151 } else {
152 Err(self.error.unwrap())
153 }
154 }
155
156 pub fn into_message(self) -> Message {
157 Message {
158 jsonrpc: self.jsonrpc,
159 method: None,
160 id: Some(self.id),
161 params: None,
162 result: self.result.map(|p| serde_json::to_value(p).unwrap()),
163 error: self.error,
164 }
165 }
166}
167
168impl Response<serde_json::Value> {
169 pub fn into_params<P: DeserializeOwned>(self) -> Response<P> {
170 Response {
171 jsonrpc: self.jsonrpc,
172 id: self.id,
173 result: self.result.map(|v| serde_json::from_value(v).unwrap()),
174 error: self.error,
175 }
176 }
177}
178
179impl Response<()> {
180 pub fn error(err: Error) -> Self {
181 Response {
182 jsonrpc: "2.0".into(),
183 id: lsp_types::NumberOrString::Number(0),
184 result: None,
185 error: Some(err),
186 }
187 }
188}
189
190impl<E, R> From<Result<R, E>> for Response<R>
191where
192 R: Serialize + for<'r> Deserialize<'r>,
193 E: Into<Error>,
194{
195 fn from(res: Result<R, E>) -> Self {
196 match res {
197 Ok(r) => Response {
198 jsonrpc: "2.0".into(),
199 id: lsp_types::NumberOrString::Number(0),
200 result: Some(r),
201 error: None,
202 },
203 Err(err) => Response {
204 jsonrpc: "2.0".into(),
205 id: lsp_types::NumberOrString::Number(0),
206 result: None,
207 error: Some(err.into()),
208 },
209 }
210 }
211}
212
213#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
214pub struct Error {
215 pub code: i32,
216 pub message: String,
217 pub data: Option<serde_json::Value>,
218}
219
220impl core::fmt::Display for Error {
221 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
222 write!(f, "RPC error ({}): {}", self.code, self.message)
223 }
224}
225
226impl Error {
227 pub fn new(message: &str) -> Self {
228 Error {
229 code: 0,
230 message: message.into(),
231 data: None,
232 }
233 }
234
235 pub fn with_code(mut self, code: i32) -> Self {
236 self.code = code;
237 self
238 }
239
240 pub fn with_data(mut self, data: impl Serialize) -> Self {
241 self.data = Some(serde_json::to_value(data).unwrap());
242 self
243 }
244
245 pub fn parse() -> Error {
246 Error {
247 code: -32700,
248 message: "Parse error".into(),
249 data: None,
250 }
251 }
252
253 pub fn invalid_request() -> Error {
254 Error {
255 code: -32600,
256 message: "Invalid request".into(),
257 data: None,
258 }
259 }
260
261 pub fn method_not_found() -> Error {
262 Error {
263 code: -32601,
264 message: "Method not found".into(),
265 data: None,
266 }
267 }
268
269 pub fn invalid_params() -> Error {
270 Error {
271 code: -32602,
272 message: "Invalid params".into(),
273 data: None,
274 }
275 }
276
277 pub fn internal_error() -> Error {
278 Error {
279 code: -32603,
280 message: "Internal error".into(),
281 data: None,
282 }
283 }
284
285 pub fn server_not_initialized() -> Error {
286 Error {
287 code: -32002,
288 message: "Server not initialized".into(),
289 data: None,
290 }
291 }
292
293 pub fn request_cancelled() -> Error {
294 Error {
295 code: -32800,
296 message: "Request cancelled".into(),
297 data: None,
298 }
299 }
300
301 pub fn content_modified() -> Error {
302 Error {
303 code: -32801,
304 message: "Content modified".into(),
305 data: None,
306 }
307 }
308
309 pub fn server(code: i32) -> Error {
310 if code < -32000 || code > -32099 {
311 panic!("code must be between -32000 and -32099")
312 }
313
314 Error {
315 code: -32603,
316 message: "Server error".into(),
317 data: None,
318 }
319 }
320}
321
322impl std::error::Error for Error {}