use core::ops::{Add, AddAssign, Sub, SubAssign};
use crate::{Duration, NANOS_PER_MICRO, NANOS_PER_MILLI, NANOS_PER_SEC};
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Instant(u64);
impl Instant {
pub const ZERO: Self = Self(0);
pub const MAX: Self = Self(u64::MAX);
#[must_use]
pub const fn from_nanos(nanos: u64) -> Self {
Self(nanos)
}
#[must_use]
pub const fn from_micros(micros: u64) -> Self {
Self(micros.saturating_mul(NANOS_PER_MICRO))
}
#[must_use]
pub const fn from_millis(millis: u64) -> Self {
Self(millis.saturating_mul(NANOS_PER_MILLI))
}
#[must_use]
pub const fn from_secs(secs: u64) -> Self {
Self(secs.saturating_mul(NANOS_PER_SEC))
}
#[must_use]
pub const fn as_nanos(self) -> u64 {
self.0
}
#[must_use]
pub const fn as_micros(self) -> u64 {
self.since_epoch().as_micros()
}
#[must_use]
pub const fn as_millis(self) -> u64 {
self.since_epoch().as_millis()
}
#[must_use]
pub const fn as_secs(self) -> u64 {
self.since_epoch().as_secs()
}
#[must_use]
pub const fn checked_add(self, duration: Duration) -> Option<Self> {
match self.0.checked_add(duration.as_nanos()) {
Some(nanos) => Some(Self(nanos)),
None => None,
}
}
#[must_use]
pub const fn saturating_add(self, duration: Duration) -> Self {
Self(self.0.saturating_add(duration.as_nanos()))
}
#[must_use]
pub const fn checked_sub(self, duration: Duration) -> Option<Self> {
match self.0.checked_sub(duration.as_nanos()) {
Some(nanos) => Some(Self(nanos)),
None => None,
}
}
#[must_use]
pub const fn saturating_sub(self, duration: Duration) -> Self {
Self(self.0.saturating_sub(duration.as_nanos()))
}
#[must_use]
pub const fn checked_duration_since(self, earlier: Self) -> Option<Duration> {
match self.0.checked_sub(earlier.0) {
Some(nanos) => Some(Duration::from_nanos(nanos)),
None => None,
}
}
#[must_use]
pub const fn saturating_duration_since(self, earlier: Self) -> Duration {
Duration::from_nanos(self.0.saturating_sub(earlier.0))
}
#[must_use]
pub const fn min(self, other: Self) -> Self {
if self.0 <= other.0 {
self
} else {
other
}
}
#[must_use]
pub const fn max(self, other: Self) -> Self {
if self.0 >= other.0 {
self
} else {
other
}
}
const fn since_epoch(self) -> Duration {
Duration::from_nanos(self.0)
}
}
impl Add<Duration> for Instant {
type Output = Self;
fn add(self, rhs: Duration) -> Self {
self.saturating_add(rhs)
}
}
impl AddAssign<Duration> for Instant {
fn add_assign(&mut self, rhs: Duration) {
*self = self.saturating_add(rhs);
}
}
impl Sub<Duration> for Instant {
type Output = Self;
fn sub(self, rhs: Duration) -> Self {
self.saturating_sub(rhs)
}
}
impl SubAssign<Duration> for Instant {
fn sub_assign(&mut self, rhs: Duration) {
*self = self.saturating_sub(rhs);
}
}
impl Sub for Instant {
type Output = Duration;
fn sub(self, rhs: Self) -> Duration {
self.saturating_duration_since(rhs)
}
}