use __private::QueueableSealed;
use crate::reactor::{Reactor, Readable, Registration};
use crate::Async;
use std::future::Future;
use std::io::{Error, Result};
use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, OwnedFd, RawFd};
use std::pin::Pin;
use std::process::Child;
use std::task::{Context, Poll};
#[derive(Debug)]
pub struct Filter<T>(Async<T>);
impl<T> AsRef<T> for Filter<T> {
fn as_ref(&self) -> &T {
self.0.as_ref()
}
}
impl<T> AsMut<T> for Filter<T> {
fn as_mut(&mut self) -> &mut T {
self.get_mut()
}
}
impl<T: Queueable> Filter<T> {
pub fn new(mut filter: T) -> Result<Self> {
Ok(Self(Async {
source: Reactor::get().insert_io(filter.registration())?,
io: Some(filter),
}))
}
}
impl<T: AsRawFd> AsRawFd for Filter<T> {
fn as_raw_fd(&self) -> RawFd {
self.0.as_raw_fd()
}
}
impl<T: AsFd> AsFd for Filter<T> {
fn as_fd(&self) -> BorrowedFd<'_> {
self.0.as_fd()
}
}
impl<T: AsFd + From<OwnedFd>> TryFrom<OwnedFd> for Filter<T> {
type Error = Error;
fn try_from(fd: OwnedFd) -> Result<Self> {
Ok(Self(Async::try_from(fd)?))
}
}
impl<T: Into<OwnedFd>> TryFrom<Filter<T>> for OwnedFd {
type Error = Error;
fn try_from(filter: Filter<T>) -> Result<Self> {
filter.0.try_into()
}
}
impl<T> Filter<T> {
pub fn get_ref(&self) -> &T {
self.0.get_ref()
}
pub fn get_mut(&mut self) -> &mut T {
unsafe { 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)
}
}
pub trait Queueable: QueueableSealed {}
#[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub struct Signal(pub i32);
impl QueueableSealed for Signal {
fn registration(&mut self) -> Registration {
Registration::Signal(*self)
}
}
impl Queueable for Signal {}
#[derive(Debug)]
pub struct Exit(Option<Child>);
impl Exit {
pub fn new(child: Child) -> Self {
Self(Some(child))
}
}
impl QueueableSealed for Exit {
fn registration(&mut self) -> Registration {
Registration::Process(self.0.take().expect("Cannot reregister child"))
}
}
impl Queueable for Exit {}
mod __private {
use crate::reactor::Registration;
#[doc(hidden)]
pub trait QueueableSealed {
fn registration(&mut self) -> Registration;
}
}