use std::fmt;
use std::ops::{BitOr, BitOrAssign};
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(transparent)]
pub struct Ready(u8);
const READABLE: u8 = 1 << 0;
const WRITABLE: u8 = 1 << 1;
const ERROR: u8 = 1 << 2;
const TIMER: u8 = 1 << 3;
#[cfg(unix)]
const HUP: u8 = 1 << 4;
impl Ready {
pub const READABLE: Ready = Ready(READABLE);
pub const WRITABLE: Ready = Ready(WRITABLE);
pub const ERROR: Ready = Ready(ERROR);
pub const TIMER: Ready = Ready(TIMER);
#[cfg(unix)]
pub const HUP: Ready = Ready(HUP);
#[inline]
pub(crate) fn empty() -> Ready {
Ready(0)
}
#[inline]
pub(crate) fn insert(&mut self, other: Ready) {
self.0 |= other.0;
}
#[inline]
pub fn contains(self, other: Ready) -> bool {
(self.0 & other.0) == other.0
}
#[inline]
pub fn is_readable(self) -> bool {
self.contains(Self::READABLE)
}
#[inline]
pub fn is_writable(self) -> bool {
self.contains(Self::WRITABLE)
}
#[inline]
pub fn is_error(self) -> bool {
self.contains(Self::ERROR)
}
#[inline]
pub fn is_timer(self) -> bool {
self.contains(Self::TIMER)
}
#[inline]
#[cfg(unix)]
pub fn is_hup(self) -> bool {
self.contains(Self::HUP)
}
}
impl BitOr for Ready {
type Output = Self;
#[inline]
fn bitor(self, rhs: Self) -> Self {
Ready(self.0 | rhs.0)
}
}
impl BitOrAssign for Ready {
#[inline]
fn bitor_assign(&mut self, rhs: Self) {
self.0 |= rhs.0
}
}
macro_rules! fmt_debug {
($self:expr, $f:expr, $($flag:expr),+) => {{
let mut first = true;
$(
if $self.0 & $flag != 0 {
if !first {
$f.write_str(" | ")?;
} else {
first = false;
}
$f.write_str(stringify!($flag))?;
}
)+
if first {
$f.write_str("(empty)")?;
}
Ok(())
}}
}
impl fmt::Debug for Ready {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt_debug!(self, f, READABLE, WRITABLE, ERROR, TIMER, HUP)
}
}
#[cfg(test)]
mod tests {
use crate::event::Ready;
#[test]
fn is_tests() {
assert!(!Ready::empty().is_readable());
assert!(!Ready::empty().is_writable());
assert!(!Ready::empty().is_error());
assert!(!Ready::empty().is_timer());
#[cfg(unix)]
assert!(!Ready::empty().is_hup());
assert!(Ready::READABLE.is_readable());
assert!(!Ready::READABLE.is_writable());
assert!(!Ready::READABLE.is_error());
assert!(!Ready::READABLE.is_timer());
#[cfg(unix)]
assert!(!Ready::READABLE.is_hup());
assert!(!Ready::WRITABLE.is_readable());
assert!(Ready::WRITABLE.is_writable());
assert!(!Ready::WRITABLE.is_error());
assert!(!Ready::WRITABLE.is_timer());
#[cfg(unix)]
assert!(!Ready::WRITABLE.is_hup());
assert!(!Ready::ERROR.is_readable());
assert!(!Ready::ERROR.is_writable());
assert!(Ready::ERROR.is_error());
assert!(!Ready::ERROR.is_timer());
#[cfg(unix)]
assert!(!Ready::ERROR.is_hup());
assert!(!Ready::TIMER.is_readable());
assert!(!Ready::TIMER.is_writable());
assert!(!Ready::TIMER.is_error());
assert!(Ready::TIMER.is_timer());
#[cfg(unix)]
assert!(!Ready::TIMER.is_hup());
#[cfg(unix)]
{
assert!(!Ready::HUP.is_readable());
assert!(!Ready::HUP.is_writable());
assert!(!Ready::HUP.is_error());
assert!(!Ready::HUP.is_timer());
assert!(Ready::HUP.is_hup());
}
}
#[test]
fn contains() {
assert!(!Ready::READABLE.contains(Ready::READABLE | Ready::WRITABLE));
assert!(!Ready::WRITABLE.contains(Ready::READABLE | Ready::WRITABLE));
assert!((Ready::READABLE | Ready::WRITABLE).contains(Ready::READABLE | Ready::WRITABLE));
assert!((Ready::READABLE | Ready::WRITABLE).contains(Ready::READABLE));
}
#[test]
fn bit_or() {
let readiness = Ready::READABLE | Ready::WRITABLE | Ready::ERROR;
assert!(readiness.is_readable());
assert!(readiness.is_writable());
assert!(readiness.is_error());
assert!(!readiness.is_timer());
#[cfg(unix)]
assert!(!readiness.is_hup());
}
#[test]
fn bit_or_assign() {
let mut readiness = Ready::READABLE;
readiness |= Ready::WRITABLE;
assert!(readiness.is_readable());
assert!(readiness.is_writable());
assert!(!readiness.is_error());
assert!(!readiness.is_timer());
#[cfg(unix)]
assert!(!readiness.is_hup());
}
#[test]
fn fmt_debug() {
assert_eq!(format!("{:?}", Ready::READABLE), "READABLE");
assert_eq!(format!("{:?}", Ready::WRITABLE), "WRITABLE");
assert_eq!(format!("{:?}", Ready::ERROR), "ERROR");
assert_eq!(format!("{:?}", Ready::TIMER), "TIMER");
#[cfg(unix)]
assert_eq!(format!("{:?}", Ready::HUP), "HUP");
assert_eq!(format!("{:?}", Ready::empty()), "(empty)");
assert_eq!(format!("{:?}", Ready::READABLE | Ready::WRITABLE), "READABLE | WRITABLE");
assert_eq!(format!("{:?}", Ready::ERROR | Ready::TIMER), "ERROR | TIMER");
assert_eq!(format!("{:?}", Ready::READABLE | Ready::WRITABLE | Ready::ERROR | Ready::TIMER),
"READABLE | WRITABLE | ERROR | TIMER");
}
}