use std::{
pin::Pin,
task::{Context, Poll},
};
use pin_project_lite::pin_project;
pub use crate::{
flash::Instant,
native::time::{Duration, SystemTime, TimeoutError},
};
pub async fn sleep(duration: Duration) {
if crate::flash::flash_enabled() {
crate::flash::FlashSleep::new(duration).await;
} else {
crate::native::time::sleep(duration).await;
}
}
pub async fn timeout<F>(duration: Duration, future: F) -> Result<F::Output, TimeoutError>
where
F: Future,
{
if crate::flash::flash_enabled() {
FlashTimeout {
future,
sleep: crate::flash::FlashSleep::new(duration),
}
.await
} else {
crate::native::time::timeout(duration, future).await
}
}
pin_project! {
pub(crate) struct FlashTimeout<F> {
#[pin]
pub(crate) future: F,
#[pin]
pub(crate) sleep: crate::flash::FlashSleep,
}
}
impl<F: Future> Future for FlashTimeout<F> {
type Output = Result<F::Output, TimeoutError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
if let Poll::Ready(out) = this.future.poll(cx) {
return Poll::Ready(Ok(out));
}
match this.sleep.poll(cx) {
Poll::Ready(()) => Poll::Ready(Err(TimeoutError)),
Poll::Pending => Poll::Pending,
}
}
}