use core::fmt;
use core::num::NonZeroU64;
use core::ops::{Add, Sub};
use super::Duration;
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Instant {
micros: NonZeroU64,
}
impl Instant {
pub const MAX: Instant = Instant {
micros: NonZeroU64::MAX,
};
pub const MIN: Instant = Instant {
micros: NonZeroU64::MIN,
};
pub const fn duration_since(&self, earlier: Instant) -> Option<Duration> {
if self.micros.get() < earlier.micros.get() {
return None;
}
Some(Duration::from_micros(
self.micros.get() - earlier.micros.get(),
))
}
pub fn checked_add(self, rhs: Duration) -> Option<Instant> {
self.micros
.checked_add(rhs.as_micros())
.map(|micros| Instant { micros })
}
pub fn checked_sub(&self, rhs: Duration) -> Option<Instant> {
self.micros
.get()
.checked_sub(rhs.as_micros())
.and_then(NonZeroU64::new)
.map(|micros| Instant { micros })
}
}
impl Add<Duration> for Instant {
type Output = Self;
fn add(self, rhs: Duration) -> Self::Output {
let Some(result) = self.checked_add(rhs) else {
panic!("overflow when adding a duration to an instant");
};
result
}
}
impl Sub<Duration> for Instant {
type Output = Self;
fn sub(self, rhs: Duration) -> Self::Output {
let Some(result) = self.checked_sub(rhs) else {
panic!("underflow when subtracting a duration from an instant");
};
result
}
}
impl fmt::Debug for Instant {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.duration_since(Self::MIN)
.expect("instant should be at least Instant::MIN")
.fmt(f)
}
}