use std::task::Poll;
use futures_util::Future;
use pin_project::pin_project;
pub trait InfallibleExt<T, E, F: Future<Output = Result<T, E>>> {
fn infallible(self) -> InfalImpl<T, E, F>;
}
impl<T, E, F: Future<Output = Result<T, E>>> InfallibleExt<T, E, F> for F {
fn infallible(self) -> InfalImpl<T, E, F> {
InfalImpl {
fut: self,
resolved: false,
}
}
}
#[pin_project]
pub struct InfalImpl<T, E, F: Future<Output = Result<T, E>>> {
#[pin]
fut: F,
resolved: bool,
}
impl<T, E, F: Future<Output = Result<T, E>>> Future for InfalImpl<T, E, F> {
type Output = T;
fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
let this = self.project();
if *this.resolved {
return Poll::Pending;
}
match this.fut.poll(cx) {
Poll::Ready(val) => match val {
Ok(val) => Poll::Ready(val),
Err(_) => {
*this.resolved = true;
Poll::Pending
}
},
Poll::Pending => Poll::Pending,
}
}
}