use pin_project_lite::pin_project;
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
pin_project! {
pub struct Cancellable<F, C> {
#[pin]
future: F,
#[pin]
cancel_future: C,
}
}
impl<F: Future + Send, C: Future + Send> Cancellable<F, C> {
pub fn new(future: F, cancel_future: C) -> Self {
Self { future, cancel_future }
}
}
impl<F: Future + Send, C: Future + Send> Future for Cancellable<F, C> {
type Output = Result<F::Output, ()>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut _self = self.project();
let future = unsafe { Pin::new_unchecked(&mut _self.future) };
if let Poll::Ready(output) = future.poll(cx) {
return Poll::Ready(Ok(output));
}
let cancel_future = unsafe { Pin::new_unchecked(&mut _self.cancel_future) };
if cancel_future.poll(cx).is_ready() {
return Poll::Ready(Err(()));
}
Poll::Pending
}
}