Skip to main content

c_ares/
events.rs

1use crate::types::Socket;
2use bitflags::bitflags;
3use std::fmt;
4
5bitflags!(
6    /// Events used by FdEvents.
7    #[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
8    pub struct FdEventFlags: u32 {
9        /// Read event (including disconnect/error).
10        const READ = c_ares_sys::ares_fd_eventflag_t::ARES_FD_EVENT_READ as u32;
11        /// Write event.
12        const WRITE = c_ares_sys::ares_fd_eventflag_t::ARES_FD_EVENT_WRITE as u32;
13    }
14);
15
16bitflags!(
17    /// Flags used by [`crate::Channel::process_fds()`].
18    #[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
19    pub struct ProcessFlags: u32 {
20        /// Skip any processing unrelated to the file descriptor events passed in.
21        const SKIP_NON_FD = c_ares_sys::ares_process_flag_t::ARES_PROCESS_FLAG_SKIP_NON_FD as u32;
22    }
23);
24
25/// Type holding a file descriptor and mask of events, used by [`crate::Channel::process_fds()`].
26#[repr(transparent)]
27pub struct FdEvents(c_ares_sys::ares_fd_events_t);
28
29impl FdEvents {
30    /// Returns a new `FdEvents`.
31    pub fn new(socket: Socket, events: FdEventFlags) -> Self {
32        let events = c_ares_sys::ares_fd_events_t {
33            fd: socket,
34            events: events.bits(),
35        };
36        FdEvents(events)
37    }
38}
39
40impl fmt::Debug for FdEvents {
41    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42        f.debug_struct("FdEvents")
43            .field("fd", &self.0.fd)
44            .field("events", &FdEventFlags::from_bits_truncate(self.0.events))
45            .finish()
46    }
47}
48
49#[cfg(test)]
50mod tests {
51    use super::*;
52
53    #[test]
54    fn fd_event_flags_empty() {
55        let flags = FdEventFlags::empty();
56        assert!(flags.is_empty());
57    }
58
59    #[test]
60    fn fd_event_flags_read() {
61        let flags = FdEventFlags::READ;
62        assert!(flags.contains(FdEventFlags::READ));
63        assert!(!flags.contains(FdEventFlags::WRITE));
64    }
65
66    #[test]
67    fn fd_event_flags_write() {
68        let flags = FdEventFlags::WRITE;
69        assert!(flags.contains(FdEventFlags::WRITE));
70        assert!(!flags.contains(FdEventFlags::READ));
71    }
72
73    #[test]
74    fn fd_event_flags_combined() {
75        let flags = FdEventFlags::READ | FdEventFlags::WRITE;
76        assert!(flags.contains(FdEventFlags::READ));
77        assert!(flags.contains(FdEventFlags::WRITE));
78    }
79
80    #[test]
81    fn process_flags_empty() {
82        let flags = ProcessFlags::empty();
83        assert!(flags.is_empty());
84    }
85
86    #[test]
87    fn process_flags_skip_non_fd() {
88        let flags = ProcessFlags::SKIP_NON_FD;
89        assert!(flags.contains(ProcessFlags::SKIP_NON_FD));
90    }
91
92    #[test]
93    fn fd_events_new() {
94        let events = FdEvents::new(42, FdEventFlags::READ);
95        assert_eq!(events.0.fd, 42);
96        assert_eq!(events.0.events, FdEventFlags::READ.bits());
97    }
98
99    #[test]
100    fn debug_fd_events() {
101        let events = FdEvents::new(42, FdEventFlags::READ | FdEventFlags::WRITE);
102        let debug = format!("{events:?}");
103        assert!(debug.contains("FdEvents"));
104        assert!(debug.contains("42"));
105        assert!(debug.contains("READ"));
106        assert!(debug.contains("WRITE"));
107    }
108}