use std::fmt::{Debug, Formatter};
use std::ops::{Add, AddAssign, Sub, SubAssign};
use std::time::{Duration, Instant, SystemTime};
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Copy, Clone, PartialEq, PartialOrd)]
pub struct Spot {
inner: Instant,
}
impl Debug for Spot {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.inner.fmt(f)
}
}
impl Spot {
pub fn now() -> Self {
Spot {
inner: Instant::now(),
}
}
pub fn elapsed(&self) -> Duration {
Spot::now() - *self
}
pub fn duration_since(&self, earlier: Spot) -> Duration {
self.checked_duration_since(earlier).unwrap_or_default()
}
pub fn checked_duration_since(&self, earlier: Spot) -> Option<Duration> {
self.inner.checked_duration_since(earlier.inner)
}
pub fn saturating_duration_since(&self, earlier: Spot) -> Duration {
self.inner.saturating_duration_since(earlier.inner)
}
pub fn checked_add(&self, duration: Duration) -> Option<Spot> {
self.inner.checked_add(duration).map(|inner| Spot { inner })
}
pub fn checked_sub(&self, duration: Duration) -> Option<Spot> {
self.inner.checked_sub(duration).map(|inner| Spot { inner })
}
pub fn duration_since_epoch(&self) -> Duration {
let duration_since_epoch = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.expect("Failed to get time since epoch");
let duration_since_instant = self.elapsed();
duration_since_epoch - duration_since_instant
}
}
impl Add<Duration> for Spot {
type Output = Spot;
fn add(self, other: Duration) -> Spot {
self.checked_add(other)
.expect("overflow when adding duration to instant")
}
}
impl AddAssign<Duration> for Spot {
fn add_assign(&mut self, other: Duration) {
*self = *self + other;
}
}
impl Sub<Duration> for Spot {
type Output = Spot;
fn sub(self, other: Duration) -> Spot {
self.checked_sub(other)
.expect("overflow when subtracting duration from instant")
}
}
impl SubAssign<Duration> for Spot {
fn sub_assign(&mut self, other: Duration) {
*self = *self - other;
}
}
impl Sub<Spot> for Spot {
type Output = Duration;
fn sub(self, other: Spot) -> Duration {
self.duration_since(other)
}
}