use futures01::{Async, Future, Poll};
#[derive(Debug)]
#[must_use = "futures do nothing unless polled"]
pub struct Cancellable<F, S>
where
F: Future,
S: Future,
{
inner: F,
stopper: Option<S>,
}
#[derive(Debug)]
pub enum CancellableError<C, E> {
Cancelled(C),
Errored(E),
}
impl<F, S> Future for Cancellable<F, S>
where
F: Future,
S: Future,
{
type Error = CancellableError<S::Item, F::Error>;
type Item = F::Item;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let inner = match self.inner.poll() {
Ok(ok @ Async::NotReady) => Ok(ok),
Ok(ok @ Async::Ready(_)) => {
return Ok(ok); }
Err(e) => Err(CancellableError::Errored(e)),
};
if let Some(ref mut stopper) = self.stopper {
match stopper.poll() {
Ok(Async::Ready(s)) => return Err(CancellableError::Cancelled(s)),
Ok(_) => {}
Err(_) => {
self.stopper = None;
}
}
}
inner
}
}
pub trait FutureCancellable: Future {
fn cancel_with<S>(self, stopper: impl FnOnce() -> S) -> Cancellable<Self, S>
where
S: Future,
Self: Sized,
{
Cancellable { inner: self, stopper: Some((stopper)()) }
}
}
impl<T: ?Sized> FutureCancellable for T where T: Future {}