Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tokio: move I/O helpers to ext traits #1204

Merged
merged 1 commit into from
Jun 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions tokio/src/io/async_read_ext.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use crate::io::copy::{copy, Copy};
use crate::io::read::{read, Read};
use crate::io::read_exact::{read_exact, ReadExact};

use tokio_io::{AsyncRead, AsyncWrite};

/// An extension trait which adds utility methods to `AsyncRead` types.
pub trait AsyncReadExt: AsyncRead {

/// Copy all data from `self` into the provided `AsyncWrite`.
///
/// The returned future will copy all the bytes read from `reader` into the
/// `writer` specified. This future will only complete once the `reader`
/// has hit EOF and all bytes have been written to and flushed from the
/// `writer` provided.
///
/// On success the number of bytes is returned and the `reader` and `writer`
/// are consumed. On error the error is returned and the I/O objects are
/// consumed as well.
///
/// # Examples
///
/// ```
/// unimplemented!();
/// ```
fn copy<'a, W>(&'a mut self, dst: &'a mut W) -> Copy<'a, Self, W>
where
Self: Unpin,
W: AsyncWrite + Unpin + ?Sized,
{
copy(self, dst)
}

/// Read data into the provided buffer.
///
/// The returned future will resolve to the number of bytes read once the
/// read operation is completed.
///
/// # Examples
///
/// ```
/// unimplemented!();
/// ```
fn read<'a>(&'a mut self, dst: &'a mut [u8]) -> Read<'a, Self>
where Self: Unpin,
{
read(self, dst)
}

/// Read exactly the amount of data needed to fill the provided buffer.
///
/// # Examples
///
/// ```
/// unimplemented!();
/// ```
fn read_exact<'a>(&'a mut self, dst: &'a mut [u8]) -> ReadExact<'a, Self>
where Self: Unpin,
{
read_exact(self, dst)
}
}

impl<R: AsyncRead + ?Sized> AsyncReadExt for R {}
24 changes: 24 additions & 0 deletions tokio/src/io/async_write_ext.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use crate::io::write::{write, Write};

use tokio_io::AsyncWrite;

/// An extension trait which adds utility methods to `AsyncWrite` types.
pub trait AsyncWriteExt: AsyncWrite {
/// Write the provided data into `self`.
///
/// The returned future will resolve to the number of bytes written once the
/// write operation is completed.
///
/// # Examples
///
/// ```
/// unimplemented!();
/// ````
fn write<'a>(&'a mut self, src: &'a [u8]) -> Write<'a, Self>
where Self: Unpin,
{
write(self, src)
}
}

impl<W: AsyncWrite + ?Sized> AsyncWriteExt for W {}
38 changes: 6 additions & 32 deletions tokio/src/io/copy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,8 @@ use std::pin::Pin;
use std::task::{Context, Poll};
use tokio_io::{AsyncRead, AsyncWrite};

macro_rules! ready {
($e:expr) => {
match $e {
::std::task::Poll::Ready(t) => t,
::std::task::Poll::Pending => return ::std::task::Poll::Pending,
}
};
}

/// A future which will copy all data from a reader into a writer.
///
/// Created by the [`copy`] function, this future will resolve to the number of
/// bytes copied or an error if one happens.
///
/// [`copy`]: fn.copy.html
#[derive(Debug)]
pub struct Copy<'a, R, W> {
pub struct Copy<'a, R: ?Sized, W: ?Sized> {
reader: &'a mut R,
read_done: bool,
writer: &'a mut W,
Expand All @@ -30,21 +15,10 @@ pub struct Copy<'a, R, W> {
buf: Box<[u8]>,
}

