From 72a3722470e5297c72dcaccaf2f113e7b758606d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 30 Aug 2019 17:24:11 +0300 Subject: move lsp-server to a separate repository --- crates/gen_lsp_server/src/lib.rs | 136 --------------------------------------- 1 file changed, 136 deletions(-) delete mode 100644 crates/gen_lsp_server/src/lib.rs (limited to 'crates/gen_lsp_server/src/lib.rs') diff --git a/crates/gen_lsp_server/src/lib.rs b/crates/gen_lsp_server/src/lib.rs deleted file mode 100644 index 0984e3e25..000000000 --- a/crates/gen_lsp_server/src/lib.rs +++ /dev/null @@ -1,136 +0,0 @@ -//! A language server scaffold, exposing a synchronous crossbeam-channel based API. -//! This crate handles protocol handshaking and parsing messages, while you -//! control the message dispatch loop yourself. -//! -//! Run with `RUST_LOG=gen_lsp_server=debug` to see all the messages. -//! -//! ```no_run -//! use std::error::Error; -//! use crossbeam_channel::{Sender, Receiver}; -//! use lsp_types::{ServerCapabilities, InitializeParams, request::{GotoDefinition, GotoDefinitionResponse}}; -//! use gen_lsp_server::{run_server, stdio_transport, handle_shutdown, RawMessage, RawResponse}; -//! -//! fn main() -> Result<(), Box> { -//! let (receiver, sender, io_threads) = stdio_transport(); -//! run_server( -//! ServerCapabilities::default(), -//! receiver, -//! sender, -//! main_loop, -//! )?; -//! io_threads.join()?; -//! Ok(()) -//! } -//! -//! fn main_loop( -//! _params: InitializeParams, -//! receiver: &Receiver, -//! sender: &Sender, -//! ) -> Result<(), Box> { -//! for msg in receiver { -//! match msg { -//! RawMessage::Request(req) => { -//! let req = match handle_shutdown(req, sender) { -//! None => return Ok(()), -//! Some(req) => req, -//! }; -//! match req.cast::() { -//! Ok((id, _params)) => { -//! let resp = RawResponse::ok::( -//! id, -//! &Some(GotoDefinitionResponse::Array(Vec::new())), -//! ); -//! sender.send(RawMessage::Response(resp))?; -//! continue; -//! }, -//! Err(req) => req, -//! }; -//! // ... -//! } -//! RawMessage::Response(_resp) => (), -//! RawMessage::Notification(_not) => (), -//! } -//! } -//! Ok(()) -//! } -//! ``` - -use std::error::Error; - -mod msg; -mod stdio; - -use crossbeam_channel::{Receiver, Sender}; -use lsp_types::{ - notification::{Exit, Initialized}, - request::{Initialize, Shutdown}, - InitializeParams, InitializeResult, ServerCapabilities, -}; - -pub type Result = std::result::Result>; -pub use crate::{ - msg::{ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse, RawResponseError}, - stdio::{stdio_transport, Threads}, -}; - -/// Main entry point: runs the server from initialization to shutdown. -/// To attach server to standard input/output streams, use the `stdio_transport` -/// function to create corresponding `sender` and `receiver` pair. -/// -/// `server` should use the `handle_shutdown` function to handle the `Shutdown` -/// request. -pub fn run_server( - caps: ServerCapabilities, - receiver: Receiver, - sender: Sender, - server: impl FnOnce(InitializeParams, &Receiver, &Sender) -> Result<()>, -) -> Result<()> { - log::info!("lsp server initializes"); - let params = initialize(&receiver, &sender, caps)?; - log::info!("lsp server initialized, serving requests"); - server(params, &receiver, &sender)?; - log::info!("lsp server waiting for exit notification"); - match receiver.recv() { - Ok(RawMessage::Notification(n)) => n - .cast::() - .map_err(|n| format!("unexpected notification during shutdown: {:?}", n))?, - m => Err(format!("unexpected message during shutdown: {:?}", m))?, - } - log::info!("lsp server shutdown complete"); - Ok(()) -} - -/// If `req` is `Shutdown`, respond to it and return `None`, otherwise return `Some(req)` -pub fn handle_shutdown(req: RawRequest, sender: &Sender) -> Option { - match req.cast::() { - Ok((id, ())) => { - let resp = RawResponse::ok::(id, &()); - let _ = sender.send(RawMessage::Response(resp)); - None - } - Err(req) => Some(req), - } -} - -fn initialize( - receiver: &Receiver, - sender: &Sender, - caps: ServerCapabilities, -) -> Result { - let (id, params) = match receiver.recv() { - Ok(RawMessage::Request(req)) => match req.cast::() { - Err(req) => Err(format!("expected initialize request, got {:?}", req))?, - Ok(req) => req, - }, - msg => Err(format!("expected initialize request, got {:?}", msg))?, - }; - let resp = RawResponse::ok::(id, &InitializeResult { capabilities: caps }); - sender.send(RawMessage::Response(resp)).unwrap(); - match receiver.recv() { - Ok(RawMessage::Notification(n)) => { - n.cast::().map_err(|_| "expected initialized notification")?; - } - _ => Err("expected initialized notification".to_string())?, - } - Ok(params) -} -- cgit v1.2.3