jobber 1.1.2-alpha

Minimalistic console work time tracker
use crate::{
    commands::{Cli, Config, Result, current_job},
    database::Error,
    entities::{Duration, Limit},
    jobber::JobberGet,
};
use clap::Parser;
use color_print::cprintln;

#[derive(Parser, Debug)]
pub(crate) struct ShowWork {
    /// Job's identifier
    #[clap(long, short)]
    job_id: Option<usize>,
    /// Work's position
    work_pos: Option<usize>,
}

impl ShowWork {
    pub(crate) fn run(&self, cli: &Cli) -> Result<()> {
        println!();
        let config = Config::load()?;
        let database = cli.open_database()?;
        let job_id = self.job_id.unwrap_or(current_job(&config, &database)?);
        let job = database.get_job(job_id)?;
        let scheme = &job.scheme(job_id)?;
        if let Some(pos) = self.work_pos {
            if pos < job.work.len() {
                let work = &job.work[pos];
                cprintln!("  Work pos: <s>{pos}</>");
                cprintln!("       Job: <s>#{job_id}</>");
                cprintln!("    Worker: <s>{}</>", job.worker);
                cprintln!(
                    "      Time: <s>{}</> .. <s>{}</> (<s>{}</>)",
                    scheme.format_date_time(work.start()),
                    scheme.format_time(work.end()),
                    scheme.format_duration(work.duration(), Limit::Day, cli.ansi())
                );
                cprintln!("   Subject: <i>{}</>", work.subject);
                if !work.tags.is_empty() {
                    println!(
                        "{}",
                        work.tags
                            .iter()
                            .map(|t| t.as_str())
                            .collect::<Vec<_>>()
                            .join(",")
                    );
                }
            } else {
                Err(Error::JobNotFound(pos))?;
            }
        } else {
            if let Some(running) = &job.running {
                let duration = running.duration();
                if duration >= Duration::zero() {
                    cprintln!(
                        "You (<s>{worker}</>) are working since <s>{duration}</> for client <s>{client}</>.",
                        duration =
                            scheme.format_duration(running.duration(), Limit::Day, cli.ansi()),
                        worker = job.worker,
                        client = job.client
                    );
                } else {
                    println!(
                        "You (<s>{worker}</>) start working at <s>{start}</> (in <s>{duration}</>) for client <s>{client}</>.",
                        start = scheme.format_date_time(running.start),
                        duration =
                            scheme.format_duration(-running.duration(), Limit::Day, cli.ansi()),
                        worker = job.worker,
                        client = job.client
                    );
                }
            } else {
                Err(Error::NotWorking)?;
            }
        };

        Ok(())
    }
}