1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use std::{fmt, ops};

#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord)]
pub struct EpollOpt(usize);

const EDGE: usize    = 0b0001;
const LEVEL: usize   = 0b0010;
const ONESHOT: usize = 0b0100;

impl EpollOpt {
    #[inline]
    pub fn empty() -> EpollOpt {
        EpollOpt(0)
    }

    #[inline]
    pub fn edge() -> EpollOpt {
        EpollOpt(EDGE)
    }

    #[inline]
    pub fn level() -> EpollOpt {
        EpollOpt(LEVEL)
    }

    #[inline]
    pub fn oneshot() -> EpollOpt {
        EpollOpt(ONESHOT)
    }

    #[inline]
    pub fn is_edge(self) -> bool {
        self.contains(EpollOpt::edge())
    }

    #[inline]
    pub fn is_level(self) -> bool {
        self.contains(EpollOpt::level())
    }

    #[inline]
    pub fn is_oneshot(self) -> bool {
        self.contains(EpollOpt::oneshot())
    }

    #[inline]
    pub fn contains(self, other: EpollOpt) -> bool {
        (self & other) == other
    }

    #[inline]
    pub fn insert(&mut self, other: EpollOpt) {
        self.0 |= other.0;
    }

    #[inline]
    pub fn remove(&mut self, other: EpollOpt) {
        self.0 &= !other.0;
    }

    pub fn as_usize(self) -> usize {
        self.0
    }
}

impl ops::BitOr for EpollOpt {
    type Output = EpollOpt;

    #[inline]
    fn bitor(self, other: EpollOpt) -> EpollOpt {
        EpollOpt(self.0 | other.0)
    }
}

impl ops::BitXor for EpollOpt {
    type Output = EpollOpt;

    #[inline]
    fn bitxor(self, other: EpollOpt) -> EpollOpt {
        EpollOpt(self.0 ^ other.0)
    }
}

impl ops::BitAnd for EpollOpt {
    type Output = EpollOpt;

    #[inline]
    fn bitand(self, other: EpollOpt) -> EpollOpt {
        EpollOpt(self.0 & other.0)
    }
}

impl ops::Sub for EpollOpt {
    type Output = EpollOpt;

    #[inline]
    fn sub(self, other: EpollOpt) -> EpollOpt {
        EpollOpt(self.0 & !other.0)
    }
}

impl ops::Not for EpollOpt {
    type Output = EpollOpt;

    #[inline]
    fn not(self) -> EpollOpt {
        EpollOpt(!self.0)
    }
}

impl From<usize> for EpollOpt {
    fn from(opt: usize) -> EpollOpt {
        EpollOpt(opt)
    }
}

impl fmt::Debug for EpollOpt {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let mut one = false;
        let flags = [
            (EpollOpt::edge(), "Edge-Triggered"),
            (EpollOpt::level(), "Level-Triggered"),
            (EpollOpt::oneshot(), "OneShot")];

        for &(flag, msg) in &flags {
            if self.contains(flag) {
                if one { write!(fmt, " | ")? }
                write!(fmt, "{}", msg)?;

                one = true
            }
        }

        Ok(())
    }
}