#[cfg(feature = "popol")]
pub mod popol;
use std::fmt::{self, Display, Formatter};
use std::os::unix::io::AsRawFd;
use std::time::Duration;
use std::{io, ops};
use crate::resource::Io;
use crate::ResourceId;
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
pub struct IoType {
pub read: bool,
pub write: bool,
}
impl IoType {
pub fn none() -> Self {
Self {
read: false,
write: false,
}
}
pub fn read_only() -> Self {
Self {
read: true,
write: false,
}
}
pub fn write_only() -> Self {
Self {
read: false,
write: true,
}
}
pub fn read_write() -> Self {
Self {
read: true,
write: true,
}
}
pub fn is_none(self) -> bool { !self.read && !self.write }
pub fn is_read_only(self) -> bool { self.read && !self.write }
pub fn is_write_only(self) -> bool { !self.read && self.write }
pub fn is_read_write(self) -> bool { self.read && self.write }
}
impl ops::Not for IoType {
type Output = Self;
fn not(self) -> Self::Output {
Self {
read: !self.read,
write: !self.write,
}
}
}
impl Iterator for IoType {
type Item = Io;
fn next(&mut self) -> Option<Self::Item> {
if self.write {
self.write = false;
Some(Io::Write)
} else if self.read {
self.read = false;
Some(Io::Read)
} else {
None
}
}
}
impl Display for IoType {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
if self.is_none() {
f.write_str("none")
} else if self.is_read_write() {
f.write_str("read-write")
} else if self.read {
f.write_str("read")
} else if self.write {
f.write_str("write")
} else {
unreachable!()
}
}
}
#[derive(Copy, Clone, Debug, Display, Error)]
#[display(doc_comments)]
pub enum IoFail {
Connectivity(i16),
Os(i16),
}
pub trait Poll
where
Self: Send + Iterator<Item = (ResourceId, Result<IoType, IoFail>)>,
for<'a> &'a mut Self: Iterator<Item = (ResourceId, Result<IoType, IoFail>)>,
{
type Waker: Waker;
fn register_waker(&mut self, fd: &impl AsRawFd);
fn register(&mut self, fd: &impl AsRawFd, interest: IoType) -> ResourceId;
fn unregister(&mut self, id: ResourceId);
fn set_interest(&mut self, id: ResourceId, interest: IoType) -> bool;
fn poll(&mut self, timeout: Option<Duration>) -> io::Result<usize>;
}
pub trait Waker {
type Send: WakerSend;
type Recv: WakerRecv;
fn pair() -> Result<(Self::Send, Self::Recv), io::Error>;
}
pub trait WakerSend: Send + Sync + Clone {
fn wake(&self) -> io::Result<()>;
}
pub trait WakerRecv: AsRawFd + Send + io::Read {
fn reset(&self);
}