mirror of
https://github.com/latex-lsp/texlab.git
synced 2025-12-23 09:19:21 +00:00
81 lines
2 KiB
Rust
81 lines
2 KiB
Rust
use anyhow::Result;
|
|
use log::warn;
|
|
use lsp_server::{ErrorCode, Notification, Request, RequestId, Response};
|
|
use serde::de::DeserializeOwned;
|
|
|
|
pub struct NotificationDispatcher {
|
|
not: Option<Notification>,
|
|
}
|
|
|
|
impl NotificationDispatcher {
|
|
pub fn new(not: Notification) -> Self {
|
|
Self { not: Some(not) }
|
|
}
|
|
|
|
pub fn on<N, F>(mut self, handler: F) -> Result<Self>
|
|
where
|
|
N: lsp_types::notification::Notification,
|
|
N::Params: DeserializeOwned,
|
|
F: FnOnce(N::Params) -> Result<()>,
|
|
{
|
|
if let Some(not) = self.not {
|
|
match not.extract::<N::Params>(N::METHOD) {
|
|
Ok(params) => {
|
|
handler(params)?;
|
|
self.not = None;
|
|
}
|
|
Err(not) => {
|
|
self.not = Some(not);
|
|
}
|
|
};
|
|
}
|
|
Ok(self)
|
|
}
|
|
|
|
pub fn default(self) {
|
|
if let Some(not) = &self.not {
|
|
warn!("Unknown notification: {}", not.method);
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct RequestDispatcher {
|
|
req: Option<Request>,
|
|
}
|
|
|
|
impl RequestDispatcher {
|
|
pub fn new(req: Request) -> Self {
|
|
Self { req: Some(req) }
|
|
}
|
|
|
|
pub fn on<R, F>(mut self, handler: F) -> Result<Self>
|
|
where
|
|
R: lsp_types::request::Request,
|
|
R::Params: DeserializeOwned,
|
|
F: FnOnce(RequestId, R::Params) -> Result<()>,
|
|
{
|
|
if let Some(req) = self.req {
|
|
match req.extract::<R::Params>(R::METHOD) {
|
|
Ok((id, params)) => {
|
|
handler(id, params)?;
|
|
self.req = None;
|
|
}
|
|
Err(req) => {
|
|
self.req = Some(req);
|
|
}
|
|
}
|
|
}
|
|
Ok(self)
|
|
}
|
|
|
|
pub fn default(self) -> Option<Response> {
|
|
self.req.map(|req| {
|
|
warn!("Unknown request: {}", req.method);
|
|
Response::new_err(
|
|
req.id,
|
|
ErrorCode::MethodNotFound as i32,
|
|
"method not found".to_string(),
|
|
)
|
|
})
|
|
}
|
|
}
|