use super::{Context, MessageWriter, Params};
use crate::rpc;
use async_trait::async_trait;
use futures::{Future, SinkExt};
use lsp_types::{notification::Notification, request::Request};
use serde::{de::DeserializeOwned, Serialize};
use std::marker::PhantomData;
#[async_trait(?Send)]
pub(crate) trait Handler<W: Clone> {
fn method(&self) -> &'static str;
async fn handle(
&mut self,
context: Context<W>,
message: rpc::Request<serde_json::Value>,
writer: Option<&mut dyn MessageWriter>,
);
fn box_clone(&self) -> Box<dyn Handler<W>>;
}
impl<W: Clone> Clone for Box<dyn Handler<W>> {
fn clone(&self) -> Self {
self.box_clone()
}
}
pub struct RequestHandler<R, F, W>
where
R: Request,
F: Future<Output = Result<R::Result, rpc::Error>>,
W: Clone,
{
f: fn(Context<W>, Params<R::Params>) -> F,
t: PhantomData<W>,
}
impl<R, F, W> Clone for RequestHandler<R, F, W>
where
R: Request,
F: Future<Output = Result<R::Result, rpc::Error>>,
W: Clone,
{
fn clone(&self) -> Self {
Self {
f: self.f,
t: Default::default(),
}
}
}
impl<R, F, W> RequestHandler<R, F, W>
where
R: Request,
F: Future<Output = Result<R::Result, rpc::Error>>,
W: Clone,
{
pub fn new(f: fn(Context<W>, Params<R::Params>) -> F) -> Self {
Self {
f,
t: Default::default(),
}
}
}
#[async_trait(?Send)]
impl<R, F, P, W> Handler<W> for RequestHandler<R, F, W>
where
R: Request<Params = P> + 'static,
P: Serialize + DeserializeOwned + 'static,
F: Future<Output = Result<R::Result, rpc::Error>> + 'static,
W: Clone + 'static,
{
fn method(&self) -> &'static str {
R::METHOD
}
async fn handle(
&mut self,
context: Context<W>,
message: rpc::Request<serde_json::Value>,
writer: Option<&mut dyn MessageWriter>,
) {
let req_id = message.id.clone();
let req = match message.into_params::<R::Params>() {
Ok(r) => r,
Err(e) => {
if let Some(w) = writer {
w.send(
rpc::Response::error(rpc::Error::invalid_params().with_data(e.to_string()))
.with_request_id(req_id.unwrap())
.into_message(),
)
.await
.unwrap();
}
return;
}
};
let call_result = (self.f)(context, req.params.into()).await;
if let Some(w) = writer {
let res = rpc::Response::from(call_result).with_request_id(req.id.unwrap());
w.send(res.into_message()).await.unwrap();
}
}
fn box_clone(&self) -> Box<dyn Handler<W>> {
Box::new((*self).clone())
}
}
#[derive(Clone)]
pub struct NotificationHandler<N, F, W>
where
N: Notification,
F: Future,
W: Clone,
{
f: fn(Context<W>, Params<N::Params>) -> F,
t: PhantomData<W>,
}
impl<N, F, W> NotificationHandler<N, F, W>
where
N: Notification,
F: Future,
W: Clone,
{
pub fn new(f: fn(Context<W>, Params<N::Params>) -> F) -> Self {
Self {
f,
t: Default::default(),
}
}
}
impl<N, F, W> NotificationHandler<N, F, W>
where
N: Notification,
F: Future,
W: Clone,
{
fn clone(&self) -> Self {
Self {
f: self.f,
t: Default::default(),
}
}
}
#[async_trait(?Send)]
impl<N, F, P, W> Handler<W> for NotificationHandler<N, F, W>
where
N: Notification<Params = P> + 'static,
P: Serialize + DeserializeOwned + 'static,
F: Future + 'static,
W: Clone + 'static,
{
fn method(&self) -> &'static str {
N::METHOD
}
async fn handle(
&mut self,
context: Context<W>,
message: rpc::Request<serde_json::Value>,
_writer: Option<&mut dyn MessageWriter>,
) {
let req = match message.into_params::<N::Params>() {
Ok(r) => r,
Err(_) => return,
};
(self.f)(context, req.params.into()).await;
}
fn box_clone(&self) -> Box<dyn Handler<W>> {
Box::new((*self).clone())
}
}