Skip to main content

inquisitor_core/
time.rs

1use crate::error::InquisitorError;
2use std::time::Duration;
3
4/// Represents an amount of microseconds
5pub 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
22/// Parse a duration like 10s, 25m, 3.5h into a duration. Decimal numbers are
23/// allowed, and the allowed time units are: seconds (s), minutes (m) and
24/// hours (h).
25pub 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}