use {
crate::{
TRACER,
database::{
chunk::RecordWriter,
storage::Partitions,
},
protocol::{
jsonrpc::{
self,
Response,
},
lsp::{
LSPAny,
LanguageServer,
},
macros::{
match_notification,
match_request,
},
},
scheduler::{
lanes::Lane,
task::TaskContext,
},
},
futures::future::{
BoxFuture,
FutureExt,
},
std::{
marker::PhantomData,
sync::Arc,
},
};
type RequestHandlerFn<P, T> = Box<
dyn FnOnce(
String,
jsonrpc::Id,
Option<LSPAny>,
TaskContext<P, T>,
RecordWriter<P>,
) -> BoxFuture<'static, (Option<Response>, RecordWriter<P>)>
+ Send,
>;
type NotificationHandlerFn<P, T> = Box<
dyn FnOnce(
String,
Option<LSPAny>,
TaskContext<P, T>,
RecordWriter<P>,
) -> BoxFuture<'static, RecordWriter<P>>
+ Send,
>;
pub struct RequestRouter<P: Partitions, T: LanguageServer<P>> {
server: Arc<T>,
_phantom: PhantomData<P>,
}
impl<P: Partitions, T: LanguageServer<P>> RequestRouter<P, T> {
pub fn new(server: Arc<T>) -> Self {
Self {
server: server.clone(),
_phantom: PhantomData,
}
}
fn route<Params, Result, F, Fut>(
server: Arc<T>,
method_fn: F,
lane: Lane,
) -> (RequestHandlerFn<P, T>, Lane)
where
Params: serde::de::DeserializeOwned,
Result: serde::Serialize,
F: Fn(Arc<T>, Params, TaskContext<P, T>, RecordWriter<P>) -> Fut
+ Send
+ 'static,
Fut: std::future::Future<Output = (jsonrpc::Result<Result>, RecordWriter<P>)>
+ Send
+ 'static,
{
let handler: RequestHandlerFn<P, T> =
Box::new(move |_method, id, params, ctx, writer| {
let server = server.clone();
async move {
let params: Params = match params {
| Some(p) => {
match serde_json::from_value(p) {
| Ok(params) => params,
| Err(e) => {
let response = Response::from_error(
id,
jsonrpc::Error::invalid_params(e.to_string()),
);
return (Some(response), writer);
},
}
},
| None => {
let response = Response::from_error(
id,
jsonrpc::Error::invalid_params("Missing params"),
);
return (Some(response), writer);
},
};
let (result, writer) = method_fn(server, params, ctx, writer).await;
let response = match result {
| Ok(res) => {
match serde_json::to_value(res) {
| Ok(value) => Response::from_ok(id, value),
| Err(e) => {
Response::from_error(id, jsonrpc::Error {
code: jsonrpc::ErrorCode::InternalError,
message: e.to_string().into(),
data: None,
})
},
}
},
| Err(e) => Response::from_error(id, e),
};
(Some(response), writer)
}
.boxed()
});
(handler, lane)
}
pub fn get_notification_handler(
&self,
method: &str,
) -> (NotificationHandlerFn<P, T>, Lane) {
match_notification! {
match method on self.server => {
@"notebookDocument/didOpen" => notebook_did_open,
@"notebookDocument/didChange" => notebook_did_change,
@"notebookDocument/didSave" => notebook_did_save,
@"notebookDocument/didClose" => notebook_did_close,
@"textDocument/didOpen" => did_open,
@"textDocument/didChange" => did_change,
@"textDocument/willSave" => will_save,
@"textDocument/didSave" => did_save,
@"textDocument/didClose" => did_close,
@"workspace/didChangeConfiguration" => did_change_configuration,
@"workspace/didChangeWorkspaceFolders" => did_change_workspace_folders,
@"workspace/didCreateFiles" => did_create_files,
@"workspace/didRenameFiles" => did_rename_files,
@"workspace/didDeleteFiles" => did_delete_files,
@"workspace/didChangeWatchedFiles" => did_change_watched_files,
}
}
}
pub fn get_request_handler(
&self,
method: &str,
) -> (RequestHandlerFn<P, T>, Lane) {
match_request! {
match method on self.server => {
"initialize" => initialize,
"textDocument/hover" => hover,
"textDocument/completion" => completion,
"completionItem/resolve" => completion_resolve,
"textDocument/declaration" => goto_declaration,
"textDocument/definition" => goto_definition,
"textDocument/typeDefinition" => goto_type_definition,
"textDocument/implementation" => goto_implementation,
"textDocument/references" => references,
"textDocument/prepareCallHierarchy" => prepare_call_hierarchy,
"callHierarchy/incomingCalls" => incoming_calls,
"callHierarchy/outgoingCalls" => outgoing_calls,
"textDocument/codeAction" => code_action,
"codeAction/resolve" => code_action_resolve,
"textDocument/codeLens" => code_lens,
"codeLens/resolve" => code_lens_resolve,
"textDocument/documentColor" => document_color,
"textDocument/colorPresentation" => color_presentation,
"textDocument/diagnostic" => diagnostic,
"textDocument/documentHighlight" => document_highlight,
"textDocument/documentLink" => document_link,
"documentLink/resolve" => document_link_resolve,
"textDocument/documentSymbol" => document_symbol,
"textDocument/foldingRange" => folding_range,
"textDocument/formatting" => formatting,
"textDocument/rangeFormatting" => range_formatting,
"textDocument/onTypeFormatting" => on_type_formatting,
"textDocument/inlayHint" => inlay_hint,
"inlayHint/resolve" => inlay_hint_resolve,
"textDocument/inlineValue" => inline_value,
"textDocument/linkedEditingRange" => linked_editing_range,
"textDocument/moniker" => moniker,
"textDocument/rename" => rename,
"textDocument/prepareRename" => prepare_rename,
"textDocument/selectionRange" => selection_range,
"textDocument/semanticTokens/full" => semantic_tokens_full,
"textDocument/semanticTokens/full/delta" => semantic_tokens_full_delta,
"textDocument/semanticTokens/range" => semantic_tokens_range,
"textDocument/signatureHelp" => signature_help,
"textDocument/willSaveWaitUntil" => will_save_wait_until,
"textDocument/prepareTypeHierarchy" => prepare_type_hierarchy,
"typeHierarchy/supertypes" => supertypes,
"typeHierarchy/subtypes" => subtypes,
"workspace/willCreateFiles" => will_create_files,
"workspace/willRenameFiles" => will_rename_files,
"workspace/willDeleteFiles" => will_delete_files,
"workspace/executeCommand" => execute_command,
"workspace/diagnostic" => workspace_diagnostic,
"workspace/symbol" => symbol,
"workspaceSymbol/resolve" => symbol_resolve,
}
}
}
}