1mod part1;
2mod part2;
3mod part3;
4mod patch;
5
6use std::fmt::Debug;
7
8pub use part1::*;
9pub use part2::*;
10pub use part3::*;
11pub use patch::*;
12
13pub const VERSION: &str = "3.16";
15
16macro_rules! serde_empty {
17 ($type:ty) => {
18 impl<'de> serde::Deserialize<'de> for $type {
19 fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
20 where
21 D: serde::Deserializer<'de>,
22 {
23 Ok(Self::default())
24 }
25 }
26
27 impl serde::Serialize for $type {
28 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
29 where
30 S: serde::Serializer,
31 {
32 serializer.serialize_none()
33 }
34 }
35 };
36}
37
38serde_empty!(ExitParams);
39serde_empty!(InitializedParams);
40serde_empty!(SemanticTokensRefreshParams);
41serde_empty!(ShutdownParams);
42serde_empty!(WorkspaceFolderParams);
43serde_empty!(Empty);
44
45pub trait FromReq: Sized {
46 const METHOD: &'static str;
47 type Ret;
48
49 fn from_req(req: RequestMessage) -> OneOf<(ReqId, Self), RequestMessage>;
52
53 fn can_cast(req: &RequestMessage) -> bool {
55 Self::METHOD == req.method
56 }
57}
58
59#[macro_export]
60macro_rules! impl_req {
61 ($type:ty, $method:literal, $ret:path) => {
62 impl FromReq for $type {
63 const METHOD: &'static str = $method;
64 type Ret = $ret;
65
66 fn from_req(req: RequestMessage) -> OneOf<(ReqId, Self), RequestMessage> {
67 if <Self as FromReq>::can_cast(&req) {
68 let RequestMessage { id, params, .. } = req;
69 let params: Self =
70 serde_json::from_value(params.unwrap_or_else(|| serde_json::Value::Null))
71 .unwrap();
72 OneOf::This((id, params))
73 } else {
74 OneOf::Other(req)
75 }
76 }
77 }
78
79 impl $type {
80 pub fn ret(result: $ret) -> $ret {
83 result
84 }
85 }
86 };
87 ($type:ty, $method:literal) => {
88 impl_req!($type, $method, serde_json::Value);
89 };
90}
91
92impl_req!(InitializeParams, "initialize", InitializeResult);
93impl_req!(
94 ShowMessageRequestParams,
95 "window/showMessageRequest",
96 Option<MessageActionItem>
97);
98impl_req!(
99 ShowDocumentParams,
100 "window/showDocument",
101 ShowDocumentResult
102);
103impl_req!(RegistrationParams, "client/registerCapability", Empty);
104impl_req!(UnregistrationParams, "client/unregisterCapability", Empty);
105impl_req!(
106 ConfigurationParams,
107 "workspace/configuration",
108 Vec<serde_json::Value>
109);
110impl_req!(
111 WorkspaceSymbolParams,
112 "workspace/symbol",
113 Vec<SymbolInformation>
114);
115impl_req!(ExecuteCommandParams, "workspace/executeCommand");
116impl_req!(
117 ApplyWorkspaceEditParams,
118 "workspace/applyEdit",
119 ApplyWorkspaceEditResponse
120);
121impl_req!(
122 CreateFilesParams,
123 "workspace/willCreateFiles",
124 Option<WorkspaceEdit>
125);
126impl_req!(
127 RenameFilesParams,
128 "workspace/willRenameFiles",
129 Option<WorkspaceEdit>
130);
131impl_req!(
132 DeleteFilesParams,
133 "workspace/willDeleteFiles",
134 Option<WorkspaceEdit>
135);
136impl_req!(
137 WillSaveTextDocumentParams,
138 "textDocument/willSaveWaitUntil",
139 Vec<TextEdit>
140);
141impl_req!(
142 CompletionParams,
143 "textDocument/completion",
144 OneOf<Vec<CompletionItem>, CompletionList>
145);
146impl_req!(CompletionItem, "completionItem/resolve", CompletionItem);
147impl_req!(HoverParams, "textDocument/hover", Option<Hover>);
148impl_req!(
149 SignatureHelpParams,
150 "textDocument/signatureHelp",
151 Option<SignatureHelp>
152);
153impl_req!(
154 DeclarationParams,
155 "textDocument/declaration",
156 OneOf<Vec<Location>, Vec<LocationLink>>
157);
158impl_req!(
159 DefinitionParams,
160 "textDocument/definition",
161 OneOf<Vec<Location>, Vec<LocationLink>>
162);
163impl_req!(
164 TypeDefinitionParams,
165 "textDocument/typeDefinition",
166 OneOf<Vec<Location>, Vec<LocationLink>>
167);
168impl_req!(
169 ImplementationParams,
170 "textDocument/implementation",
171 OneOf<Vec<Location>, Vec<LocationLink>>
172);
173impl_req!(ReferenceParams, "textDocument/references", Vec<Location>);
174impl_req!(
175 DocumentHighlightParams,
176 "textDocument/documentHighlight",
177 Vec<DocumentHighlight>
178);
179impl_req!(
180 DocumentSymbolParams,
181 "textDocument/documentSymbol",
182 OneOf<Vec<DocumentSymbol>, Vec<SymbolInformation>>
183);
184impl_req!(
185 CodeActionParams,
186 "textDocument/codeAction",
187 Vec<OneOf<Command, CodeAction>>
188);
189impl_req!(CodeAction, "codeAction/resolve", CodeAction);
190impl_req!(CodeLensParams, "textDocument/codeLens", Vec<CodeLens>);
191impl_req!(CodeLens, "codeLens/resolve", CodeLens);
192impl_req!(
193 DocumentLinkParams,
194 "textDocument/documentLink",
195 Vec<DocumentLink>
196);
197impl_req!(DocumentLink, "documentLink/resolve", DocumentLink);
198impl_req!(
199 DocumentFormattingParams,
200 "textDocument/formatting",
201 Vec<TextEdit>
202);
203impl_req!(
204 DocumentRangeFormattingParams,
205 "DocumentRangeFormattingParams",
206 Vec<TextEdit>
207);
208impl_req!(
209 DocumentOnTypeFormattingParams,
210 "textDocument/onTypeFormatting",
211 Vec<TextEdit>
212);
213impl_req!(RenameParams, "textDocument/rename", Option<WorkspaceEdit>);
214impl_req!(
215 PrepareRenameParams,
216 "textDocument/prepareRename",
217 Option<OneOf3<Range, PrepareRenameResult1, PrepareRenameResult2>>
218);
219impl_req!(
220 FoldingRangeParams,
221 "textDocument/foldingRange",
222 Vec<FoldingRange>
223);
224impl_req!(ShutdownParams, "shutdown", Empty);
225impl_req!(
226 WorkDoneProgressCreateParams,
227 "window/workDoneProgress/create",
228 Empty
229);
230impl_req!(
231 CallHierarchyPrepareParams,
232 "textDocument/prepareCallHierarchy",
233 Vec<CallHierarchyItem>
234);
235impl_req!(
236 CallHierarchyIncomingCallsParams,
237 "callHierarchy/incomingCalls",
238 Vec<CallHierarchyIncomingCall>
239);
240impl_req!(
241 CallHierarchyOutgoingCallsParams,
242 "callHierarchy/outgoingCalls",
243 Vec<CallHierarchyOutgoingCall>
244);
245impl_req!(
246 SelectionRangeParams,
247 "textDocument/selectionRange",
248 Vec<SelectionRange>
249);
250impl_req!(
251 WorkspaceFolderParams,
252 "workspace/workspaceFolders",
253 Vec<WorkspaceFolder>
254);
255impl_req!(
256 DocumentColorParams,
257 "textDocument/documentColor",
258 Vec<ColorInformation>
259);
260impl_req!(
261 ColorPresentationParams,
262 "textDocument/colorPresentation",
263 Vec<ColorPresentation>
264);
265impl_req!(
266 SemanticTokensParams,
267 "textDocument/semanticTokens/full",
268 Option<SemanticTokens>
269);
270impl_req!(
271 SemanticTokensDeltaParams,
272 "textDocument/semanticTokens/full/delta",
273 Option<OneOf<SemanticTokens, SemanticTokensDelta>>
274);
275impl_req!(
276 SemanticTokensRangeParams,
277 "textDocument/semanticTokens/range",
278 Option<SemanticTokens>
279);
280impl_req!(
281 SemanticTokensRefreshParams,
282 "workspace/semanticTokens/refresh",
283 Empty
284);
285impl_req!(
286 LinkedEditingRangeParams,
287 "textDocument/linkedEditingRange",
288 Option<LinkedEditingRanges>
289);
290impl_req!(MonikerParams, "textDocument/moniker", Vec<Moniker>);
291
292pub trait FromNotice: Sized + serde::Serialize {
293 const METHOD: &'static str;
294
295 fn from_notice(notice: NotificationMessage) -> OneOf<Self, NotificationMessage>;
298
299 fn into_notice(self) -> NotificationMessage {
302 NotificationMessage {
303 jsonrpc: "2.0".to_string(),
304 method: <Self as FromNotice>::METHOD.to_string(),
305 params: Some(serde_json::to_value(self).unwrap()),
306 }
307 }
308
309 fn can_cast(notice: &NotificationMessage) -> bool {
311 Self::METHOD == notice.method
312 }
313}
314
315#[macro_export]
316macro_rules! impl_notice {
317 ($type:ty, $method:literal) => {
318 impl FromNotice for $type {
319 const METHOD: &'static str = $method;
320
321 fn from_notice(notice: NotificationMessage) -> OneOf<Self, NotificationMessage> {
322 if <Self as FromNotice>::can_cast(¬ice) {
323 let NotificationMessage { params, .. } = notice;
324 let params =
325 serde_json::from_value(params.unwrap_or_else(|| serde_json::Value::Null))
326 .unwrap();
327 OneOf::This(params)
328 } else {
329 OneOf::Other(notice)
330 }
331 }
332 }
333 };
334}
335
336impl_notice!(CancelParams, "$/cancelRequest");
337impl_notice!(ProgressParams, "$/progress");
338impl_notice!(InitializedParams, "initialized");
339impl_notice!(ExitParams, "exit");
340impl_notice!(LogTraceParams, "$/logTrace");
341impl_notice!(SetTraceParams, "$/setTrace");
342impl_notice!(ShowMessageParams, "window/showMessage");
343impl_notice!(LogMessageParams, "window/logMessage");
344impl_notice!(
345 WorkDoneProgressCancelParams,
346 "window/workDoneProgress/cancel"
347);
348impl_notice!(
349 DidChangeWorkspaceFoldersParams,
350 "workspace/didChangeWorkspaceFolders"
351);
352impl_notice!(
353 DidChangeConfigurationParams,
354 "workspace/didChangeConfiguration"
355);
356impl_notice!(
357 DidChangeWatchedFilesParams,
358 "workspace/didChangeWatchedFiles"
359);
360impl_notice!(CreateFilesParams, "workspace/didCreateFiles");
361impl_notice!(DeleteFilesParams, "workspace/didDeleteFiles");
362impl_notice!(DidOpenTextDocumentParams, "textDocument/didOpen");
363impl_notice!(DidChangeTextDocumentParams, "textDocument/didChange");
364impl_notice!(WillSaveTextDocumentParams, "textDocument/willSave");
365impl_notice!(DidSaveTextDocumentParams, "textDocument/didSave");
366impl_notice!(DidCloseTextDocumentParams, "textDocument/didClose");
367impl_notice!(PublishDiagnosticsParams, "textDocument/publishDiagnostics");