#[cfg(feature = "std")]
use std::time::Instant;
#[cfg(feature = "std")]
fn now_as_micros() -> usize {
let start = Instant::now();
let elapsed = start.elapsed().as_micros();
elapsed as usize
}
const OUTDATED_TIME_DIFFERENCE_IN_MICROSECONDS: usize = 1_000_000;
pub type MicroSeconds = usize;
pub struct TimeDelta {
now_fn: fn() -> usize,
last: usize,
}
impl Default for TimeDelta {
fn default() -> Self {
Self::new(now_as_micros, 0)
}
}
impl TimeDelta {
pub fn new(now_fn: fn() -> usize, last: usize) -> Self {
Self { now_fn, last }
}
pub fn diff(&mut self) -> MicroSeconds {
let now = (self.now_fn)();
let mut delta: usize;
if now >= self.last {
delta = now - self.last;
} else {
delta = usize::MAX - self.last;
delta += now;
delta += 1;
}
self.last = now;
if delta > OUTDATED_TIME_DIFFERENCE_IN_MICROSECONDS {
return 0;
}
delta
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn time_delta_ok() {
assert_eq!(TimeDelta::new(|| 1000_001, 0).diff(), 0);
assert_eq!(TimeDelta::new(|| 0, 0).diff(), 0);
assert_eq!(TimeDelta::new(|| 1, 0).diff(), 1);
assert_eq!(TimeDelta::new(|| 1, usize::MAX - 1).diff(), 3);
}
}