1 use futures_core::task::{Context, Poll}; 2 use futures_io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, SeekFrom}; 3 use std::io; 4 use std::pin::Pin; 5 6 /// A `Cursor` wraps an in-memory buffer and provides it with a 7 /// [`AsyncSeek`] implementation. 8 /// 9 /// `Cursor`s are used with in-memory buffers, anything implementing 10 /// `AsRef<[u8]>`, to allow them to implement [`AsyncRead`] and/or [`AsyncWrite`], 11 /// allowing these buffers to be used anywhere you might use a reader or writer 12 /// that does actual I/O. 13 /// 14 /// This library implements some I/O traits on various types which 15 /// are commonly used as a buffer, like `Cursor<`[`Vec`]`<u8>>` and 16 /// `Cursor<`[`&[u8]`][bytes]`>`. 17 /// 18 /// [`AsyncSeek`]: trait.AsyncSeek.html 19 /// [`AsyncRead`]: trait.AsyncRead.html 20 /// [`AsyncWrite`]: trait.AsyncWrite.html 21 /// [bytes]: https://doc.rust-lang.org/std/primitive.slice.html 22 #[derive(Clone, Debug, Default)] 23 pub struct Cursor<T> { 24 inner: io::Cursor<T>, 25 } 26 27 impl<T> Cursor<T> { 28 /// Creates a new cursor wrapping the provided underlying in-memory buffer. 29 /// 30 /// Cursor initial position is `0` even if underlying buffer (e.g., `Vec`) 31 /// is not empty. So writing to cursor starts with overwriting `Vec` 32 /// content, not with appending to it. 33 /// 34 /// # Examples 35 /// 36 /// ``` 37 /// use futures::io::Cursor; 38 /// 39 /// let buff = Cursor::new(Vec::new()); 40 /// # fn force_inference(_: &Cursor<Vec<u8>>) {} 41 /// # force_inference(&buff); 42 /// ``` new(inner: T) -> Self43 pub fn new(inner: T) -> Self { 44 Self { inner: io::Cursor::new(inner) } 45 } 46 47 /// Consumes this cursor, returning the underlying value. 48 /// 49 /// # Examples 50 /// 51 /// ``` 52 /// use futures::io::Cursor; 53 /// 54 /// let buff = Cursor::new(Vec::new()); 55 /// # fn force_inference(_: &Cursor<Vec<u8>>) {} 56 /// # force_inference(&buff); 57 /// 58 /// let vec = buff.into_inner(); 59 /// ``` into_inner(self) -> T60 pub fn into_inner(self) -> T { 61 self.inner.into_inner() 62 } 63 64 /// Gets a reference to the underlying value in this cursor. 65 /// 66 /// # Examples 67 /// 68 /// ``` 69 /// use futures::io::Cursor; 70 /// 71 /// let buff = Cursor::new(Vec::new()); 72 /// # fn force_inference(_: &Cursor<Vec<u8>>) {} 73 /// # force_inference(&buff); 74 /// 75 /// let reference = buff.get_ref(); 76 /// ``` get_ref(&self) -> &T77 pub fn get_ref(&self) -> &T { 78 self.inner.get_ref() 79 } 80 81 /// Gets a mutable reference to the underlying value in this cursor. 82 /// 83 /// Care should be taken to avoid modifying the internal I/O state of the 84 /// underlying value as it may corrupt this cursor's position. 85 /// 86 /// # Examples 87 /// 88 /// ``` 89 /// use futures::io::Cursor; 90 /// 91 /// let mut buff = Cursor::new(Vec::new()); 92 /// # fn force_inference(_: &Cursor<Vec<u8>>) {} 93 /// # force_inference(&buff); 94 /// 95 /// let reference = buff.get_mut(); 96 /// ``` get_mut(&mut self) -> &mut T97 pub fn get_mut(&mut self) -> &mut T { 98 self.inner.get_mut() 99 } 100 101 /// Returns the current position of this cursor. 102 /// 103 /// # Examples 104 /// 105 /// ``` 106 /// # futures::executor::block_on(async { 107 /// use futures::io::{AsyncSeekExt, Cursor, SeekFrom}; 108 /// 109 /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); 110 /// 111 /// assert_eq!(buff.position(), 0); 112 /// 113 /// buff.seek(SeekFrom::Current(2)).await?; 114 /// assert_eq!(buff.position(), 2); 115 /// 116 /// buff.seek(SeekFrom::Current(-1)).await?; 117 /// assert_eq!(buff.position(), 1); 118 /// # Ok::<(), Box<dyn std::error::Error>>(()) }).unwrap(); 119 /// ``` position(&self) -> u64120 pub fn position(&self) -> u64 { 121 self.inner.position() 122 } 123 124 /// Sets the position of this cursor. 125 /// 126 /// # Examples 127 /// 128 /// ``` 129 /// use futures::io::Cursor; 130 /// 131 /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); 132 /// 133 /// assert_eq!(buff.position(), 0); 134 /// 135 /// buff.set_position(2); 136 /// assert_eq!(buff.position(), 2); 137 /// 138 /// buff.set_position(4); 139 /// assert_eq!(buff.position(), 4); 140 /// ``` set_position(&mut self, pos: u64)141 pub fn set_position(&mut self, pos: u64) { 142 self.inner.set_position(pos) 143 } 144 } 145 146 impl<T> AsyncSeek for Cursor<T> 147 where 148 T: AsRef<[u8]> + Unpin, 149 { poll_seek( mut self: Pin<&mut Self>, _: &mut Context<'_>, pos: SeekFrom, ) -> Poll<io::Result<u64>>150 fn poll_seek( 151 mut self: Pin<&mut Self>, 152 _: &mut Context<'_>, 153 pos: SeekFrom, 154 ) -> Poll<io::Result<u64>> { 155 Poll::Ready(io::Seek::seek(&mut self.inner, pos)) 156 } 157 } 158 159 impl<T: AsRef<[u8]> + Unpin> AsyncRead for Cursor<T> { poll_read( mut self: Pin<&mut Self>, _cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll<io::Result<usize>>160 fn poll_read( 161 mut self: Pin<&mut Self>, 162 _cx: &mut Context<'_>, 163 buf: &mut [u8], 164 ) -> Poll<io::Result<usize>> { 165 Poll::Ready(io::Read::read(&mut self.inner, buf)) 166 } 167 poll_read_vectored( mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>], ) -> Poll<io::Result<usize>>168 fn poll_read_vectored( 169 mut self: Pin<&mut Self>, 170 _: &mut Context<'_>, 171 bufs: &mut [IoSliceMut<'_>], 172 ) -> Poll<io::Result<usize>> { 173 Poll::Ready(io::Read::read_vectored(&mut self.inner, bufs)) 174 } 175 } 176 177 impl<T> AsyncBufRead for Cursor<T> 178 where 179 T: AsRef<[u8]> + Unpin, 180 { poll_fill_buf(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<&[u8]>>181 fn poll_fill_buf(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<&[u8]>> { 182 Poll::Ready(io::BufRead::fill_buf(&mut self.get_mut().inner)) 183 } 184 consume(mut self: Pin<&mut Self>, amt: usize)185 fn consume(mut self: Pin<&mut Self>, amt: usize) { 186 io::BufRead::consume(&mut self.inner, amt) 187 } 188 } 189 190 macro_rules! delegate_async_write_to_stdio { 191 () => { 192 fn poll_write( 193 mut self: Pin<&mut Self>, 194 _: &mut Context<'_>, 195 buf: &[u8], 196 ) -> Poll<io::Result<usize>> { 197 Poll::Ready(io::Write::write(&mut self.inner, buf)) 198 } 199 200 fn poll_write_vectored( 201 mut self: Pin<&mut Self>, 202 _: &mut Context<'_>, 203 bufs: &[IoSlice<'_>], 204 ) -> Poll<io::Result<usize>> { 205 Poll::Ready(io::Write::write_vectored(&mut self.inner, bufs)) 206 } 207 208 fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> { 209 Poll::Ready(io::Write::flush(&mut self.inner)) 210 } 211 212 fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> { 213 self.poll_flush(cx) 214 } 215 }; 216 } 217 218 impl AsyncWrite for Cursor<&mut [u8]> { 219 delegate_async_write_to_stdio!(); 220 } 221 222 impl AsyncWrite for Cursor<&mut Vec<u8>> { 223 delegate_async_write_to_stdio!(); 224 } 225 226 impl AsyncWrite for Cursor<Vec<u8>> { 227 delegate_async_write_to_stdio!(); 228 } 229 230 impl AsyncWrite for Cursor<Box<[u8]>> { 231 delegate_async_write_to_stdio!(); 232 } 233