use crate::reactor::{Reactor, Readable, Registration};
use crate::Async;
use std::future::Future;
use std::io::{self, Result};
use std::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle, OwnedHandle, RawHandle};
use std::pin::Pin;
use std::task::{Context, Poll};
#[derive(Debug)]
pub struct Waitable<T>(Async<T>);
impl<T> AsRef<T> for Waitable<T> {
fn as_ref(&self) -> &T {
self.0.as_ref()
}
}
impl<T: AsHandle> Waitable<T> {
pub fn new(handle: T) -> Result<Self> {
Ok(Self(Async {
source: Reactor::get()
.insert_io(unsafe { Registration::new_waitable(handle.as_handle()) })?,
io: Some(handle),
}))
}
}
impl<T: AsRawHandle> AsRawHandle for Waitable<T> {
fn as_raw_handle(&self) -> RawHandle {
self.get_ref().as_raw_handle()
}
}
impl<T: AsHandle> AsHandle for Waitable<T> {
fn as_handle(&self) -> BorrowedHandle<'_> {
self.get_ref().as_handle()
}
}
impl<T: AsHandle + From<OwnedHandle>> TryFrom<OwnedHandle> for Waitable<T> {
type Error = io::Error;
fn try_from(handle: OwnedHandle) -> Result<Self> {
Self::new(handle.into())
}
}
impl<T: Into<OwnedHandle>> TryFrom<Waitable<T>> for OwnedHandle {
type Error = io::Error;
fn try_from(value: Waitable<T>) -> std::result::Result<Self, Self::Error> {
value.into_inner().map(|handle| handle.into())
}
}
impl<T> Waitable<T> {
pub fn get_ref(&self) -> &T {
self.0.get_ref()
}
pub unsafe fn get_mut(&mut self) -> &mut T {
self.0.get_mut()
}
pub fn into_inner(self) -> Result<T> {
self.0.into_inner()
}
pub fn ready(&self) -> Ready<'_, T> {
Ready(self.0.readable())
}
pub fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<()>> {
self.0.poll_readable(cx)
}
}
#[must_use = "futures do nothing unless you `.await` or poll them"]
#[derive(Debug)]
pub struct Ready<'a, T>(Readable<'a, T>);
impl<T> Future for Ready<'_, T> {
type Output = Result<()>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Pin::new(&mut self.0).poll(cx)
}
}