Skip to main content

nuclei/io/
ready.rs

1//! What a socket's readiness calls ask for and answer: [`Interest`] and
2//! [`Ready`]. Nuclei's sockets are completed by the driver, so "ready" is
3//! about the handle's own buffers: readable once a read would end at once
4//! (bytes read ahead, the end of the stream, or an error), writable once a
5//! write would be taken at once (room in the write-behind, or an error).
6
7use core::ops::BitOr;
8
9/// What a readiness call waits for: reading, writing, or either.
10#[derive(Clone, Copy, Debug, PartialEq, Eq)]
11pub struct Interest(u8);
12
13impl Interest {
14    /// A read would end at once.
15    pub const READABLE: Interest = Interest(1);
16    /// A write would be taken at once.
17    pub const WRITABLE: Interest = Interest(2);
18
19    /// Whether it asks for reading.
20    pub fn is_readable(self) -> bool {
21        self.0 & 1 != 0
22    }
23
24    /// Whether it asks for writing.
25    pub fn is_writable(self) -> bool {
26        self.0 & 2 != 0
27    }
28}
29
30impl BitOr for Interest {
31    type Output = Interest;
32
33    fn bitor(self, other: Interest) -> Interest {
34        Interest(self.0 | other.0)
35    }
36}
37
38/// What a readiness call found.
39#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
40pub struct Ready(u8);
41
42impl Ready {
43    /// Nothing is ready.
44    pub const EMPTY: Ready = Ready(0);
45    /// A read would end at once.
46    pub const READABLE: Ready = Ready(1);
47    /// A write would be taken at once.
48    pub const WRITABLE: Ready = Ready(2);
49    /// The stream ended: reads answer zero from now on.
50    pub const READ_CLOSED: Ready = Ready(4);
51    /// Writing failed: writes answer the error from now on.
52    pub const WRITE_CLOSED: Ready = Ready(8);
53
54    pub fn is_empty(self) -> bool {
55        self.0 == 0
56    }
57
58    pub fn is_readable(self) -> bool {
59        self.0 & (Self::READABLE.0 | Self::READ_CLOSED.0) != 0
60    }
61
62    pub fn is_writable(self) -> bool {
63        self.0 & (Self::WRITABLE.0 | Self::WRITE_CLOSED.0) != 0
64    }
65
66    pub fn is_read_closed(self) -> bool {
67        self.0 & Self::READ_CLOSED.0 != 0
68    }
69
70    pub fn is_write_closed(self) -> bool {
71        self.0 & Self::WRITE_CLOSED.0 != 0
72    }
73}
74
75impl BitOr for Ready {
76    type Output = Ready;
77
78    fn bitor(self, other: Ready) -> Ready {
79        Ready(self.0 | other.0)
80    }
81}
82
83#[cfg(test)]
84mod tests {
85    use super::*;
86
87    #[test]
88    fn interests_and_readiness_combine() {
89        let both = Interest::READABLE | Interest::WRITABLE;
90        assert!(both.is_readable() && both.is_writable());
91        assert!(!Interest::READABLE.is_writable());
92        let ready = Ready::READABLE | Ready::READ_CLOSED;
93        assert!(ready.is_readable() && ready.is_read_closed() && !ready.is_writable());
94        assert!(Ready::EMPTY.is_empty() && !ready.is_empty());
95        assert!(Ready::WRITE_CLOSED.is_writable());
96    }
97}