use std::time::Instant as StdInstant;
use crate::Duration;
mod sealed {
pub trait Sealed: Sized {}
impl Sealed for std::time::Instant {}
}
pub trait InstantExt: sealed::Sealed {
fn add_signed(self, duration: Duration) -> Self {
self.checked_add_signed(duration)
.expect("overflow when adding duration to instant")
}
fn sub_signed(self, duration: Duration) -> Self {
self.checked_sub_signed(duration)
.expect("overflow when subtracting duration from instant")
}
fn checked_add_signed(&self, duration: Duration) -> Option<Self>;
fn checked_sub_signed(&self, duration: Duration) -> Option<Self>;
fn signed_duration_since(&self, earlier: Self) -> Duration;
}
impl InstantExt for StdInstant {
fn checked_add_signed(&self, duration: Duration) -> Option<Self> {
if duration.is_positive() {
self.checked_add(duration.unsigned_abs())
} else if duration.is_negative() {
self.checked_sub(duration.unsigned_abs())
} else {
debug_assert!(duration.is_zero());
Some(*self)
}
}
fn checked_sub_signed(&self, duration: Duration) -> Option<Self> {
if duration.is_positive() {
self.checked_sub(duration.unsigned_abs())
} else if duration.is_negative() {
self.checked_add(duration.unsigned_abs())
} else {
debug_assert!(duration.is_zero());
Some(*self)
}
}
fn signed_duration_since(&self, earlier: Self) -> Duration {
if *self > earlier {
self.saturating_duration_since(earlier)
.try_into()
.unwrap_or(Duration::MAX)
} else {
earlier
.saturating_duration_since(*self)
.try_into()
.map_or(Duration::MIN, |d: Duration| -d)
}
}
}