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