mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-29 00:00:11 +02:00
io, stream: make ext trait futures !Unpin (#2910)
Make these future `!Unpin` for compatibility with async trait methods.
This commit is contained in:
+14
-18
@@ -1,16 +1,22 @@
|
|||||||
use crate::io::AsyncSeek;
|
use crate::io::AsyncSeek;
|
||||||
|
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::io::{self, SeekFrom};
|
use std::io::{self, SeekFrom};
|
||||||
|
use std::marker::PhantomPinned;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
cfg_io_util! {
|
pin_project! {
|
||||||
/// Future for the [`seek`](crate::io::AsyncSeekExt::seek) method.
|
/// Future for the [`seek`](crate::io::AsyncSeekExt::seek) method.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||||
pub struct Seek<'a, S: ?Sized> {
|
pub struct Seek<'a, S: ?Sized> {
|
||||||
seek: &'a mut S,
|
seek: &'a mut S,
|
||||||
pos: Option<SeekFrom>,
|
pos: Option<SeekFrom>,
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,6 +27,7 @@ where
|
|||||||
Seek {
|
Seek {
|
||||||
seek,
|
seek,
|
||||||
pos: Some(pos),
|
pos: Some(pos),
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,29 +37,18 @@ where
|
|||||||
{
|
{
|
||||||
type Output = io::Result<u64>;
|
type Output = io::Result<u64>;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let me = &mut *self;
|
let me = self.project();
|
||||||
match me.pos {
|
match me.pos {
|
||||||
Some(pos) => match Pin::new(&mut me.seek).start_seek(cx, pos) {
|
Some(pos) => match Pin::new(&mut *me.seek).start_seek(cx, *pos) {
|
||||||
Poll::Ready(Ok(())) => {
|
Poll::Ready(Ok(())) => {
|
||||||
me.pos = None;
|
*me.pos = None;
|
||||||
Pin::new(&mut me.seek).poll_complete(cx)
|
Pin::new(&mut *me.seek).poll_complete(cx)
|
||||||
}
|
}
|
||||||
Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
|
Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
|
||||||
Poll::Pending => Poll::Pending,
|
Poll::Pending => Poll::Pending,
|
||||||
},
|
},
|
||||||
None => Pin::new(&mut me.seek).poll_complete(cx),
|
None => Pin::new(&mut *me.seek).poll_complete(cx),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn assert_unpin() {
|
|
||||||
use std::marker::PhantomPinned;
|
|
||||||
crate::is_unpin::<Seek<'_, PhantomPinned>>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -37,6 +37,12 @@ cfg_io_util! {
|
|||||||
/// Creates a future which will seek an IO object, and then yield the
|
/// Creates a future which will seek an IO object, and then yield the
|
||||||
/// new position in the object and the object itself.
|
/// new position in the object and the object itself.
|
||||||
///
|
///
|
||||||
|
/// Equivalent to:
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// async fn seek(&mut self, pos: SeekFrom) -> io::Result<u64>;
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
/// In the case of an error the buffer and the object will be discarded, with
|
/// In the case of an error the buffer and the object will be discarded, with
|
||||||
/// the error yielded.
|
/// the error yielded.
|
||||||
///
|
///
|
||||||
|
|||||||
+13
-15
@@ -1,18 +1,24 @@
|
|||||||
use crate::io::AsyncWrite;
|
use crate::io::AsyncWrite;
|
||||||
|
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::marker::PhantomPinned;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
cfg_io_util! {
|
pin_project! {
|
||||||
/// A future used to fully flush an I/O object.
|
/// A future used to fully flush an I/O object.
|
||||||
///
|
///
|
||||||
/// Created by the [`AsyncWriteExt::flush`][flush] function.
|
/// Created by the [`AsyncWriteExt::flush`][flush] function.
|
||||||
/// [flush]: crate::io::AsyncWriteExt::flush
|
/// [flush]: crate::io::AsyncWriteExt::flush
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||||
pub struct Flush<'a, A: ?Sized> {
|
pub struct Flush<'a, A: ?Sized> {
|
||||||
a: &'a mut A,
|
a: &'a mut A,
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,7 +27,10 @@ pub(super) fn flush<A>(a: &mut A) -> Flush<'_, A>
|
|||||||
where
|
where
|
||||||
A: AsyncWrite + Unpin + ?Sized,
|
A: AsyncWrite + Unpin + ?Sized,
|
||||||
{
|
{
|
||||||
Flush { a }
|
Flush {
|
||||||
|
a,
|
||||||
|
_pin: PhantomPinned,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A> Future for Flush<'_, A>
|
impl<A> Future for Flush<'_, A>
|
||||||
@@ -30,19 +39,8 @@ where
|
|||||||
{
|
{
|
||||||
type Output = io::Result<()>;
|
type Output = io::Result<()>;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let me = &mut *self;
|
let me = self.project();
|
||||||
Pin::new(&mut *me.a).poll_flush(cx)
|
Pin::new(&mut *me.a).poll_flush(cx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn assert_unpin() {
|
|
||||||
use std::marker::PhantomPinned;
|
|
||||||
crate::is_unpin::<Flush<'_, PhantomPinned>>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+15
-17
@@ -1,7 +1,9 @@
|
|||||||
use crate::io::{AsyncRead, ReadBuf};
|
use crate::io::{AsyncRead, ReadBuf};
|
||||||
|
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::marker::PhantomPinned;
|
||||||
use std::marker::Unpin;
|
use std::marker::Unpin;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
@@ -15,10 +17,14 @@ pub(crate) fn read<'a, R>(reader: &'a mut R, buf: &'a mut [u8]) -> Read<'a, R>
|
|||||||
where
|
where
|
||||||
R: AsyncRead + Unpin + ?Sized,
|
R: AsyncRead + Unpin + ?Sized,
|
||||||
{
|
{
|
||||||
Read { reader, buf }
|
Read {
|
||||||
|
reader,
|
||||||
|
buf,
|
||||||
|
_pin: PhantomPinned,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg_io_util! {
|
pin_project! {
|
||||||
/// A future which can be used to easily read available number of bytes to fill
|
/// A future which can be used to easily read available number of bytes to fill
|
||||||
/// a buffer.
|
/// a buffer.
|
||||||
///
|
///
|
||||||
@@ -28,6 +34,9 @@ cfg_io_util! {
|
|||||||
pub struct Read<'a, R: ?Sized> {
|
pub struct Read<'a, R: ?Sized> {
|
||||||
reader: &'a mut R,
|
reader: &'a mut R,
|
||||||
buf: &'a mut [u8],
|
buf: &'a mut [u8],
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,21 +46,10 @@ where
|
|||||||
{
|
{
|
||||||
type Output = io::Result<usize>;
|
type Output = io::Result<usize>;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<usize>> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<usize>> {
|
||||||
let me = &mut *self;
|
let me = self.project();
|
||||||
let mut buf = ReadBuf::new(me.buf);
|
let mut buf = ReadBuf::new(*me.buf);
|
||||||
ready!(Pin::new(&mut *me.reader).poll_read(cx, &mut buf))?;
|
ready!(Pin::new(me.reader).poll_read(cx, &mut buf))?;
|
||||||
Poll::Ready(Ok(buf.filled().len()))
|
Poll::Ready(Ok(buf.filled().len()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn assert_unpin() {
|
|
||||||
use std::marker::PhantomPinned;
|
|
||||||
crate::is_unpin::<Read<'_, PhantomPinned>>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
use crate::io::{AsyncRead, ReadBuf};
|
use crate::io::{AsyncRead, ReadBuf};
|
||||||
|
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::marker::PhantomPinned;
|
||||||
use std::marker::Unpin;
|
use std::marker::Unpin;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
@@ -18,10 +20,11 @@ where
|
|||||||
ReadExact {
|
ReadExact {
|
||||||
reader,
|
reader,
|
||||||
buf: ReadBuf::new(buf),
|
buf: ReadBuf::new(buf),
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg_io_util! {
|
pin_project! {
|
||||||
/// Creates a future which will read exactly enough bytes to fill `buf`,
|
/// Creates a future which will read exactly enough bytes to fill `buf`,
|
||||||
/// returning an error if EOF is hit sooner.
|
/// returning an error if EOF is hit sooner.
|
||||||
///
|
///
|
||||||
@@ -31,6 +34,9 @@ cfg_io_util! {
|
|||||||
pub struct ReadExact<'a, A: ?Sized> {
|
pub struct ReadExact<'a, A: ?Sized> {
|
||||||
reader: &'a mut A,
|
reader: &'a mut A,
|
||||||
buf: ReadBuf<'a>,
|
buf: ReadBuf<'a>,
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,30 +50,20 @@ where
|
|||||||
{
|
{
|
||||||
type Output = io::Result<usize>;
|
type Output = io::Result<usize>;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<usize>> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<usize>> {
|
||||||
|
let mut me = self.project();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// if our buffer is empty, then we need to read some data to continue.
|
// if our buffer is empty, then we need to read some data to continue.
|
||||||
let rem = self.buf.remaining();
|
let rem = me.buf.remaining();
|
||||||
if rem != 0 {
|
if rem != 0 {
|
||||||
let me = &mut *self;
|
|
||||||
ready!(Pin::new(&mut *me.reader).poll_read(cx, &mut me.buf))?;
|
ready!(Pin::new(&mut *me.reader).poll_read(cx, &mut me.buf))?;
|
||||||
if me.buf.remaining() == rem {
|
if me.buf.remaining() == rem {
|
||||||
return Err(eof()).into();
|
return Err(eof()).into();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Poll::Ready(Ok(self.buf.capacity()));
|
return Poll::Ready(Ok(me.buf.capacity()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn assert_unpin() {
|
|
||||||
use std::marker::PhantomPinned;
|
|
||||||
crate::is_unpin::<ReadExact<'_, PhantomPinned>>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use pin_project_lite::pin_project;
|
|||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::ErrorKind::UnexpectedEof;
|
use std::io::ErrorKind::UnexpectedEof;
|
||||||
|
use std::marker::PhantomPinned;
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
@@ -16,11 +17,15 @@ macro_rules! reader {
|
|||||||
($name:ident, $ty:ty, $reader:ident, $bytes:expr) => {
|
($name:ident, $ty:ty, $reader:ident, $bytes:expr) => {
|
||||||
pin_project! {
|
pin_project! {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||||
pub struct $name<R> {
|
pub struct $name<R> {
|
||||||
#[pin]
|
#[pin]
|
||||||
src: R,
|
src: R,
|
||||||
buf: [u8; $bytes],
|
buf: [u8; $bytes],
|
||||||
read: u8,
|
read: u8,
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,6 +35,7 @@ macro_rules! reader {
|
|||||||
src,
|
src,
|
||||||
buf: [0; $bytes],
|
buf: [0; $bytes],
|
||||||
read: 0,
|
read: 0,
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,15 +83,22 @@ macro_rules! reader8 {
|
|||||||
pin_project! {
|
pin_project! {
|
||||||
/// Future returned from `read_u8`
|
/// Future returned from `read_u8`
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||||
pub struct $name<R> {
|
pub struct $name<R> {
|
||||||
#[pin]
|
#[pin]
|
||||||
reader: R,
|
reader: R,
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R> $name<R> {
|
impl<R> $name<R> {
|
||||||
pub(crate) fn new(reader: R) -> $name<R> {
|
pub(crate) fn new(reader: R) -> $name<R> {
|
||||||
$name { reader }
|
$name {
|
||||||
|
reader,
|
||||||
|
_pin: PhantomPinned,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,27 +1,32 @@
|
|||||||
use crate::io::util::read_until::read_until_internal;
|
use crate::io::util::read_until::read_until_internal;
|
||||||
use crate::io::AsyncBufRead;
|
use crate::io::AsyncBufRead;
|
||||||
|
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::marker::PhantomPinned;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::string::FromUtf8Error;
|
use std::string::FromUtf8Error;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
cfg_io_util! {
|
pin_project! {
|
||||||
/// Future for the [`read_line`](crate::io::AsyncBufReadExt::read_line) method.
|
/// Future for the [`read_line`](crate::io::AsyncBufReadExt::read_line) method.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||||
pub struct ReadLine<'a, R: ?Sized> {
|
pub struct ReadLine<'a, R: ?Sized> {
|
||||||
reader: &'a mut R,
|
reader: &'a mut R,
|
||||||
/// This is the buffer we were provided. It will be replaced with an empty string
|
// This is the buffer we were provided. It will be replaced with an empty string
|
||||||
/// while reading to postpone utf-8 handling until after reading.
|
// while reading to postpone utf-8 handling until after reading.
|
||||||
output: &'a mut String,
|
output: &'a mut String,
|
||||||
/// The actual allocation of the string is moved into this vector instead.
|
// The actual allocation of the string is moved into this vector instead.
|
||||||
buf: Vec<u8>,
|
buf: Vec<u8>,
|
||||||
/// The number of bytes appended to buf. This can be less than buf.len() if
|
// The number of bytes appended to buf. This can be less than buf.len() if
|
||||||
/// the buffer was not empty when the operation was started.
|
// the buffer was not empty when the operation was started.
|
||||||
read: usize,
|
read: usize,
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,6 +39,7 @@ where
|
|||||||
buf: mem::replace(string, String::new()).into_bytes(),
|
buf: mem::replace(string, String::new()).into_bytes(),
|
||||||
output: string,
|
output: string,
|
||||||
read: 0,
|
read: 0,
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,25 +111,9 @@ pub(super) fn read_line_internal<R: AsyncBufRead + ?Sized>(
|
|||||||
impl<R: AsyncBufRead + ?Sized + Unpin> Future for ReadLine<'_, R> {
|
impl<R: AsyncBufRead + ?Sized + Unpin> Future for ReadLine<'_, R> {
|
||||||
type Output = io::Result<usize>;
|
type Output = io::Result<usize>;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let Self {
|
let me = self.project();
|
||||||
reader,
|
|
||||||
output,
|
|
||||||
buf,
|
|
||||||
read,
|
|
||||||
} = &mut *self;
|
|
||||||
|
|
||||||
read_line_internal(Pin::new(reader), cx, output, buf, read)
|
read_line_internal(Pin::new(*me.reader), cx, me.output, me.buf, me.read)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn assert_unpin() {
|
|
||||||
use std::marker::PhantomPinned;
|
|
||||||
crate::is_unpin::<ReadLine<'_, PhantomPinned>>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,26 @@
|
|||||||
use crate::io::{AsyncRead, ReadBuf};
|
use crate::io::{AsyncRead, ReadBuf};
|
||||||
|
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::marker::PhantomPinned;
|
||||||
use std::mem::{self, MaybeUninit};
|
use std::mem::{self, MaybeUninit};
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
#[derive(Debug)]
|
pin_project! {
|
||||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
|
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||||
pub struct ReadToEnd<'a, R: ?Sized> {
|
pub struct ReadToEnd<'a, R: ?Sized> {
|
||||||
reader: &'a mut R,
|
reader: &'a mut R,
|
||||||
buf: &'a mut Vec<u8>,
|
buf: &'a mut Vec<u8>,
|
||||||
/// The number of bytes appended to buf. This can be less than buf.len() if
|
// The number of bytes appended to buf. This can be less than buf.len() if
|
||||||
/// the buffer was not empty when the operation was started.
|
// the buffer was not empty when the operation was started.
|
||||||
read: usize,
|
read: usize,
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn read_to_end<'a, R>(reader: &'a mut R, buffer: &'a mut Vec<u8>) -> ReadToEnd<'a, R>
|
pub(crate) fn read_to_end<'a, R>(reader: &'a mut R, buffer: &'a mut Vec<u8>) -> ReadToEnd<'a, R>
|
||||||
@@ -25,6 +31,7 @@ where
|
|||||||
reader,
|
reader,
|
||||||
buf: buffer,
|
buf: buffer,
|
||||||
read: 0,
|
read: 0,
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,20 +107,9 @@ where
|
|||||||
{
|
{
|
||||||
type Output = io::Result<usize>;
|
type Output = io::Result<usize>;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let Self { reader, buf, read } = &mut *self;
|
let me = self.project();
|
||||||
|
|
||||||
read_to_end_internal(buf, Pin::new(*reader), read, cx)
|
read_to_end_internal(me.buf, Pin::new(*me.reader), me.read, cx)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn assert_unpin() {
|
|
||||||
use std::marker::PhantomPinned;
|
|
||||||
crate::is_unpin::<ReadToEnd<'_, PhantomPinned>>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,25 +2,30 @@ use crate::io::util::read_line::finish_string_read;
|
|||||||
use crate::io::util::read_to_end::read_to_end_internal;
|
use crate::io::util::read_to_end::read_to_end_internal;
|
||||||
use crate::io::AsyncRead;
|
use crate::io::AsyncRead;
|
||||||
|
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
use std::marker::PhantomPinned;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
use std::{io, mem};
|
use std::{io, mem};
|
||||||
|
|
||||||
cfg_io_util! {
|
pin_project! {
|
||||||
/// Future for the [`read_to_string`](super::AsyncReadExt::read_to_string) method.
|
/// Future for the [`read_to_string`](super::AsyncReadExt::read_to_string) method.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||||
pub struct ReadToString<'a, R: ?Sized> {
|
pub struct ReadToString<'a, R: ?Sized> {
|
||||||
reader: &'a mut R,
|
reader: &'a mut R,
|
||||||
/// This is the buffer we were provided. It will be replaced with an empty string
|
// This is the buffer we were provided. It will be replaced with an empty string
|
||||||
/// while reading to postpone utf-8 handling until after reading.
|
// while reading to postpone utf-8 handling until after reading.
|
||||||
output: &'a mut String,
|
output: &'a mut String,
|
||||||
/// The actual allocation of the string is moved into this vector instead.
|
// The actual allocation of the string is moved into this vector instead.
|
||||||
buf: Vec<u8>,
|
buf: Vec<u8>,
|
||||||
/// The number of bytes appended to buf. This can be less than buf.len() if
|
// The number of bytes appended to buf. This can be less than buf.len() if
|
||||||
/// the buffer was not empty when the operation was started.
|
// the buffer was not empty when the operation was started.
|
||||||
read: usize,
|
read: usize,
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,6 +42,7 @@ where
|
|||||||
buf,
|
buf,
|
||||||
output: string,
|
output: string,
|
||||||
read: 0,
|
read: 0,
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,26 +74,10 @@ where
|
|||||||
{
|
{
|
||||||
type Output = io::Result<usize>;
|
type Output = io::Result<usize>;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let Self {
|
let me = self.project();
|
||||||
reader,
|
|
||||||
buf,
|
|
||||||
output,
|
|
||||||
read,
|
|
||||||
} = &mut *self;
|
|
||||||
|
|
||||||
// safety: The constructor of ReadToString called `prepare_buffer`.
|
// safety: The constructor of ReadToString called `prepare_buffer`.
|
||||||
unsafe { read_to_string_internal(Pin::new(*reader), output, buf, read, cx) }
|
unsafe { read_to_string_internal(Pin::new(*me.reader), me.output, me.buf, me.read, cx) }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn assert_unpin() {
|
|
||||||
use std::marker::PhantomPinned;
|
|
||||||
crate::is_unpin::<ReadToString<'_, PhantomPinned>>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
use crate::io::AsyncBufRead;
|
use crate::io::AsyncBufRead;
|
||||||
|
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::marker::PhantomPinned;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
cfg_io_util! {
|
pin_project! {
|
||||||
/// Future for the [`read_until`](crate::io::AsyncBufReadExt::read_until) method.
|
/// Future for the [`read_until`](crate::io::AsyncBufReadExt::read_until) method.
|
||||||
/// The delimeter is included in the resulting vector.
|
/// The delimeter is included in the resulting vector.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -15,9 +17,12 @@ cfg_io_util! {
|
|||||||
reader: &'a mut R,
|
reader: &'a mut R,
|
||||||
delimeter: u8,
|
delimeter: u8,
|
||||||
buf: &'a mut Vec<u8>,
|
buf: &'a mut Vec<u8>,
|
||||||
/// The number of bytes appended to buf. This can be less than buf.len() if
|
// The number of bytes appended to buf. This can be less than buf.len() if
|
||||||
/// the buffer was not empty when the operation was started.
|
// the buffer was not empty when the operation was started.
|
||||||
read: usize,
|
read: usize,
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,6 +39,7 @@ where
|
|||||||
delimeter,
|
delimeter,
|
||||||
buf,
|
buf,
|
||||||
read: 0,
|
read: 0,
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,24 +72,8 @@ pub(super) fn read_until_internal<R: AsyncBufRead + ?Sized>(
|
|||||||
impl<R: AsyncBufRead + ?Sized + Unpin> Future for ReadUntil<'_, R> {
|
impl<R: AsyncBufRead + ?Sized + Unpin> Future for ReadUntil<'_, R> {
|
||||||
type Output = io::Result<usize>;
|
type Output = io::Result<usize>;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let Self {
|
let me = self.project();
|
||||||
reader,
|
read_until_internal(Pin::new(*me.reader), cx, *me.delimeter, me.buf, me.read)
|
||||||
delimeter,
|
|
||||||
buf,
|
|
||||||
read,
|
|
||||||
} = &mut *self;
|
|
||||||
read_until_internal(Pin::new(reader), cx, *delimeter, buf, read)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn assert_unpin() {
|
|
||||||
use std::marker::PhantomPinned;
|
|
||||||
crate::is_unpin::<ReadUntil<'_, PhantomPinned>>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,24 @@
|
|||||||
use crate::io::AsyncWrite;
|
use crate::io::AsyncWrite;
|
||||||
|
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::marker::PhantomPinned;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
cfg_io_util! {
|
pin_project! {
|
||||||
/// A future used to shutdown an I/O object.
|
/// A future used to shutdown an I/O object.
|
||||||
///
|
///
|
||||||
/// Created by the [`AsyncWriteExt::shutdown`][shutdown] function.
|
/// Created by the [`AsyncWriteExt::shutdown`][shutdown] function.
|
||||||
/// [shutdown]: crate::io::AsyncWriteExt::shutdown
|
/// [shutdown]: crate::io::AsyncWriteExt::shutdown
|
||||||
|
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Shutdown<'a, A: ?Sized> {
|
pub struct Shutdown<'a, A: ?Sized> {
|
||||||
a: &'a mut A,
|
a: &'a mut A,
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,7 +27,10 @@ pub(super) fn shutdown<A>(a: &mut A) -> Shutdown<'_, A>
|
|||||||
where
|
where
|
||||||
A: AsyncWrite + Unpin + ?Sized,
|
A: AsyncWrite + Unpin + ?Sized,
|
||||||
{
|
{
|
||||||
Shutdown { a }
|
Shutdown {
|
||||||
|
a,
|
||||||
|
_pin: PhantomPinned,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A> Future for Shutdown<'_, A>
|
impl<A> Future for Shutdown<'_, A>
|
||||||
@@ -30,19 +39,8 @@ where
|
|||||||
{
|
{
|
||||||
type Output = io::Result<()>;
|
type Output = io::Result<()>;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let me = &mut *self;
|
let me = self.project();
|
||||||
Pin::new(&mut *me.a).poll_shutdown(cx)
|
Pin::new(me.a).poll_shutdown(cx)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn assert_unpin() {
|
|
||||||
use std::marker::PhantomPinned;
|
|
||||||
crate::is_unpin::<Shutdown<'_, PhantomPinned>>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,22 @@
|
|||||||
use crate::io::AsyncWrite;
|
use crate::io::AsyncWrite;
|
||||||
|
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::marker::PhantomPinned;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
cfg_io_util! {
|
pin_project! {
|
||||||
/// A future to write some of the buffer to an `AsyncWrite`.
|
/// A future to write some of the buffer to an `AsyncWrite`.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||||
pub struct Write<'a, W: ?Sized> {
|
pub struct Write<'a, W: ?Sized> {
|
||||||
writer: &'a mut W,
|
writer: &'a mut W,
|
||||||
buf: &'a [u8],
|
buf: &'a [u8],
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,7 +26,11 @@ pub(crate) fn write<'a, W>(writer: &'a mut W, buf: &'a [u8]) -> Write<'a, W>
|
|||||||
where
|
where
|
||||||
W: AsyncWrite + Unpin + ?Sized,
|
W: AsyncWrite + Unpin + ?Sized,
|
||||||
{
|
{
|
||||||
Write { writer, buf }
|
Write {
|
||||||
|
writer,
|
||||||
|
buf,
|
||||||
|
_pin: PhantomPinned,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W> Future for Write<'_, W>
|
impl<W> Future for Write<'_, W>
|
||||||
@@ -30,8 +39,8 @@ where
|
|||||||
{
|
{
|
||||||
type Output = io::Result<usize>;
|
type Output = io::Result<usize>;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<usize>> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<usize>> {
|
||||||
let me = &mut *self;
|
let me = self.project();
|
||||||
Pin::new(&mut *me.writer).poll_write(cx, me.buf)
|
Pin::new(&mut *me.writer).poll_write(cx, me.buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,22 @@
|
|||||||
use crate::io::AsyncWrite;
|
use crate::io::AsyncWrite;
|
||||||
|
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::marker::PhantomPinned;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
cfg_io_util! {
|
pin_project! {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||||
pub struct WriteAll<'a, W: ?Sized> {
|
pub struct WriteAll<'a, W: ?Sized> {
|
||||||
writer: &'a mut W,
|
writer: &'a mut W,
|
||||||
buf: &'a [u8],
|
buf: &'a [u8],
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -19,7 +24,11 @@ pub(crate) fn write_all<'a, W>(writer: &'a mut W, buf: &'a [u8]) -> WriteAll<'a,
|
|||||||
where
|
where
|
||||||
W: AsyncWrite + Unpin + ?Sized,
|
W: AsyncWrite + Unpin + ?Sized,
|
||||||
{
|
{
|
||||||
WriteAll { writer, buf }
|
WriteAll {
|
||||||
|
writer,
|
||||||
|
buf,
|
||||||
|
_pin: PhantomPinned,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W> Future for WriteAll<'_, W>
|
impl<W> Future for WriteAll<'_, W>
|
||||||
@@ -28,13 +37,13 @@ where
|
|||||||
{
|
{
|
||||||
type Output = io::Result<()>;
|
type Output = io::Result<()>;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
||||||
let me = &mut *self;
|
let me = self.project();
|
||||||
while !me.buf.is_empty() {
|
while !me.buf.is_empty() {
|
||||||
let n = ready!(Pin::new(&mut me.writer).poll_write(cx, me.buf))?;
|
let n = ready!(Pin::new(&mut *me.writer).poll_write(cx, me.buf))?;
|
||||||
{
|
{
|
||||||
let (_, rest) = mem::replace(&mut me.buf, &[]).split_at(n);
|
let (_, rest) = mem::replace(&mut *me.buf, &[]).split_at(n);
|
||||||
me.buf = rest;
|
*me.buf = rest;
|
||||||
}
|
}
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return Poll::Ready(Err(io::ErrorKind::WriteZero.into()));
|
return Poll::Ready(Err(io::ErrorKind::WriteZero.into()));
|
||||||
@@ -44,14 +53,3 @@ where
|
|||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn assert_unpin() {
|
|
||||||
use std::marker::PhantomPinned;
|
|
||||||
crate::is_unpin::<WriteAll<'_, PhantomPinned>>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use bytes::BufMut;
|
|||||||
use pin_project_lite::pin_project;
|
use pin_project_lite::pin_project;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::marker::PhantomPinned;
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
@@ -15,20 +16,25 @@ macro_rules! writer {
|
|||||||
($name:ident, $ty:ty, $writer:ident, $bytes:expr) => {
|
($name:ident, $ty:ty, $writer:ident, $bytes:expr) => {
|
||||||
pin_project! {
|
pin_project! {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||||
pub struct $name<W> {
|
pub struct $name<W> {
|
||||||
#[pin]
|
#[pin]
|
||||||
dst: W,
|
dst: W,
|
||||||
buf: [u8; $bytes],
|
buf: [u8; $bytes],
|
||||||
written: u8,
|
written: u8,
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W> $name<W> {
|
impl<W> $name<W> {
|
||||||
pub(crate) fn new(w: W, value: $ty) -> Self {
|
pub(crate) fn new(w: W, value: $ty) -> Self {
|
||||||
let mut writer = $name {
|
let mut writer = Self {
|
||||||
buf: [0; $bytes],
|
buf: [0; $bytes],
|
||||||
written: 0,
|
written: 0,
|
||||||
dst: w,
|
dst: w,
|
||||||
|
_pin: PhantomPinned,
|
||||||
};
|
};
|
||||||
BufMut::$writer(&mut &mut writer.buf[..], value);
|
BufMut::$writer(&mut &mut writer.buf[..], value);
|
||||||
writer
|
writer
|
||||||
@@ -72,16 +78,24 @@ macro_rules! writer8 {
|
|||||||
($name:ident, $ty:ty) => {
|
($name:ident, $ty:ty) => {
|
||||||
pin_project! {
|
pin_project! {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||||
pub struct $name<W> {
|
pub struct $name<W> {
|
||||||
#[pin]
|
#[pin]
|
||||||
dst: W,
|
dst: W,
|
||||||
byte: $ty,
|
byte: $ty,
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W> $name<W> {
|
impl<W> $name<W> {
|
||||||
pub(crate) fn new(dst: W, byte: $ty) -> Self {
|
pub(crate) fn new(dst: W, byte: $ty) -> Self {
|
||||||
Self { dst, byte }
|
Self {
|
||||||
|
dst,
|
||||||
|
byte,
|
||||||
|
_pin: PhantomPinned,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+22
-12
@@ -1,25 +1,34 @@
|
|||||||
use crate::stream::Stream;
|
use crate::stream::Stream;
|
||||||
|
|
||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
|
use core::marker::PhantomPinned;
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
|
|
||||||
/// Future for the [`all`](super::StreamExt::all) method.
|
pin_project! {
|
||||||
#[derive(Debug)]
|
/// Future for the [`all`](super::StreamExt::all) method.
|
||||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
#[derive(Debug)]
|
||||||
pub struct AllFuture<'a, St: ?Sized, F> {
|
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||||
stream: &'a mut St,
|
pub struct AllFuture<'a, St: ?Sized, F> {
|
||||||
f: F,
|
stream: &'a mut St,
|
||||||
|
f: F,
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, St: ?Sized, F> AllFuture<'a, St, F> {
|
impl<'a, St: ?Sized, F> AllFuture<'a, St, F> {
|
||||||
pub(super) fn new(stream: &'a mut St, f: F) -> Self {
|
pub(super) fn new(stream: &'a mut St, f: F) -> Self {
|
||||||
Self { stream, f }
|
Self {
|
||||||
|
stream,
|
||||||
|
f,
|
||||||
|
_pin: PhantomPinned,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<St: ?Sized + Unpin, F> Unpin for AllFuture<'_, St, F> {}
|
|
||||||
|
|
||||||
impl<St, F> Future for AllFuture<'_, St, F>
|
impl<St, F> Future for AllFuture<'_, St, F>
|
||||||
where
|
where
|
||||||
St: ?Sized + Stream + Unpin,
|
St: ?Sized + Stream + Unpin,
|
||||||
@@ -27,12 +36,13 @@ where
|
|||||||
{
|
{
|
||||||
type Output = bool;
|
type Output = bool;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let next = futures_core::ready!(Pin::new(&mut self.stream).poll_next(cx));
|
let me = self.project();
|
||||||
|
let next = futures_core::ready!(Pin::new(me.stream).poll_next(cx));
|
||||||
|
|
||||||
match next {
|
match next {
|
||||||
Some(v) => {
|
Some(v) => {
|
||||||
if !(&mut self.f)(v) {
|
if !(me.f)(v) {
|
||||||
Poll::Ready(false)
|
Poll::Ready(false)
|
||||||
} else {
|
} else {
|
||||||
cx.waker().wake_by_ref();
|
cx.waker().wake_by_ref();
|
||||||
|
|||||||
+22
-12
@@ -1,25 +1,34 @@
|
|||||||
use crate::stream::Stream;
|
use crate::stream::Stream;
|
||||||
|
|
||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
|
use core::marker::PhantomPinned;
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
|
|
||||||
/// Future for the [`any`](super::StreamExt::any) method.
|
pin_project! {
|
||||||
#[derive(Debug)]
|
/// Future for the [`any`](super::StreamExt::any) method.
|
||||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
#[derive(Debug)]
|
||||||
pub struct AnyFuture<'a, St: ?Sized, F> {
|
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||||
stream: &'a mut St,
|
pub struct AnyFuture<'a, St: ?Sized, F> {
|
||||||
f: F,
|
stream: &'a mut St,
|
||||||
|
f: F,
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, St: ?Sized, F> AnyFuture<'a, St, F> {
|
impl<'a, St: ?Sized, F> AnyFuture<'a, St, F> {
|
||||||
pub(super) fn new(stream: &'a mut St, f: F) -> Self {
|
pub(super) fn new(stream: &'a mut St, f: F) -> Self {
|
||||||
Self { stream, f }
|
Self {
|
||||||
|
stream,
|
||||||
|
f,
|
||||||
|
_pin: PhantomPinned,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<St: ?Sized + Unpin, F> Unpin for AnyFuture<'_, St, F> {}
|
|
||||||
|
|
||||||
impl<St, F> Future for AnyFuture<'_, St, F>
|
impl<St, F> Future for AnyFuture<'_, St, F>
|
||||||
where
|
where
|
||||||
St: ?Sized + Stream + Unpin,
|
St: ?Sized + Stream + Unpin,
|
||||||
@@ -27,12 +36,13 @@ where
|
|||||||
{
|
{
|
||||||
type Output = bool;
|
type Output = bool;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
let next = futures_core::ready!(Pin::new(&mut self.stream).poll_next(cx));
|
let me = self.project();
|
||||||
|
let next = futures_core::ready!(Pin::new(me.stream).poll_next(cx));
|
||||||
|
|
||||||
match next {
|
match next {
|
||||||
Some(v) => {
|
Some(v) => {
|
||||||
if (&mut self.f)(v) {
|
if (me.f)(v) {
|
||||||
Poll::Ready(true)
|
Poll::Ready(true)
|
||||||
} else {
|
} else {
|
||||||
cx.waker().wake_by_ref();
|
cx.waker().wake_by_ref();
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use crate::stream::Stream;
|
|||||||
|
|
||||||
use bytes::{Buf, BufMut, Bytes, BytesMut};
|
use bytes::{Buf, BufMut, Bytes, BytesMut};
|
||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
|
use core::marker::PhantomPinned;
|
||||||
use core::mem;
|
use core::mem;
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
@@ -10,7 +11,7 @@ use pin_project_lite::pin_project;
|
|||||||
// Do not export this struct until `FromStream` can be unsealed.
|
// Do not export this struct until `FromStream` can be unsealed.
|
||||||
pin_project! {
|
pin_project! {
|
||||||
/// Future returned by the [`collect`](super::StreamExt::collect) method.
|
/// Future returned by the [`collect`](super::StreamExt::collect) method.
|
||||||
#[must_use = "streams do nothing unless polled"]
|
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Collect<T, U>
|
pub struct Collect<T, U>
|
||||||
where
|
where
|
||||||
@@ -20,6 +21,9 @@ pin_project! {
|
|||||||
#[pin]
|
#[pin]
|
||||||
stream: T,
|
stream: T,
|
||||||
collection: U::InternalCollection,
|
collection: U::InternalCollection,
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +48,11 @@ where
|
|||||||
let (lower, upper) = stream.size_hint();
|
let (lower, upper) = stream.size_hint();
|
||||||
let collection = U::initialize(sealed::Internal, lower, upper);
|
let collection = U::initialize(sealed::Internal, lower, upper);
|
||||||
|
|
||||||
Collect { stream, collection }
|
Collect {
|
||||||
|
stream,
|
||||||
|
collection,
|
||||||
|
_pin: PhantomPinned,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use crate::stream::Stream;
|
use crate::stream::Stream;
|
||||||
|
|
||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
|
use core::marker::PhantomPinned;
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
use pin_project_lite::pin_project;
|
use pin_project_lite::pin_project;
|
||||||
@@ -8,11 +9,15 @@ use pin_project_lite::pin_project;
|
|||||||
pin_project! {
|
pin_project! {
|
||||||
/// Future returned by the [`fold`](super::StreamExt::fold) method.
|
/// Future returned by the [`fold`](super::StreamExt::fold) method.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||||
pub struct FoldFuture<St, B, F> {
|
pub struct FoldFuture<St, B, F> {
|
||||||
#[pin]
|
#[pin]
|
||||||
stream: St,
|
stream: St,
|
||||||
acc: Option<B>,
|
acc: Option<B>,
|
||||||
f: F,
|
f: F,
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,6 +27,7 @@ impl<St, B, F> FoldFuture<St, B, F> {
|
|||||||
stream,
|
stream,
|
||||||
acc: Some(init),
|
acc: Some(init),
|
||||||
f,
|
f,
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -572,6 +572,12 @@ pub trait StreamExt: Stream {
|
|||||||
|
|
||||||
/// Tests if every element of the stream matches a predicate.
|
/// Tests if every element of the stream matches a predicate.
|
||||||
///
|
///
|
||||||
|
/// Equivalent to:
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// async fn all<F>(&mut self, f: F) -> bool;
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
/// `all()` takes a closure that returns `true` or `false`. It applies
|
/// `all()` takes a closure that returns `true` or `false`. It applies
|
||||||
/// this closure to each element of the stream, and if they all return
|
/// this closure to each element of the stream, and if they all return
|
||||||
/// `true`, then so does `all`. If any of them return `false`, it
|
/// `true`, then so does `all`. If any of them return `false`, it
|
||||||
@@ -627,6 +633,12 @@ pub trait StreamExt: Stream {
|
|||||||
|
|
||||||
/// Tests if any element of the stream matches a predicate.
|
/// Tests if any element of the stream matches a predicate.
|
||||||
///
|
///
|
||||||
|
/// Equivalent to:
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// async fn any<F>(&mut self, f: F) -> bool;
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
/// `any()` takes a closure that returns `true` or `false`. It applies
|
/// `any()` takes a closure that returns `true` or `false`. It applies
|
||||||
/// this closure to each element of the stream, and if any of them return
|
/// this closure to each element of the stream, and if any of them return
|
||||||
/// `true`, then so does `any()`. If they all return `false`, it
|
/// `true`, then so does `any()`. If they all return `false`, it
|
||||||
@@ -716,6 +728,12 @@ pub trait StreamExt: Stream {
|
|||||||
/// A combinator that applies a function to every element in a stream
|
/// A combinator that applies a function to every element in a stream
|
||||||
/// producing a single, final value.
|
/// producing a single, final value.
|
||||||
///
|
///
|
||||||
|
/// Equivalent to:
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// async fn fold<B, F>(self, init: B, f: F) -> B;
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
/// Basic usage:
|
/// Basic usage:
|
||||||
/// ```
|
/// ```
|
||||||
@@ -739,6 +757,12 @@ pub trait StreamExt: Stream {
|
|||||||
|
|
||||||
/// Drain stream pushing all emitted values into a collection.
|
/// Drain stream pushing all emitted values into a collection.
|
||||||
///
|
///
|
||||||
|
/// Equivalent to:
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// async fn collect<T>(self) -> T;
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
/// `collect` streams all values, awaiting as needed. Values are pushed into
|
/// `collect` streams all values, awaiting as needed. Values are pushed into
|
||||||
/// a collection. A number of different target collection types are
|
/// a collection. A number of different target collection types are
|
||||||
/// supported, including [`Vec`](std::vec::Vec),
|
/// supported, including [`Vec`](std::vec::Vec),
|
||||||
@@ -871,6 +895,7 @@ pub trait StreamExt: Stream {
|
|||||||
{
|
{
|
||||||
Timeout::new(self, duration)
|
Timeout::new(self, duration)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Slows down a stream by enforcing a delay between items.
|
/// Slows down a stream by enforcing a delay between items.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
|
|||||||
+19
-10
@@ -1,28 +1,37 @@
|
|||||||
use crate::stream::Stream;
|
use crate::stream::Stream;
|
||||||
|
|
||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
|
use core::marker::PhantomPinned;
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
|
|
||||||
/// Future for the [`next`](super::StreamExt::next) method.
|
pin_project! {
|
||||||
#[derive(Debug)]
|
/// Future for the [`next`](super::StreamExt::next) method.
|
||||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
#[derive(Debug)]
|
||||||
pub struct Next<'a, St: ?Sized> {
|
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||||
stream: &'a mut St,
|
pub struct Next<'a, St: ?Sized> {
|
||||||
|
stream: &'a mut St,
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<St: ?Sized + Unpin> Unpin for Next<'_, St> {}
|
|
||||||
|
|
||||||
impl<'a, St: ?Sized> Next<'a, St> {
|
impl<'a, St: ?Sized> Next<'a, St> {
|
||||||
pub(super) fn new(stream: &'a mut St) -> Self {
|
pub(super) fn new(stream: &'a mut St) -> Self {
|
||||||
Next { stream }
|
Next {
|
||||||
|
stream,
|
||||||
|
_pin: PhantomPinned,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<St: ?Sized + Stream + Unpin> Future for Next<'_, St> {
|
impl<St: ?Sized + Stream + Unpin> Future for Next<'_, St> {
|
||||||
type Output = Option<St::Item>;
|
type Output = Option<St::Item>;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
Pin::new(&mut self.stream).poll_next(cx)
|
let me = self.project();
|
||||||
|
Pin::new(me.stream).poll_next(cx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,29 @@
|
|||||||
use crate::stream::{Next, Stream};
|
use crate::stream::{Next, Stream};
|
||||||
|
|
||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
|
use core::marker::PhantomPinned;
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
|
use pin_project_lite::pin_project;
|
||||||
|
|
||||||
/// Future for the [`try_next`](super::StreamExt::try_next) method.
|
pin_project! {
|
||||||
#[derive(Debug)]
|
/// Future for the [`try_next`](super::StreamExt::try_next) method.
|
||||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
#[derive(Debug)]
|
||||||
pub struct TryNext<'a, St: ?Sized> {
|
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||||
inner: Next<'a, St>,
|
pub struct TryNext<'a, St: ?Sized> {
|
||||||
|
#[pin]
|
||||||
|
inner: Next<'a, St>,
|
||||||
|
// Make this future `!Unpin` for compatibility with async trait methods.
|
||||||
|
#[pin]
|
||||||
|
_pin: PhantomPinned,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<St: ?Sized + Unpin> Unpin for TryNext<'_, St> {}
|
|
||||||
|
|
||||||
impl<'a, St: ?Sized> TryNext<'a, St> {
|
impl<'a, St: ?Sized> TryNext<'a, St> {
|
||||||
pub(super) fn new(stream: &'a mut St) -> Self {
|
pub(super) fn new(stream: &'a mut St) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: Next::new(stream),
|
inner: Next::new(stream),
|
||||||
|
_pin: PhantomPinned,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,7 +31,8 @@ impl<'a, St: ?Sized> TryNext<'a, St> {
|
|||||||
impl<T, E, St: ?Sized + Stream<Item = Result<T, E>> + Unpin> Future for TryNext<'_, St> {
|
impl<T, E, St: ?Sized + Stream<Item = Result<T, E>> + Unpin> Future for TryNext<'_, St> {
|
||||||
type Output = Result<Option<T>, E>;
|
type Output = Result<Option<T>, E>;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
Pin::new(&mut self.inner).poll(cx).map(Option::transpose)
|
let me = self.project();
|
||||||
|
me.inner.poll(cx).map(Option::transpose)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user