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 | |