monoio_io_wrapper/
lib.rs

1#![allow(clippy::unsafe_removed_from_name)]
2
3use monoio::io::{AsyncReadRent, AsyncWriteRent};
4
5mod safe_io;
6#[cfg(feature = "unsafe_io")]
7mod unsafe_io;
8
9#[derive(Debug)]
10pub enum ReadBuffer {
11    Safe(safe_io::SafeRead),
12    #[cfg(feature = "unsafe_io")]
13    Unsafe(unsafe_io::UnsafeRead),
14}
15
16#[derive(Debug)]
17pub enum WriteBuffer {
18    Safe(safe_io::SafeWrite),
19    #[cfg(feature = "unsafe_io")]
20    Unsafe(unsafe_io::UnsafeWrite),
21}
22
23impl ReadBuffer {
24    /// Create a new ReadBuffer with given buffer size.
25    #[inline]
26    pub fn new(buffer_size: usize) -> Self {
27        Self::Safe(safe_io::SafeRead::new(buffer_size))
28    }
29
30    /// Create a new ReadBuffer that uses unsafe I/O.
31    /// # Safety
32    /// Users must make sure the buffer ptr and len is valid until io finished.
33    /// So the Future cannot be dropped directly. Consider using CancellableIO.
34    #[inline]
35    #[cfg(feature = "unsafe_io")]
36    pub const unsafe fn new_unsafe() -> Self {
37        Self::Unsafe(unsafe_io::UnsafeRead::new())
38    }
39
40    #[inline]
41    pub async fn do_io<IO: AsyncReadRent>(&mut self, mut io: IO) -> std::io::Result<usize> {
42        match self {
43            Self::Safe(b) => b.do_io(&mut io).await,
44            #[cfg(feature = "unsafe_io")]
45            Self::Unsafe(b) => unsafe { b.do_io(&mut io).await },
46        }
47    }
48
49    #[inline]
50    #[cfg(feature = "unsafe_io")]
51    pub fn is_safe(&self) -> bool {
52        match self {
53            Self::Safe(_) => true,
54            #[cfg(feature = "unsafe_io")]
55            Self::Unsafe(_) => false,
56        }
57    }
58
59    #[inline]
60    #[cfg(not(feature = "unsafe_io"))]
61    pub const fn is_safe(&self) -> bool {
62        true
63    }
64}
65
66impl Default for ReadBuffer {
67    #[inline]
68    fn default() -> Self {
69        Self::Safe(Default::default())
70    }
71}
72
73impl std::io::Read for ReadBuffer {
74    #[inline]
75    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
76        match self {
77            Self::Safe(b) => b.read(buf),
78            #[cfg(feature = "unsafe_io")]
79            Self::Unsafe(b) => b.read(buf),
80        }
81    }
82}
83
84impl WriteBuffer {
85    /// Create a new WriteBuffer with given buffer size.
86    #[inline]
87    pub fn new(buffer_size: usize) -> Self {
88        Self::Safe(safe_io::SafeWrite::new(buffer_size))
89    }
90
91    /// Create a new WriteBuffer that uses unsafe I/O.
92    /// # Safety
93    /// Users must make sure the buffer ptr and len is valid until io finished.
94    /// So the Future cannot be dropped directly. Consider using CancellableIO.
95    #[inline]
96    #[cfg(feature = "unsafe_io")]
97    pub const unsafe fn new_unsafe() -> Self {
98        Self::Unsafe(unsafe_io::UnsafeWrite::new())
99    }
100
101    #[inline]
102    pub async fn do_io<IO: AsyncWriteRent>(&mut self, mut io: IO) -> std::io::Result<usize> {
103        match self {
104            Self::Safe(buf) => buf.do_io(&mut io).await,
105            #[cfg(feature = "unsafe_io")]
106            Self::Unsafe(buf) => unsafe { buf.do_io(&mut io).await },
107        }
108    }
109
110    #[inline]
111    #[cfg(feature = "unsafe_io")]
112    pub fn is_safe(&self) -> bool {
113        match self {
114            Self::Safe(_) => true,
115            #[cfg(feature = "unsafe_io")]
116            Self::Unsafe(_) => false,
117        }
118    }
119
120    #[inline]
121    #[cfg(not(feature = "unsafe_io"))]
122    pub const fn is_safe(&self) -> bool {
123        true
124    }
125}
126
127impl Default for WriteBuffer {
128    #[inline]
129    fn default() -> Self {
130        Self::Safe(Default::default())
131    }
132}
133
134impl std::io::Write for WriteBuffer {
135    #[inline]
136    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
137        match self {
138            Self::Safe(b) => b.write(buf),
139            #[cfg(feature = "unsafe_io")]
140            Self::Unsafe(b) => b.write(buf),
141        }
142    }
143
144    #[inline]
145    fn flush(&mut self) -> std::io::Result<()> {
146        match self {
147            Self::Safe(b) => b.flush(),
148            #[cfg(feature = "unsafe_io")]
149            Self::Unsafe(b) => b.flush(),
150        }
151    }
152}