59 lines
2.0 KiB
Rust
59 lines
2.0 KiB
Rust
use std::env;
|
|
use std::fs;
|
|
use std::io::{self, BufReader, BufRead};
|
|
use regex::Regex;
|
|
use itertools::Itertools;
|
|
use timelogging::timetracking::{nearest, process_input_file, generate_individual_timecards};
|
|
|
|
fn main() {
|
|
// set up a regex for escaping regex characters
|
|
let cat_esc = Regex::new(r"(?P<char>[-*^$+?])").unwrap();
|
|
|
|
// Process the file (stdin or file argument)
|
|
let input = env::args().nth(1);
|
|
let mut reader: Box<dyn BufRead> = match input {
|
|
None => Box::new(BufReader::new(io::stdin())),
|
|
Some(filename) => Box::new(BufReader::new(fs::File::open(filename).unwrap()))
|
|
};
|
|
|
|
// For each line of input (build internal data structures)
|
|
let (mut start, mut finish, categories) = process_input_file(&mut reader);
|
|
|
|
|
|
// generate individual timecards
|
|
let (ind, gtoth) = generate_individual_timecards(&mut start, &mut finish);
|
|
|
|
// print the output
|
|
let mut running_total: f64 = 0.0;
|
|
for cat in categories {
|
|
let mut subtotal: f64 = 0.0;
|
|
let catre = Regex::new(&format!(r"\[{}\]\s+.*\s*$",
|
|
cat_esc.replace_all(&cat, r"\$char".to_string()))
|
|
.to_string())
|
|
.unwrap();
|
|
for (act, duration) in ind.iter().sorted_by_key(|x| x.0) {
|
|
if ! catre.is_match(&act.to_string()) {
|
|
continue
|
|
};
|
|
let mut f: f64 = nearest(*duration as f64/3600.00);
|
|
if f == 0.0 {
|
|
f = 0.08;
|
|
};
|
|
let fhrs: String = format!("{:.2}hrs", f);
|
|
println!("{}", format!("{:<75}{:>10}", act.to_string(), fhrs.to_string()));
|
|
subtotal += f;
|
|
};
|
|
running_total += subtotal;
|
|
println!();
|
|
println!("{}", format!("{:<20}{:.2}hrs", "Section total:", subtotal));
|
|
println!("{}", format!("{:<20}{:.2}hrs", "Subtotal:", running_total));
|
|
println!();
|
|
println!();
|
|
};
|
|
|
|
println!();
|
|
|
|
println!("{}", format!("Grand total: {:.2}", gtoth));
|
|
}
|
|
|