use std::{
cmp::Ordering,
time::{Duration, SystemTime},
};
pub(crate) trait SystemTimeExt {
fn cmp_nearly(&self, other: SystemTime) -> Ordering;
fn eq_nearly(&self, other: SystemTime) -> bool;
}
impl SystemTimeExt for SystemTime {
fn cmp_nearly(&self, other: SystemTime) -> Ordering {
let (diff, ordering) = if *self > other {
(self.duration_since(other).unwrap(), Ordering::Greater)
} else {
(other.duration_since(*self).unwrap(), Ordering::Less)
};
if diff < Duration::from_nanos(100) {
return Ordering::Equal;
}
ordering
}
fn eq_nearly(&self, other: SystemTime) -> bool {
self.cmp_nearly(other) == Ordering::Equal
}
}
#[cfg(test)]
mod tests {
use std::ops::{Add, Sub};
use std::time::UNIX_EPOCH;
use super::*;
#[test]
fn cmp_nearly() {
let time = UNIX_EPOCH + Duration::new(12345, 67890);
assert_eq!(time.cmp_nearly(time), Ordering::Equal);
assert!(time.eq_nearly(time));
let add = time.add(Duration::new(0, 10));
let sub = time.sub(Duration::new(0, 90));
assert_eq!(time.cmp_nearly(add), Ordering::Equal);
assert_eq!(time.cmp_nearly(sub), Ordering::Equal);
assert!(time.eq_nearly(add));
assert!(time.eq_nearly(sub));
let add = time.add(Duration::new(0, 100));
assert_eq!(time.cmp_nearly(add), Ordering::Less);
assert!(!time.eq_nearly(add));
let sub = time.sub(Duration::new(0, 100));
assert_eq!(time.cmp_nearly(sub), Ordering::Greater);
assert!(!time.eq_nearly(sub));
}
}