1use crate::client::ClientError;
2use crate::lsp_types::*;
3use serde_json::json;
4use serde_json::Value;
5use std::collections::HashMap;
6use std::sync::atomic::{AtomicU64, Ordering};
7use std::sync::Arc;
8use tokio::sync::{mpsc, oneshot, Mutex};
9
10#[derive(Debug, Clone)]
13pub struct ServerHandle {
14 pub(crate) sender: mpsc::Sender<Value>,
15 pub(crate) pending: Arc<Mutex<HashMap<u64, oneshot::Sender<Value>>>>,
16 pub(crate) next_id: Arc<AtomicU64>,
17}
18
19impl ServerHandle {
20 pub fn new(
21 sender: mpsc::Sender<Value>,
22 pending: Arc<Mutex<HashMap<u64, oneshot::Sender<Value>>>>,
23 next_id: Arc<AtomicU64>,
24 ) -> Self {
25 Self {
26 sender,
27 pending,
28 next_id,
29 }
30 }
31
32 pub async fn notify(&self, method: &str, params: impl serde::Serialize) {
34 let msg = json!({
35 "jsonrpc": "2.0",
36 "method": method,
37 "params": params,
38 });
39 let _ = self.sender.send(msg).await;
40 }
41
42 pub async fn request<R>(
44 &self,
45 method: &str,
46 params: impl serde::Serialize,
47 ) -> Result<Option<R>, ClientError>
48 where
49 R: serde::de::DeserializeOwned,
50 {
51 let id = self.next_id.fetch_add(1, Ordering::SeqCst);
52 let msg = json!({
53 "jsonrpc": "2.0",
54 "id": id,
55 "method": method,
56 "params": params,
57 });
58
59 let (tx, rx) = oneshot::channel::<Value>();
60 self.pending.lock().await.insert(id, tx);
61
62 if self.sender.send(msg).await.is_err() {
63 self.pending.lock().await.remove(&id);
64 return Ok(None);
65 }
66
67 match tokio::time::timeout(std::time::Duration::from_secs(30), rx).await {
68 Ok(Ok(result)) => {
69 if result.is_null() {
70 return Ok(None);
71 }
72 match serde_json::from_value::<R>(result) {
73 Ok(v) => Ok(Some(v)),
74 Err(_) => Ok(None),
75 }
76 }
77 Ok(Err(_)) => Ok(None), Err(_) => {
79 self.pending.lock().await.remove(&id);
81 Ok(None)
82 }
83 }
84 }
85
86 pub async fn initialize(
89 &self,
90 params: InitializeParams,
91 ) -> Result<InitializeResult, ClientError> {
92 match self
93 .request::<InitializeResult>("initialize", params)
94 .await?
95 {
96 Some(r) => Ok(r),
97 None => Ok(InitializeResult::default()),
98 }
99 }
100 pub async fn initialized(&self, params: InitializedParams) {
101 self.notify("initialized", params).await;
102 }
103 pub async fn shutdown(&self) -> Result<(), ClientError> {
104 let _ = self.request::<()>("shutdown", ()).await;
105 Ok(())
106 }
107 pub async fn exit(&self) {
108 self.notify("exit", ()).await;
109 }
110
111 pub async fn did_open(&self, params: DidOpenTextDocumentParams) {
114 self.notify("textDocument/didOpen", params).await;
115 }
116 pub async fn did_change(&self, params: DidChangeTextDocumentParams) {
117 self.notify("textDocument/didChange", params).await;
118 }
119 pub async fn did_save(&self, params: DidSaveTextDocumentParams) {
120 self.notify("textDocument/didSave", params).await;
121 }
122 pub async fn did_close(&self, params: DidCloseTextDocumentParams) {
123 self.notify("textDocument/didClose", params).await;
124 }
125
126 pub async fn hover(&self, params: HoverParams) -> Result<Option<Hover>, ClientError> {
129 self.request("textDocument/hover", params).await
130 }
131 pub async fn completion(
132 &self,
133 params: CompletionParams,
134 ) -> Result<Option<CompletionResponse>, ClientError> {
135 self.request("textDocument/completion", params).await
136 }
137 pub async fn completion_resolve(
138 &self,
139 params: CompletionItem,
140 ) -> Result<CompletionItem, ClientError> {
141 match self
142 .request::<CompletionItem>("completionItem/resolve", params.clone())
143 .await?
144 {
145 Some(r) => Ok(r),
146 None => Ok(params),
147 }
148 }
149
150 pub async fn signature_help(
151 &self,
152 params: SignatureHelpParams,
153 ) -> Result<Option<SignatureHelp>, ClientError> {
154 self.request("textDocument/signatureHelp", params).await
155 }
156
157 pub async fn goto_definition(
158 &self,
159 params: GotoDefinitionParams,
160 ) -> Result<Option<GotoDefinitionResponse>, ClientError> {
161 self.request("textDocument/definition", params).await
162 }
163 pub async fn goto_declaration(
164 &self,
165 params: GotoDefinitionParams,
166 ) -> Result<Option<GotoDefinitionResponse>, ClientError> {
167 self.request("textDocument/declaration", params).await
168 }
169 pub async fn goto_implementation(
170 &self,
171 params: GotoDefinitionParams,
172 ) -> Result<Option<GotoDefinitionResponse>, ClientError> {
173 self.request("textDocument/implementation", params).await
174 }
175 pub async fn goto_type_definition(
176 &self,
177 params: GotoDefinitionParams,
178 ) -> Result<Option<GotoDefinitionResponse>, ClientError> {
179 self.request("textDocument/typeDefinition", params).await
180 }
181
182 pub async fn references(
183 &self,
184 params: ReferenceParams,
185 ) -> Result<Option<Vec<Location>>, ClientError> {
186 self.request("textDocument/references", params).await
187 }
188 pub async fn document_highlight(
189 &self,
190 params: DocumentHighlightParams,
191 ) -> Result<Option<Vec<DocumentHighlight>>, ClientError> {
192 self.request("textDocument/documentHighlight", params).await
193 }
194 pub async fn document_symbol(
195 &self,
196 params: DocumentSymbolParams,
197 ) -> Result<Option<DocumentSymbolResponse>, ClientError> {
198 self.request("textDocument/documentSymbol", params).await
199 }
200
201 pub async fn code_action(
202 &self,
203 params: CodeActionParams,
204 ) -> Result<Option<CodeActionResponse>, ClientError> {
205 self.request("textDocument/codeAction", params).await
206 }
207 pub async fn code_action_resolve(&self, params: CodeAction) -> Result<CodeAction, ClientError> {
208 match self
209 .request::<CodeAction>("codeAction/resolve", params.clone())
210 .await?
211 {
212 Some(r) => Ok(r),
213 None => Ok(params),
214 }
215 }
216
217 pub async fn code_lens(
218 &self,
219 params: CodeLensParams,
220 ) -> Result<Option<Vec<CodeLens>>, ClientError> {
221 self.request("textDocument/codeLens", params).await
222 }
223 pub async fn code_lens_resolve(&self, params: CodeLens) -> Result<CodeLens, ClientError> {
224 match self
225 .request::<CodeLens>("codeLens/resolve", params.clone())
226 .await?
227 {
228 Some(r) => Ok(r),
229 None => Ok(params),
230 }
231 }
232
233 pub async fn formatting(
234 &self,
235 params: DocumentFormattingParams,
236 ) -> Result<Option<Vec<TextEdit>>, ClientError> {
237 self.request("textDocument/formatting", params).await
238 }
239 pub async fn range_formatting(
240 &self,
241 params: DocumentRangeFormattingParams,
242 ) -> Result<Option<Vec<TextEdit>>, ClientError> {
243 self.request("textDocument/rangeFormatting", params).await
244 }
245 pub async fn rename(&self, params: RenameParams) -> Result<Option<WorkspaceEdit>, ClientError> {
246 self.request("textDocument/rename", params).await
247 }
248 pub async fn prepare_rename(
249 &self,
250 params: TextDocumentPositionParams,
251 ) -> Result<Option<PrepareRenameResponse>, ClientError> {
252 self.request("textDocument/prepareRename", params).await
253 }
254
255 pub async fn semantic_tokens_full(
256 &self,
257 params: SemanticTokensParams,
258 ) -> Result<Option<SemanticTokensResult>, ClientError> {
259 self.request("textDocument/semanticTokens/full", params)
260 .await
261 }
262 pub async fn semantic_tokens_full_delta(
263 &self,
264 params: SemanticTokensDeltaParams,
265 ) -> Result<Option<SemanticTokensFullDeltaResult>, ClientError> {
266 self.request("textDocument/semanticTokens/full/delta", params)
267 .await
268 }
269 pub async fn semantic_tokens_range(
270 &self,
271 params: SemanticTokensRangeParams,
272 ) -> Result<Option<SemanticTokensRangeResult>, ClientError> {
273 self.request("textDocument/semanticTokens/range", params)
274 .await
275 }
276
277 pub async fn inlay_hint(
278 &self,
279 params: InlayHintParams,
280 ) -> Result<Option<Vec<InlayHint>>, ClientError> {
281 self.request("textDocument/inlayHint", params).await
282 }
283 pub async fn inlay_hint_resolve(&self, params: InlayHint) -> Result<InlayHint, ClientError> {
284 match self
285 .request::<InlayHint>("inlayHint/resolve", params.clone())
286 .await?
287 {
288 Some(r) => Ok(r),
289 None => Ok(params),
290 }
291 }
292
293 pub async fn symbol(
296 &self,
297 params: WorkspaceSymbolParams,
298 ) -> Result<Option<Vec<SymbolInformation>>, ClientError> {
299 self.request("workspace/symbol", params).await
300 }
301 pub async fn execute_command(
302 &self,
303 params: ExecuteCommandParams,
304 ) -> Result<Option<Value>, ClientError> {
305 self.request("workspace/executeCommand", params).await
306 }
307 pub async fn did_change_configuration(&self, params: DidChangeConfigurationParams) {
308 self.notify("workspace/didChangeConfiguration", params)
309 .await;
310 }
311 pub async fn did_change_watched_files(&self, params: DidChangeWatchedFilesParams) {
312 self.notify("workspace/didChangeWatchedFiles", params).await;
313 }
314 pub async fn did_change_workspace_folders(&self, params: DidChangeWorkspaceFoldersParams) {
315 self.notify("workspace/didChangeWorkspaceFolders", params)
316 .await;
317 }
318}