use cassiopeia::{error::ParseResult, meta, Cassiopeia}; use clap::{App, Arg, SubCommand}; fn main() { let cli = App::new(meta::NAME) .version(meta::VERSION) .about(meta::ABOUT) .after_help("To learn more on how to use cassiopeia, check out the documentation \ at https://git.spacekookie.de/kookienomicon/tree/apps/cassiopeia If you want to report a bug, please do so on my mailing list: lists.sr.ht/~spacekookie/public-inbox") .author(meta::AUTHOR) .max_term_width(120) .setting(clap::AppSettings::SubcommandRequiredElseHelp) .global_settings(&[ clap::AppSettings::DisableHelpSubcommand, clap::AppSettings::VersionlessSubcommands, ]) .arg( Arg::with_name(meta::ARG_FILE) .short("f") .long("file") .help(meta::ARG_FILE_ABOUT) .default_value("./time.cass") .takes_value(true), ) .subcommand(SubCommand::with_name(meta::CMD_UPDATE).about(meta::CMD_UPDATE_ABOUT)) .subcommand( SubCommand::with_name(meta::CMD_START) .about(meta::CMD_START_ABOUT) .arg(Arg::with_name(meta::ARG_ROUNDING).short("r").long("no-round").help(meta::ARG_ROUNDING_ABOUT)), ) .subcommand( SubCommand::with_name(meta::CMD_STOP) .about(meta::CMD_STOP_ABOUT) .arg(Arg::with_name(meta::ARG_ROUNDING).short("r").long("no-round").help(meta::ARG_ROUNDING_ABOUT)), ) .subcommand( SubCommand::with_name(meta::CMD_INVOICE) .about(meta::CMD_INVOICE_ABOUT) .arg( Arg::with_name(meta::ARG_CLIENT) .short("c") .long("client") .takes_value(true) .help(meta::ARG_CLIENT_ABOUT), ) .arg( Arg::with_name(meta::ARG_PROJECT) .short("p") .long("project") .takes_value(true) .help(meta::ARG_PROJECT_ABOUT), ) .arg( Arg::with_name(meta::ARG_GEN_YAML) .short("g") .long("gen") .help(meta::ARG_GEN_YAML_ABOUT), ) .arg( Arg::with_name(meta::ARG_CLIENT_DB) .long("client-db") .takes_value(true) .help(meta::ARG_CLIENT_DB_ABOUT), ) ) .subcommand(SubCommand::with_name(meta::CMD_STAT).about(meta::CMD_STAT_ABOUT)) .get_matches(); let cass_file = cli.value_of(meta::ARG_FILE).unwrap(); let mut cass = match Cassiopeia::load(cass_file) { Ok(cf) => cf, Err(e) => { eprintln!("{}", e); std::process::exit(1); } }; // Parse the matches generated by clap match cli.subcommand() { ("start", Some(ops)) => { let round = ops.is_present(meta::ARG_ROUNDING); run_command(|| cass.start(!round)); } ("stop", Some(ops)) => { let round = ops.is_present(meta::ARG_ROUNDING); run_command(|| cass.stop(!round)); } ("invoice", _) => { eprintln!("Invoice command only partially implemented! No generation is supported"); run_command(|| cass.invoice().run()); } ("update", _) => run_command(|| cass.update()), (meta::CMD_STAT, _) => run_command(|| { let stats = cass.stat()?; println!("{}", stats); Ok(()) }), (_, _) => todo!(), } } /// Run a closure and print the associated error message /// /// Set the exit code for the program. fn run_command(mut cmd: F) where F: FnMut() -> ParseResult<()>, { match cmd() { Ok(_) => std::process::exit(0), Err(e) => { eprintln!("{}", e); std::process::exit(2); } } }