Skip to main content

bacnet_time/
format.rs

1//! `Debug` for [`Duration`] and [`Instant`]: nanoseconds, with the unit, as
2//! `Duration(1500ns)`.
3
4use core::fmt;
5
6use crate::divide::div_rem;
7use crate::{Duration, Instant, NANOS_PER_SEC};
8
9impl fmt::Debug for Duration {
10    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11        write_nanos(f, "Duration", self.as_nanos())
12    }
13}
14
15impl fmt::Debug for Instant {
16    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17        write_nanos(f, "Instant", self.as_nanos())
18    }
19}
20
21/// Writes `name(<nanos>ns)`.
22///
23/// The count goes out as up to three parts below 10^9, each a `u32`, split
24/// off by [`div_rem`]: formatting a `u64` directly divides it by powers of
25/// ten, which on a 32-bit target links a 64-bit division routine.
26fn write_nanos(f: &mut fmt::Formatter<'_>, name: &str, nanos: u64) -> fmt::Result {
27    let (upper, low) = div_rem(nanos, NANOS_PER_SEC);
28    let (high, middle) = div_rem(upper, NANOS_PER_SEC);
29    // u64::MAX is under 19 * 10^18, so `high` is at most 18, and the other
30    // two are remainders below 10^9: each fits a u32.
31    let (high, middle, low) = (high as u32, middle as u32, low as u32);
32    if high != 0 {
33        write!(f, "{name}({high}{middle:09}{low:09}ns)")
34    } else if middle != 0 {
35        write!(f, "{name}({middle}{low:09}ns)")
36    } else {
37        write!(f, "{name}({low}ns)")
38    }
39}