Files
timetrack/src/main.rs
2025-05-14 15:15:32 +02:00

123 lines
3.2 KiB
Rust

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<String>,
/// The time and date when this Task was Started
#[arg(short, long)]
at: Option<String>,
},
/// Checks out of the current timesheet
Out {
#[arg(short, long)]
at: Option<String>,
},
/// 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<String>,
/// Filter the tasks based on when they ended
#[arg(short, long)]
end: Option<String>,
/// 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<String>,
},
/// 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(())
}