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() { // Process the file (stdin or file argument) let input = env::args().nth(1); let mut reader: Box = 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).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)); }