use std::process::ExitCode;
use super::{Operations, SubcommandError, parse};
#[must_use = "the exit code must be returned from main"]
pub fn run(operations: impl Operations) -> ExitCode {
let args: Vec<String> = std::env::args().skip(1).collect();
let subcommand = match args.split_first() {
None => {
eprintln!("error: {}", SubcommandError::Missing);
return ExitCode::FAILURE;
}
Some((sub, trailing)) => {
let subcommand = match parse(std::iter::once(sub.clone())) {
Ok(sub) => sub,
Err(error) => {
eprintln!("error: {error}");
return ExitCode::FAILURE;
}
};
let trailing: Vec<String> = trailing.to_vec();
(subcommand, trailing)
}
};
let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build();
let handle = match runtime {
Ok(handle) => handle,
Err(error) => {
eprintln!("error: cannot start the Tokio runtime: {error}");
return ExitCode::FAILURE;
}
};
let result = handle.block_on(super::dispatch::dispatch(
&operations,
subcommand.0,
&subcommand.1,
));
match result {
Ok(()) => ExitCode::SUCCESS,
Err(error) => {
eprintln!("error: {error}");
ExitCode::FAILURE
}
}
}