use std::future::Future;
use std::io::Result;
use std::pin::Pin;
use std::task::{
Context,
Poll,
};
use crate::{
AsyncClose,
traits::normalize_async_error,
};
#[must_use = "futures do nothing unless polled"]
pub struct CloseFuture<'a, O>
where
O: AsyncClose + ?Sized,
{
output: Pin<&'a mut O>,
completed: bool,
}
impl<'a, O> CloseFuture<'a, O>
where
O: AsyncClose + ?Sized,
{
#[inline(always)]
pub const fn new(output: Pin<&'a mut O>) -> Self {
Self {
output,
completed: false,
}
}
}
impl<O> Future for CloseFuture<'_, O>
where
O: AsyncClose + ?Sized,
{
type Output = Result<()>;
#[inline]
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.get_mut();
assert!(!this.completed, "CloseFuture polled after completion");
let result = this
.output
.as_mut()
.poll_close(cx)
.map(|result| result.map_err(normalize_async_error));
if result.is_ready() {
this.completed = true;
}
result
}
}