use core::cmp::{Ord, Ordering, PartialEq, PartialOrd};
use core::convert::{TryFrom, TryInto};
use core::ops::{Add, AddAssign, Sub, SubAssign};
use core::time::Duration as StdDuration;
use std::time::Instant as StdInstant;
use crate::Duration;
#[cfg_attr(__time_03_docs, doc(cfg(feature = "std")))]
#[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.abs_std()).map(Self)
} else {
self.0.checked_sub(duration.abs_std()).map(Self)
}
}
pub fn checked_sub(self, duration: Duration) -> Option<Self> {
self.checked_add(-duration)
}
}
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.abs_std())
} else if duration.is_negative() {
Self(self.0 - duration.abs_std())
} else {
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<T> AddAssign<T> for Instant
where
Self: Add<T, Output = Self>,
{
fn add_assign(&mut self, rhs: T) {
*self = *self + rhs;
}
}
impl AddAssign<Duration> for StdInstant {
fn add_assign(&mut self, duration: Duration) {
*self = *self + duration;
}
}
impl Sub<Duration> for Instant {
type Output = Self;
fn sub(self, duration: Duration) -> Self::Output {
self + -duration
}
}
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 {
Self(self.0 - duration)
}
}
impl<T> SubAssign<T> for Instant
where
Self: Sub<T, Output = Self>,
{
fn sub_assign(&mut self, rhs: T) {
*self = *self - rhs;
}
}
impl SubAssign<Duration> for StdInstant {
fn sub_assign(&mut self, duration: Duration) {
*self = *self - 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)
}
}