main.rs

 1use fs::RealFs;
 2use futures::channel::mpsc;
 3use gpui::Context as _;
 4use remote::{
 5    json_log::LogRecord,
 6    protocol::{read_message, write_message},
 7    SshSession,
 8};
 9use remote_server::HeadlessProject;
10use smol::{io::AsyncWriteExt, stream::StreamExt as _, Async};
11use std::{
12    env,
13    io::{self, Write},
14    mem, process,
15    sync::Arc,
16};
17
18fn main() {
19    env::set_var("RUST_BACKTRACE", "1");
20    env_logger::builder()
21        .format(|buf, record| {
22            serde_json::to_writer(&mut *buf, &LogRecord::new(&record))?;
23            buf.write_all(b"\n")?;
24            Ok(())
25        })
26        .init();
27
28    let subcommand = std::env::args().nth(1);
29    match subcommand.as_deref() {
30        Some("run") => {}
31        Some("version") => {
32            println!("{}", env!("ZED_PKG_VERSION"));
33            return;
34        }
35        _ => {
36            eprintln!("usage: remote <run|version>");
37            process::exit(1);
38        }
39    }
40
41    gpui::App::headless().run(move |cx| {
42        HeadlessProject::init(cx);
43
44        let (incoming_tx, incoming_rx) = mpsc::unbounded();
45        let (outgoing_tx, mut outgoing_rx) = mpsc::unbounded();
46
47        let mut stdin = Async::new(io::stdin()).unwrap();
48        let mut stdout = Async::new(io::stdout()).unwrap();
49
50        let session = SshSession::server(incoming_rx, outgoing_tx, cx);
51        let project = cx.new_model(|cx| {
52            HeadlessProject::new(
53                session.clone(),
54                Arc::new(RealFs::new(Default::default(), None)),
55                cx,
56            )
57        });
58
59        cx.background_executor()
60            .spawn(async move {
61                let mut output_buffer = Vec::new();
62                while let Some(message) = outgoing_rx.next().await {
63                    write_message(&mut stdout, &mut output_buffer, message).await?;
64                    stdout.flush().await?;
65                }
66                anyhow::Ok(())
67            })
68            .detach();
69
70        cx.background_executor()
71            .spawn(async move {
72                let mut input_buffer = Vec::new();
73                loop {
74                    let message = match read_message(&mut stdin, &mut input_buffer).await {
75                        Ok(message) => message,
76                        Err(error) => {
77                            log::warn!("error reading message: {:?}", error);
78                            process::exit(0);
79                        }
80                    };
81                    incoming_tx.unbounded_send(message).ok();
82                }
83            })
84            .detach();
85
86        mem::forget(project);
87    });
88}