#![deny(
future_incompatible,
missing_debug_implementations,
nonstandard_style,
rust_2021_compatibility,
unused
)]
use std::{
cmp,
io::{self, Write},
process,
};
use nreplops_tool::{self, error::Error, outputs::OutputTarget, version, *};
fn main() {
let args = cli::Args::from_command_line().unwrap_or_else(die);
if let Some(ref required) = args.version_range {
let current = version::crate_version();
use cmp::Ordering::*;
match current.cmp_to_range(required) {
Less => die(Error::TooOldVersion(current, required.clone())),
Greater => die(Error::TooNewVersion(current, required.clone())),
Equal => (),
}
}
let conn_expr = args.conn_expr_src.resolve_expr().unwrap_or_else(die);
let host_opts_table =
hosts_files::load_default_hosts_files().unwrap_or_else(die);
let sources =
sources::load_sources(&args.source_args[..], &args.template_args[..])
.unwrap_or_else(die);
if sources.is_empty() {
return;
}
let conn_routes =
routes::resolve_routes(&conn_expr, &host_opts_table).unwrap_or_else(die);
let outputs = outputs::Outputs::try_from_args(&args).unwrap_or_else(die);
let socket = socket::connect(conn_routes).unwrap_or_else(die);
let con = nrepl::Connection::new(socket);
let mut session = con.session().unwrap_or_else(die);
match eval_sources(&mut session, &sources, &outputs) {
Ok(_) => {
session.close().unwrap_or_else(die);
}
Err(Error::HostDisconnected) => die(Error::HostDisconnected),
Err(err) => {
eprintln!("Error: {:?}", err);
session.close().unwrap_or_else(die);
process::exit(1);
}
};
}
fn die<T>(e: Error) -> T {
eprintln!("Error: {}", e);
process::exit(1);
}
fn eval_sources(
session: &mut nrepl::Session,
sources: &[sources::Source],
outputs: &outputs::Outputs,
) -> Result<(), Error> {
fn xform_err(output: &outputs::Output, _: io::Error) -> Error {
match output.target() {
OutputTarget::StdOut => panic!("cannot write to stdout"),
OutputTarget::StdErr => panic!("cannot write to stderr"),
OutputTarget::File(path) => {
Error::CannotWriteFile(path.to_string_lossy().to_string())
}
}
}
for input in sources.iter() {
session.eval(&input.content, None, Some(1), Some(1), |response| {
if let Some(ref s) = response.value {
if let Some(ref output) = outputs.nrepl_results {
writeln!(output.writer(), "{}", s)
.map_err(|e| xform_err(output, e))?;
}
}
if let Some(ref s) = response.out {
if let Some(ref output) = outputs.nrepl_stdout {
write!(output.writer(), "{}", s).map_err(|e| xform_err(output, e))?;
}
}
if let Some(ref s) = response.err {
if let Some(ref output) = outputs.nrepl_stderr {
write!(output.writer(), "{}", s).map_err(|e| xform_err(output, e))?;
}
}
Ok(())
})?;
}
Ok(())
}