/// Creates a future which represents copying all the bytes from one object to
/// another.
///
/// The returned future will copy all the bytes read from `reader` into the
/// `writer` specified. This future will only complete once the `reader` has hit
/// EOF and all bytes have been written to and flushed from the `writer`
/// provided.
///
/// On success the number of bytes is returned and the `reader` and `writer` are
/// consumed. On error the error is returned and the I/O objects are consumed as
/// well.
pub fn copy<'a, R, W>(reader: &'a mut R, writer: &'a mut W) -> Copy<'a, R, W>
pub(crate) fn copy<'a, R, W>(reader: &'a mut R, writer: &'a mut W) -> Copy<'a, R, W>
where
R: AsyncRead + Unpin,
W: AsyncWrite + Unpin,
R: AsyncRead + Unpin + ?Sized,
W: AsyncWrite + Unpin + ?Sized,
{
Copy {
reader,
Expand All @@ -59,8 +33,8 @@ where

impl<'a, R, W> Future for Copy<'a, R, W>
where
R: AsyncRead + Unpin,
W: AsyncWrite + Unpin,
R: AsyncRead + Unpin + ?Sized,
W: AsyncWrite + Unpin + ?Sized,
{
type Output = io::Result<u64>;

Expand Down
21 changes: 10 additions & 11 deletions tokio/src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,21 @@
//! [`ErrorKind`]: enum.ErrorKind.html
//! [`Result`]: type.Result.html

pub use tokio_io::{AsyncRead, AsyncWrite};
mod async_read_ext;
mod async_write_ext;
mod copy;
mod read;
mod write;
mod read_exact;

pub use self::async_read_ext::AsyncReadExt;
pub use self::async_write_ext::AsyncWriteExt;

// standard input, output, and error
#[cfg(feature = "fs")]
pub use tokio_fs::{stderr, stdin, stdout, Stderr, Stdin, Stdout};
pub use tokio_io::{AsyncRead, AsyncWrite};

// Re-export io::Error so that users don't have to deal
// with conflicts when `use`ing `futures::io` and `std::io`.
pub use std::io::{Error, ErrorKind, Result};

mod copy;
mod read;
mod write;
mod read_exact;

pub use self::copy::{copy, Copy};
pub use self::read::{read, Read};
pub use self::write::{write, Write};
pub use self::read_exact::{read_exact, ReadExact};
2 changes: 1 addition & 1 deletion tokio/src/io/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use tokio_io::AsyncRead;
///
/// The returned future will resolve to both the I/O stream and the buffer
/// as well as the number of bytes read once the read operation is completed.
pub fn read<'a, R>(reader: &'a mut R, buf: &'a mut [u8]) -> Read<'a, R>
pub(crate) fn read<'a, R>(reader: &'a mut R, buf: &'a mut [u8]) -> Read<'a, R>
where
R: AsyncRead + Unpin + ?Sized,
{
Expand Down
12 changes: 1 addition & 11 deletions tokio/src/io/read_exact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,13 @@ use std::pin::Pin;
use std::task::{Context, Poll};
use tokio_io::AsyncRead;

macro_rules! ready {
($e:expr) => {
match $e {
::std::task::Poll::Ready(t) => t,
::std::task::Poll::Pending => return ::std::task::Poll::Pending,
}
};
}


/// A future which can be used to easily read exactly enough bytes to fill
/// a buffer.
///
/// Created by the [`read_exact`] function.
///
/// [`read_exact`]: fn.read_exact.html
pub fn read_exact<'a, A>(reader: &'a mut A, buf: &'a mut[u8]) -> ReadExact<'a, A>
pub(crate) fn read_exact<'a, A>(reader: &'a mut A, buf: &'a mut[u8]) -> ReadExact<'a, A>
where
A: AsyncRead + Unpin + ?Sized
{
Expand Down
2 changes: 1 addition & 1 deletion tokio/src/io/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub struct Write<'a, W: ?Sized> {

/// Tries to write some bytes from the given `buf` to the writer in an
/// asynchronous manner, returning a future.
pub fn write<'a, W>(writer: &'a mut W, buf: &'a [u8]) -> Write<'a, W>
pub(crate) fn write<'a, W>(writer: &'a mut W, buf: &'a [u8]) -> Write<'a, W>
where
W: AsyncWrite + Unpin + ?Sized,
{
Expand Down
9 changes: 9 additions & 0 deletions tokio/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ macro_rules! if_runtime {
)*)
}

macro_rules! ready {
($e:expr) => {
match $e {
::std::task::Poll::Ready(t) => t,
::std::task::Poll::Pending => return ::std::task::Poll::Pending,
}
};
}

#[cfg(feature = "timer")]
pub mod clock;
#[cfg(feature = "codec")]
Expand Down
Loading