use crate::Duration;
use core::{
cmp::{Ord, Ordering, PartialEq, PartialOrd},
ops::{Add, AddAssign, Sub, SubAssign},
time::Duration as StdDuration,
};
use standback::convert::{TryFrom, TryInto};
use std::time::Instant as StdInstant;
#[cfg_attr(__time_02_docs, doc(cfg(feature = "std")))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Instant {
inner: StdInstant,
}
impl Instant {
pub fn now() -> Self {
Self {
inner: StdInstant::now(),
}
}
pub fn elapsed(self) -> Duration {
Self::now() - self
}
#[cfg(__time_02_instant_checked_ops)]
pub fn checked_add(self, duration: Duration) -> Option<Self> {
if duration.is_zero() {
Some(self)
} else if duration.is_positive() {
self.inner.checked_add(duration.abs_std()).map(From::from)
} else {
self.inner.checked_sub(duration.abs_std()).map(From::from)
}
}
#[cfg(__time_02_instant_checked_ops)]
pub fn checked_sub(self, duration: Duration) -> Option<Self> {
self.checked_add(-duration)
}
}
#[allow(clippy::missing_docs_in_private_items)]
impl Instant {
#[cfg(feature = "deprecated")]
#[deprecated(since = "0.2.0", note = "Use `rhs - lhs`")]
pub fn to(&self, later: Self) -> Duration {
later - *self
}
}
impl From<StdInstant> for Instant {
fn from(instant: StdInstant) -> Self {
Self { inner: instant }
}
}
impl From<Instant> for StdInstant {
fn from(instant: Instant) -> Self {
instant.inner
}
}
impl Sub for Instant {
type Output = Duration;
fn sub(self, other: Self) -> Self::Output {
match self.inner.cmp(&other.inner) {
Ordering::Equal => Duration::zero(),
Ordering::Greater => (self.inner - other.inner)
.try_into()
.expect("overflow converting `std::time::Duration` to `time::Duration`"),
Ordering::Less => -Duration::try_from(other.inner - self.inner)
.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::from(other)
}
}
impl Sub<Instant> for StdInstant {
type Output = Duration;
fn sub(self, other: Instant) -> Self::Output {
Instant::from(self) - other
}
}
impl Add<Duration> for Instant {
type Output = Self;
fn add(self, duration: Duration) -> Self::Output {
if duration.is_positive() {
(self.inner + duration.abs_std()).into()
} else if duration.is_negative() {
(self.inner - duration.abs_std()).into()
} else {
self
}
}
}
impl Add<Duration> for StdInstant {
type Output = Self;
fn add(self, duration: Duration) -> Self::Output {
(Instant::from(self) + duration).into()
}
}
impl Add<StdDuration> for Instant {
type Output = Self;
fn add(self, duration: StdDuration) -> Self::Output {
Self {
inner: self.inner + duration,
}
}
}
impl AddAssign<Duration> for Instant {
fn add_assign(&mut self, duration: Duration) {
*self = *self + duration;
}
}
impl AddAssign<Duration> for StdInstant {
fn add_assign(&mut self, duration: Duration) {
*self = *self + duration;
}
}
impl AddAssign<StdDuration> for Instant {
fn add_assign(&mut self, duration: StdDuration) {
*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::from(self) - duration).into()
}
}
impl Sub<StdDuration> for Instant {
type Output = Self;
fn sub(self, duration: StdDuration) -> Self::Output {
Self {
inner: self.inner - duration,
}
}
}
impl SubAssign<Duration> for Instant {
fn sub_assign(&mut self, duration: Duration) {
*self = *self - duration;
}
}
impl SubAssign<Duration> for StdInstant {
fn sub_assign(&mut self, duration: Duration) {
*self = *self - duration;
}
}
impl SubAssign<StdDuration> for Instant {
fn sub_assign(&mut self, duration: StdDuration) {
*self = *self - duration;
}
}
impl PartialEq<StdInstant> for Instant {
fn eq(&self, rhs: &StdInstant) -> bool {
self.inner.eq(rhs)
}
}
impl PartialEq<Instant> for StdInstant {
fn eq(&self, rhs: &Instant) -> bool {
self.eq(&rhs.inner)
}
}
impl PartialOrd<StdInstant> for Instant {
fn partial_cmp(&self, rhs: &StdInstant) -> Option<Ordering> {
self.inner.partial_cmp(rhs)
}
}
impl PartialOrd<Instant> for StdInstant {
fn partial_cmp(&self, rhs: &Instant) -> Option<Ordering> {
self.partial_cmp(&rhs.inner)
}
}