From 4ccdca7a83c21b67650fd3121fd227ddea3553c1 Mon Sep 17 00:00:00 2001 From: Steve Dignam Date: Mon, 16 Mar 2026 12:51:27 -0400 Subject: [PATCH] server: refactor request handling to embrace types Based on rust-analyzer's approach https://github.com/rust-lang/rust-analyzer/blob/2efc80078029894eec0699f62ec8d5c1a56af763/crates/rust-analyzer/src/handlers/dispatch.rs#L259C6-L259C6 --- crates/squawk_server/src/dispatch.rs | 78 +++++++++++++++++++ crates/squawk_server/src/handlers.rs | 4 +- .../squawk_server/src/handlers/code_action.rs | 19 +---- .../squawk_server/src/handlers/completion.rs | 28 ++----- .../src/handlers/document_symbol.rs | 20 ++--- .../src/handlers/folding_range.rs | 20 ++--- .../src/handlers/goto_definition.rs | 19 +---- crates/squawk_server/src/handlers/hover.rs | 21 +---- .../squawk_server/src/handlers/inlay_hints.rs | 20 ++--- .../squawk_server/src/handlers/references.rs | 18 +---- .../src/handlers/selection_range.rs | 18 +---- .../squawk_server/src/handlers/syntax_tree.rs | 28 +++---- crates/squawk_server/src/handlers/tokens.rs | 30 +++---- crates/squawk_server/src/lib.rs | 1 + crates/squawk_server/src/lsp_utils.rs | 2 +- crates/squawk_server/src/server.rs | 62 +++++---------- 16 files changed, 164 insertions(+), 224 deletions(-) create mode 100644 crates/squawk_server/src/dispatch.rs diff --git a/crates/squawk_server/src/dispatch.rs b/crates/squawk_server/src/dispatch.rs new file mode 100644 index 00000000..d4aee76d --- /dev/null +++ b/crates/squawk_server/src/dispatch.rs @@ -0,0 +1,78 @@ +// Based on https://github.com/rust-lang/rust-analyzer/blob/2efc80078029894eec0699f62ec8d5c1a56af763/crates/rust-analyzer/src/handlers/dispatch.rs#L277C5-L277C5 + +use anyhow::Result; +use log::{error, info}; +use lsp_server::{Connection, Message, Response}; +use lsp_types::request::Request as LspRequest; + +use crate::system::System; + +pub(crate) struct RequestDispatcher<'a> { + connection: &'a Connection, + req: Option, + system: &'a dyn System, +} + +impl<'a> RequestDispatcher<'a> { + pub(crate) fn new( + connection: &'a Connection, + req: lsp_server::Request, + system: &'a dyn System, + ) -> Self { + Self { + connection, + req: Some(req), + system, + } + } + + fn parse(&mut self) -> Option<(lsp_server::RequestId, R::Params)> + where + R: LspRequest, + { + let req = self.req.take_if(|req| req.method.as_str() == R::METHOD)?; + let id = req.id.clone(); + + match req.extract(R::METHOD) { + Ok((id, params)) => Some((id, params)), + Err(err) => { + let response = lsp_server::Response::new_err( + id, + lsp_server::ErrorCode::InvalidParams as i32, + err.to_string(), + ); + if let Err(err) = self.connection.sender.send(Message::Response(response)) { + error!("Failed to send parse error response: {err}"); + } + None + } + } + } + + pub(crate) fn on( + mut self, + handler: fn(&dyn System, R::Params) -> Result, + ) -> Result + where + R: LspRequest, + { + if let Some((id, params)) = self.parse::() { + // TODO: we probably need to send an error here + let result = handler(self.system, params)?; + let resp = Response { + id, + result: Some(serde_json::to_value(result)?), + error: None, + }; + self.connection.sender.send(Message::Response(resp))?; + } + + Ok(self) + } + + pub(crate) fn finish(self) { + if let Some(req) = self.req { + info!("Ignoring unhandled request: {}", req.method); + } + } +} diff --git a/crates/squawk_server/src/handlers.rs b/crates/squawk_server/src/handlers.rs index 44f2de87..2e53b9f9 100644 --- a/crates/squawk_server/src/handlers.rs +++ b/crates/squawk_server/src/handlers.rs @@ -21,5 +21,5 @@ pub(crate) use inlay_hints::handle_inlay_hints; pub(crate) use notifications::{handle_did_change, handle_did_close, handle_did_open}; pub(crate) use references::handle_references; pub(crate) use selection_range::handle_selection_range; -pub(crate) use syntax_tree::handle_syntax_tree; -pub(crate) use tokens::handle_tokens; +pub(crate) use syntax_tree::{SyntaxTreeRequest, handle_syntax_tree}; +pub(crate) use tokens::{TokensRequest, handle_tokens}; diff --git a/crates/squawk_server/src/handlers/code_action.rs b/crates/squawk_server/src/handlers/code_action.rs index 80557300..9e43e9a7 100644 --- a/crates/squawk_server/src/handlers/code_action.rs +++ b/crates/squawk_server/src/handlers/code_action.rs @@ -1,5 +1,4 @@ use anyhow::{Context, Result}; -use lsp_server::{Connection, Message, Response}; use lsp_types::{ CodeAction, CodeActionKind, CodeActionOrCommand, CodeActionParams, CodeActionResponse, Command, WorkspaceEdit, @@ -13,11 +12,9 @@ use crate::lsp_utils; use crate::system::System; pub(crate) fn handle_code_action( - connection: &Connection, - req: lsp_server::Request, - system: &impl System, -) -> Result<()> { - let params: CodeActionParams = serde_json::from_value(req.params)?; + system: &dyn System, + params: CodeActionParams, +) -> Result> { let uri = params.text_document.uri; let mut actions: CodeActionResponse = vec![]; @@ -135,13 +132,5 @@ pub(crate) fn handle_code_action( } } - let result: CodeActionResponse = actions; - let resp = Response { - id: req.id, - result: Some(serde_json::to_value(&result).unwrap()), - error: None, - }; - - connection.sender.send(Message::Response(resp))?; - Ok(()) + Ok(Some(actions)) } diff --git a/crates/squawk_server/src/handlers/completion.rs b/crates/squawk_server/src/handlers/completion.rs index 6bd2f2a0..5c04777e 100644 --- a/crates/squawk_server/src/handlers/completion.rs +++ b/crates/squawk_server/src/handlers/completion.rs @@ -1,5 +1,4 @@ use anyhow::Result; -use lsp_server::{Connection, Message, Response}; use lsp_types::{CompletionParams, CompletionResponse}; use squawk_ide::completion::completion; use squawk_ide::db::line_index; @@ -8,11 +7,9 @@ use crate::lsp_utils; use crate::system::System; pub(crate) fn handle_completion( - connection: &Connection, - req: lsp_server::Request, - system: &impl System, -) -> Result<()> { - let params: CompletionParams = serde_json::from_value(req.params)?; + system: &dyn System, + params: CompletionParams, +) -> Result> { let uri = params.text_document_position.text_document.uri; let position = params.text_document_position.position; @@ -21,13 +18,7 @@ pub(crate) fn handle_completion( let line_index = line_index(db, file); let Some(offset) = lsp_utils::offset(&line_index, position) else { - let resp = Response { - id: req.id, - result: Some(serde_json::to_value(CompletionResponse::Array(vec![])).unwrap()), - error: None, - }; - connection.sender.send(Message::Response(resp))?; - return Ok(()); + return Ok(Some(CompletionResponse::Array(vec![]))); }; let completion_items = completion(db, file, offset) @@ -35,14 +26,5 @@ pub(crate) fn handle_completion( .map(lsp_utils::completion_item) .collect(); - let result = CompletionResponse::Array(completion_items); - - let resp = Response { - id: req.id, - result: Some(serde_json::to_value(&result).unwrap()), - error: None, - }; - - connection.sender.send(Message::Response(resp))?; - Ok(()) + Ok(Some(CompletionResponse::Array(completion_items))) } diff --git a/crates/squawk_server/src/handlers/document_symbol.rs b/crates/squawk_server/src/handlers/document_symbol.rs index e628d6f3..df31ae94 100644 --- a/crates/squawk_server/src/handlers/document_symbol.rs +++ b/crates/squawk_server/src/handlers/document_symbol.rs @@ -1,7 +1,6 @@ use ::line_index::LineIndex; use anyhow::Result; -use lsp_server::{Connection, Message, Response}; -use lsp_types::{DocumentSymbol, DocumentSymbolParams, SymbolKind}; +use lsp_types::{DocumentSymbol, DocumentSymbolParams, DocumentSymbolResponse, SymbolKind}; use squawk_ide::db::line_index; use squawk_ide::document_symbols::{DocumentSymbolKind, document_symbols}; @@ -9,11 +8,9 @@ use crate::lsp_utils; use crate::system::System; pub(crate) fn handle_document_symbol( - connection: &Connection, - req: lsp_server::Request, - system: &impl System, -) -> Result<()> { - let params: DocumentSymbolParams = serde_json::from_value(req.params)?; + system: &dyn System, + params: DocumentSymbolParams, +) -> Result> { let uri = params.text_document.uri; let db = system.db(); @@ -81,12 +78,5 @@ pub(crate) fn handle_document_symbol( .map(|sym| convert_symbol(sym, &line_index)) .collect(); - let resp = Response { - id: req.id, - result: Some(serde_json::to_value(&lsp_symbols).unwrap()), - error: None, - }; - - connection.sender.send(Message::Response(resp))?; - Ok(()) + Ok(Some(DocumentSymbolResponse::Nested(lsp_symbols))) } diff --git a/crates/squawk_server/src/handlers/folding_range.rs b/crates/squawk_server/src/handlers/folding_range.rs index 042377a2..2fecfb6f 100644 --- a/crates/squawk_server/src/handlers/folding_range.rs +++ b/crates/squawk_server/src/handlers/folding_range.rs @@ -1,6 +1,5 @@ use anyhow::Result; -use lsp_server::{Connection, Message, Response}; -use lsp_types::FoldingRange; +use lsp_types::{FoldingRange, FoldingRangeParams}; use squawk_ide::db::line_index; use squawk_ide::folding_ranges::folding_ranges; @@ -8,11 +7,9 @@ use crate::lsp_utils; use crate::system::System; pub(crate) fn handle_folding_range( - connection: &Connection, - req: lsp_server::Request, - system: &impl System, -) -> Result<()> { - let params: lsp_types::FoldingRangeParams = serde_json::from_value(req.params)?; + system: &dyn System, + params: FoldingRangeParams, +) -> Result>> { let uri = params.text_document.uri; let db = system.db(); @@ -24,12 +21,5 @@ pub(crate) fn handle_folding_range( .map(|fold| lsp_utils::folding_range(&line_idx, fold)) .collect(); - let resp = Response { - id: req.id, - result: Some(serde_json::to_value(&lsp_folds).unwrap()), - error: None, - }; - - connection.sender.send(Message::Response(resp))?; - Ok(()) + Ok(Some(lsp_folds)) } diff --git a/crates/squawk_server/src/handlers/goto_definition.rs b/crates/squawk_server/src/handlers/goto_definition.rs index 06b5df3c..65b2d80c 100644 --- a/crates/squawk_server/src/handlers/goto_definition.rs +++ b/crates/squawk_server/src/handlers/goto_definition.rs @@ -1,5 +1,4 @@ use anyhow::Result; -use lsp_server::{Connection, Message, Response}; use lsp_types::{GotoDefinitionParams, GotoDefinitionResponse}; use squawk_ide::db::line_index; use squawk_ide::goto_definition::goto_definition; @@ -8,11 +7,9 @@ use crate::lsp_utils::{self, to_location}; use crate::system::System; pub(crate) fn handle_goto_definition( - connection: &Connection, - req: lsp_server::Request, - system: &impl System, -) -> Result<()> { - let params: GotoDefinitionParams = serde_json::from_value(req.params)?; + system: &dyn System, + params: GotoDefinitionParams, +) -> Result> { let uri = params.text_document_position_params.text_document.uri; let position = params.text_document_position_params.position; @@ -32,13 +29,5 @@ pub(crate) fn handle_goto_definition( }) .collect(); - let result = GotoDefinitionResponse::Array(ranges); - let resp = Response { - id: req.id, - result: Some(serde_json::to_value(&result).unwrap()), - error: None, - }; - - connection.sender.send(Message::Response(resp))?; - Ok(()) + Ok(Some(GotoDefinitionResponse::Array(ranges))) } diff --git a/crates/squawk_server/src/handlers/hover.rs b/crates/squawk_server/src/handlers/hover.rs index 5e9ce165..87a6120c 100644 --- a/crates/squawk_server/src/handlers/hover.rs +++ b/crates/squawk_server/src/handlers/hover.rs @@ -1,5 +1,4 @@ use anyhow::Result; -use lsp_server::{Connection, Message, Response}; use lsp_types::{Hover, HoverContents, HoverParams, LanguageString, MarkedString}; use squawk_ide::db::line_index; use squawk_ide::hover::hover; @@ -7,12 +6,7 @@ use squawk_ide::hover::hover; use crate::lsp_utils; use crate::system::System; -pub(crate) fn handle_hover( - connection: &Connection, - req: lsp_server::Request, - system: &impl System, -) -> Result<()> { - let params: HoverParams = serde_json::from_value(req.params)?; +pub(crate) fn handle_hover(system: &dyn System, params: HoverParams) -> Result> { let uri = params.text_document_position_params.text_document.uri; let position = params.text_document_position_params.position; @@ -23,20 +17,11 @@ pub(crate) fn handle_hover( let type_info = hover(db, file, offset); - let result = type_info.map(|type_str| Hover { + Ok(type_info.map(|type_str| Hover { contents: HoverContents::Scalar(MarkedString::LanguageString(LanguageString { language: "sql".to_string(), value: type_str, })), range: None, - }); - - let resp = Response { - id: req.id, - result: Some(serde_json::to_value(&result).unwrap()), - error: None, - }; - - connection.sender.send(Message::Response(resp))?; - Ok(()) + })) } diff --git a/crates/squawk_server/src/handlers/inlay_hints.rs b/crates/squawk_server/src/handlers/inlay_hints.rs index becf9d86..91700ecc 100644 --- a/crates/squawk_server/src/handlers/inlay_hints.rs +++ b/crates/squawk_server/src/handlers/inlay_hints.rs @@ -1,5 +1,4 @@ use anyhow::Result; -use lsp_server::{Connection, Message, Response}; use lsp_types::{ InlayHint, InlayHintKind, InlayHintLabel, InlayHintLabelPart, InlayHintParams, Location, }; @@ -11,11 +10,9 @@ use crate::lsp_utils; use crate::system::System; pub(crate) fn handle_inlay_hints( - connection: &Connection, - req: lsp_server::Request, - system: &impl System, -) -> Result<()> { - let params: InlayHintParams = serde_json::from_value(req.params)?; + system: &dyn System, + params: InlayHintParams, +) -> Result>> { let uri = params.text_document.uri; let db = system.db(); @@ -41,8 +38,8 @@ pub(crate) fn handle_inlay_hints( }; let kind: InlayHintKind = match hint.kind { - squawk_ide::inlay_hints::InlayHintKind::Type => InlayHintKind::TYPE, squawk_ide::inlay_hints::InlayHintKind::Parameter => InlayHintKind::PARAMETER, + squawk_ide::inlay_hints::InlayHintKind::Type => InlayHintKind::TYPE, }; let label = if let Some(target_range) = hint.target { @@ -72,12 +69,5 @@ pub(crate) fn handle_inlay_hints( }) .collect(); - let resp = Response { - id: req.id, - result: Some(serde_json::to_value(&lsp_hints).unwrap()), - error: None, - }; - - connection.sender.send(Message::Response(resp))?; - Ok(()) + Ok(Some(lsp_hints)) } diff --git a/crates/squawk_server/src/handlers/references.rs b/crates/squawk_server/src/handlers/references.rs index fae7f24e..e32b010f 100644 --- a/crates/squawk_server/src/handlers/references.rs +++ b/crates/squawk_server/src/handlers/references.rs @@ -1,5 +1,4 @@ use anyhow::Result; -use lsp_server::{Connection, Message, Response}; use lsp_types::{Location, ReferenceParams}; use squawk_ide::db::line_index; use squawk_ide::find_references::find_references; @@ -8,11 +7,9 @@ use crate::lsp_utils::{self, to_location}; use crate::system::System; pub(crate) fn handle_references( - connection: &Connection, - req: lsp_server::Request, - system: &impl System, -) -> Result<()> { - let params: ReferenceParams = serde_json::from_value(req.params)?; + system: &dyn System, + params: ReferenceParams, +) -> Result>> { let uri = params.text_document_position.text_document.uri; let position = params.text_document_position.position; @@ -30,12 +27,5 @@ pub(crate) fn handle_references( .filter_map(|loc| to_location(db, system, &uri, loc)) .collect(); - let resp = Response { - id: req.id, - result: Some(serde_json::to_value(&locations).unwrap()), - error: None, - }; - - connection.sender.send(Message::Response(resp))?; - Ok(()) + Ok(Some(locations)) } diff --git a/crates/squawk_server/src/handlers/selection_range.rs b/crates/squawk_server/src/handlers/selection_range.rs index d5a100bd..23a52c76 100644 --- a/crates/squawk_server/src/handlers/selection_range.rs +++ b/crates/squawk_server/src/handlers/selection_range.rs @@ -1,5 +1,4 @@ use anyhow::Result; -use lsp_server::{Connection, Message, Response}; use lsp_types::SelectionRangeParams; use rowan::TextRange; use squawk_ide::db::{line_index, parse}; @@ -8,11 +7,9 @@ use crate::lsp_utils; use crate::system::System; pub(crate) fn handle_selection_range( - connection: &Connection, - req: lsp_server::Request, - system: &impl System, -) -> Result<()> { - let params: SelectionRangeParams = serde_json::from_value(req.params)?; + system: &dyn System, + params: SelectionRangeParams, +) -> Result>> { let uri = params.text_document.uri; let db = system.db(); @@ -55,12 +52,5 @@ pub(crate) fn handle_selection_range( selection_ranges.push(range); } - let resp = Response { - id: req.id, - result: Some(serde_json::to_value(&selection_ranges).unwrap()), - error: None, - }; - - connection.sender.send(Message::Response(resp))?; - Ok(()) + Ok(Some(selection_ranges)) } diff --git a/crates/squawk_server/src/handlers/syntax_tree.rs b/crates/squawk_server/src/handlers/syntax_tree.rs index 45228848..6894d4e6 100644 --- a/crates/squawk_server/src/handlers/syntax_tree.rs +++ b/crates/squawk_server/src/handlers/syntax_tree.rs @@ -1,22 +1,25 @@ use anyhow::Result; use log::info; -use lsp_server::{Connection, Message, Response}; +use lsp_types::request::Request; use squawk_ide::db::parse; use crate::system::System; -#[derive(serde::Deserialize)] +#[derive(serde::Deserialize, serde::Serialize)] pub(crate) struct SyntaxTreeParams { #[serde(rename = "textDocument")] text_document: lsp_types::TextDocumentIdentifier, } -pub(crate) fn handle_syntax_tree( - connection: &Connection, - req: lsp_server::Request, - system: &impl System, -) -> Result<()> { - let params: SyntaxTreeParams = serde_json::from_value(req.params)?; +pub(crate) enum SyntaxTreeRequest {} + +impl Request for SyntaxTreeRequest { + type Params = SyntaxTreeParams; + type Result = String; + const METHOD: &'static str = "squawk/syntaxTree"; +} + +pub(crate) fn handle_syntax_tree(system: &dyn System, params: SyntaxTreeParams) -> Result { let uri = params.text_document.uri; info!("Generating syntax tree for: {uri}"); @@ -26,12 +29,5 @@ pub(crate) fn handle_syntax_tree( let parse = parse(db, file); let syntax_tree = format!("{:#?}", parse.syntax_node()); - let resp = Response { - id: req.id, - result: Some(serde_json::to_value(&syntax_tree).unwrap()), - error: None, - }; - - connection.sender.send(Message::Response(resp))?; - Ok(()) + Ok(syntax_tree) } diff --git a/crates/squawk_server/src/handlers/tokens.rs b/crates/squawk_server/src/handlers/tokens.rs index 7460035f..fec367d1 100644 --- a/crates/squawk_server/src/handlers/tokens.rs +++ b/crates/squawk_server/src/handlers/tokens.rs @@ -1,21 +1,24 @@ use anyhow::Result; use log::info; -use lsp_server::{Connection, Message, Response}; +use lsp_types::request::Request; use crate::system::System; -#[derive(serde::Deserialize)] +#[derive(serde::Deserialize, serde::Serialize)] pub(crate) struct TokensParams { #[serde(rename = "textDocument")] text_document: lsp_types::TextDocumentIdentifier, } -pub(crate) fn handle_tokens( - connection: &Connection, - req: lsp_server::Request, - system: &impl System, -) -> Result<()> { - let params: TokensParams = serde_json::from_value(req.params)?; +pub(crate) enum TokensRequest {} + +impl Request for TokensRequest { + type Params = TokensParams; + type Result = String; + const METHOD: &'static str = "squawk/tokens"; +} + +pub(crate) fn handle_tokens(system: &dyn System, params: TokensParams) -> Result { let uri = params.text_document.uri; info!("Generating tokens for: {uri}"); @@ -40,14 +43,5 @@ pub(crate) fn handle_tokens( char_pos = token_end; } - let tokens_output = output.join("\n"); - - let resp = Response { - id: req.id, - result: Some(serde_json::to_value(&tokens_output).unwrap()), - error: None, - }; - - connection.sender.send(Message::Response(resp))?; - Ok(()) + Ok(output.join("\n")) } diff --git a/crates/squawk_server/src/lib.rs b/crates/squawk_server/src/lib.rs index 195c28e7..bb5c7ce8 100644 --- a/crates/squawk_server/src/lib.rs +++ b/crates/squawk_server/src/lib.rs @@ -1,4 +1,5 @@ mod diagnostic; +mod dispatch; mod handlers; mod ignore; mod lint; diff --git a/crates/squawk_server/src/lsp_utils.rs b/crates/squawk_server/src/lsp_utils.rs index 49b7ae43..675a4f06 100644 --- a/crates/squawk_server/src/lsp_utils.rs +++ b/crates/squawk_server/src/lsp_utils.rs @@ -216,7 +216,7 @@ pub(crate) fn apply_incremental_changes( pub(crate) fn to_location( db: &dyn salsa::Database, - system: &impl System, + system: &dyn System, uri: &Url, loc: squawk_ide::goto_definition::Location, ) -> Option { diff --git a/crates/squawk_server/src/server.rs b/crates/squawk_server/src/server.rs index c6a13992..68062d6d 100644 --- a/crates/squawk_server/src/server.rs +++ b/crates/squawk_server/src/server.rs @@ -11,15 +11,16 @@ use lsp_types::{ }, request::{ CodeActionRequest, Completion, DocumentSymbolRequest, FoldingRangeRequest, GotoDefinition, - HoverRequest, InlayHintRequest, References, Request, SelectionRangeRequest, + HoverRequest, InlayHintRequest, References, SelectionRangeRequest, }, }; +use crate::dispatch::RequestDispatcher; use crate::handlers::{ - handle_code_action, handle_completion, handle_did_change, handle_did_close, handle_did_open, - handle_document_symbol, handle_folding_range, handle_goto_definition, handle_hover, - handle_inlay_hints, handle_references, handle_selection_range, handle_syntax_tree, - handle_tokens, + SyntaxTreeRequest, TokensRequest, handle_code_action, handle_completion, handle_did_change, + handle_did_close, handle_did_open, handle_document_symbol, handle_folding_range, + handle_goto_definition, handle_hover, handle_inlay_hints, handle_references, + handle_selection_range, handle_syntax_tree, handle_tokens, }; use crate::system::GlobalState; @@ -94,44 +95,19 @@ fn main_loop(connection: Connection, params: serde_json::Value) -> Result<()> { return Ok(()); } - match req.method.as_ref() { - GotoDefinition::METHOD => { - handle_goto_definition(&connection, req, &system)?; - } - HoverRequest::METHOD => { - handle_hover(&connection, req, &system)?; - } - CodeActionRequest::METHOD => { - handle_code_action(&connection, req, &system)?; - } - SelectionRangeRequest::METHOD => { - handle_selection_range(&connection, req, &system)?; - } - InlayHintRequest::METHOD => { - handle_inlay_hints(&connection, req, &system)?; - } - DocumentSymbolRequest::METHOD => { - handle_document_symbol(&connection, req, &system)?; - } - FoldingRangeRequest::METHOD => { - handle_folding_range(&connection, req, &system)?; - } - Completion::METHOD => { - handle_completion(&connection, req, &system)?; - } - "squawk/syntaxTree" => { - handle_syntax_tree(&connection, req, &system)?; - } - "squawk/tokens" => { - handle_tokens(&connection, req, &system)?; - } - References::METHOD => { - handle_references(&connection, req, &system)?; - } - _ => { - info!("Ignoring unhandled request: {}", req.method); - } - } + RequestDispatcher::new(&connection, req, &system) + .on::(handle_goto_definition)? + .on::(handle_hover)? + .on::(handle_code_action)? + .on::(handle_selection_range)? + .on::(handle_inlay_hints)? + .on::(handle_document_symbol)? + .on::(handle_folding_range)? + .on::(handle_completion)? + .on::(handle_syntax_tree)? + .on::(handle_tokens)? + .on::(handle_references)? + .finish(); } Message::Response(resp) => { info!("Received response: id={:?}", resp.id);