summaryrefslogtreecommitdiff
path: root/support/texlab/crates
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-05-23 03:00:39 +0000
committerNorbert Preining <norbert@preining.info>2021-05-23 03:00:39 +0000
commitf1261b349e875b842745b63258c3e338cb1fe3bf (patch)
treeb5d402b3e80818cde2c079a42249f3dcb9732247 /support/texlab/crates
parent58aa1ac09b1d9e4769d0a0661cf12e2b2db41b14 (diff)
CTAN sync 202105230300
Diffstat (limited to 'support/texlab/crates')
-rw-r--r--support/texlab/crates/jsonrpc/Cargo.toml20
-rw-r--r--support/texlab/crates/jsonrpc/src/client.rs77
-rw-r--r--support/texlab/crates/jsonrpc/src/lib.rs67
-rw-r--r--support/texlab/crates/jsonrpc/src/server.rs131
-rw-r--r--support/texlab/crates/jsonrpc/src/types.rs144
-rw-r--r--support/texlab/crates/jsonrpc_derive/Cargo.toml15
-rw-r--r--support/texlab/crates/jsonrpc_derive/src/lib.rs207
7 files changed, 0 insertions, 661 deletions
diff --git a/support/texlab/crates/jsonrpc/Cargo.toml b/support/texlab/crates/jsonrpc/Cargo.toml
deleted file mode 100644
index c5cec72074..0000000000
--- a/support/texlab/crates/jsonrpc/Cargo.toml
+++ /dev/null
@@ -1,20 +0,0 @@
-[package]
-name = "jsonrpc"
-version = "0.1.0"
-authors = [
- "Eric Förster <eric.foerster@outlook.com>",
- "Patrick Förster <patrick.foerster@outlook.de>"]
-edition = "2018"
-
-[lib]
-doctest = false
-
-[dependencies]
-async-trait = "0.1"
-chashmap = "2.2"
-futures = "0.3"
-log = "0.4"
-serde = { version = "1.0", features = ["derive", "rc"] }
-serde_json = "1.0"
-serde_repr = "0.1"
-tokio = { version = "0.2", features = ["rt-core"] }
diff --git a/support/texlab/crates/jsonrpc/src/client.rs b/support/texlab/crates/jsonrpc/src/client.rs
deleted file mode 100644
index 7d714283c6..0000000000
--- a/support/texlab/crates/jsonrpc/src/client.rs
+++ /dev/null
@@ -1,77 +0,0 @@
-use super::types::*;
-use async_trait::async_trait;
-use chashmap::CHashMap;
-use futures::{
- channel::{mpsc, oneshot},
- prelude::*,
-};
-use serde::Serialize;
-use serde_json::json;
-use std::sync::atomic::{AtomicU64, Ordering};
-
-pub type Result<T> = std::result::Result<T, Error>;
-
-#[async_trait]
-pub trait ResponseHandler {
- async fn handle(&self, response: Response);
-}
-
-#[derive(Debug)]
-pub struct Client {
- output: mpsc::Sender<String>,
- request_id: AtomicU64,
- senders_by_id: CHashMap<Id, oneshot::Sender<Result<serde_json::Value>>>,
-}
-
-impl Client {
- pub fn new(output: mpsc::Sender<String>) -> Self {
- Self {
- output,
- request_id: AtomicU64::new(0),
- senders_by_id: CHashMap::new(),
- }
- }
-
- pub async fn send_request<T: Serialize>(
- &self,
- method: String,
- params: T,
- ) -> Result<serde_json::Value> {
- let id = self.request_id.fetch_add(1, Ordering::SeqCst);
- let request = Request::new(method, json!(params), Id::Number(id));
-
- let (result_tx, result_rx) = oneshot::channel();
- self.senders_by_id.insert(request.id.clone(), result_tx);
- self.send(Message::Request(request)).await;
-
- result_rx.await.unwrap()
- }
-
- pub async fn send_notification<T: Serialize>(&self, method: String, params: T) {
- let notification = Notification::new(method, json!(params));
- self.send(Message::Notification(notification)).await;
- }
-
- async fn send(&self, message: Message) {
- let mut output = self.output.clone();
- let json = serde_json::to_string(&message).unwrap();
- output.send(json).await.unwrap();
- }
-}
-
-#[async_trait]
-impl ResponseHandler for Client {
- async fn handle(&self, response: Response) {
- let id = response.id.expect("Expected response with id");
- let result = match response.error {
- Some(why) => Err(why),
- None => Ok(response.result.unwrap_or(serde_json::Value::Null)),
- };
-
- let result_tx = self
- .senders_by_id
- .remove(&id)
- .expect("Unexpected response received");
- result_tx.send(result).unwrap();
- }
-}
diff --git a/support/texlab/crates/jsonrpc/src/lib.rs b/support/texlab/crates/jsonrpc/src/lib.rs
deleted file mode 100644
index 3a771e6ba5..0000000000
--- a/support/texlab/crates/jsonrpc/src/lib.rs
+++ /dev/null
@@ -1,67 +0,0 @@
-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::mpsc, prelude::*};
-use log::error;
-use std::sync::Arc;
-
-#[derive(Debug)]
-pub struct MessageHandler<S, C> {
- pub server: Arc<S>,
- pub client: Arc<C>,
- pub output: mpsc::Sender<String>,
-}
-
-impl<S, C> MessageHandler<S, C>
-where
- S: RequestHandler + Middleware + Send + Sync + 'static,
- C: ResponseHandler + Send + Sync + 'static,
-{
- pub async fn handle(&mut self, json: &str) {
- self.server.before_message().await;
-
- match serde_json::from_str(json).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).await;
- 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;
- });
- }
-}
diff --git a/support/texlab/crates/jsonrpc/src/server.rs b/support/texlab/crates/jsonrpc/src/server.rs
deleted file mode 100644
index ce34dc8b60..0000000000
--- a/support/texlab/crates/jsonrpc/src/server.rs
+++ /dev/null
@@ -1,131 +0,0 @@
-use super::types::*;
-use async_trait::async_trait;
-use futures::prelude::*;
-use serde::{de::DeserializeOwned, Serialize};
-use serde_json::json;
-
-pub type Result<T> = std::result::Result<T, String>;
-
-#[async_trait]
-pub trait RequestHandler {
- async fn handle_request(&self, request: Request) -> Response;
-
- async fn handle_notification(&self, notification: Notification);
-}
-
-#[async_trait]
-pub trait Middleware {
- async fn before_message(&self);
-
- async fn after_message(&self);
-}
-
-pub async fn handle_request<'a, H, F, I, O>(request: Request, handler: H) -> Response
-where
- H: Fn(I) -> F + Send + Sync + 'a,
- F: Future<Output = Result<O>> + Send,
- I: DeserializeOwned + Send,
- O: Serialize,
-{
- let handle = |json| async move {
- let params: I = serde_json::from_value(json).map_err(|_| Error::deserialize_error())?;
- let result = handler(params).await.map_err(Error::internal_error)?;
- Ok(result)
- };
-
- match handle(request.params).await {
- Ok(result) => Response::result(json!(result), request.id),
- Err(error) => Response::error(error, Some(request.id)),
- }
-}
-
-pub async fn handle_notification<'a, H, F, I>(notification: Notification, handler: H)
-where
- H: Fn(I) -> F + Send + Sync + 'a,
- F: Future<Output = ()> + Send,
- I: DeserializeOwned + Send,
-{
- let error = Error::deserialize_error().message;
- let params = serde_json::from_value(notification.params).expect(&error);
- handler(params).await;
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- const METHOD_NAME: &str = "foo";
-
- async fn increment(i: i32) -> Result<i32> {
- Ok(i + 1)
- }
-
- async fn panic(_params: ()) {
- panic!("success");
- }
-
- fn setup_request<T: Serialize>(value: T) -> Request {
- Request {
- jsonrpc: PROTOCOL_VERSION.to_owned(),
- params: json!(value),
- method: METHOD_NAME.to_owned(),
- id: Id::Number(0),
- }
- }
-
- fn setup_notification() -> Notification {
- Notification {
- jsonrpc: PROTOCOL_VERSION.to_owned(),
- method: METHOD_NAME.to_owned(),
- params: json!(()),
- }
- }
-
- #[tokio::test]
- async fn request_valid() {
- let value = 42;
- let request = setup_request(value);
-
- let response = handle_request(request.clone(), increment).await;
- let expected = Response {
- jsonrpc: request.jsonrpc,
- result: Some(json!(increment(value).await.unwrap())),
- error: None,
- id: Some(request.id),
- };
-
- assert_eq!(response, expected);
- }
-
- #[tokio::test]
- async fn request_invalid_params() {
- let request = setup_request((0, 0));
-
- let response = handle_request(request.clone(), increment).await;
- let expected = Response {
- jsonrpc: request.jsonrpc.clone(),
- result: None,
- error: Some(Error::deserialize_error()),
- id: Some(request.id),
- };
-
- assert_eq!(response, expected);
- }
-
- #[tokio::test]
- #[should_panic(expected = "success")]
- async fn notification_valid() {
- let notification = setup_notification();
- handle_notification(notification, panic).await;
- }
-
- #[tokio::test]
- #[should_panic]
- async fn notification_invalid_params() {
- let notification = Notification {
- params: json!(0),
- ..setup_notification()
- };
- handle_notification(notification, panic).await;
- }
-}
diff --git a/support/texlab/crates/jsonrpc/src/types.rs b/support/texlab/crates/jsonrpc/src/types.rs
deleted file mode 100644
index 30036d1c7f..0000000000
--- a/support/texlab/crates/jsonrpc/src/types.rs
+++ /dev/null
@@ -1,144 +0,0 @@
-use serde::{Deserialize, Serialize};
-use serde_repr::*;
-
-pub const PROTOCOL_VERSION: &str = "2.0";
-
-#[derive(Debug, Eq, Hash, PartialEq, Clone, Deserialize, Serialize)]
-#[serde(untagged)]
-pub enum Id {
- Number(u64),
- String(String),
-}
-
-#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize_repr, Serialize_repr)]
-#[repr(i32)]
-pub enum ErrorCode {
- ParseError = -32700,
- InvalidRequest = -32600,
- MethodNotFound = -32601,
- InvalidParams = -32602,
- InternalError = -32603,
- ServerNotInitialized = -32002,
- UnknownErrorCode = -32001,
- RequestCancelled = -32800,
-}
-
-#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
-pub struct Error {
- pub code: ErrorCode,
- pub message: String,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub data: Option<serde_json::Value>,
-}
-
-impl Error {
- pub fn parse_error() -> Self {
- Self {
- code: ErrorCode::ParseError,
- message: "Could not parse the input".to_owned(),
- data: None,
- }
- }
-
- pub fn method_not_found_error() -> Self {
- Self {
- code: ErrorCode::MethodNotFound,
- message: "Method not found".to_owned(),
- data: None,
- }
- }
-
- pub fn deserialize_error() -> Self {
- Self {
- code: ErrorCode::InvalidParams,
- message: "Could not deserialize parameter object".to_owned(),
- data: None,
- }
- }
-
- pub fn internal_error(message: String) -> Self {
- Self {
- code: ErrorCode::InternalError,
- message,
- data: None,
- }
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
-pub struct Request {
- pub jsonrpc: String,
- pub method: String,
- pub params: serde_json::Value,
- pub id: Id,
-}
-
-impl Request {
- pub fn new(method: String, params: serde_json::Value, id: Id) -> Self {
- Self {
- jsonrpc: PROTOCOL_VERSION.to_owned(),
- method,
- params,
- id,
- }
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
-pub struct Response {
- pub jsonrpc: String,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub result: Option<serde_json::Value>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub error: Option<Error>,
-
- pub id: Option<Id>,
-}
-
-impl Response {
- pub fn result(result: serde_json::Value, id: Id) -> Self {
- Self {
- jsonrpc: PROTOCOL_VERSION.to_owned(),
- result: Some(result),
- error: None,
- id: Some(id),
- }
- }
-
- pub fn error(error: Error, id: Option<Id>) -> Self {
- Self {
- jsonrpc: PROTOCOL_VERSION.to_owned(),
- result: None,
- error: Some(error),
- id,
- }
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
-pub struct Notification {
- pub jsonrpc: String,
- pub method: String,
- pub params: serde_json::Value,
-}
-
-impl Notification {
- pub fn new(method: String, params: serde_json::Value) -> Self {
- Self {
- jsonrpc: PROTOCOL_VERSION.to_owned(),
- method,
- params,
- }
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
-#[serde(untagged)]
-pub enum Message {
- Request(Request),
- Notification(Notification),
- Response(Response),
-}
diff --git a/support/texlab/crates/jsonrpc_derive/Cargo.toml b/support/texlab/crates/jsonrpc_derive/Cargo.toml
deleted file mode 100644
index fb99f16a26..0000000000
--- a/support/texlab/crates/jsonrpc_derive/Cargo.toml
+++ /dev/null
@@ -1,15 +0,0 @@
-[package]
-name = "jsonrpc-derive"
-version = "0.1.0"
-authors = [
- "Eric Förster <eric.foerster@outlook.com>",
- "Patrick Förster <patrick.foerster@outlook.de>"]
-edition = "2018"
-
-[lib]
-proc-macro = true
-doctest = false
-
-[dependencies]
-syn = "1.0"
-quote = "1.0"
diff --git a/support/texlab/crates/jsonrpc_derive/src/lib.rs b/support/texlab/crates/jsonrpc_derive/src/lib.rs
deleted file mode 100644
index 283be858db..0000000000
--- a/support/texlab/crates/jsonrpc_derive/src/lib.rs
+++ /dev/null
@@ -1,207 +0,0 @@
-#![recursion_limit = "128"]
-
-extern crate proc_macro;
-
-use proc_macro::TokenStream;
-use quote::quote;
-use syn::{export::TokenStream2, *};
-
-macro_rules! unwrap {
- ($input:expr, $arm:pat => $value:expr) => {{
- match $input {
- $arm => $value,
- _ => panic!(),
- }
- }};
-}
-
-enum MethodKind {
- Request,
- Notification,
-}
-
-struct MethodMeta {
- pub name: String,
- pub kind: MethodKind,
-}
-
-impl MethodMeta {
- pub fn parse(attr: &Attribute) -> Self {
- let meta = attr.parse_meta().unwrap();
- if meta.path().get_ident().unwrap() != "jsonrpc_method" {
- panic!("Expected jsonrpc_method attribute");
- }
-
- let nested = unwrap!(meta, Meta::List(x) => x.nested);
- let name = unwrap!(&nested[0], NestedMeta::Lit(Lit::Str(x)) => x.value());
- let kind = {
- let lit = unwrap!(&nested[1], NestedMeta::Meta(Meta::NameValue(x)) => &x.lit);
- let kind = unwrap!(lit, Lit::Str(x) => x.value());
- match kind.as_str() {
- "request" => MethodKind::Request,
- "notification" => MethodKind::Notification,
- _ => panic!(
- "Invalid method kind. Valid options are \"request\" and \"notification\""
- ),
- }
- };
-
- Self { name, kind }
- }
-}
-
-#[proc_macro_attribute]
-pub fn jsonrpc_method(_attr: TokenStream, item: TokenStream) -> TokenStream {
- item
-}
-
-#[proc_macro_attribute]
-pub fn jsonrpc_server(_attr: TokenStream, item: TokenStream) -> TokenStream {
- let impl_: ItemImpl = parse_macro_input!(item);
- let generics = &impl_.generics;
- let self_ty = &impl_.self_ty;
- let (requests, notifications) = generate_server_skeletons(&impl_.items);
-
- let tokens = quote! {
- #impl_
-
- #[async_trait::async_trait]
- impl #generics jsonrpc::RequestHandler for #self_ty {
- async fn handle_request(&self, request: jsonrpc::Request) -> jsonrpc::Response {
- use jsonrpc::*;
-
- match request.method.as_str() {
- #(#requests),*,
- _ => {
- Response::error(Error::method_not_found_error(), Some(request.id))
- }
- }
- }
-
- async fn handle_notification(&self, notification: jsonrpc::Notification) {
- match notification.method.as_str() {
- #(#notifications),*,
- _ => log::warn!("{}: {}", "Method not found", notification.method),
- }
- }
- }
- };
-
- tokens.into()
-}
-
-#[proc_macro_attribute]
-pub fn jsonrpc_client(attr: TokenStream, item: TokenStream) -> TokenStream {
- let trait_: ItemTrait = parse_macro_input!(item);
- let trait_ident = &trait_.ident;
- let stubs = generate_client_stubs(&trait_.items);
- let attr: AttributeArgs = parse_macro_input!(attr);
- let struct_ident = unwrap!(attr.first().unwrap(), NestedMeta::Meta(Meta::Path(x)) => x);
-
- let tokens = quote! {
- #[async_trait::async_trait]
- #trait_
-
- pub struct #struct_ident {
- client: jsonrpc::Client
- }
-
- impl #struct_ident
- {
- pub fn new(output: futures::channel::mpsc::Sender<String>) -> Self {
- Self {
- client: jsonrpc::Client::new(output),
- }
- }
- }
-
- #[async_trait::async_trait]
- impl #trait_ident for #struct_ident
- {
- #(#stubs)*
- }
-
- #[async_trait::async_trait]
- impl jsonrpc::ResponseHandler for #struct_ident
- {
- async fn handle(&self, response: jsonrpc::Response) -> () {
- self.client.handle(response).await
- }
- }
- };
-
- tokens.into()
-}
-
-fn generate_server_skeletons(items: &Vec<ImplItem>) -> (Vec<TokenStream2>, Vec<TokenStream2>) {
- let mut requests = Vec::new();
- let mut notifications = Vec::new();
- for item in items {
- let method = unwrap!(item, ImplItem::Method(x) => x);
- if method.attrs.is_empty() {
- continue;
- }
-
- let ident = &method.sig.ident;
- let param_ty = unwrap!(&method.sig.inputs[1], FnArg::Typed(x) => &x.ty);
- let meta = MethodMeta::parse(method.attrs.first().unwrap());
- let name = &meta.name.as_str();
-
- match meta.kind {
- MethodKind::Request => {
- requests.push(quote!(
- #name => {
- let handler = |param: #param_ty| async move {
- self.#ident(param).await
- };
-
- jsonrpc::handle_request(request, handler).await
- }
- ));
- }
- MethodKind::Notification => {
- notifications.push(quote!(
- #name => {
- let handler = |param: #param_ty| async move {
- self.#ident(param).await;
- };
-
- jsonrpc::handle_notification(notification, handler).await;
- }
- ));
- }
- }
- }
-
- (requests, notifications)
-}
-
-fn generate_client_stubs(items: &Vec<TraitItem>) -> Vec<TokenStream2> {
- let mut stubs = Vec::new();
- for item in items {
- let method = unwrap!(item, TraitItem::Method(x) => x);
- let attrs = &method.attrs;
- let sig = &method.sig;
- let param = unwrap!(&sig.inputs[1], FnArg::Typed(x) => &x.pat);
- let meta = MethodMeta::parse(attrs.first().unwrap());
- let name = &meta.name;
-
- let stub = match meta.kind {
- MethodKind::Request => quote!(
- #sig {
- let result = self.client.send_request(#name.to_owned(), #param).await?;
- serde_json::from_value(result).map_err(|_| jsonrpc::Error::deserialize_error())
- }
- ),
- MethodKind::Notification => quote!(
- #sig {
- self.client.send_notification(#name.to_owned(), #param).await
- }
- ),
- };
-
- stubs.push(stub);
- }
-
- stubs
-}