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::string::String; 5 use std::vec::Vec; 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 } read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize>124 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { 125 self.0.read_to_end(buf) 126 } read_to_string(&mut self, buf: &mut String) -> io::Result<usize>127 fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> { 128 self.0.read_to_string(buf) 129 } read_exact(&mut self, buf: &mut [u8]) -> io::Result<()>130 fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { 131 self.0.read_exact(buf) 132 } 133 } 134 135 impl<T> AsyncRead for AllowStdIo<T> 136 where 137 T: io::Read, 138 { poll_read( mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &mut [u8], ) -> Poll<io::Result<usize>>139 fn poll_read( 140 mut self: Pin<&mut Self>, 141 _: &mut Context<'_>, 142 buf: &mut [u8], 143 ) -> Poll<io::Result<usize>> { 144 Poll::Ready(Ok(try_with_interrupt!(self.0.read(buf)))) 145 } 146 poll_read_vectored( mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>], ) -> Poll<io::Result<usize>>147 fn poll_read_vectored( 148 mut self: Pin<&mut Self>, 149 _: &mut Context<'_>, 150 bufs: &mut [IoSliceMut<'_>], 151 ) -> Poll<io::Result<usize>> { 152 Poll::Ready(Ok(try_with_interrupt!(self.0.read_vectored(bufs)))) 153 } 154 } 155 156 impl<T> io::Seek for AllowStdIo<T> 157 where 158 T: io::Seek, 159 { seek(&mut self, pos: SeekFrom) -> io::Result<u64>160 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { 161 self.0.seek(pos) 162 } 163 } 164 165 impl<T> AsyncSeek for AllowStdIo<T> 166 where 167 T: io::Seek, 168 { poll_seek( mut self: Pin<&mut Self>, _: &mut Context<'_>, pos: SeekFrom, ) -> Poll<io::Result<u64>>169 fn poll_seek( 170 mut self: Pin<&mut Self>, 171 _: &mut Context<'_>, 172 pos: SeekFrom, 173 ) -> Poll<io::Result<u64>> { 174 Poll::Ready(Ok(try_with_interrupt!(self.0.seek(pos)))) 175 } 176 } 177 178 impl<T> io::BufRead for AllowStdIo<T> 179 where 180 T: io::BufRead, 181 { fill_buf(&mut self) -> io::Result<&[u8]>182 fn fill_buf(&mut self) -> io::Result<&[u8]> { 183 self.0.fill_buf() 184 } consume(&mut self, amt: usize)185 fn consume(&mut self, amt: usize) { 186 self.0.consume(amt) 187 } 188 } 189 190 impl<T> AsyncBufRead for AllowStdIo<T> 191 where 192 T: io::BufRead, 193 { poll_fill_buf(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<&[u8]>>194 fn poll_fill_buf(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<&[u8]>> { 195 let this: *mut Self = &mut *self as *mut _; 196 Poll::Ready(Ok(try_with_interrupt!(unsafe { &mut *this }.0.fill_buf()))) 197 } 198 consume(mut self: Pin<&mut Self>, amt: usize)199 fn consume(mut self: Pin<&mut Self>, amt: usize) { 200 self.0.consume(amt) 201 } 202 } 203