summaryrefslogtreecommitdiff
path: root/support/texlab/src/dispatch.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/src/dispatch.rs')
-rw-r--r--support/texlab/src/dispatch.rs81
1 files changed, 81 insertions, 0 deletions
diff --git a/support/texlab/src/dispatch.rs b/support/texlab/src/dispatch.rs
new file mode 100644
index 0000000000..a080016480
--- /dev/null
+++ b/support/texlab/src/dispatch.rs
@@ -0,0 +1,81 @@
+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(),
+ )
+ })
+ }
+}