#![feature(iter_intersperse)]
mod bencode;
mod cli;
mod error;
mod host_resolution;
mod nrepl;
mod outputs;
mod sources;
use std::{net, process};
fn main() {
if let Err(e) = main1() {
eprintln!("Error: {}", e);
process::exit(1);
}
}
fn main1() -> Result<(), anyhow::Error> {
let args = cli::Args::from_command_line()?;
let host = host_resolution::resolve_host_from_args(&args.host)?;
let sources =
sources::load_sources(&args.source_args[..], &args.template_args[..])?;
let outputs = outputs::Outputs::try_from_args(&args)?;
let stream = net::TcpStream::connect(host)?;
stream.set_nodelay(true)?;
let mut con = nrepl::Connection::new(stream);
con.send(&nrepl::WireRequest {
op: nrepl::Op::Clone.to_string(),
id: "1".into(),
session: None,
ns: None,
code: None,
line: None,
column: None,
file: None,
})?;
let first_resp = con.try_recv()?;
let session = first_resp.new_session.unwrap();
for (ix, input) in sources.into_iter().enumerate() {
let id = format!("eval-{}", ix + 1);
con.send(&nrepl::WireRequest {
op: nrepl::Op::Eval.to_string(),
id: id.clone(),
session: Some(session.clone()),
ns: None,
code: Some(input.content),
line: Some(1),
column: Some(1),
file: input.file,
})?;
loop {
let resp = con.try_recv().unwrap();
if resp.id.as_deref().unwrap_or("") != id {
continue;
}
if let Some(ref s) = resp.value {
if let Some(ref w) = outputs.nrepl_results {
writeln!(w.borrow_mut(), "{}", s)?;
}
}
if let Some(ref s) = resp.out {
if let Some(ref w) = outputs.nrepl_stdout {
write!(w.borrow_mut(), "{}", s)?;
}
}
if let Some(ref s) = resp.err {
if let Some(ref w) = outputs.nrepl_stderr {
write!(w.borrow_mut(), "{}", s)?;
}
}
if resp.has_status("done") {
break;
}
}
}
Ok(())
}