sozu_command_lib/
ready.rs

1use std::fmt;
2
3/// Binary representation of a file descriptor readiness (obtained through epoll)
4#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord)]
5pub struct Ready(pub u16);
6
7impl Ready {
8    pub const EMPTY: Ready = Ready(0);
9    pub const READABLE: Ready = Ready(0b00001);
10    pub const WRITABLE: Ready = Ready(0b00010);
11    pub const ERROR: Ready = Ready(0b00100);
12    /// Hang UP (see EPOLLHUP in epoll_ctl man page)
13    pub const HUP: Ready = Ready(0b01000);
14    pub const ALL: Ready = Ready(0b00011);
15
16    #[inline]
17    pub fn is_empty(&self) -> bool {
18        self.0 == 0
19    }
20
21    #[inline]
22    pub fn is_readable(&self) -> bool {
23        self.contains(Ready::READABLE)
24    }
25
26    #[inline]
27    pub fn is_writable(&self) -> bool {
28        self.contains(Ready::WRITABLE)
29    }
30
31    pub fn is_error(&self) -> bool {
32        self.contains(Ready::ERROR)
33    }
34
35    pub fn is_hup(&self) -> bool {
36        self.contains(Ready::HUP)
37    }
38
39    #[inline]
40    pub fn insert<T: Into<Self>>(&mut self, other: T) {
41        let other = other.into();
42        self.0 |= other.0;
43    }
44
45    #[inline]
46    pub fn remove<T: Into<Self>>(&mut self, other: T) {
47        let other = other.into();
48        self.0 &= !other.0;
49    }
50
51    #[inline]
52    pub fn contains<T: Into<Self>>(&self, other: T) -> bool {
53        let other = other.into();
54        (*self & other) == other
55    }
56}
57
58//pub(crate) const RWINTEREST: mio::Interest = mio::Interest::READABLE | mio::Interest::WRITABLE;
59
60use std::ops;
61impl<T: Into<Ready>> ops::BitOr<T> for Ready {
62    type Output = Ready;
63
64    #[inline]
65    fn bitor(self, other: T) -> Ready {
66        Ready(self.0 | other.into().0)
67    }
68}
69
70impl<T: Into<Ready>> ops::BitOrAssign<T> for Ready {
71    #[inline]
72    fn bitor_assign(&mut self, other: T) {
73        self.0 |= other.into().0;
74    }
75}
76
77impl<T: Into<Ready>> ops::BitAnd<T> for Ready {
78    type Output = Ready;
79
80    #[inline]
81    fn bitand(self, other: T) -> Ready {
82        Ready(self.0 & other.into().0)
83    }
84}
85
86impl fmt::Debug for Ready {
87    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
88        let mut one = false;
89        let flags = [
90            (Ready::READABLE, "Readable"),
91            (Ready::WRITABLE, "Writable"),
92            (Ready::ERROR, "Error"),
93            (Ready::HUP, "Hup"),
94        ];
95
96        for &(flag, msg) in &flags {
97            if self.contains(flag) {
98                if one {
99                    write!(fmt, " | ")?
100                }
101                write!(fmt, "{msg}")?;
102
103                one = true
104            }
105        }
106
107        if !one {
108            fmt.write_str("(empty)")?;
109        }
110
111        Ok(())
112    }
113}
114
115impl std::convert::From<mio::Interest> for Ready {
116    fn from(i: mio::Interest) -> Self {
117        let mut r = Ready::EMPTY;
118        if i.is_readable() {
119            r.insert(Ready::READABLE);
120        }
121        if i.is_writable() {
122            r.insert(Ready::WRITABLE);
123        }
124
125        r
126    }
127}
128
129impl std::convert::From<&mio::event::Event> for Ready {
130    fn from(e: &mio::event::Event) -> Self {
131        let mut r = Ready::EMPTY;
132        if e.is_readable() {
133            r.insert(Ready::READABLE);
134        }
135        if e.is_writable() {
136            r.insert(Ready::WRITABLE);
137        }
138        if e.is_error() {
139            r.insert(Ready::ERROR);
140        }
141        //FIXME: handle HUP events
142        if e.is_read_closed() || e.is_write_closed() {
143            r.insert(Ready::HUP);
144        }
145
146        r
147    }
148}