use crate::Duration;
use core::marker::PhantomData;
use core::ops::{Add, AddAssign, Sub, SubAssign};
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
pub struct TimePoint<Clock> {
since_epoch: Duration,
_phantom: PhantomData<Clock>,
}
impl<Clock> TimePoint<Clock> {
pub const fn new(since_epoch: Duration) -> Self {
Self {
since_epoch,
_phantom: PhantomData,
}
}
#[inline]
pub fn duration_since(&self, earlier: Self) -> Duration {
self.since_epoch - earlier.since_epoch
}
#[inline]
pub fn checked_duration_since(&self, earlier: Self) -> Option<Duration> {
self.since_epoch.checked_sub(earlier.since_epoch)
}
#[inline]
pub fn duration_since_epoch(&self) -> Duration {
self.since_epoch
}
}
impl<Clock> Add<Duration> for TimePoint<Clock> {
type Output = Self;
#[inline]
fn add(mut self, rhs: Duration) -> Self::Output {
self.since_epoch += rhs;
self
}
}
impl<Clock> AddAssign<Duration> for TimePoint<Clock> {
#[inline]
fn add_assign(&mut self, rhs: Duration) {
self.since_epoch += rhs;
}
}
impl<Clock> Sub<Self> for TimePoint<Clock> {
type Output = Duration;
#[inline]
fn sub(self, rhs: Self) -> Self::Output {
self.duration_since(rhs)
}
}
impl<Clock> Sub<Duration> for TimePoint<Clock> {
type Output = Self;
#[inline]
fn sub(mut self, rhs: Duration) -> Self::Output {
self.since_epoch -= rhs;
self
}
}
impl<Clock> SubAssign<Duration> for TimePoint<Clock> {
#[inline]
fn sub_assign(&mut self, rhs: Duration) {
self.since_epoch -= rhs;
}
}
#[cfg(test)]
mod tests {
use crate::{Duration, TimePoint};
#[test]
#[should_panic]
fn duration_since() {
struct C;
let later: TimePoint<C> = TimePoint::new(Duration::from_micros(-2));
let earlier = TimePoint::new(Duration::MAX);
let _ = later.duration_since(earlier);
}
}