2019-08-12 10:43:44 +00:00
|
|
|
use std::pin::Pin;
|
|
|
|
|
|
|
|
use cfg_if::cfg_if;
|
|
|
|
|
2019-08-12 16:00:21 +00:00
|
|
|
use crate::future::Future;
|
2019-08-14 13:35:46 +00:00
|
|
|
use crate::io::{self, SeekFrom};
|
2019-08-12 16:00:21 +00:00
|
|
|
use crate::task::{Context, Poll};
|
2019-09-26 11:46:29 +00:00
|
|
|
use crate::utils::extension_trait;
|
2019-08-12 16:00:21 +00:00
|
|
|
|
2019-08-12 10:43:44 +00:00
|
|
|
cfg_if! {
|
2019-08-12 17:50:30 +00:00
|
|
|
if #[cfg(feature = "docs")] {
|
2019-09-21 08:39:56 +00:00
|
|
|
use std::ops::{Deref, DerefMut};
|
2019-09-26 11:46:29 +00:00
|
|
|
}
|
|
|
|
}
|
2019-09-21 08:39:56 +00:00
|
|
|
|
2019-09-26 11:46:29 +00:00
|
|
|
extension_trait! {
|
2019-09-26 18:21:27 +00:00
|
|
|
#[doc = r#"
|
|
|
|
Allows seeking through a byte stream.
|
|
|
|
|
|
|
|
This trait is a re-export of [`futures::io::AsyncSeek`] and is an async version of
|
|
|
|
[`std::io::Seek`].
|
|
|
|
|
|
|
|
The [provided methods] do not really exist in the trait itself, but they become
|
|
|
|
available when the prelude is imported:
|
|
|
|
|
|
|
|
```
|
|
|
|
# #[allow(unused_imports)]
|
|
|
|
use async_std::prelude::*;
|
|
|
|
```
|
|
|
|
|
|
|
|
[`std::io::Seek`]: https://doc.rust-lang.org/std/io/trait.Seek.html
|
|
|
|
[`futures::io::AsyncSeek`]:
|
|
|
|
https://docs.rs/futures-preview/0.3.0-alpha.17/futures/io/trait.AsyncSeek.html
|
|
|
|
[provided methods]: #provided-methods
|
|
|
|
"#]
|
2019-09-26 11:46:29 +00:00
|
|
|
pub trait Seek [SeekExt: futures_io::AsyncSeek] {
|
2019-09-26 18:21:27 +00:00
|
|
|
#[doc = r#"
|
|
|
|
Attempt to seek to an offset, in bytes, in a stream.
|
|
|
|
"#]
|
2019-09-26 11:46:29 +00:00
|
|
|
fn poll_seek(
|
|
|
|
self: Pin<&mut Self>,
|
|
|
|
cx: &mut Context<'_>,
|
|
|
|
pos: SeekFrom,
|
|
|
|
) -> Poll<io::Result<u64>>;
|
2019-09-21 08:39:56 +00:00
|
|
|
|
2019-09-26 18:21:27 +00:00
|
|
|
#[doc = r#"
|
|
|
|
Seeks to a new position in a byte stream.
|
|
|
|
|
|
|
|
Returns the new position in the byte stream.
|
|
|
|
|
|
|
|
A seek beyond the end of stream is allowed, but behavior is defined by the
|
|
|
|
implementation.
|
|
|
|
|
|
|
|
# Examples
|
|
|
|
|
|
|
|
```no_run
|
|
|
|
# fn main() -> std::io::Result<()> { async_std::task::block_on(async {
|
|
|
|
#
|
|
|
|
use async_std::fs::File;
|
|
|
|
use async_std::io::SeekFrom;
|
|
|
|
use async_std::prelude::*;
|
|
|
|
|
|
|
|
let mut file = File::open("a.txt").await?;
|
|
|
|
|
|
|
|
let file_len = file.seek(SeekFrom::End(0)).await?;
|
|
|
|
#
|
|
|
|
# Ok(()) }) }
|
|
|
|
```
|
|
|
|
"#]
|
2019-09-26 11:46:29 +00:00
|
|
|
fn seek(
|
|
|
|
&mut self,
|
|
|
|
pos: SeekFrom,
|
|
|
|
) -> impl Future<Output = io::Result<u64>> [SeekFuture<'_, Self>]
|
|
|
|
where
|
|
|
|
Self: Unpin,
|
|
|
|
{
|
|
|
|
SeekFuture { seeker: self, pos }
|
2019-08-12 10:43:44 +00:00
|
|
|
}
|
2019-09-26 11:46:29 +00:00
|
|
|
}
|
2019-09-21 08:39:56 +00:00
|
|
|
|
2019-09-26 11:46:29 +00:00
|
|
|
impl<T: Seek + Unpin + ?Sized> Seek for Box<T> {
|
|
|
|
fn poll_seek(
|
|
|
|
self: Pin<&mut Self>,
|
|
|
|
cx: &mut Context<'_>,
|
|
|
|
pos: SeekFrom,
|
|
|
|
) -> Poll<io::Result<u64>> {
|
2019-09-26 18:21:27 +00:00
|
|
|
unreachable!("this impl only appears in the rendered docs")
|
2019-09-21 08:39:56 +00:00
|
|
|
}
|
2019-09-26 11:46:29 +00:00
|
|
|
}
|
2019-09-21 08:39:56 +00:00
|
|
|
|
2019-09-26 11:46:29 +00:00
|
|
|
impl<T: Seek + Unpin + ?Sized> Seek for &mut T {
|
|
|
|
fn poll_seek(
|
|
|
|
self: Pin<&mut Self>,
|
|
|
|
cx: &mut Context<'_>,
|
|
|
|
pos: SeekFrom,
|
|
|
|
) -> Poll<io::Result<u64>> {
|
2019-09-26 18:21:27 +00:00
|
|
|
unreachable!("this impl only appears in the rendered docs")
|
2019-09-21 08:39:56 +00:00
|
|
|
}
|
2019-08-12 10:43:44 +00:00
|
|
|
}
|
|
|
|
|
2019-09-26 11:46:29 +00:00
|
|
|
impl<P> Seek for Pin<P>
|
2019-08-12 10:43:44 +00:00
|
|
|
where
|
2019-09-26 11:46:29 +00:00
|
|
|
P: DerefMut + Unpin,
|
|
|
|
<P as Deref>::Target: Seek,
|
2019-09-21 08:39:56 +00:00
|
|
|
{
|
2019-09-26 11:46:29 +00:00
|
|
|
fn poll_seek(
|
|
|
|
self: Pin<&mut Self>,
|
|
|
|
cx: &mut Context<'_>,
|
|
|
|
pos: SeekFrom,
|
|
|
|
) -> Poll<io::Result<u64>> {
|
2019-09-26 18:21:27 +00:00
|
|
|
unreachable!("this impl only appears in the rendered docs")
|
2019-09-26 11:46:29 +00:00
|
|
|
}
|
2019-08-12 10:43:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[doc(hidden)]
|
|
|
|
#[allow(missing_debug_implementations)]
|
|
|
|
pub struct SeekFuture<'a, T: Unpin + ?Sized> {
|
|
|
|
seeker: &'a mut T,
|
|
|
|
pos: SeekFrom,
|
|
|
|
}
|
|
|
|
|
2019-09-21 08:39:56 +00:00
|
|
|
impl<T: SeekExt + Unpin + ?Sized> Future for SeekFuture<'_, T> {
|
2019-08-12 10:43:44 +00:00
|
|
|
type Output = io::Result<u64>;
|
|
|
|
|
|
|
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
|
|
let pos = self.pos;
|
|
|
|
Pin::new(&mut *self.seeker).poll_seek(cx, pos)
|
|
|
|
}
|
|
|
|
}
|