safer_ring/operation/
types.rs

1//! Operation type definitions and utilities.
2
3/// Type of I/O operation to perform.
4///
5/// This enum represents the different types of operations that can be submitted
6/// to io_uring. Each variant corresponds to a specific system call or operation type.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8#[repr(u8)]
9pub enum OperationType {
10    /// Read data from a file descriptor into a buffer
11    Read = 0,
12    /// Write data from a buffer to a file descriptor
13    Write = 1,
14    /// Accept a connection on a listening socket
15    Accept = 2,
16    /// Send data on a socket
17    Send = 3,
18    /// Receive data from a socket
19    Recv = 4,
20    /// Vectored read operation (readv)
21    ReadVectored = 5,
22    /// Vectored write operation (writev)
23    WriteVectored = 6,
24}
25
26impl OperationType {
27    /// Returns true if this operation type requires a buffer.
28    ///
29    /// Accept operations don't require a buffer as they only return
30    /// a new file descriptor for the accepted connection.
31    #[inline]
32    pub const fn requires_buffer(self) -> bool {
33        match self {
34            Self::Read
35            | Self::Write
36            | Self::Send
37            | Self::Recv
38            | Self::ReadVectored
39            | Self::WriteVectored => true,
40            Self::Accept => false,
41        }
42    }
43
44    /// Returns true if this operation type is a read-like operation.
45    ///
46    /// Read-like operations populate the buffer with data from the kernel.
47    #[inline]
48    pub const fn is_read_like(self) -> bool {
49        matches!(self, Self::Read | Self::Recv | Self::ReadVectored)
50    }
51
52    /// Returns true if this operation type is a write-like operation.
53    ///
54    /// Write-like operations send data from the buffer to the kernel.
55    #[inline]
56    pub const fn is_write_like(self) -> bool {
57        matches!(self, Self::Write | Self::Send | Self::WriteVectored)
58    }
59
60    /// Returns true if this operation type is vectored.
61    ///
62    /// Vectored operations use multiple buffers (scatter-gather I/O).
63    #[inline]
64    pub const fn is_vectored(self) -> bool {
65        matches!(self, Self::ReadVectored | Self::WriteVectored)
66    }
67}
68
69impl std::fmt::Display for OperationType {
70    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71        match self {
72            Self::Read => write!(f, "read"),
73            Self::Write => write!(f, "write"),
74            Self::Accept => write!(f, "accept"),
75            Self::Send => write!(f, "send"),
76            Self::Recv => write!(f, "recv"),
77            Self::ReadVectored => write!(f, "readv"),
78            Self::WriteVectored => write!(f, "writev"),
79        }
80    }
81}
82
83#[cfg(test)]
84mod tests {
85    use super::*;
86
87    #[test]
88    fn test_operation_type_properties() {
89        assert!(OperationType::Read.requires_buffer());
90        assert!(OperationType::Write.requires_buffer());
91        assert!(!OperationType::Accept.requires_buffer());
92        assert!(OperationType::Send.requires_buffer());
93        assert!(OperationType::Recv.requires_buffer());
94        assert!(OperationType::ReadVectored.requires_buffer());
95        assert!(OperationType::WriteVectored.requires_buffer());
96
97        assert!(OperationType::Read.is_read_like());
98        assert!(!OperationType::Write.is_read_like());
99        assert!(OperationType::Recv.is_read_like());
100        assert!(OperationType::ReadVectored.is_read_like());
101        assert!(!OperationType::WriteVectored.is_read_like());
102
103        assert!(!OperationType::Read.is_write_like());
104        assert!(OperationType::Write.is_write_like());
105        assert!(OperationType::Send.is_write_like());
106        assert!(!OperationType::ReadVectored.is_write_like());
107        assert!(OperationType::WriteVectored.is_write_like());
108
109        assert!(!OperationType::Read.is_vectored());
110        assert!(!OperationType::Write.is_vectored());
111        assert!(OperationType::ReadVectored.is_vectored());
112        assert!(OperationType::WriteVectored.is_vectored());
113    }
114
115    #[test]
116    fn test_operation_type_display() {
117        assert_eq!(OperationType::Read.to_string(), "read");
118        assert_eq!(OperationType::Write.to_string(), "write");
119        assert_eq!(OperationType::Accept.to_string(), "accept");
120        assert_eq!(OperationType::Send.to_string(), "send");
121        assert_eq!(OperationType::Recv.to_string(), "recv");
122        assert_eq!(OperationType::ReadVectored.to_string(), "readv");
123        assert_eq!(OperationType::WriteVectored.to_string(), "writev");
124    }
125}