Coverage Report

Created: 2025-11-28 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.48.0/src/io/ready.rs
Line
Count
Source
1
#![cfg_attr(not(feature = "net"), allow(unreachable_pub))]
2
3
use crate::io::interest::Interest;
4
5
use std::fmt;
6
use std::ops;
7
8
const READABLE: usize = 0b0_01;
9
const WRITABLE: usize = 0b0_10;
10
const READ_CLOSED: usize = 0b0_0100;
11
const WRITE_CLOSED: usize = 0b0_1000;
12
#[cfg(any(target_os = "linux", target_os = "android"))]
13
const PRIORITY: usize = 0b1_0000;
14
const ERROR: usize = 0b10_0000;
15
16
/// Describes the readiness state of an I/O resources.
17
///
18
/// `Ready` tracks which operation an I/O resource is ready to perform.
19
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
20
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
21
pub struct Ready(usize);
22
23
impl Ready {
24
    /// Returns the empty `Ready` set.
25
    pub const EMPTY: Ready = Ready(0);
26
27
    /// Returns a `Ready` representing readable readiness.
28
    pub const READABLE: Ready = Ready(READABLE);
29
30
    /// Returns a `Ready` representing writable readiness.
31
    pub const WRITABLE: Ready = Ready(WRITABLE);
32
33
    /// Returns a `Ready` representing read closed readiness.
34
    pub const READ_CLOSED: Ready = Ready(READ_CLOSED);
35
36
    /// Returns a `Ready` representing write closed readiness.
37
    pub const WRITE_CLOSED: Ready = Ready(WRITE_CLOSED);
38
39
    /// Returns a `Ready` representing priority readiness.
40
    #[cfg(any(target_os = "linux", target_os = "android"))]
41
    #[cfg_attr(docsrs, doc(cfg(any(target_os = "linux", target_os = "android"))))]
42
    pub const PRIORITY: Ready = Ready(PRIORITY);
43
44
    /// Returns a `Ready` representing error readiness.
45
    pub const ERROR: Ready = Ready(ERROR);
46
47
    /// Returns a `Ready` representing readiness for all operations.
48
    #[cfg(any(target_os = "linux", target_os = "android"))]
49
    pub const ALL: Ready =
50
        Ready(READABLE | WRITABLE | READ_CLOSED | WRITE_CLOSED | ERROR | PRIORITY);
51
52
    /// Returns a `Ready` representing readiness for all operations.
53
    #[cfg(not(any(target_os = "linux", target_os = "android")))]
54
    pub const ALL: Ready = Ready(READABLE | WRITABLE | READ_CLOSED | WRITE_CLOSED | ERROR);
55
56
    // Must remain crate-private to avoid adding a public dependency on Mio.
57
0
    pub(crate) fn from_mio(event: &mio::event::Event) -> Ready {
58
0
        let mut ready = Ready::EMPTY;
59
60
        #[cfg(all(target_os = "freebsd", feature = "net"))]
61
        {
62
            if event.is_aio() {
63
                ready |= Ready::READABLE;
64
            }
65
66
            if event.is_lio() {
67
                ready |= Ready::READABLE;
68
            }
69
        }
70
71
0
        if event.is_readable() {
72
0
            ready |= Ready::READABLE;
73
0
        }
74
75
0
        if event.is_writable() {
76
0
            ready |= Ready::WRITABLE;
77
0
        }
78
79
0
        if event.is_read_closed() {
80
0
            ready |= Ready::READ_CLOSED;
81
0
        }
82
83
0
        if event.is_write_closed() {
84
0
            ready |= Ready::WRITE_CLOSED;
85
0
        }
86
87
0
        if event.is_error() {
88
0
            ready |= Ready::ERROR;
89
0
        }
90
91
        #[cfg(any(target_os = "linux", target_os = "android"))]
92
        {
93
0
            if event.is_priority() {
94
0
                ready |= Ready::PRIORITY;
95
0
            }
96
        }
97
98
0
        ready
99
0
    }
100
101
    /// Returns true if `Ready` is the empty set.
102
    ///
103
    /// # Examples
104
    ///
105
    /// ```
106
    /// use tokio::io::Ready;
107
    ///
108
    /// assert!(Ready::EMPTY.is_empty());
109
    /// assert!(!Ready::READABLE.is_empty());
110
    /// ```
111
0
    pub fn is_empty(self) -> bool {
112
0
        self == Ready::EMPTY
113
0
    }
114
115
    /// Returns `true` if the value includes `readable`.
116
    ///
117
    /// # Examples
118
    ///
119
    /// ```
120
    /// use tokio::io::Ready;
121
    ///
122
    /// assert!(!Ready::EMPTY.is_readable());
123
    /// assert!(Ready::READABLE.is_readable());
124
    /// assert!(Ready::READ_CLOSED.is_readable());
125
    /// assert!(!Ready::WRITABLE.is_readable());
126
    /// ```
127
0
    pub fn is_readable(self) -> bool {
128
0
        self.contains(Ready::READABLE) || self.is_read_closed()
129
0
    }
130
131
    /// Returns `true` if the value includes writable `readiness`.
132
    ///
133
    /// # Examples
134
    ///
135
    /// ```
136
    /// use tokio::io::Ready;
137
    ///
138
    /// assert!(!Ready::EMPTY.is_writable());
139
    /// assert!(!Ready::READABLE.is_writable());
140
    /// assert!(Ready::WRITABLE.is_writable());
141
    /// assert!(Ready::WRITE_CLOSED.is_writable());
142
    /// ```
143
0
    pub fn is_writable(self) -> bool {
144
0
        self.contains(Ready::WRITABLE) || self.is_write_closed()
145
0
    }
146
147
    /// Returns `true` if the value includes read-closed `readiness`.
148
    ///
149
    /// # Examples
150
    ///
151
    /// ```
152
    /// use tokio::io::Ready;
153
    ///
154
    /// assert!(!Ready::EMPTY.is_read_closed());
155
    /// assert!(!Ready::READABLE.is_read_closed());
156
    /// assert!(Ready::READ_CLOSED.is_read_closed());
157
    /// ```
158
0
    pub fn is_read_closed(self) -> bool {
159
0
        self.contains(Ready::READ_CLOSED)
160
0
    }
161
162
    /// Returns `true` if the value includes write-closed `readiness`.
163
    ///
164
    /// # Examples
165
    ///
166
    /// ```
167
    /// use tokio::io::Ready;
168
    ///
169
    /// assert!(!Ready::EMPTY.is_write_closed());
170
    /// assert!(!Ready::WRITABLE.is_write_closed());
171
    /// assert!(Ready::WRITE_CLOSED.is_write_closed());
172
    /// ```
173
0
    pub fn is_write_closed(self) -> bool {
174
0
        self.contains(Ready::WRITE_CLOSED)
175
0
    }
176
177
    /// Returns `true` if the value includes priority `readiness`.
178
    ///
179
    /// # Examples
180
    ///
181
    /// ```
182
    /// use tokio::io::Ready;
183
    ///
184
    /// assert!(!Ready::EMPTY.is_priority());
185
    /// assert!(!Ready::WRITABLE.is_priority());
186
    /// assert!(Ready::PRIORITY.is_priority());
187
    /// ```
188
    #[cfg(any(target_os = "linux", target_os = "android"))]
189
    #[cfg_attr(docsrs, doc(cfg(any(target_os = "linux", target_os = "android"))))]
190
0
    pub fn is_priority(self) -> bool {
191
0
        self.contains(Ready::PRIORITY)
192
0
    }
193
194
    /// Returns `true` if the value includes error `readiness`.
195
    ///
196
    /// # Examples
197
    ///
198
    /// ```
199
    /// use tokio::io::Ready;
200
    ///
201
    /// assert!(!Ready::EMPTY.is_error());
202
    /// assert!(!Ready::WRITABLE.is_error());
203
    /// assert!(Ready::ERROR.is_error());
204
    /// ```
205
0
    pub fn is_error(self) -> bool {
206
0
        self.contains(Ready::ERROR)
207
0
    }
208
209
    /// Returns true if `self` is a superset of `other`.
210
    ///
211
    /// `other` may represent more than one readiness operations, in which case
212
    /// the function only returns true if `self` contains all readiness
213
    /// specified in `other`.
214
0
    pub(crate) fn contains<T: Into<Self>>(self, other: T) -> bool {
215
0
        let other = other.into();
216
0
        (self & other) == other
217
0
    }
218
219
    /// Creates a `Ready` instance using the given `usize` representation.
220
    ///
221
    /// The `usize` representation must have been obtained from a call to
222
    /// `Readiness::as_usize`.
223
    ///
224
    /// This function is mainly provided to allow the caller to get a
225
    /// readiness value from an `AtomicUsize`.
226
0
    pub(crate) fn from_usize(val: usize) -> Ready {
227
0
        Ready(val & Ready::ALL.as_usize())
228
0
    }
229
230
    /// Returns a `usize` representation of the `Ready` value.
231
    ///
232
    /// This function is mainly provided to allow the caller to store a
233
    /// readiness value in an `AtomicUsize`.
234
0
    pub(crate) fn as_usize(self) -> usize {
235
0
        self.0
236
0
    }
237
238
0
    pub(crate) fn from_interest(interest: Interest) -> Ready {
239
0
        let mut ready = Ready::EMPTY;
240
241
0
        if interest.is_readable() {
242
0
            ready |= Ready::READABLE;
243
0
            ready |= Ready::READ_CLOSED;
244
0
        }
245
246
0
        if interest.is_writable() {
247
0
            ready |= Ready::WRITABLE;
248
0
            ready |= Ready::WRITE_CLOSED;
249
0
        }
250
251
        #[cfg(any(target_os = "linux", target_os = "android"))]
252
0
        if interest.is_priority() {
253
0
            ready |= Ready::PRIORITY;
254
0
            ready |= Ready::READ_CLOSED;
255
0
        }
256
257
0
        if interest.is_error() {
258
0
            ready |= Ready::ERROR;
259
0
        }
260
261
0
        ready
262
0
    }
263
264
0
    pub(crate) fn intersection(self, interest: Interest) -> Ready {
265
0
        Ready(self.0 & Ready::from_interest(interest).0)
266
0
    }
267
268
0
    pub(crate) fn satisfies(self, interest: Interest) -> bool {
269
0
        self.0 & Ready::from_interest(interest).0 != 0
270
0
    }
271
}
272
273
impl ops::BitOr<Ready> for Ready {
274
    type Output = Ready;
275
276
    #[inline]
277
0
    fn bitor(self, other: Ready) -> Ready {
278
0
        Ready(self.0 | other.0)
279
0
    }
280
}
281
282
impl ops::BitOrAssign<Ready> for Ready {
283
    #[inline]
284
0
    fn bitor_assign(&mut self, other: Ready) {
285
0
        self.0 |= other.0;
286
0
    }
287
}
288
289
impl ops::BitAnd<Ready> for Ready {
290
    type Output = Ready;
291
292
    #[inline]
293
0
    fn bitand(self, other: Ready) -> Ready {
294
0
        Ready(self.0 & other.0)
295
0
    }
296
}
297
298
impl ops::Sub<Ready> for Ready {
299
    type Output = Ready;
300
301
    #[inline]
302
0
    fn sub(self, other: Ready) -> Ready {
303
0
        Ready(self.0 & !other.0)
304
0
    }
305
}
306
307
impl fmt::Debug for Ready {
308
0
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
309
0
        let mut fmt = fmt.debug_struct("Ready");
310
311
0
        fmt.field("is_readable", &self.is_readable())
312
0
            .field("is_writable", &self.is_writable())
313
0
            .field("is_read_closed", &self.is_read_closed())
314
0
            .field("is_write_closed", &self.is_write_closed())
315
0
            .field("is_error", &self.is_error());
316
317
        #[cfg(any(target_os = "linux", target_os = "android"))]
318
0
        fmt.field("is_priority", &self.is_priority());
319
320
0
        fmt.finish()
321
0
    }
322
}