aboutsummaryrefslogtreecommitdiff
path: root/crates/gen_lsp_server/src/stdio.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/stdio.rs
parentf5669dfc56b2b64d79f368eefed13dd75a6f027b (diff)
add gen_lsp_server
Diffstat (limited to 'crates/gen_lsp_server/src/stdio.rs')
-rw-r--r--crates/gen_lsp_server/src/stdio.rs49
1 files changed, 49 insertions, 0 deletions
diff --git a/crates/gen_lsp_server/src/stdio.rs b/crates/gen_lsp_server/src/stdio.rs
new file mode 100644
index 000000000..81397bb2a
--- /dev/null
+++ b/crates/gen_lsp_server/src/stdio.rs
@@ -0,0 +1,49 @@
1use std::{
2 thread,
3 io::{
4 stdout, stdin,
5 },
6};
7
8use crossbeam_channel::{Receiver, Sender, bounded};
9
10use {RawMessage, Result};
11
12pub fn stdio_transport() -> (Receiver<RawMessage>, Sender<RawMessage>, Threads) {
13 let (writer_sender, mut writer_receiver) = bounded::<RawMessage>(16);
14 let writer = thread::spawn(move || {
15 let stdout = stdout();
16 let mut stdout = stdout.lock();
17 writer_receiver.try_for_each(|it| it.write(&mut stdout))?;
18 Ok(())
19 });
20 let (reader_sender, reader_receiver) = bounded::<RawMessage>(16);
21 let reader = thread::spawn(move || {
22 let stdin = stdin();
23 let mut stdin = stdin.lock();
24 while let Some(msg) = RawMessage::read(&mut stdin)? {
25 reader_sender.send(msg);
26 }
27 Ok(())
28 });
29 let threads = Threads { reader, writer };
30 (reader_receiver, writer_sender, threads)
31}
32
33pub struct Threads {
34 reader: thread::JoinHandle<Result<()>>,
35 writer: thread::JoinHandle<Result<()>>,
36}
37
38impl Threads {
39 pub fn join(self) -> Result<()> {
40 match self.reader.join() {
41 Ok(r) => r?,
42 Err(_) => bail!("reader panicked"),
43 }
44 match self.writer.join() {
45 Ok(r) => r,
46 Err(_) => bail!("writer panicked"),
47 }
48 }
49}