ra_ap_lsp_server/
stdio.rs1use std::{
2 io::{self, stdin, stdout},
3 thread,
4};
5
6use crossbeam_channel::{bounded, Receiver, Sender};
7
8use crate::Message;
9
10pub(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
41pub(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
49pub struct IoThreads {
50 reader: thread::JoinHandle<io::Result<()>>,
51 writer: thread::JoinHandle<io::Result<()>>,
52}
53
54impl 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}