diff options
Diffstat (limited to 'crates/gen_lsp_server/src/stdio.rs')
-rw-r--r-- | crates/gen_lsp_server/src/stdio.rs | 49 |
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 @@ | |||
1 | use std::{ | ||
2 | thread, | ||
3 | io::{ | ||
4 | stdout, stdin, | ||
5 | }, | ||
6 | }; | ||
7 | |||
8 | use crossbeam_channel::{Receiver, Sender, bounded}; | ||
9 | |||
10 | use {RawMessage, Result}; | ||
11 | |||
12 | pub 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 | |||
33 | pub struct Threads { | ||
34 | reader: thread::JoinHandle<Result<()>>, | ||
35 | writer: thread::JoinHandle<Result<()>>, | ||
36 | } | ||
37 | |||
38 | impl 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 | } | ||