1#![deny(missing_docs)]
2#![forbid(unsafe_code)]
3
4use std::io::{Read, Result, Write};
9
10pub struct ReadWrite<R: Read, W: Write>(pub R, pub W);
12
13impl<R: Read, W: Write> From<(R, W)> for ReadWrite<R, W> {
14 fn from((r, w): (R, W)) -> Self {
15 ReadWrite(r, w)
16 }
17}
18impl<R: Read, W: Write> ReadWrite<R, W> {
19 pub fn new(r: R, w: W) -> Self {
21 ReadWrite(r, w)
22 }
23 pub fn borrow(&self) -> (&R, &W) {
25 (&self.0, &self.1)
26 }
27 pub fn borrow_read(&self) -> &R {
29 &self.0
30 }
31 pub fn borrow_write(&self) -> &W {
33 &self.1
34 }
35 pub fn borrow_mut(&mut self) -> (&mut R, &mut W) {
37 (&mut self.0, &mut self.1)
38 }
39 pub fn borrow_mut_read(&mut self) -> &mut R {
41 &mut self.0
42 }
43 pub fn borrow_mut_write(&mut self) -> &mut W {
45 &mut self.1
46 }
47 pub fn into_inner(self) -> (R, W) {
49 (self.0, self.1)
50 }
51 pub fn into_reader(self) -> R {
53 self.0
54 }
55 pub fn into_writer(self) -> W {
57 self.1
58 }
59}
60
61impl<R: Read, W: Write> Read for ReadWrite<R, W> {
62 fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
63 self.0.read(buf)
64 }
65
66 fn read_vectored(&mut self, bufs: &mut [std::io::IoSliceMut<'_>]) -> Result<usize> {
67 self.0.read_vectored(bufs)
68 }
69}
70impl<R: Read, W: Write> Write for ReadWrite<R, W> {
71 fn write(&mut self, buf: &[u8]) -> Result<usize> {
72 self.1.write(buf)
73 }
74 fn flush(&mut self) -> Result<()> {
75 self.1.flush()
76 }
77
78 fn write_vectored(&mut self, bufs: &[std::io::IoSlice<'_>]) -> Result<usize> {
79 self.1.write_vectored(bufs)
80 }
81}
82
83#[cfg(all(feature = "tokio"))]
84mod tokio {
85 use tokio_dep::io::{AsyncRead, AsyncWrite};
86
87 use std::pin::Pin;
88
89 pin_project_lite::pin_project! {
90 pub struct ReadWriteTokio<R, W> {
93 #[pin]
94 r: R,
95 #[pin]
96 w: W,
97 }
98 }
99
100 impl<R: AsyncRead, W: AsyncWrite> From<(R, W)> for ReadWriteTokio<R, W> {
101 fn from((r, w): (R, W)) -> Self {
102 ReadWriteTokio { r, w }
103 }
104 }
105 impl<R: AsyncRead, W: AsyncWrite> ReadWriteTokio<R, W> {
106 pub fn new(r: R, w: W) -> Self {
108 ReadWriteTokio { r, w }
109 }
110 pub fn borrow(&self) -> (&R, &W) {
112 (&self.r, &self.w)
113 }
114 pub fn borrow_read(&self) -> &R {
116 &self.r
117 }
118 pub fn borrow_write(&self) -> &W {
120 &self.w
121 }
122 pub fn borrow_mut(&mut self) -> (&mut R, &mut W) {
124 (&mut self.r, &mut self.w)
125 }
126 pub fn borrow_mut_read(&mut self) -> &mut R {
128 &mut self.r
129 }
130 pub fn borrow_mut_write(&mut self) -> &mut W {
132 &mut self.w
133 }
134 pub fn into_inner(self) -> (R, W) {
136 (self.r, self.w)
137 }
138 pub fn into_reader(self) -> R {
140 self.r
141 }
142 pub fn into_writer(self) -> W {
144 self.w
145 }
146
147 pub fn borrow_pin(self: Pin<&mut Self>) -> (Pin<&mut R>, Pin<&mut W>) {
149 let p = self.project();
150 (p.r, p.w)
151 }
152 pub fn borrow_pin_read(self: Pin<&mut Self>) -> Pin<&mut R> {
154 self.project().r
155 }
156 pub fn borrow_pin_write(self: Pin<&mut Self>) -> Pin<&mut W> {
158 self.project().w
159 }
160 }
161
162 impl<R: AsyncRead, W> AsyncRead for ReadWriteTokio<R, W> {
163 fn poll_read(
164 self: std::pin::Pin<&mut Self>,
165 cx: &mut std::task::Context<'_>,
166 buf: &mut tokio_dep::io::ReadBuf<'_>,
167 ) -> std::task::Poll<std::io::Result<()>> {
168 AsyncRead::poll_read(self.project().r, cx, buf)
169 }
170 }
171
172 impl<R, W: AsyncWrite> AsyncWrite for ReadWriteTokio<R, W> {
173 fn poll_write(
174 self: Pin<&mut Self>,
175 cx: &mut std::task::Context<'_>,
176 buf: &[u8],
177 ) -> std::task::Poll<Result<usize, std::io::Error>> {
178 self.project().w.poll_write(cx, buf)
179 }
180
181 fn poll_flush(
182 self: Pin<&mut Self>,
183 cx: &mut std::task::Context<'_>,
184 ) -> std::task::Poll<Result<(), std::io::Error>> {
185 self.project().w.poll_flush(cx)
186 }
187
188 fn poll_shutdown(
189 self: Pin<&mut Self>,
190 cx: &mut std::task::Context<'_>,
191 ) -> std::task::Poll<Result<(), std::io::Error>> {
192 self.project().w.poll_shutdown(cx)
193 }
194
195 fn poll_write_vectored(
196 self: Pin<&mut Self>,
197 cx: &mut std::task::Context<'_>,
198 bufs: &[std::io::IoSlice<'_>],
199 ) -> std::task::Poll<Result<usize, std::io::Error>> {
200 self.project().w.poll_write_vectored(cx, bufs)
201 }
202
203 fn is_write_vectored(&self) -> bool {
204 self.w.is_write_vectored()
205 }
206 }
207}
208#[cfg(all(feature = "tokio"))]
209pub use tokio::ReadWriteTokio;
210
211#[cfg(all(feature = "asyncstd"))]
212mod asyncstd {
213 use futures::io::{AsyncRead, AsyncWrite};
214
215 use std::pin::Pin;
216
217 pin_project_lite::pin_project! {
218 pub struct ReadWriteAsyncstd<R, W> {
221 #[pin]
222 r: R,
223 #[pin]
224 w: W,
225 }
226 }
227
228 impl<R: AsyncRead, W: AsyncWrite> From<(R, W)> for ReadWriteAsyncstd<R, W> {
229 fn from((r, w): (R, W)) -> Self {
230 ReadWriteAsyncstd { r, w }
231 }
232 }
233 impl<R: AsyncRead, W: AsyncWrite> ReadWriteAsyncstd<R, W> {
234 pub fn new(r: R, w: W) -> Self {
236 ReadWriteAsyncstd { r, w }
237 }
238 pub fn borrow(&self) -> (&R, &W) {
240 (&self.r, &self.w)
241 }
242 pub fn borrow_read(&self) -> &R {
244 &self.r
245 }
246 pub fn borrow_write(&self) -> &W {
248 &self.w
249 }
250 pub fn borrow_mut(&mut self) -> (&mut R, &mut W) {
252 (&mut self.r, &mut self.w)
253 }
254 pub fn borrow_mut_read(&mut self) -> &mut R {
256 &mut self.r
257 }
258 pub fn borrow_mut_write(&mut self) -> &mut W {
260 &mut self.w
261 }
262 pub fn into_inner(self) -> (R, W) {
264 (self.r, self.w)
265 }
266 pub fn into_reader(self) -> R {
268 self.r
269 }
270 pub fn into_writer(self) -> W {
272 self.w
273 }
274
275 pub fn borrow_pin(self: Pin<&mut Self>) -> (Pin<&mut R>, Pin<&mut W>) {
277 let p = self.project();
278 (p.r, p.w)
279 }
280 pub fn borrow_pin_read(self: Pin<&mut Self>) -> Pin<&mut R> {
282 self.project().r
283 }
284 pub fn borrow_pin_write(self: Pin<&mut Self>) -> Pin<&mut W> {
286 self.project().w
287 }
288 }
289
290 impl<R: AsyncRead, W> AsyncRead for ReadWriteAsyncstd<R, W> {
291 fn poll_read(
292 self: Pin<&mut Self>,
293 cx: &mut std::task::Context<'_>,
294 buf: &mut [u8],
295 ) -> std::task::Poll<std::io::Result<usize>> {
296 self.project().r.poll_read(cx, buf)
297 }
298
299 fn poll_read_vectored(
300 self: Pin<&mut Self>,
301 cx: &mut std::task::Context<'_>,
302 bufs: &mut [std::io::IoSliceMut<'_>],
303 ) -> std::task::Poll<std::io::Result<usize>> {
304 self.project().r.poll_read_vectored(cx, bufs)
305 }
306 }
307
308 impl<R, W: AsyncWrite> AsyncWrite for ReadWriteAsyncstd<R, W> {
309 fn poll_write(
310 self: Pin<&mut Self>,
311 cx: &mut std::task::Context<'_>,
312 buf: &[u8],
313 ) -> std::task::Poll<std::io::Result<usize>> {
314 self.project().w.poll_write(cx, buf)
315 }
316
317 fn poll_flush(
318 self: Pin<&mut Self>,
319 cx: &mut std::task::Context<'_>,
320 ) -> std::task::Poll<std::io::Result<()>> {
321 self.project().w.poll_flush(cx)
322 }
323
324 fn poll_close(
325 self: Pin<&mut Self>,
326 cx: &mut std::task::Context<'_>,
327 ) -> std::task::Poll<std::io::Result<()>> {
328 self.project().w.poll_close(cx)
329 }
330
331 fn poll_write_vectored(
332 self: Pin<&mut Self>,
333 cx: &mut std::task::Context<'_>,
334 bufs: &[std::io::IoSlice<'_>],
335 ) -> std::task::Poll<std::io::Result<usize>> {
336 self.project().w.poll_write_vectored(cx, bufs)
337 }
338 }
339}
340#[cfg(all(feature = "asyncstd"))]
341pub use asyncstd::ReadWriteAsyncstd;