lsp_async_stub/
rpc.rs

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 {}