mod commands; mod config; mod database; mod entry; mod state; mod style; mod utils; use crate::database::create_tables; use crate::style::{style_string, Styles}; use anyhow::{Context, Result}; use clap::{ArgAction, Args, Parser, Subcommand}; use commands::*; use config::Config; use database::{connect_to_db, ensure_db_exists}; use directories::ProjectDirs; pub use entry::Entry; use langtime::parse; pub use state::State; #[derive(Parser, Debug)] #[command(author, version, about, infer_subcommands = true)] struct Cli { #[command(subcommand)] command: SubCommands, } #[derive(Subcommand, Debug)] enum SubCommands { /// Checks into the current timesheet In { /// Task description task: Option, /// The time and date when this Task was Started #[arg(short, long)] at: Option, }, /// Checks out of the current timesheet Out { #[arg(short, long)] at: Option, }, /// Display the current timesheet Display { /// Show an JSON #[arg(long)] json: bool, /// Show the Task IDs #[arg(short, long)] ids: bool, /// Filter the thask based on when they started #[arg(short, long)] start: Option, /// Filter the tasks based on when they ended #[arg(short, long)] end: Option, /// Just filter by whole days, do not take into account the time #[arg(short, long)] filter_by_date: bool, /// The timesehet to display, or the current one sheet: Option, }, /// List available timesheet List, /// Shows the active task for the current sheet Current, } fn main() { if let Err(e) = cli() { println!("{} {}", style_string("Error: ", Styles::Error), e); std::process::exit(1); } } fn cli() -> Result<()> { let config = Config::build().context("Failed to build configuration")?; setup(&config).context("Programmdatanbank konnte nicht erstellt werden")?; let mut state = State::build(&config).context("Could not load the programm state")?; let cli = Cli::parse(); match &cli.command { SubCommands::In { task, at } => { let target_time = at.as_ref().map(|at| parse(at)).transpose()?; let task = task.as_ref(); let default_task = "".to_string(); let task = task.unwrap_or(&default_task); start_task(task, target_time, &state).context("Could not start task")?; } SubCommands::Out { at } => { let target_time = at.as_ref().map(|at| parse(at)).transpose()?; stop_task(target_time, &mut state).context("Could not stop task")?; } SubCommands::Display { json, ids, start, end, filter_by_date, sheet, } => {} SubCommands::List => { list_sheets(&state).context("Could not list sheets")?; } SubCommands::Current => { current_task(&state).context("could not get current task")?; } } Ok(()) } fn setup(config: &Config) -> Result<()> { ensure_db_exists(config)?; let db = connect_to_db(config)?; create_tables(&db)?; Ok(()) }