diff options
author | Aleksey Kladov <[email protected]> | 2018-09-01 14:18:02 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-09-01 14:18:02 +0100 |
commit | 3588d6b2da6e63730cc560c9986ba7fda5de816e (patch) | |
tree | beb948f7527836c2c3e1c4b9dcc2dd2a79a16abf /crates/gen_lsp_server/src/lib.rs | |
parent | f5669dfc56b2b64d79f368eefed13dd75a6f027b (diff) |
add gen_lsp_server
Diffstat (limited to 'crates/gen_lsp_server/src/lib.rs')
-rw-r--r-- | crates/gen_lsp_server/src/lib.rs | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/crates/gen_lsp_server/src/lib.rs b/crates/gen_lsp_server/src/lib.rs new file mode 100644 index 000000000..a31e90f35 --- /dev/null +++ b/crates/gen_lsp_server/src/lib.rs | |||
@@ -0,0 +1,77 @@ | |||
1 | #[macro_use] | ||
2 | extern crate failure; | ||
3 | #[macro_use] | ||
4 | extern crate log; | ||
5 | extern crate serde; | ||
6 | extern crate serde_json; | ||
7 | #[macro_use] | ||
8 | extern crate serde_derive; | ||
9 | extern crate crossbeam_channel; | ||
10 | extern crate languageserver_types; | ||
11 | |||
12 | mod msg; | ||
13 | mod stdio; | ||
14 | |||
15 | use crossbeam_channel::{Sender, Receiver}; | ||
16 | use languageserver_types::{ | ||
17 | ServerCapabilities, InitializeResult, | ||
18 | request::{Initialize}, | ||
19 | notification::{Initialized, Exit}, | ||
20 | }; | ||
21 | |||
22 | pub type Result<T> = ::std::result::Result<T, failure::Error>; | ||
23 | pub use { | ||
24 | msg::{RawMessage, RawRequest, RawResponse, RawResponseError, RawNotification}, | ||
25 | stdio::{stdio_transport, Threads}, | ||
26 | }; | ||
27 | |||
28 | pub type LspServer = fn(&mut Receiver<RawMessage>, &mut Sender<RawMessage>) -> Result<()>; | ||
29 | |||
30 | pub fn run_server( | ||
31 | caps: ServerCapabilities, | ||
32 | server: LspServer, | ||
33 | mut receiver: Receiver<RawMessage>, | ||
34 | mut sender: Sender<RawMessage>, | ||
35 | ) -> Result<()> { | ||
36 | info!("lsp server initializes"); | ||
37 | initialize(&mut receiver, &mut sender, caps)?; | ||
38 | info!("lsp server initialized, serving requests"); | ||
39 | server(&mut receiver, &mut sender)?; | ||
40 | info!("lsp server waiting for exit notification"); | ||
41 | match receiver.recv() { | ||
42 | Some(RawMessage::Notification(n)) => { | ||
43 | n.cast::<Exit>().map_err(|n| format_err!( | ||
44 | "unexpected notification during shutdown: {:?}", n | ||
45 | ))? | ||
46 | } | ||
47 | m => bail!("unexpected message during shutdown: {:?}", m) | ||
48 | } | ||
49 | info!("lsp server shutdown complete"); | ||
50 | Ok(()) | ||
51 | } | ||
52 | |||
53 | fn initialize( | ||
54 | receiver: &mut Receiver<RawMessage>, | ||
55 | sender: &mut Sender<RawMessage>, | ||
56 | caps: ServerCapabilities, | ||
57 | ) -> Result<()> { | ||
58 | let id = match receiver.recv() { | ||
59 | Some(RawMessage::Request(req)) => match req.cast::<Initialize>() { | ||
60 | Err(req) => bail!("expected initialize request, got {:?}", req), | ||
61 | Ok(req) => req.0, | ||
62 | } | ||
63 | msg => | ||
64 | bail!("expected initialize request, got {:?}", msg), | ||
65 | }; | ||
66 | let resp = RawResponse::ok(id, InitializeResult { capabilities: caps }); | ||
67 | sender.send(RawMessage::Response(resp)); | ||
68 | match receiver.recv() { | ||
69 | Some(RawMessage::Notification(n)) => { | ||
70 | n.cast::<Initialized>().map_err(|_| format_err!( | ||
71 | "expected initialized notification" | ||
72 | ))?; | ||
73 | } | ||
74 | _ => bail!("expected initialized notification"), | ||
75 | } | ||
76 | Ok(()) | ||
77 | } | ||