]> git.lizzy.rs Git - rust.git/blob - lib/lsp-server/src/stdio.rs
Auto merge of #12271 - bitgaoshu:box_with_expec, r=flodiebold
[rust.git] / lib / lsp-server / src / stdio.rs
1 use std::{
2     io::{self, stdin, stdout},
3     thread,
4 };
5
6 use crossbeam_channel::{bounded, Receiver, Sender};
7
8 use crate::Message;
9
10 /// Creates an LSP connection via stdio.
11 pub(crate) fn stdio_transport() -> (Sender<Message>, Receiver<Message>, IoThreads) {
12     let (writer_sender, writer_receiver) = bounded::<Message>(0);
13     let writer = thread::spawn(move || {
14         let stdout = stdout();
15         let mut stdout = stdout.lock();
16         writer_receiver.into_iter().try_for_each(|it| it.write(&mut stdout))?;
17         Ok(())
18     });
19     let (reader_sender, reader_receiver) = bounded::<Message>(0);
20     let reader = thread::spawn(move || {
21         let stdin = stdin();
22         let mut stdin = stdin.lock();
23         while let Some(msg) = Message::read(&mut stdin)? {
24             let is_exit = match &msg {
25                 Message::Notification(n) => n.is_exit(),
26                 _ => false,
27             };
28
29             reader_sender.send(msg).unwrap();
30
31             if is_exit {
32                 break;
33             }
34         }
35         Ok(())
36     });
37     let threads = IoThreads { reader, writer };
38     (writer_sender, reader_receiver, threads)
39 }
40
41 // Creates an IoThreads
42 pub(crate) fn make_io_threads(
43     reader: thread::JoinHandle<io::Result<()>>,
44     writer: thread::JoinHandle<io::Result<()>>,
45 ) -> IoThreads {
46     IoThreads { reader, writer }
47 }
48
49 pub struct IoThreads {
50     reader: thread::JoinHandle<io::Result<()>>,
51     writer: thread::JoinHandle<io::Result<()>>,
52 }
53
54 impl IoThreads {
55     pub fn join(self) -> io::Result<()> {
56         match self.reader.join() {
57             Ok(r) => r?,
58             Err(err) => {
59                 println!("reader panicked!");
60                 std::panic::panic_any(err)
61             }
62         }
63         match self.writer.join() {
64             Ok(r) => r,
65             Err(err) => {
66                 println!("writer panicked!");
67                 std::panic::panic_any(err);
68             }
69         }
70     }
71 }