//! Parse args use super::*; pub fn usage() -> ! { println!(r#"Usage: {program} VersIoning DELeter v{version}, by {authours} with <3 (Licensed GPL 3.0 or later)"#, program = program_name(), version = env!("CARGO_PKG_VERSION"), authours = env!("CARGO_PKG_AUTHORS")); std::process::exit(1) } pub fn program_name() -> &'static str { lazy_static! { static ref PROGRAM: String = std::env::args().next().unwrap(); } &PROGRAM[..] } /// Process program args in parallel spawning the `callback` closure of the argument in a new task for each. /// /// The returned future can be awaited to wait for all tasks to complete. If one or more tasks are cancelled or panic, this future will immediately output `Err()`, if they all complete successfully, it will output an aggregate `Vec` of the output of each argument in order. pub fn process(mut callback: F) -> (usize, impl Future>>) where F: FnMut(String) -> T, T: Future + Send + 'static, T::Output: Send, { let args = std::env::args(); let output: Vec<_> = args.skip(1).dedup().map(|arg| tokio::spawn(callback(arg))).collect(); let mut real_output = Vec::with_capacity(output.len()); (output.len(), async move { let mut j=0; for x in futures::future::try_join_all(output).await .wrap_err(eyre!("Child panic or cancel.")) .with_note(|| format!("Child for argument {}", j).header("While processing")) .with_section(|| format!("{:?}", std::env::args().skip(1).nth(j)).header("Argument was"))? { real_output.push(x); j+=1; } Ok(real_output) }) }