Skip to content

Implement Service for Client #226

@ebkalderon

Description

@ebkalderon

It seems like a design oversight that the Client type does not implement the tower_service::Service trait. Implementing this trait would enable compatibility with the tower middleware, and hopefully simplify the request dispatching logic.

Unlike LspService as described in issue #177, Client should be perfectly capable of having a unary request/response model. In this case, the Request type parameter would be ClientRequest and the associated types would be as follows:

type Response = Option<Response>; // Response is `None` if the request was a notification.
type Error = crate::jsonrpc::Error;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;

It would be great if it were possible to implement Service generically, specializing over R: lsp_types::Request and N: lsp_types::Notification and accepting Params from both as input, but this is impossible to express in the Rust type system, as far as I can tell. I think the above approach is good enough solution for our use case.

We should think about whether ClientRequest should be redesigned to not include the id field for requests, in favor of having the Client manage it internally instead, using the request_id field. This prevents callers from submitting the same request ID twice, preventing accidental collisions and improving type safety.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions