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