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