summaryrefslogtreecommitdiff
path: root/support/texlab/crates/jsonrpc/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/crates/jsonrpc/src/lib.rs')
-rw-r--r--support/texlab/crates/jsonrpc/src/lib.rs72
1 files changed, 72 insertions, 0 deletions
diff --git a/support/texlab/crates/jsonrpc/src/lib.rs b/support/texlab/crates/jsonrpc/src/lib.rs
new file mode 100644
index 0000000000..8786598d58
--- /dev/null
+++ b/support/texlab/crates/jsonrpc/src/lib.rs
@@ -0,0 +1,72 @@
+pub mod client;
+pub mod server;
+mod types;
+
+pub use self::{
+ client::{Client, ResponseHandler},
+ server::{handle_notification, handle_request, Middleware, RequestHandler},
+ types::*,
+};
+
+use futures::channel::*;
+use futures::prelude::*;
+use log::error;
+use std::io;
+use std::sync::Arc;
+
+pub struct MessageHandler<S, C, I> {
+ pub server: Arc<S>,
+ pub client: Arc<C>,
+ pub input: I,
+ pub output: mpsc::Sender<String>,
+}
+
+impl<S, C, I> MessageHandler<S, C, I>
+where
+ S: RequestHandler + Middleware + Send + Sync + 'static,
+ C: ResponseHandler + Send + Sync + 'static,
+ I: Stream<Item = io::Result<String>> + Unpin,
+{
+ pub async fn listen(&mut self) {
+ while let Some(json) = self.input.next().await {
+ self.server.before_message().await;
+
+ match serde_json::from_str(&json.unwrap()).map_err(|_| Error::parse_error()) {
+ Ok(Message::Request(request)) => {
+ let server = Arc::clone(&self.server);
+ let mut output = self.output.clone();
+ tokio::spawn(async move {
+ let response = server.handle_request(request).await;
+ if let Some(error) = response.error.as_ref() {
+ error!("{:?}", error);
+ }
+ let json = serde_json::to_string(&response).unwrap();
+ output.send(json).await.unwrap();
+ server.after_message().await;
+ });
+ }
+ Ok(Message::Notification(notification)) => {
+ self.server.handle_notification(notification);
+ self.after_message();
+ }
+ Ok(Message::Response(response)) => {
+ self.client.handle(response).await;
+ self.after_message();
+ }
+ Err(why) => {
+ let response = Response::error(why, None);
+ let json = serde_json::to_string(&response).unwrap();
+ self.output.send(json).await.unwrap();
+ self.after_message();
+ }
+ };
+ }
+ }
+
+ fn after_message(&self) {
+ let server = Arc::clone(&self.server);
+ tokio::spawn(async move {
+ server.after_message().await;
+ });
+ }
+}