nc.rs

 1use anyhow::Result;
 2
 3#[cfg(windows)]
 4pub fn main(_socket: &str) -> Result<()> {
 5    // It looks like we can't get an async stdio stream on Windows from smol.
 6    panic!("--nc isn't yet supported on Windows");
 7}
 8
 9/// The main function for when Zed is running in netcat mode
10#[cfg(not(windows))]
11pub fn main(socket: &str) -> Result<()> {
12    use futures::{AsyncReadExt as _, AsyncWriteExt as _, FutureExt as _, io::BufReader, select};
13    use net::async_net::UnixStream;
14    use smol::{Unblock, io::AsyncBufReadExt};
15
16    smol::block_on(async {
17        let socket_stream = UnixStream::connect(socket).await?;
18        let (socket_read, mut socket_write) = socket_stream.split();
19        let mut socket_reader = BufReader::new(socket_read);
20
21        let mut stdout = Unblock::new(std::io::stdout());
22        let stdin = Unblock::new(std::io::stdin());
23        let mut stdin_reader = BufReader::new(stdin);
24
25        let mut socket_line = Vec::new();
26        let mut stdin_line = Vec::new();
27
28        loop {
29            select! {
30                bytes_read = socket_reader.read_until(b'\n', &mut socket_line).fuse() => {
31                    if bytes_read? == 0 {
32                        break
33                    }
34                    stdout.write_all(&socket_line).await?;
35                    stdout.flush().await?;
36                    socket_line.clear();
37                }
38                bytes_read = stdin_reader.read_until(b'\n', &mut stdin_line).fuse() => {
39                    if bytes_read? == 0 {
40                        break
41                    }
42                    socket_write.write_all(&stdin_line).await?;
43                    socket_write.flush().await?;
44                    stdin_line.clear();
45                }
46            }
47        }
48
49        anyhow::Ok(())
50    })
51}