mod time;
mod traits;
pub use self::{time::*, traits::*};
use std::time::Instant;
const DECIMAL: usize = 4;
pub struct ExecutionTime {
start_time: Instant,
}
impl ExecutionTime {
pub fn start() -> Self {
Self {
start_time: Instant::now(),
}
}
fn split_time(&self, total_seconds: f64) -> Time {
const SECONDS_IN_DAY: f64 = 86400.0;
const SECONDS_IN_HOUR: f64 = 3600.0;
const SECONDS_IN_MINUTE: f64 = 60.0;
let remaining_day = total_seconds % SECONDS_IN_DAY;
let remaining_hour = remaining_day % SECONDS_IN_HOUR;
let days = (total_seconds / SECONDS_IN_DAY).floor() as u64;
let hours = (remaining_day / SECONDS_IN_HOUR).floor() as u8;
let minutes = (remaining_hour / SECONDS_IN_MINUTE).floor() as u8;
let seconds = (remaining_hour % SECONDS_IN_MINUTE).round_float(DECIMAL);
Time {
days,
hours,
minutes,
seconds,
}
}
pub fn get_elapsed_time(&self) -> String {
let total_seconds = self.start_time.elapsed().as_secs_f64();
let time_total = total_seconds.format_unit(DECIMAL, "second", "seconds");
if total_seconds >= 60.0 {
let time_dhms = self.split_time(total_seconds).format_time();
format!("{time_dhms} ({time_total})")
} else {
time_total
}
}
pub fn print_elapsed_time(&self) {
println!("Elapsed time: {}", self.get_elapsed_time());
}
}
#[cfg(test)]
mod tests {
use super::*;
type Error = Box<dyn std::error::Error>;
#[test]
fn elapsed_time_less_than_minute() -> Result<(), Error> {
let timer = ExecutionTime::start();
let total_seconds: f64 = 0.01516345;
let formatted_total_seconds = "0.0152 second";
let time_dhms = timer.split_time(total_seconds).format_time();
let time_total = total_seconds.format_unit(DECIMAL, "second", "seconds");
let formatted_output = if total_seconds >= 60.0 {
format!("{time_dhms} ({time_total})")
} else {
time_total
};
println!("total_seconds: {total_seconds}");
println!("formatted_total_seconds: {formatted_total_seconds}");
println!("formatted_output: {formatted_output}\n");
assert_eq!(formatted_total_seconds, formatted_output);
Ok(())
}
#[test]
fn elapsed_time_more_than_minute() -> Result<(), Error> {
let timer = ExecutionTime::start();
let total_seconds: f64 = 65.080012345;
let formatted_total_seconds = "1 minute, 5.0800 seconds (65.0800 seconds)";
let time_dhms = timer.split_time(total_seconds).format_time();
let time_total = total_seconds.format_unit(DECIMAL, "second", "seconds");
let formatted_output = if total_seconds >= 60.0 {
format!("{time_dhms} ({time_total})")
} else {
time_total
};
println!("total_seconds: {total_seconds}");
println!("formatted_total_seconds: {formatted_total_seconds}");
println!("formatted_output: {formatted_output}\n");
assert_eq!(formatted_total_seconds, formatted_output);
Ok(())
}
#[test]
fn elapsed_time_more_than_hour() -> Result<(), Error> {
let timer = ExecutionTime::start();
let total_seconds: f64 = 3700.05689123;
let formatted_total_seconds = "1 hour, 1 minute, 40.0569 seconds (3700.0569 seconds)";
let time_dhms = timer.split_time(total_seconds).format_time();
let time_total = total_seconds.format_unit(DECIMAL, "second", "seconds");
let formatted_output = if total_seconds >= 60.0 {
format!("{time_dhms} ({time_total})")
} else {
time_total
};
println!("total_seconds: {total_seconds}");
println!("formatted_total_seconds: {formatted_total_seconds}");
println!("formatted_output: {formatted_output}\n");
assert_eq!(formatted_total_seconds, formatted_output);
Ok(())
}
#[test]
fn elapsed_time_more_than_day() -> Result<(), Error> {
let timer = ExecutionTime::start();
let total_seconds: f64 = 86400.0 + 3700.03;
let formatted_total_seconds =
"1 day, 1 hour, 1 minute, 40.0300 seconds (90100.0300 seconds)";
let time_dhms = timer.split_time(total_seconds).format_time();
let time_total = total_seconds.format_unit(DECIMAL, "second", "seconds");
let formatted_output = if total_seconds >= 60.0 {
format!("{time_dhms} ({time_total})")
} else {
time_total
};
println!("total_seconds: {total_seconds}");
println!("formatted_total_seconds: {formatted_total_seconds}");
println!("formatted_output: {formatted_output}\n");
assert_eq!(formatted_total_seconds, formatted_output);
Ok(())
}
}