use core::num::NonZeroU64;
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum WakePrecision {
Nanosecond,
Microsecond,
Millisecond,
Second,
}
impl WakePrecision {
pub const fn nanoseconds_per_tick(self) -> NonZeroU64 {
match self {
Self::Nanosecond => NonZeroU64::MIN,
Self::Microsecond => const { NonZeroU64::MIN.saturating_add(999) },
Self::Millisecond => const { NonZeroU64::MIN.saturating_add(999_999) },
Self::Second => const { NonZeroU64::MIN.saturating_add(999_999_999) },
}
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct WakeAfter {
ticks: NonZeroU64,
precision: WakePrecision,
}
impl WakeAfter {
pub const fn nanoseconds(ticks: NonZeroU64) -> Self {
Self::new(ticks, WakePrecision::Nanosecond)
}
pub const fn microseconds(ticks: NonZeroU64) -> Self {
Self::new(ticks, WakePrecision::Microsecond)
}
pub const fn milliseconds(ticks: NonZeroU64) -> Self {
Self::new(ticks, WakePrecision::Millisecond)
}
pub const fn seconds(ticks: NonZeroU64) -> Self {
Self::new(ticks, WakePrecision::Second)
}
pub const fn new(ticks: NonZeroU64, precision: WakePrecision) -> Self {
Self { ticks, precision }
}
pub const fn ticks(self) -> NonZeroU64 {
self.ticks
}
pub const fn precision(self) -> WakePrecision {
self.precision
}
pub const fn checked_nanoseconds(self) -> Option<NonZeroU64> {
let nanoseconds = self
.ticks
.get()
.checked_mul(self.precision.nanoseconds_per_tick().get());
match nanoseconds {
Some(nanoseconds) => NonZeroU64::new(nanoseconds),
None => None,
}
}
}