use crate::{Clock, DurationCalibration, InherentlyCalibrated, Time};
use core::cmp::Ordering;
use std::time::{Duration, Instant, SystemTime};
pub struct InstantTime;
impl Time for InstantTime {
type Instant = std::time::Instant;
type Duration = Duration;
#[inline]
fn instant_sub(a: Self::Instant, b: Self::Instant) -> Self::Duration {
a.checked_duration_since(b)
.expect("instant_sub: a is earlier than b; Duration cannot represent negative values")
}
#[inline]
fn duration_sub(a: Self::Duration, b: Self::Duration) -> Self::Duration {
a - b
}
#[inline]
fn duration_add(a: Self::Duration, b: Self::Duration) -> Self::Duration {
a + b
}
#[inline]
fn mixed_sub(a: Self::Instant, b: Self::Duration) -> Self::Instant {
a - b
}
#[inline]
fn mixed_add(a: Self::Instant, b: Self::Duration) -> Self::Instant {
a + b
}
#[inline]
fn instant_cmp(a: Self::Instant, b: Self::Instant) -> Ordering {
a.cmp(&b)
}
}
pub struct SystemTimeTime;
impl Time for SystemTimeTime {
type Instant = SystemTime;
type Duration = Duration;
#[inline]
fn instant_sub(a: SystemTime, b: SystemTime) -> Duration {
a.duration_since(b)
.expect("instant_sub: a is earlier than b; Duration cannot represent negative values")
}
#[inline]
fn duration_sub(a: Duration, b: Duration) -> Duration {
a - b
}
#[inline]
fn duration_add(a: Duration, b: Duration) -> Duration {
a + b
}
#[inline]
fn mixed_sub(a: SystemTime, b: Duration) -> SystemTime {
a - b
}
#[inline]
fn mixed_add(a: SystemTime, b: Duration) -> SystemTime {
a + b
}
#[inline]
fn instant_cmp(a: Self::Instant, b: Self::Instant) -> Ordering {
a.cmp(&b)
}
}
macro_rules! std_clock {
($(#[$meta:meta])* $Instant:ty, $Clock:ident, $TimeType:ty) => {
$(#[$meta])*
#[derive(Clone, Copy, Debug)]
pub struct $Clock;
impl Clock for $Clock {
type Time = $TimeType;
type Calibration = InherentlyCalibrated;
fn now(&self) -> $Instant {
<$Instant>::now()
}
}
};
}
std_clock!(
Instant, InstantClock, InstantTime
);
std_clock!(
SystemTime, SystemClock, SystemTimeTime
);
impl DurationCalibration<Duration> for InherentlyCalibrated {
#[inline]
fn convert_to_ns(&self, d: Duration) -> u64 {
d.as_nanos()
.try_into()
.expect("duration exceeds u64::MAX nanoseconds (~584 years)")
}
#[inline]
fn convert_from_ns(&self, ns: u64) -> Duration {
Duration::from_nanos(ns)
}
}