1use crate::io::AsyncSeek;
2use std::future::Future;
3use std::io::{self, SeekFrom};
4use std::pin::Pin;
5use std::task::{Context, Poll};
6
7#[derive(Debug)]
9#[must_use = "futures do nothing unless you `.await` or poll them"]
10pub struct Seek<'a, S: ?Sized> {
11 seek: &'a mut S,
12 pos: Option<SeekFrom>,
13}
14
15pub(crate) fn seek<S>(seek: &mut S, pos: SeekFrom) -> Seek<'_, S>
16where
17 S: AsyncSeek + ?Sized + Unpin,
18{
19 Seek {
20 seek,
21 pos: Some(pos),
22 }
23}
24
25impl<S> Future for Seek<'_, S>
26where
27 S: AsyncSeek + ?Sized + Unpin,
28{
29 type Output = io::Result<u64>;
30
31 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
32 let me = &mut *self;
33 match me.pos {
34 Some(pos) => match Pin::new(&mut me.seek).start_seek(cx, pos) {
35 Poll::Ready(Ok(())) => {
36 me.pos = None;
37 Pin::new(&mut me.seek).poll_complete(cx)
38 }
39 Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
40 Poll::Pending => Poll::Pending,
41 },
42 None => Pin::new(&mut me.seek).poll_complete(cx),
43 }
44 }
45}
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50
51 #[test]
52 fn assert_unpin() {
53 use std::marker::PhantomPinned;
54 crate::is_unpin::<Seek<'_, PhantomPinned>>();
55 }
56}