use core::{cmp::Ordering, marker::PhantomData, ops};
use num_traits::PrimInt;
use typenum::{NonZero, Unsigned};
use crate::{
duration::{Duration, Period},
helpers::Helpers,
};
#[macro_use]
mod macros;
#[derive(Clone, Copy, Debug)]
pub struct Instant<T, Numer, Denom>
where
T: PrimInt,
Denom: NonZero,
{
pub since_start: Duration<T, Numer, Denom>,
}
impl_instant_for_integer!(u32);
impl_instant_for_integer!(u64);
impl<T, Numer, Denom> Instant<T, Numer, Denom>
where
T: PrimInt,
Denom: NonZero,
{
#[inline]
pub const fn ticks(&self) -> T {
self.since_start.ticks
}
#[inline]
pub const fn from_ticks(ticks: T) -> Self {
Self {
since_start: Duration {
ticks,
_period: Period {
_numer: PhantomData,
_denom: PhantomData,
},
},
}
}
#[inline]
pub const fn duration_since_epoch(self) -> Duration<T, Numer, Denom> {
self.since_start
}
}
impl<ST, OT, Numer, Denom> ops::SubAssign<Duration<OT, Numer, Denom>> for Instant<ST, Numer, Denom>
where
ST: PrimInt,
OT: PrimInt,
Self: ops::Sub<Duration<OT, Numer, Denom>, Output = Self>,
Numer: Unsigned,
Denom: Unsigned + NonZero,
{
#[inline]
fn sub_assign(&mut self, other: Duration<OT, Numer, Denom>) {
*self = *self - other;
}
}
impl<ST, OT, Numer, Denom> ops::AddAssign<Duration<OT, Numer, Denom>> for Instant<ST, Numer, Denom>
where
ST: PrimInt,
OT: PrimInt,
Self: ops::Add<Duration<OT, Numer, Denom>, Output = Self>,
Numer: Unsigned,
Denom: Unsigned + NonZero,
{
#[inline]
fn add_assign(&mut self, other: Duration<OT, Numer, Denom>) {
*self = *self + other;
}
}
impl<Numer, Denom> ops::Sub<Duration<u32, Numer, Denom>> for Instant<u64, Numer, Denom>
where
Numer: Unsigned,
Denom: Unsigned + NonZero,
{
type Output = Instant<u64, Numer, Denom>;
#[inline]
fn sub(self, other: Duration<u32, Numer, Denom>) -> Self::Output {
if let Some(v) = self.checked_sub_duration(other.into()) {
v
} else {
panic!("Sub failed! Overflow");
}
}
}
impl<Numer, Denom> ops::Add<Duration<u32, Numer, Denom>> for Instant<u64, Numer, Denom>
where
Numer: Unsigned,
Denom: Unsigned + NonZero,
{
type Output = Instant<u64, Numer, Denom>;
#[inline]
fn add(self, other: Duration<u32, Numer, Denom>) -> Self::Output {
if let Some(v) = self.checked_add_duration(other.into()) {
v
} else {
panic!("Add failed! Overflow");
}
}
}