use core::borrow::Borrow;
use core::cmp::{Ord, Ordering, PartialEq, PartialOrd};
use core::ops::{Add, Sub};
use core::time::Duration as StdDuration;
use std::time::Instant as StdInstant;
use crate::internal_macros::{impl_add_assign, impl_sub_assign};
use crate::Duration;
#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Instant(pub StdInstant);
impl Instant {
pub fn now() -> Self {
Self(StdInstant::now())
}
pub fn elapsed(self) -> Duration {
Self::now() - self
}
pub fn checked_add(self, duration: Duration) -> Option<Self> {
if duration.is_zero() {
Some(self)
} else if duration.is_positive() {
self.0.checked_add(duration.unsigned_abs()).map(Self)
} else {
debug_assert!(duration.is_negative());
self.0.checked_sub(duration.unsigned_abs()).map(Self)
}
}
pub fn checked_sub(self, duration: Duration) -> Option<Self> {
if duration.is_zero() {
Some(self)
} else if duration.is_positive() {
self.0.checked_sub(duration.unsigned_abs()).map(Self)
} else {
debug_assert!(duration.is_negative());
self.0.checked_add(duration.unsigned_abs()).map(Self)
}
}
pub const fn into_inner(self) -> StdInstant {
self.0
}
}
impl From<StdInstant> for Instant {
fn from(instant: StdInstant) -> Self {
Self(instant)
}
}
impl From<Instant> for StdInstant {
fn from(instant: Instant) -> Self {
instant.0
}
}
impl Sub for Instant {
type Output = Duration;
fn sub(self, other: Self) -> Self::Output {
match self.0.cmp(&other.0) {
Ordering::Equal => Duration::ZERO,
Ordering::Greater => (self.0 - other.0)
.try_into()
.expect("overflow converting `std::time::Duration` to `time::Duration`"),
Ordering::Less => -Duration::try_from(other.0 - self.0)
.expect("overflow converting `std::time::Duration` to `time::Duration`"),
}
}
}
impl Sub<StdInstant> for Instant {
type Output = Duration;
fn sub(self, other: StdInstant) -> Self::Output {
self - Self(other)
}
}
impl Sub<Instant> for StdInstant {
type Output = Duration;
fn sub(self, other: Instant) -> Self::Output {
Instant(self) - other
}
}
impl Add<Duration> for Instant {
type Output = Self;
fn add(self, duration: Duration) -> Self::Output {
if duration.is_positive() {
Self(self.0 + duration.unsigned_abs())
} else if duration.is_negative() {
#[allow(clippy::unchecked_duration_subtraction)]
Self(self.0 - duration.unsigned_abs())
} else {
debug_assert!(duration.is_zero());
self
}
}
}
impl Add<Duration> for StdInstant {
type Output = Self;
fn add(self, duration: Duration) -> Self::Output {
(Instant(self) + duration).0
}
}
impl Add<StdDuration> for Instant {
type Output = Self;
fn add(self, duration: StdDuration) -> Self::Output {
Self(self.0 + duration)
}
}
impl_add_assign!(Instant: Duration, StdDuration);
impl_add_assign!(StdInstant: Duration);
impl Sub<Duration> for Instant {
type Output = Self;
fn sub(self, duration: Duration) -> Self::Output {
if duration.is_positive() {
#[allow(clippy::unchecked_duration_subtraction)]
Self(self.0 - duration.unsigned_abs())
} else if duration.is_negative() {
Self(self.0 + duration.unsigned_abs())
} else {
debug_assert!(duration.is_zero());
self
}
}
}
impl Sub<Duration> for StdInstant {
type Output = Self;
fn sub(self, duration: Duration) -> Self::Output {
(Instant(self) - duration).0
}
}
impl Sub<StdDuration> for Instant {
type Output = Self;
fn sub(self, duration: StdDuration) -> Self::Output {
#[allow(clippy::unchecked_duration_subtraction)]
Self(self.0 - duration)
}
}
impl_sub_assign!(Instant: Duration, StdDuration);
impl_sub_assign!(StdInstant: Duration);
impl PartialEq<StdInstant> for Instant {
fn eq(&self, rhs: &StdInstant) -> bool {
self.0.eq(rhs)
}
}
impl PartialEq<Instant> for StdInstant {
fn eq(&self, rhs: &Instant) -> bool {
self.eq(&rhs.0)
}
}
impl PartialOrd<StdInstant> for Instant {
fn partial_cmp(&self, rhs: &StdInstant) -> Option<Ordering> {
self.0.partial_cmp(rhs)
}
}
impl PartialOrd<Instant> for StdInstant {
fn partial_cmp(&self, rhs: &Instant) -> Option<Ordering> {
self.partial_cmp(&rhs.0)
}
}
impl AsRef<StdInstant> for Instant {
fn as_ref(&self) -> &StdInstant {
&self.0
}
}
impl Borrow<StdInstant> for Instant {
fn borrow(&self) -> &StdInstant {
&self.0
}
}