• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use futures_core::task::{Context, Poll};
2 use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, SeekFrom};
3 use std::pin::Pin;
4 use std::{fmt, io};
5 
6 /// A simple wrapper type which allows types which implement only
7 /// implement `std::io::Read` or `std::io::Write`
8 /// to be used in contexts which expect an `AsyncRead` or `AsyncWrite`.
9 ///
10 /// If these types issue an error with the kind `io::ErrorKind::WouldBlock`,
11 /// it is expected that they will notify the current task on readiness.
12 /// Synchronous `std` types should not issue errors of this kind and
13 /// are safe to use in this context. However, using these types with
14 /// `AllowStdIo` will cause the event loop to block, so they should be used
15 /// with care.
16 #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
17 pub struct AllowStdIo<T>(T);
18 
19 impl<T> Unpin for AllowStdIo<T> {}
20 
21 macro_rules! try_with_interrupt {
22     ($e:expr) => {
23         loop {
24             match $e {
25                 Ok(e) => {
26                     break e;
27                 }
28                 Err(ref e) if e.kind() == ::std::io::ErrorKind::Interrupted => {
29                     continue;
30                 }
31                 Err(e) => {
32                     return Poll::Ready(Err(e));
33                 }
34             }
35         }
36     };
37 }
38 
39 impl<T> AllowStdIo<T> {
40     /// Creates a new `AllowStdIo` from an existing IO object.
new(io: T) -> Self41     pub fn new(io: T) -> Self {
42         Self(io)
43     }
44 
45     /// Returns a reference to the contained IO object.
get_ref(&self) -> &T46     pub fn get_ref(&self) -> &T {
47         &self.0
48     }
49 
50     /// Returns a mutable reference to the contained IO object.
get_mut(&mut self) -> &mut T51     pub fn get_mut(&mut self) -> &mut T {
52         &mut self.0
53     }
54 
55     /// Consumes self and returns the contained IO object.
into_inner(self) -> T56     pub fn into_inner(self) -> T {
57         self.0
58     }
59 }
60 
61 impl<T> io::Write for AllowStdIo<T>
62 where
63     T: io::Write,
64 {
write(&mut self, buf: &[u8]) -> io::Result<usize>65     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
66         self.0.write(buf)
67     }
write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize>68     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
69         self.0.write_vectored(bufs)
70     }
flush(&mut self) -> io::Result<()>71     fn flush(&mut self) -> io::Result<()> {
72         self.0.flush()
73     }
write_all(&mut self, buf: &[u8]) -> io::Result<()>74     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
75         self.0.write_all(buf)
76     }
write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()>77     fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
78         self.0.write_fmt(fmt)
79     }
80 }
81 
82 impl<T> AsyncWrite for AllowStdIo<T>
83 where
84     T: io::Write,
85 {
poll_write( mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &[u8], ) -> Poll<io::Result<usize>>86     fn poll_write(
87         mut self: Pin<&mut Self>,
88         _: &mut Context<'_>,
89         buf: &[u8],
90     ) -> Poll<io::Result<usize>> {
91         Poll::Ready(Ok(try_with_interrupt!(self.0.write(buf))))
92     }
93 
poll_write_vectored( mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll<io::Result<usize>>94     fn poll_write_vectored(
95         mut self: Pin<&mut Self>,
96         _: &mut Context<'_>,
97         bufs: &[IoSlice<'_>],
98     ) -> Poll<io::Result<usize>> {
99         Poll::Ready(Ok(try_with_interrupt!(self.0.write_vectored(bufs))))
100     }
101 
poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>>102     fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
103         try_with_interrupt!(self.0.flush());
104         Poll::Ready(Ok(()))
105     }
106 
poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>>107     fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
108         self.poll_flush(cx)
109     }
110 }
111 
112 impl<T> io::Read for AllowStdIo<T>
113 where
114     T: io::Read,
115 {
read(&mut self, buf: &mut [u8]) -> io::Result<usize>116     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
117         self.0.read(buf)
118     }
read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize>119     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
120         self.0.read_vectored(bufs)
121     }
read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize>122     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
123         self.0.read_to_end(buf)
124     }
read_to_string(&mut self, buf: &mut String) -> io::Result<usize>125     fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
126         self.0.read_to_string(buf)
127     }
read_exact(&mut self, buf: &mut [u8]) -> io::Result<()>128     fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
129         self.0.read_exact(buf)
130     }
131 }
132 
133 impl<T> AsyncRead for AllowStdIo<T>
134 where
135     T: io::Read,
136 {
poll_read( mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &mut [u8], ) -> Poll<io::Result<usize>>137     fn poll_read(
138         mut self: Pin<&mut Self>,
139         _: &mut Context<'_>,
140         buf: &mut [u8],
141     ) -> Poll<io::Result<usize>> {
142         Poll::Ready(Ok(try_with_interrupt!(self.0.read(buf))))
143     }
144 
poll_read_vectored( mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>], ) -> Poll<io::Result<usize>>145     fn poll_read_vectored(
146         mut self: Pin<&mut Self>,
147         _: &mut Context<'_>,
148         bufs: &mut [IoSliceMut<'_>],
149     ) -> Poll<io::Result<usize>> {
150         Poll::Ready(Ok(try_with_interrupt!(self.0.read_vectored(bufs))))
151     }
152 }
153 
154 impl<T> io::Seek for AllowStdIo<T>
155 where
156     T: io::Seek,
157 {
seek(&mut self, pos: SeekFrom) -> io::Result<u64>158     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
159         self.0.seek(pos)
160     }
161 }
162 
163 impl<T> AsyncSeek for AllowStdIo<T>
164 where
165     T: io::Seek,
166 {
poll_seek( mut self: Pin<&mut Self>, _: &mut Context<'_>, pos: SeekFrom, ) -> Poll<io::Result<u64>>167     fn poll_seek(
168         mut self: Pin<&mut Self>,
169         _: &mut Context<'_>,
170         pos: SeekFrom,
171     ) -> Poll<io::Result<u64>> {
172         Poll::Ready(Ok(try_with_interrupt!(self.0.seek(pos))))
173     }
174 }
175 
176 impl<T> io::BufRead for AllowStdIo<T>
177 where
178     T: io::BufRead,
179 {
fill_buf(&mut self) -> io::Result<&[u8]>180     fn fill_buf(&mut self) -> io::Result<&[u8]> {
181         self.0.fill_buf()
182     }
consume(&mut self, amt: usize)183     fn consume(&mut self, amt: usize) {
184         self.0.consume(amt)
185     }
186 }
187 
188 impl<T> AsyncBufRead for AllowStdIo<T>
189 where
190     T: io::BufRead,
191 {
poll_fill_buf(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<&[u8]>>192     fn poll_fill_buf(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
193         let this: *mut Self = &mut *self as *mut _;
194         Poll::Ready(Ok(try_with_interrupt!(unsafe { &mut *this }.0.fill_buf())))
195     }
196 
consume(mut self: Pin<&mut Self>, amt: usize)197     fn consume(mut self: Pin<&mut Self>, amt: usize) {
198         self.0.consume(amt)
199     }
200 }
201