dynomite/util/time.rs
1//! Wall-clock and digit-counting helpers.
2//!
3//! Millisecond / microsecond timestamps and a decimal digit counter,
4//! gathered as plain functions over `std::time::SystemTime`.
5
6use std::time::{SystemTime, UNIX_EPOCH};
7
8use crate::core::types::{Msec, Usec};
9
10/// Microseconds since the UNIX epoch.
11///
12/// Returns zero if the system clock reports a time before the epoch.
13///
14/// # Examples
15///
16/// ```
17/// use dynomite::util::time::usec_now;
18/// assert!(usec_now() > 0);
19/// ```
20pub fn usec_now() -> Usec {
21 SystemTime::now().duration_since(UNIX_EPOCH).map_or(0, |d| {
22 let micros = d.as_micros();
23 if micros > u128::from(Usec::MAX) {
24 Usec::MAX
25 } else {
26 #[allow(clippy::cast_possible_truncation)]
27 {
28 micros as Usec
29 }
30 }
31 })
32}
33
34/// Milliseconds since the UNIX epoch.
35///
36/// # Examples
37///
38/// ```
39/// use dynomite::util::time::msec_now;
40/// let a = msec_now();
41/// let b = msec_now();
42/// assert!(b >= a);
43/// ```
44pub fn msec_now() -> Msec {
45 usec_now() / 1000
46}
47
48/// Number of decimal digits in `arg`, including a leading zero.
49///
50/// # Examples
51///
52/// ```
53/// use dynomite::util::time::count_digits;
54/// assert_eq!(count_digits(0), 1);
55/// assert_eq!(count_digits(9), 1);
56/// assert_eq!(count_digits(10), 2);
57/// assert_eq!(count_digits(u64::MAX), 20);
58/// ```
59pub fn count_digits(arg: u64) -> u32 {
60 if arg == 0 {
61 1
62 } else {
63 arg.ilog10() + 1
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn msec_is_monotone_non_decreasing() {
73 let a = msec_now();
74 for _ in 0..16 {
75 let b = msec_now();
76 assert!(b >= a);
77 }
78 }
79
80 #[test]
81 fn msec_is_within_usec_to_msec_factor() {
82 let m = msec_now();
83 let u = usec_now();
84 // The two readings happen back-to-back; allow a few ms of skew.
85 assert!(u / 1000 >= m);
86 assert!(u / 1000 <= m + 50);
87 }
88
89 #[test]
90 fn digit_table_matches_ten_powers() {
91 for d in 1u32..=18 {
92 let n = 10u64.pow(d);
93 assert_eq!(count_digits(n), d + 1);
94 assert_eq!(count_digits(n - 1), d);
95 }
96 }
97}