Compare commits
No commits in common. "main" and "v2.0.1" have entirely different histories.
6 changed files with 14 additions and 74 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -384,7 +384,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "time-track"
|
||||
version = "2.1.4"
|
||||
version = "2.0.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "time-track"
|
||||
version = "2.1.4"
|
||||
version = "2.0.1"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
|
|
|||
22
README.md
22
README.md
|
|
@ -1,22 +0,0 @@
|
|||
# time-track
|
||||
|
||||
A simple CLI tool for tracking how much time you have left to work. I find myself stressing about whether I'm hitting 8 real hours, so this little tool helps me avoid wasting
|
||||
time calculating when my work day will end.
|
||||
|
||||
Simply enter times, one per line and send an EOF character when you're done. The first lines opens a span of work and the next line closes it so that you can build up working
|
||||
time be clocking in and out. Finally, you can send additional arguments to the program to configure how long you intend to work (the default is 8 hours).
|
||||
|
||||
```
|
||||
❯ time-track
|
||||
Working for 8 hours
|
||||
Input times one per line. Send an EOF character to finish inputting...
|
||||
8:30
|
||||
9:30
|
||||
11:15
|
||||
12:30
|
||||
13:16
|
||||
18:20
|
||||
19:30
|
||||
20:11 # Send an EOF
|
||||
Exactly done
|
||||
```
|
||||
|
|
@ -5,15 +5,10 @@ use clap::Parser;
|
|||
#[command(author, version, about, long_about = None)]
|
||||
pub struct Args {
|
||||
/// How many hours you intend to work (sums with `minutes`)
|
||||
/// Usually defaults to 8 hours, but if discount is set then it defaults to 0
|
||||
#[arg(long)]
|
||||
pub hours: Option<i64>,
|
||||
#[arg(long, default_value_t = 8)]
|
||||
pub hours: i64,
|
||||
|
||||
/// How many minutes you intend to work (sums with `hours`)
|
||||
#[arg(long, default_value_t = 0)]
|
||||
pub minutes: i64,
|
||||
|
||||
/// If true, the the hours and minutes fields are treated as subtracting from 8 hours
|
||||
#[arg(long, default_value_t = false)]
|
||||
pub discount: bool,
|
||||
}
|
||||
|
|
|
|||
25
src/main.rs
25
src/main.rs
|
|
@ -11,21 +11,6 @@ use args::Args;
|
|||
fn main() -> Result<()> {
|
||||
let args = Args::parse();
|
||||
let stdin = io::stdin();
|
||||
let hours = args.hours.unwrap_or(
|
||||
if args.discount {
|
||||
0
|
||||
} else {
|
||||
8
|
||||
}
|
||||
);
|
||||
|
||||
let target_minutes = if args.discount {
|
||||
(8 * 60) - ((hours * 60) + args.minutes)
|
||||
} else {
|
||||
hours * 60 + args.minutes
|
||||
};
|
||||
let (hrs, mins) = time::to_hrs_minutes(target_minutes);
|
||||
println!("Working for {}", time::show_time(hrs, mins));
|
||||
println!("Input times one per line. Send an EOF character to finish inputting...");
|
||||
let mut lines: Vec<String> = vec![];
|
||||
for line in stdin.lock().lines() {
|
||||
|
|
@ -39,7 +24,6 @@ fn main() -> Result<()> {
|
|||
|
||||
let mut total_minutes: i64 = 0;
|
||||
let mut first: Option<DateTime<Local>> = None;
|
||||
let mut last: Option<DateTime<Local>> = None;
|
||||
for time in times {
|
||||
match first {
|
||||
None => {
|
||||
|
|
@ -47,19 +31,18 @@ fn main() -> Result<()> {
|
|||
},
|
||||
Some(prev) => {
|
||||
total_minutes += (time - prev).num_minutes();
|
||||
first = None;
|
||||
last = Some(time);
|
||||
first = None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(remaining) = first {
|
||||
let now = Local::now();
|
||||
let now_str = now.format("%-I:%M %p");
|
||||
println!("Ended with unclosed span... assuming ending now: {}", now_str);
|
||||
println!("Ended with unclosed span... assuming ending now: {}", now.time());
|
||||
total_minutes += (now - remaining).num_minutes();
|
||||
}
|
||||
|
||||
println!("{}", time::get_charaterized_time_remaining(total_minutes, target_minutes, last.unwrap_or_else(|| Local::now())));
|
||||
let target_minutes = args.hours * 60 + args.minutes;
|
||||
println!("{}", time::get_charaterized_time_remaining(total_minutes, target_minutes));
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
26
src/time.rs
26
src/time.rs
|
|
@ -27,7 +27,7 @@ pub fn from_stream<'a>(reference_date: &DateTime<Local>, stream: impl Iterator<I
|
|||
return Ok(durations);
|
||||
}
|
||||
|
||||
pub fn show_time(hours: i64, minutes: i64) -> String {
|
||||
fn show_time(hours: i64, minutes: i64) -> String {
|
||||
let pluralized_hours = match hours {
|
||||
1 => "1 hour".to_string(),
|
||||
_ => format!("{hours} hours"),
|
||||
|
|
@ -48,17 +48,13 @@ pub fn show_time(hours: i64, minutes: i64) -> String {
|
|||
return format!("{pluralized_hours} and {pluralized_minutes}");
|
||||
}
|
||||
|
||||
pub fn to_hrs_minutes(total_minutes: i64) -> (i64, i64) {
|
||||
fn to_hrs_minutes(total_minutes: i64) -> (i64, i64) {
|
||||
let minutes = total_minutes % 60;
|
||||
let hours = total_minutes / 60;
|
||||
(hours, minutes)
|
||||
}
|
||||
|
||||
pub fn get_charaterized_time_remaining(
|
||||
total_minutes: i64,
|
||||
target_minutes: i64,
|
||||
ended_at: DateTime<Local>,
|
||||
) -> String {
|
||||
pub fn get_charaterized_time_remaining(total_minutes: i64, target_minutes: i64) -> String {
|
||||
if total_minutes == target_minutes {
|
||||
return "Exactly done".to_string();
|
||||
}
|
||||
|
|
@ -70,20 +66,8 @@ pub fn get_charaterized_time_remaining(
|
|||
} else {
|
||||
let diff = target_minutes - total_minutes;
|
||||
let (hours, minutes) = to_hrs_minutes(diff);
|
||||
let now = Local::now();
|
||||
return if ended_at > now {
|
||||
let end_at = (ended_at + Duration::minutes(diff)).time();
|
||||
let end_at = (Local::now() + Duration::minutes(diff)).time();
|
||||
let end_str = end_at.format("%-I:%M %p");
|
||||
format!(
|
||||
"You have {} remaining (end at {} starting from {})",
|
||||
show_time(hours, minutes),
|
||||
end_str,
|
||||
ended_at.format("%-I:%M %p"),
|
||||
)
|
||||
} else {
|
||||
let end_at = (now + Duration::minutes(diff)).time();
|
||||
let end_str = end_at.format("%-I:%M %p");
|
||||
format!("You have {} remaining (end at {} starting now)", show_time(hours, minutes), end_str)
|
||||
}
|
||||
return format!("You have {} remaining (end at {} starting now)", show_time(hours, minutes), end_str)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue