use std::ops::Sub;
use std::time::Duration;
use allocative::Allocative;
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Allocative)]
pub(crate) struct ProfilerInstant(
#[cfg(not(test))] std::time::Instant,
#[cfg(test)] u64, );
impl ProfilerInstant {
#[cfg(test)]
pub(crate) const TEST_TICK_MILLIS: u64 = 7;
#[inline]
pub(crate) fn now() -> Self {
#[cfg(not(test))]
{
ProfilerInstant(std::time::Instant::now())
}
#[cfg(test)]
{
thread_local! {
static NOW_MILLIS: std::cell::Cell<u64> = const { std::cell::Cell::new(100003) };
}
ProfilerInstant(NOW_MILLIS.with(|v| {
let r = v.get();
v.set(r + ProfilerInstant::TEST_TICK_MILLIS);
r
}))
}
}
#[inline]
pub(crate) fn duration_since(&self, earlier: ProfilerInstant) -> Duration {
#[cfg(not(test))]
{
self.0.duration_since(earlier.0)
}
#[cfg(test)]
{
Duration::from_millis(self.0.checked_sub(earlier.0).unwrap())
}
}
#[inline]
pub(crate) fn elapsed(&self) -> Duration {
#[cfg(not(test))]
{
self.0.elapsed()
}
#[cfg(test)]
{
ProfilerInstant::now().duration_since(*self)
}
}
}
impl Sub for ProfilerInstant {
type Output = Duration;
#[inline]
fn sub(self, rhs: Self) -> Self::Output {
self.duration_since(rhs)
}
}