use crate::{timer_queue::TimerQueueBackend, TimeoutError};
use crate::Monotonic;
pub trait TimerQueueBasedMonotonic {
type Backend: TimerQueueBackend;
type Instant: TimerQueueBasedInstant<Ticks = <Self::Backend as TimerQueueBackend>::Ticks>
+ core::ops::Add<Self::Duration, Output = Self::Instant>
+ core::ops::Sub<Self::Duration, Output = Self::Instant>
+ core::ops::Sub<Self::Instant, Output = Self::Duration>;
type Duration: TimerQueueBasedDuration<Ticks = <Self::Backend as TimerQueueBackend>::Ticks>;
}
impl<T: TimerQueueBasedMonotonic> Monotonic for T {
type Instant = T::Instant;
type Duration = T::Duration;
fn now() -> Self::Instant {
Self::Instant::from_ticks(T::Backend::timer_queue().now())
}
async fn delay(duration: Self::Duration) {
T::Backend::timer_queue().delay(duration.ticks()).await
}
async fn delay_until(instant: Self::Instant) {
T::Backend::timer_queue().delay_until(instant.ticks()).await
}
async fn timeout_at<F: core::future::Future>(
instant: Self::Instant,
future: F,
) -> Result<F::Output, TimeoutError> {
T::Backend::timer_queue()
.timeout_at(instant.ticks(), future)
.await
}
async fn timeout_after<F: core::future::Future>(
duration: Self::Duration,
future: F,
) -> Result<F::Output, TimeoutError> {
T::Backend::timer_queue()
.timeout_after(duration.ticks(), future)
.await
}
}
pub trait TimerQueueBasedInstant: Ord + Copy {
type Ticks;
fn from_ticks(ticks: Self::Ticks) -> Self;
fn ticks(self) -> Self::Ticks;
}
pub trait TimerQueueBasedDuration: Copy {
type Ticks;
fn ticks(self) -> Self::Ticks;
}
impl<const NOM: u32, const DENOM: u32> TimerQueueBasedInstant for fugit::Instant<u64, NOM, DENOM> {
type Ticks = u64;
fn from_ticks(ticks: Self::Ticks) -> Self {
Self::from_ticks(ticks)
}
fn ticks(self) -> Self::Ticks {
Self::ticks(&self)
}
}
impl<const NOM: u32, const DENOM: u32> TimerQueueBasedInstant for fugit::Instant<u32, NOM, DENOM> {
type Ticks = u32;
fn from_ticks(ticks: Self::Ticks) -> Self {
Self::from_ticks(ticks)
}
fn ticks(self) -> Self::Ticks {
Self::ticks(&self)
}
}
impl<const NOM: u32, const DENOM: u32> TimerQueueBasedDuration
for fugit::Duration<u64, NOM, DENOM>
{
type Ticks = u64;
fn ticks(self) -> Self::Ticks {
Self::ticks(&self)
}
}
impl<const NOM: u32, const DENOM: u32> TimerQueueBasedDuration
for fugit::Duration<u32, NOM, DENOM>
{
type Ticks = u32;
fn ticks(self) -> Self::Ticks {
Self::ticks(&self)
}
}