#[macro_use] extern crate derivative; #[macro_use] extern crate derive_new; #[macro_use] extern crate derive_more; mod fetch; mod fetch_preload; mod subprograms; mod sync; use self::fetch::SUBPROGRAM as subprogram_fetch; use self::fetch_preload::SUBPROGRAM as subprogram_fetch_preload; use self::subprograms::Subprogram; use self::subprograms::SubprogramWithArguments; use self::sync::SUBPROGRAM as subprogram_sync; static SUBPROGRAMS: [&Subprogram; 3] = [ &subprogram_sync, &subprogram_fetch_preload, &subprogram_fetch, ]; fn main() -> Result<(), String> { let args: Vec = std::env::args().collect(); if args.iter().skip(1).any(|x| x == "--help" || x == "-h") { println!("{}", build_help_text()); } else if args.len() == 1 { println!("{}", build_help_text()); return Err("No arguments given".into()); } else { let programs_callables: Vec, String>> = args .iter() .skip(1) .map( |arg| match SUBPROGRAMS.iter().find(|sp| sp.buildable_from(arg)) { Some(sp) => sp.make_callable(arg), None => Err(format!("Subprogram {:?} not found.", arg)), }, ) .collect(); let errors: Vec<&String> = programs_callables .iter() .map(|res| match res { Ok(_) => None, Err(e) => Some(e), }) .filter(|res| res.is_some()) .map(|res| res.unwrap()) .collect(); if !errors.is_empty() { for error in errors { println!("{}", error); } return Err("At least one subprogram could not be parsed successfully".into()); } for callable in programs_callables { callable.unwrap().call().unwrap(); } } Ok(()) } fn build_help_text() -> String { let args: Vec = std::env::args().collect(); let prog: &String = args.first().unwrap(); format!( "Usage:\n {} CMD [CMD ...]\n\n CMD is one of: {:?}", prog, SUBPROGRAMS.iter().map(|it| it.name).collect::>() ) }