1use std::future::{self, Future};
2use std::io::{Cursor, Empty, Result, SeekFrom};
3use std::marker::PhantomData;
4use std::pin::Pin;
5use std::task::{Context, Poll};
6
7use completion_core::CompletionFuture;
8
9pub trait AsyncSeek: for<'a> AsyncSeekWith<'a> {}
15impl<T: for<'a> AsyncSeekWith<'a> + ?Sized> AsyncSeek for T {}
16
17pub trait AsyncSeekWith<'a> {
19 type SeekFuture: CompletionFuture<Output = Result<u64>>;
22
23 fn seek(&'a mut self, pos: SeekFrom) -> Self::SeekFuture;
25}
26
27impl<'a, S: AsyncSeekWith<'a> + ?Sized> AsyncSeekWith<'a> for &mut S {
28 type SeekFuture = S::SeekFuture;
29
30 #[inline]
31 fn seek(&'a mut self, pos: SeekFrom) -> Self::SeekFuture {
32 (**self).seek(pos)
33 }
34}
35
36impl<'a, S: AsyncSeekWith<'a> + ?Sized> AsyncSeekWith<'a> for Box<S> {
37 type SeekFuture = S::SeekFuture;
38
39 #[inline]
40 fn seek(&'a mut self, pos: SeekFrom) -> Self::SeekFuture {
41 (**self).seek(pos)
42 }
43}
44
45impl<'a> AsyncSeekWith<'a> for Empty {
46 type SeekFuture = future::Ready<Result<u64>>;
47
48 fn seek(&'a mut self, _pos: SeekFrom) -> Self::SeekFuture {
49 future::ready(Ok(0))
50 }
51}
52
53impl<'a, T: AsRef<[u8]>> AsyncSeekWith<'a> for Cursor<T> {
54 type SeekFuture = SeekCursor<'a, T>;
55
56 #[inline]
57 fn seek(&'a mut self, pos: SeekFrom) -> Self::SeekFuture {
58 SeekCursor {
59 cursor: self,
60 pos,
61 _lifetime: PhantomData,
62 }
63 }
64}
65
66#[derive(Debug)]
68pub struct SeekCursor<'a, T> {
69 cursor: *mut Cursor<T>,
72 pos: SeekFrom,
73 _lifetime: PhantomData<&'a ()>,
74}
75unsafe impl<T: Send> Send for SeekCursor<'_, T> {}
77unsafe impl<T: Sync> Sync for SeekCursor<'_, T> {}
78
79impl<T: AsRef<[u8]>> Future for SeekCursor<'_, T> {
80 type Output = Result<u64>;
81
82 fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
83 let this = &mut *self;
84 Poll::Ready(std::io::Seek::seek(unsafe { &mut *this.cursor }, this.pos))
85 }
86}
87impl<T: AsRef<[u8]>> CompletionFuture for SeekCursor<'_, T> {
88 type Output = Result<u64>;
89
90 unsafe fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
91 Future::poll(self, cx)
92 }
93 unsafe fn poll_cancel(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<()> {
94 Poll::Ready(())
95 }
96}
97
98#[cfg(test)]
99#[allow(dead_code, clippy::extra_unused_lifetimes)]
100fn test_impls_traits<'a>() {
101 fn assert_impls<R: AsyncSeek>() {}
102
103 assert_impls::<Cursor<&'a [u8]>>();
104 assert_impls::<Cursor<Vec<u8>>>();
105 assert_impls::<&'a mut Cursor<&'a [u8]>>();
106 assert_impls::<&'a mut Cursor<Vec<u8>>>();
107 assert_impls::<Box<Cursor<&'a [u8]>>>();
108 assert_impls::<Box<Cursor<Vec<u8>>>>();
109}