aboutsummaryrefslogtreecommitdiff
path: root/crates/gen_lsp_server/src/lib.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-09-01 14:18:02 +0100
committerAleksey Kladov <[email protected]>2018-09-01 14:18:02 +0100
commit3588d6b2da6e63730cc560c9986ba7fda5de816e (patch)
treebeb948f7527836c2c3e1c4b9dcc2dd2a79a16abf /crates/gen_lsp_server/src/lib.rs
parentf5669dfc56b2b64d79f368eefed13dd75a6f027b (diff)
add gen_lsp_server
Diffstat (limited to 'crates/gen_lsp_server/src/lib.rs')
-rw-r--r--crates/gen_lsp_server/src/lib.rs77
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]
2extern crate failure;
3#[macro_use]
4extern crate log;
5extern crate serde;
6extern crate serde_json;
7#[macro_use]
8extern crate serde_derive;
9extern crate crossbeam_channel;
10extern crate languageserver_types;
11
12mod msg;
13mod stdio;
14
15use crossbeam_channel::{Sender, Receiver};
16use languageserver_types::{
17 ServerCapabilities, InitializeResult,
18 request::{Initialize},
19 notification::{Initialized, Exit},
20};
21
22pub type Result<T> = ::std::result::Result<T, failure::Error>;
23pub use {
24 msg::{RawMessage, RawRequest, RawResponse, RawResponseError, RawNotification},
25 stdio::{stdio_transport, Threads},
26};
27
28pub type LspServer = fn(&mut Receiver<RawMessage>, &mut Sender<RawMessage>) -> Result<()>;
29
30pub 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
53fn 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}