use std::convert::TryInto; use std::process::exit; use std::io; use clap::ArgMatches; use chrono::Utc; use regex::Regex; use lazy_static::lazy_static; use tiempo::error; use tiempo::database::SqliteDatabase; use tiempo::env::Env; use tiempo::config::Config; use tiempo::commands::{ Command, Facts, r#in::InCommand, display::DisplayCommand, sheet::SheetCommand, today::TodayCommand, yesterday::YesterdayCommand, week::WeekCommand, month::MonthCommand, list::ListCommand, out::OutCommand, resume::ResumeCommand, backend::BackendCommand, kill::KillCommand, now::NowCommand, edit::EditCommand, archive::ArchiveCommand, configure::ConfigureCommand, }; use tiempo::io::Streams; use tiempo::cli::make_cli; lazy_static! { // https://regex101.com/r/V9zYQu/1/ pub static ref NUMBER_RE: Regex = Regex::new(r"^\d+$").unwrap(); } fn error_trap(matches: ArgMatches) -> error::Result<()> { let env = Env::read(); let facts = Facts { config: Config::read(env.timetrap_config_file.as_deref())?, env, now: Utc::now(), }; if let Some(_matches) = matches.subcommand_matches("backend") { return BackendCommand::handle(&facts.config); } let mut streams = Streams { db: SqliteDatabase::from_path_or_create(&facts.config.database_file)?, r#in: io::BufReader::new(io::stdin()), out: io::stdout(), err: io::stderr(), }; match matches.subcommand() { Some(("in", matches)) => InCommand::handle(matches.try_into()?, &mut streams, &facts), Some(("out", matches)) => OutCommand::handle(matches.try_into()?, &mut streams, &facts), Some(("resume", matches)) => ResumeCommand::handle(matches.try_into()?, &mut streams, &facts), Some(("display", matches)) => DisplayCommand::handle(matches.try_into()?, &mut streams, &facts), Some(("today", matches)) => TodayCommand::handle(matches.try_into()?, &mut streams, &facts), Some(("yesterday", matches)) => YesterdayCommand::handle(matches.try_into()?, &mut streams, &facts), Some(("week", matches)) => WeekCommand::handle(matches.try_into()?, &mut streams, &facts), Some(("month", matches)) => MonthCommand::handle(matches.try_into()?, &mut streams, &facts), Some(("sheet", matches)) => SheetCommand::handle(matches.try_into()?, &mut streams, &facts), Some(("list", matches)) => ListCommand::handle(matches.try_into()?, &mut streams, &facts), Some(("kill", matches)) => KillCommand::handle(matches.try_into()?, &mut streams, &facts), Some(("now", matches)) => NowCommand::handle(matches.try_into()?, &mut streams, &facts), Some(("edit", matches)) => EditCommand::handle(matches.try_into()?, &mut streams, &facts), Some(("archive", matches)) => ArchiveCommand::handle(matches.try_into()?, &mut streams, &facts), Some(("configure", matches)) => ConfigureCommand::handle(matches.try_into()?, &mut streams, &facts), Some((cmd, _)) => Err(error::Error::UnimplementedCommand(cmd.into())), None => Err(error::Error::MissingSubcommand), } } fn main() { let matches = make_cli().get_matches(); if let Err(e) = error_trap(matches) { eprintln!("{}", e); exit(1); } }