| 1 | use crate::io::seek::{seek, Seek}; |
| 2 | use crate::io::AsyncSeek; |
| 3 | use std::io::SeekFrom; |
| 4 | |
| 5 | cfg_io_util! { |
| 6 | /// An extension trait that adds utility methods to [`AsyncSeek`] types. |
| 7 | /// |
| 8 | /// # Examples |
| 9 | /// |
| 10 | /// ``` |
| 11 | /// use std::io::{self, Cursor, SeekFrom}; |
| 12 | /// use tokio::io::{AsyncSeekExt, AsyncReadExt}; |
| 13 | /// |
| 14 | /// #[tokio::main] |
| 15 | /// async fn main() -> io::Result<()> { |
| 16 | /// let mut cursor = Cursor::new(b"abcdefg"); |
| 17 | /// |
| 18 | /// // the `seek` method is defined by this trait |
| 19 | /// cursor.seek(SeekFrom::Start(3)).await?; |
| 20 | /// |
| 21 | /// let mut buf = [0; 1]; |
| 22 | /// let n = cursor.read(&mut buf).await?; |
| 23 | /// assert_eq!(n, 1); |
| 24 | /// assert_eq!(buf, [b'd']); |
| 25 | /// |
| 26 | /// Ok(()) |
| 27 | /// } |
| 28 | /// ``` |
| 29 | /// |
| 30 | /// See [module][crate::io] documentation for more details. |
| 31 | /// |
| 32 | /// [`AsyncSeek`]: AsyncSeek |
| 33 | pub trait AsyncSeekExt: AsyncSeek { |
| 34 | /// Creates a future which will seek an IO object, and then yield the |
| 35 | /// new position in the object and the object itself. |
| 36 | /// |
| 37 | /// Equivalent to: |
| 38 | /// |
| 39 | /// ```ignore |
| 40 | /// async fn seek(&mut self, pos: SeekFrom) -> io::Result<u64>; |
| 41 | /// ``` |
| 42 | /// |
| 43 | /// In the case of an error the buffer and the object will be discarded, with |
| 44 | /// the error yielded. |
| 45 | /// |
| 46 | /// # Examples |
| 47 | /// |
| 48 | /// ```no_run |
| 49 | /// use tokio::fs::File; |
| 50 | /// use tokio::io::{AsyncSeekExt, AsyncReadExt}; |
| 51 | /// |
| 52 | /// use std::io::SeekFrom; |
| 53 | /// |
| 54 | /// # async fn dox() -> std::io::Result<()> { |
| 55 | /// let mut file = File::open("foo.txt").await?; |
| 56 | /// file.seek(SeekFrom::Start(6)).await?; |
| 57 | /// |
| 58 | /// let mut contents = vec![0u8; 10]; |
| 59 | /// file.read_exact(&mut contents).await?; |
| 60 | /// # Ok(()) |
| 61 | /// # } |
| 62 | /// ``` |
| 63 | fn seek(&mut self, pos: SeekFrom) -> Seek<'_, Self> |
| 64 | where |
| 65 | Self: Unpin, |
| 66 | { |
| 67 | seek(self, pos) |
| 68 | } |
| 69 | |
| 70 | /// Creates a future which will rewind to the beginning of the stream. |
| 71 | /// |
| 72 | /// This is convenience method, equivalent to `self.seek(SeekFrom::Start(0))`. |
| 73 | fn rewind(&mut self) -> Seek<'_, Self> |
| 74 | where |
| 75 | Self: Unpin, |
| 76 | { |
| 77 | self.seek(SeekFrom::Start(0)) |
| 78 | } |
| 79 | |
| 80 | /// Creates a future which will return the current seek position from the |
| 81 | /// start of the stream. |
| 82 | /// |
| 83 | /// This is equivalent to `self.seek(SeekFrom::Current(0))`. |
| 84 | fn stream_position(&mut self) -> Seek<'_, Self> |
| 85 | where |
| 86 | Self: Unpin, |
| 87 | { |
| 88 | self.seek(SeekFrom::Current(0)) |
| 89 | } |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | impl<S: AsyncSeek + ?Sized> AsyncSeekExt for S {} |
| 94 | |