1use crate::error::InquisitorError;
2use std::time::Duration;
3
4pub struct Microseconds(pub f64);
6
7impl std::fmt::Display for Microseconds {
8 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
9 match self.0 {
10 x if x < 1_000.0 => write!(f, "{:.0} us", x),
11 x if x < 10_000.0 => write!(f, "{:.2} ms", x / 1000.0),
12 x if x < 100_000.0 => write!(f, "{:.1} ms", x / 1000.0),
13 x if x < 1_000_000.0 => write!(f, "{:.0} ms", x / 1000.0),
14 x if x < 10_000_000.0 => write!(f, "{:.2} s", x / 1_000_000.0),
15 x if x < 100_000_000.0 => write!(f, "{:.1} s", x / 1_000_000.0),
16 x if x < 1_000_000_000.0 => write!(f, "{:.0} s", x / 1_000_000.0),
17 x => write!(f, "{:.0} s", x / 1_000_000.0),
18 }
19 }
20}
21
22pub fn parse_duration(duration: &str) -> Result<Duration, InquisitorError> {
26 let re = regex::Regex::new(r"(\d\d*(?:\.\d\d*)??)([smh])")?;
27 let cap = re
28 .captures(duration)
29 .ok_or(InquisitorError::DurationParseError)?;
30
31 let base = cap[1]
32 .parse::<f64>()
33 .map_err(|_| InquisitorError::DurationParseError)?;
34 let mul: f64 = match &cap[2] {
35 "s" => 1_000_000.0,
36 "m" => 60.0 * 1_000_000.0,
37 "h" => 60.0 * 60.0 * 1_000_000.0,
38 _ => unreachable!(),
39 };
40
41 Ok(Duration::from_micros((base * mul) as u64))
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47
48 #[test]
49 fn displays_time_correctly() {
50 assert_eq!(Microseconds(0.0).to_string(), "0 us");
51 assert_eq!(Microseconds(1.0).to_string(), "1 us");
52 assert_eq!(Microseconds(10.0).to_string(), "10 us");
53 assert_eq!(Microseconds(100.0).to_string(), "100 us");
54 assert_eq!(Microseconds(999.0).to_string(), "999 us");
55 assert_eq!(Microseconds(1000.0).to_string(), "1.00 ms");
56 assert_eq!(Microseconds(1010.0).to_string(), "1.01 ms");
57 assert_eq!(Microseconds(10_000.0).to_string(), "10.0 ms");
58 assert_eq!(Microseconds(100_000.0).to_string(), "100 ms");
59 assert_eq!(Microseconds(999_000.0).to_string(), "999 ms");
60 assert_eq!(Microseconds(1_000_000.0).to_string(), "1.00 s");
61 assert_eq!(Microseconds(10_000_000.0).to_string(), "10.0 s");
62 assert_eq!(Microseconds(100_000_000.0).to_string(), "100 s");
63 }
64}