use crate::{Hook, Hooks};
use core::{
future::Future,
pin::Pin,
task::{Context, Poll},
};
use futures::future::BoxFuture;
mod private {
pub trait Sealed {}
impl Sealed for crate::Hooks<'_, '_> {}
}
pub trait UseFuture: private::Sealed {
fn use_future<F>(&mut self, f: F)
where
F: Future<Output = ()> + Send + 'static;
}
impl UseFuture for Hooks<'_, '_> {
fn use_future<F>(&mut self, f: F)
where
F: Future<Output = ()> + Send + 'static,
{
self.use_hook(move || UseFutureImpl::new(f));
}
}
struct UseFutureImpl {
f: Option<BoxFuture<'static, ()>>,
}
impl Hook for UseFutureImpl {
fn poll_change(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
if let Some(f) = self.f.as_mut() {
if let Poll::Ready(()) = f.as_mut().poll(cx) {
self.f = None;
}
}
Poll::Pending
}
}
impl UseFutureImpl {
pub fn new<F>(f: F) -> Self
where
F: Future<Output = ()> + Send + 'static,
{
Self {
f: Some(Box::pin(f)),
}
}
}