From 8afad767ef0618977cce1d34c47a72558a434e92 Mon Sep 17 00:00:00 2001 From: Korbinian Maier Date: Sun, 14 Jan 2024 21:53:47 +0100 Subject: [PATCH] Add check on stopping on different days than starting --- src/balance.rs | 20 +++++++++++++++++++- src/cli_input.rs | 39 +++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 src/cli_input.rs diff --git a/src/balance.rs b/src/balance.rs index c5727b1..755d5ed 100644 --- a/src/balance.rs +++ b/src/balance.rs @@ -16,6 +16,7 @@ use std::{ io::{BufReader, Read, Write}, }; +use crate::cli_input::YesNo; use crate::errors::*; use crate::storage::WorkStorage; @@ -178,7 +179,24 @@ impl TimeBalance { )); } let breaks = self.accumulate_breaks(); - let duration = time + let stop = if start.naive_local().date() != time.naive_local().date() { + println!( + "You started working on {}, do you really want to stop today? [y/N]", + start.format("%D.%M") + ); + match YesNo::wait_for_decision()? { + YesNo::Yes => time, + YesNo::No => { + let time_stamp = time.time(); + let date = start.naive_utc().date(); + let stop = date.and_time(time_stamp); + stop.and_utc() + } + } + } else { + time + }; + let duration = stop .signed_duration_since(start) .checked_sub(&breaks) .ok_or_else(|| usage_err!("Your break was longer than your work"))?; diff --git a/src/cli_input.rs b/src/cli_input.rs new file mode 100644 index 0000000..372abef --- /dev/null +++ b/src/cli_input.rs @@ -0,0 +1,39 @@ +/// Parsing and printing from and to cli. +use std::str::FromStr; + +use crate::errors::*; + +#[derive(Debug)] +pub enum YesNo { + Yes, + No, +} + +impl FromStr for YesNo { + type Err = color_eyre::eyre::Error; + + fn from_str(input: &str) -> Result { + let lower = input.trim().to_lowercase(); + match lower.as_str() { + "yes" | "y" => Ok(Self::Yes), + "no" | "n" => Ok(Self::No), + e => Err(eyre!("Failed to parse {} into 'yes' or 'no'", e)), + } + } +} + +impl YesNo { + pub fn wait_for_decision() -> Result { + let yes = loop { + let mut input = String::new(); + std::io::stdin() + .read_line(&mut input) + .wrap_err("Failed to read line from stdin")?; + if let Ok(yn) = crate::cli_input::YesNo::from_str(&input) { + log::trace!("Parsed {:?}", yn); + break yn; + } + }; + Ok(yes) + } +} diff --git a/src/lib.rs b/src/lib.rs index 1927ccc..ad09932 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,7 @@ pub mod errors; mod balance; +mod cli_input; pub mod commands; pub mod delta; pub mod month;