Update Tokio to Rust 2018 (#1082)

This commit is contained in:
Carl Lerche
2019-05-14 10:27:36 -07:00
committed by GitHub
parent 79d8820050
commit cb4aea394e
343 changed files with 1725 additions and 2813 deletions
-4
View File
@@ -153,8 +153,6 @@ The type level example for `tokio_timer::Timeout` provides a good example of a
documentation test: documentation test:
``` ```
/// # extern crate futures;
/// # extern crate tokio;
/// // import the `timeout` function, usually this is done /// // import the `timeout` function, usually this is done
/// // with `use tokio::prelude::*` /// // with `use tokio::prelude::*`
/// use tokio::prelude::FutureExt; /// use tokio::prelude::FutureExt;
@@ -192,8 +190,6 @@ If this were a documentation test for the `Timeout::new` function, then the
example would explicitly use `Timeout::new`. For example: example would explicitly use `Timeout::new`. For example:
``` ```
/// # extern crate futures;
/// # extern crate tokio;
/// use tokio::timer::Timeout; /// use tokio::timer::Timeout;
/// use futures::Future; /// use futures::Future;
/// use futures::sync::oneshot; /// use futures::sync::oneshot;
-2
View File
@@ -58,8 +58,6 @@ an asynchronous application.
A basic TCP echo server with Tokio: A basic TCP echo server with Tokio:
```rust ```rust
extern crate tokio;
use tokio::prelude::*; use tokio::prelude::*;
use tokio::io::copy; use tokio::io::copy;
use tokio::net::TcpListener; use tokio::net::TcpListener;
+1 -19
View File
@@ -25,25 +25,7 @@ name = "hyper"
path = "src/hyper.rs" path = "src/hyper.rs"
[dependencies] [dependencies]
tokio = { version = "0.1.18", features = ["async-await-preview"] } tokio = { version = "0.2.0", features = ["async-await-preview"], path = "../tokio" }
futures = "0.1.23" futures = "0.1.23"
bytes = "0.4.9" bytes = "0.4.9"
hyper = "0.12.8" hyper = "0.12.8"
# Avoid using crates.io for Tokio dependencies
[patch.crates-io]
tokio = { path = "../tokio" }
tokio-codec = { path = "../tokio-codec" }
tokio-current-thread = { path = "../tokio-current-thread" }
tokio-executor = { path = "../tokio-executor" }
tokio-fs = { path = "../tokio-fs" }
tokio-futures = { path = "../tokio-futures" }
tokio-io = { path = "../tokio-io" }
tokio-reactor = { path = "../tokio-reactor" }
tokio-signal = { path = "../tokio-signal" }
tokio-tcp = { path = "../tokio-tcp" }
tokio-threadpool = { path = "../tokio-threadpool" }
tokio-timer = { path = "../tokio-timer" }
tokio-tls = { path = "../tokio-tls" }
tokio-udp = { path = "../tokio-udp" }
tokio-uds = { path = "../tokio-uds" }
+7 -7
View File
@@ -1,6 +1,6 @@
#![feature(await_macro, async_await)] #![feature(await_macro, async_await)]
use tokio::await; use tokio::async_wait;
use tokio::codec::{LinesCodec, Decoder}; use tokio::codec::{LinesCodec, Decoder};
use tokio::net::{TcpListener, TcpStream}; use tokio::net::{TcpListener, TcpStream};
use tokio::prelude::*; use tokio::prelude::*;
@@ -33,7 +33,7 @@ async fn process(stream: TcpStream, state: Arc<Mutex<Shared>>) -> io::Result<()>
let mut lines = LinesCodec::new().framed(stream); let mut lines = LinesCodec::new().framed(stream);
// Extract the peer's name // Extract the peer's name
let name = match await!(lines.next()) { let name = match async_wait!(lines.next()) {
Some(name) => name?, Some(name) => name?,
None => { None => {
// Disconnected early // Disconnected early
@@ -56,15 +56,15 @@ async fn process(stream: TcpStream, state: Arc<Mutex<Shared>>) -> io::Result<()>
// Spawn a task that receives all lines broadcasted to us from other peers // Spawn a task that receives all lines broadcasted to us from other peers
// and writes it to the client. // and writes it to the client.
tokio::spawn_async(async move { tokio::spawn_async(async move {
while let Some(line) = await!(rx.next()) { while let Some(line) = async_wait!(rx.next()) {
let line = line.unwrap(); let line = line.unwrap();
await!(lines_tx.send_async(line)).unwrap(); async_wait!(lines_tx.send_async(line)).unwrap();
} }
}); });
// Use the current task to read lines from the socket and broadcast them to // Use the current task to read lines from the socket and broadcast them to
// other peers. // other peers.
while let Some(message) = await!(lines_rx.next()) { while let Some(message) = async_wait!(lines_rx.next()) {
// TODO: Error handling // TODO: Error handling
let message = message.unwrap(); let message = message.unwrap();
@@ -113,7 +113,7 @@ async fn main() {
// Start the Tokio runtime. // Start the Tokio runtime.
let mut incoming = listener.incoming(); let mut incoming = listener.incoming();
while let Some(stream) = await!(incoming.next()) { while let Some(stream) = async_wait!(incoming.next()) {
let stream = match stream { let stream = match stream {
Ok(stream) => stream, Ok(stream) => stream,
Err(_) => continue, Err(_) => continue,
@@ -122,7 +122,7 @@ async fn main() {
let state = state.clone(); let state = state.clone();
tokio::spawn_async(async move { tokio::spawn_async(async move {
if let Err(_) = await!(process(stream, state)) { if let Err(_) = async_wait!(process(stream, state)) {
eprintln!("failed to process connection"); eprintln!("failed to process connection");
} }
}); });
+5 -5
View File
@@ -1,6 +1,6 @@
#![feature(await_macro, async_await)] #![feature(await_macro, async_await)]
use tokio::await; use tokio::async_wait;
use tokio::net::TcpStream; use tokio::net::TcpStream;
use tokio::prelude::*; use tokio::prelude::*;
@@ -14,7 +14,7 @@ const MESSAGES: &[&str] = &[
]; ];
async fn run_client(addr: &SocketAddr) -> io::Result<()> { async fn run_client(addr: &SocketAddr) -> io::Result<()> {
let mut stream = await!(TcpStream::connect(addr))?; let mut stream = async_wait!(TcpStream::connect(addr))?;
// Buffer to read into // Buffer to read into
let mut buf = [0; 128]; let mut buf = [0; 128];
@@ -23,10 +23,10 @@ async fn run_client(addr: &SocketAddr) -> io::Result<()> {
println!(" > write = {:?}", msg); println!(" > write = {:?}", msg);
// Write the message to the server // Write the message to the server
await!(stream.write_all_async(msg.as_bytes()))?; async_wait!(stream.write_all_async(msg.as_bytes()))?;
// Read the message back from the server // Read the message back from the server
await!(stream.read_exact_async(&mut buf[..msg.len()]))?; async_wait!(stream.read_exact_async(&mut buf[..msg.len()]))?;
assert_eq!(&buf[..msg.len()], msg.as_bytes()); assert_eq!(&buf[..msg.len()], msg.as_bytes());
} }
@@ -43,7 +43,7 @@ async fn main() {
// Connect to the echo serveer // Connect to the echo serveer
match await!(run_client(&addr)) { match async_wait!(run_client(&addr)) {
Ok(_) => println!("done."), Ok(_) => println!("done."),
Err(e) => eprintln!("echo client failed; error = {:?}", e), Err(e) => eprintln!("echo client failed; error = {:?}", e),
} }
+4 -4
View File
@@ -1,6 +1,6 @@
#![feature(await_macro, async_await)] #![feature(await_macro, async_await)]
use tokio::await; use tokio::async_wait;
use tokio::net::{TcpListener, TcpStream}; use tokio::net::{TcpListener, TcpStream};
use tokio::prelude::*; use tokio::prelude::*;
@@ -11,11 +11,11 @@ fn handle(mut stream: TcpStream) {
let mut buf = [0; 1024]; let mut buf = [0; 1024];
loop { loop {
match await!(stream.read_async(&mut buf)).unwrap() { match async_wait!(stream.read_async(&mut buf)).unwrap() {
0 => break, // Socket closed 0 => break, // Socket closed
n => { n => {
// Send the data back // Send the data back
await!(stream.write_all_async(&buf[0..n])).unwrap(); async_wait!(stream.write_all_async(&buf[0..n])).unwrap();
} }
} }
} }
@@ -35,7 +35,7 @@ async fn main() {
let mut incoming = listener.incoming(); let mut incoming = listener.incoming();
while let Some(stream) = await!(incoming.next()) { while let Some(stream) = async_wait!(incoming.next()) {
let stream = stream.unwrap(); let stream = stream.unwrap();
handle(stream); handle(stream);
} }
+3 -3
View File
@@ -1,6 +1,6 @@
#![feature(await_macro, async_await)] #![feature(await_macro, async_await)]
use tokio::await; use tokio::async_wait;
use tokio::prelude::*; use tokio::prelude::*;
use hyper::Client; use hyper::Client;
@@ -13,7 +13,7 @@ async fn main() {
let uri = "http://httpbin.org/ip".parse().unwrap(); let uri = "http://httpbin.org/ip".parse().unwrap();
let response = await!({ let response = async_wait!({
client.get(uri) client.get(uri)
.timeout(Duration::from_secs(10)) .timeout(Duration::from_secs(10))
}).unwrap(); }).unwrap();
@@ -22,7 +22,7 @@ async fn main() {
let mut body = response.into_body(); let mut body = response.into_body();
while let Some(chunk) = await!(body.next()) { while let Some(chunk) = async_wait!(body.next()) {
let chunk = chunk.unwrap(); let chunk = chunk.unwrap();
println!("chunk = {}", str::from_utf8(&chunk[..]).unwrap()); println!("chunk = {}", str::from_utf8(&chunk[..]).unwrap());
} }
+2 -2
View File
@@ -1,6 +1,6 @@
#![feature(await_macro, async_await)] #![feature(await_macro, async_await)]
use tokio::await; use tokio::async_wait;
use tokio::timer::Delay; use tokio::timer::Delay;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
@@ -18,5 +18,5 @@ async fn fail_no_async() {
#[tokio::test] #[tokio::test]
async fn use_timer() { async fn use_timer() {
let when = Instant::now() + Duration::from_millis(10); let when = Instant::now() + Duration::from_millis(10);
await!(Delay::new(when)); async_wait!(Delay::new(when));
} }
+6 -2
View File
@@ -1,6 +1,9 @@
trigger: ["master"] trigger: ["master"]
pr: ["master"] pr: ["master"]
variables:
nightly: nightly-2019-05-09
jobs: jobs:
# Check formatting # Check formatting
- template: ci/azure-rustfmt.yml - template: ci/azure-rustfmt.yml
@@ -76,7 +79,7 @@ jobs:
parameters: parameters:
name: test_nightly name: test_nightly
displayName: Test Async / Await displayName: Test Async / Await
rust: nightly-2019-04-25 rust: $(nightly)
# Try cross compiling # Try cross compiling
- template: ci/azure-cross-compile.yml - template: ci/azure-cross-compile.yml
@@ -94,11 +97,12 @@ jobs:
- template: ci/azure-check-minrust.yml - template: ci/azure-check-minrust.yml
parameters: parameters:
name: minrust name: minrust
rust_version: 1.26.0 rust_version: 1.34.0
- template: ci/azure-tsan.yml - template: ci/azure-tsan.yml
parameters: parameters:
name: tsan name: tsan
rust: $(nightly)
- template: ci/azure-deploy-docs.yml - template: ci/azure-deploy-docs.yml
parameters: parameters:
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
steps: steps:
- template: azure-install-rust.yml - template: azure-install-rust.yml
parameters: parameters:
rust_version: nightly-2018-11-18 rust_version: ${{ parameters.rust }}
- template: azure-patch-crates.yml - template: azure-patch-crates.yml
- script: | - script: |
+2
View File
@@ -8,6 +8,8 @@ race:Weak*drop
# `std` mpsc is not used in any Tokio code base. This race is triggered by some # `std` mpsc is not used in any Tokio code base. This race is triggered by some
# rust runtime logic. # rust runtime logic.
race:std*mpsc_queue race:std*mpsc_queue
race:std*lang_start
race:drop*std::thread*
# Probably more fences in std. # Probably more fences in std.
race:__call_tls_dtors race:__call_tls_dtors
+4 -2
View File
@@ -7,8 +7,9 @@ name = "tokio-buf"
# - Cargo.toml # - Cargo.toml
# - README.md # - README.md
# - Update CHANGELOG.md. # - Update CHANGELOG.md.
# - Create "v0.1.x" git tag. # - Create "v0.2.x" git tag.
version = "0.1.1" version = "0.2.0"
edition = "2018"
authors = ["Carl Lerche <[email protected]>"] authors = ["Carl Lerche <[email protected]>"]
license = "MIT" license = "MIT"
repository = "https://github.com/tokio-rs/tokio" repository = "https://github.com/tokio-rs/tokio"
@@ -18,6 +19,7 @@ description = """
Asynchronous stream of byte buffers Asynchronous stream of byte buffers
""" """
categories = ["asynchronous"] categories = ["asynchronous"]
publish = false
[dependencies] [dependencies]
bytes = "0.4.10" bytes = "0.4.10"
+1 -7
View File
@@ -6,19 +6,13 @@ Asynchronous stream of byte buffers
## Usage ## Usage
First, add this to your `Cargo.toml`: Add this to your `Cargo.toml`:
```toml ```toml
[dependencies] [dependencies]
tokio-buf = "0.1.1" tokio-buf = "0.1.1"
``` ```
Next, add this to your crate:
```rust
extern crate tokio_buf;
```
You can find extensive documentation and examples about how to use this crate You can find extensive documentation and examples about how to use this crate
online at [https://tokio.rs](https://tokio.rs). The [API online at [https://tokio.rs](https://tokio.rs). The [API
documentation](https://docs.rs/tokio-buf) is also a great place to get started documentation](https://docs.rs/tokio-buf) is also a great place to get started
+8 -9
View File
@@ -1,6 +1,12 @@
#![doc(html_root_url = "https://docs.rs/tokio-buf/0.1.1")] #![doc(html_root_url = "https://docs.rs/tokio-buf/0.1.1")]
#![deny(missing_docs, missing_debug_implementations, unreachable_pub)] #![deny(
missing_docs,
missing_debug_implementations,
unreachable_pub,
rust_2018_idioms
)]
#![cfg_attr(test, deny(warnings))] #![cfg_attr(test, deny(warnings))]
#![doc(test(no_crate_inject, attr(deny(rust_2018_idioms))))]
//! Asynchronous stream of bytes. //! Asynchronous stream of bytes.
//! //!
@@ -9,13 +15,6 @@
//! instead of yielding arbitrary values, it only yields types that implement //! instead of yielding arbitrary values, it only yields types that implement
//! `Buf` (i.e, byte collections). //! `Buf` (i.e, byte collections).
extern crate bytes;
#[cfg(feature = "util")]
extern crate either;
#[allow(unused)]
#[macro_use]
extern crate futures;
mod never; mod never;
mod size_hint; mod size_hint;
mod str; mod str;
@@ -26,7 +25,7 @@ pub mod util;
pub use self::size_hint::SizeHint; pub use self::size_hint::SizeHint;
#[doc(inline)] #[doc(inline)]
#[cfg(feature = "util")] #[cfg(feature = "util")]
pub use util::BufStreamExt; pub use crate::util::BufStreamExt;
use bytes::Buf; use bytes::Buf;
use futures::Poll; use futures::Poll;
+2 -2
View File
@@ -4,13 +4,13 @@ use std::{error, fmt};
pub enum Never {} pub enum Never {}
impl fmt::Debug for Never { impl fmt::Debug for Never {
fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {} match *self {}
} }
} }
impl fmt::Display for Never { impl fmt::Display for Never {
fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {} match *self {}
} }
} }
+3 -3
View File
@@ -1,6 +1,6 @@
use never::Never; use crate::never::Never;
use BufStream; use crate::BufStream;
use SizeHint; use crate::SizeHint;
use futures::Poll; use futures::Poll;
+2 -2
View File
@@ -1,8 +1,8 @@
use crate::never::Never;
use crate::BufStream;
use bytes::{Bytes, BytesMut}; use bytes::{Bytes, BytesMut};
use futures::Poll; use futures::Poll;
use never::Never;
use std::io; use std::io;
use BufStream;
impl BufStream for Vec<u8> { impl BufStream for Vec<u8> {
type Item = io::Cursor<Vec<u8>>; type Item = io::Cursor<Vec<u8>>;
+2 -2
View File
@@ -1,7 +1,7 @@
use BufStream; use crate::BufStream;
use either::Either; use either::Either;
use futures::Poll; use futures::{try_ready, Poll};
/// A buf stream that sequences two buf streams together. /// A buf stream that sequences two buf streams together.
/// ///
+2 -2
View File
@@ -1,7 +1,7 @@
use super::FromBufStream; use super::FromBufStream;
use BufStream; use crate::BufStream;
use futures::{Future, Poll}; use futures::{try_ready, Future, Poll};
/// Consumes a buf stream, collecting the data into a single byte container. /// Consumes a buf stream, collecting the data into a single byte container.
/// ///
+3 -3
View File
@@ -1,4 +1,4 @@
use SizeHint; use crate::SizeHint;
use bytes::{Buf, BufMut, Bytes}; use bytes::{Buf, BufMut, Bytes};
@@ -138,7 +138,7 @@ impl<T: Buf> FromBufStream<T> for Bytes {
} }
impl fmt::Display for CollectVecError { impl fmt::Display for CollectVecError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "BufStream is too big") write!(fmt, "BufStream is too big")
} }
} }
@@ -150,7 +150,7 @@ impl Error for CollectVecError {
} }
impl fmt::Display for CollectBytesError { impl fmt::Display for CollectBytesError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "BufStream too big") write!(fmt, "BufStream too big")
} }
} }
+2 -2
View File
@@ -1,8 +1,8 @@
use crate::BufStream;
use bytes::Buf; use bytes::Buf;
use futures::Poll; use futures::Poll;
use std::error::Error; use std::error::Error;
use std::fmt; use std::fmt;
use BufStream;
/// Converts an `Iterator` into a `BufStream` which is always ready to yield the /// Converts an `Iterator` into a `BufStream` which is always ready to yield the
/// next value. /// next value.
@@ -42,7 +42,7 @@ where
} }
impl fmt::Display for Never { impl fmt::Display for Never {
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
unreachable!(); unreachable!();
} }
} }
+1 -1
View File
@@ -1,4 +1,4 @@
use BufStream; use crate::BufStream;
use bytes::Buf; use bytes::Buf;
use futures::Poll; use futures::Poll;
+1 -1
View File
@@ -22,7 +22,7 @@ pub mod error {
pub use super::limit::LimitError; pub use super::limit::LimitError;
} }
use BufStream; use crate::BufStream;
impl<T> BufStreamExt for T where T: BufStream {} impl<T> BufStreamExt for T where T: BufStream {}
+1 -1
View File
@@ -1,6 +1,6 @@
use crate::BufStream;
use bytes::Buf; use bytes::Buf;
use futures::{Async, Poll, Stream}; use futures::{Async, Poll, Stream};
use BufStream;
/// Converts a `Stream` of `Buf` types into a `BufStream`. /// Converts a `Stream` of `Buf` types into a `BufStream`.
/// ///
+1 -3
View File
@@ -1,7 +1,5 @@
extern crate tokio_buf;
use tokio_buf::BufStream; use tokio_buf::BufStream;
// Ensures that `BufStream` can be a trait object // Ensures that `BufStream` can be a trait object
#[allow(dead_code)] #[allow(dead_code)]
fn obj(_: &mut BufStream<Item = u32, Error = ()>) {} fn obj(_: &mut dyn BufStream<Item = u32, Error = ()>) {}
-6
View File
@@ -1,15 +1,9 @@
#![cfg(feature = "util")] #![cfg(feature = "util")]
extern crate bytes;
extern crate futures;
extern crate tokio_buf;
use futures::Async::*; use futures::Async::*;
use tokio_buf::{BufStream, BufStreamExt}; use tokio_buf::{BufStream, BufStreamExt};
#[macro_use]
mod support; mod support;
use support::*; use support::*;
#[test] #[test]
-6
View File
@@ -1,16 +1,10 @@
#![cfg(feature = "util")] #![cfg(feature = "util")]
extern crate bytes;
extern crate futures;
extern crate tokio_buf;
use bytes::Bytes; use bytes::Bytes;
use futures::Future; use futures::Future;
use tokio_buf::BufStreamExt; use tokio_buf::BufStreamExt;
#[macro_use]
mod support; mod support;
use support::*; use support::*;
macro_rules! test_collect_impl { macro_rules! test_collect_impl {
-5
View File
@@ -1,12 +1,7 @@
extern crate bytes;
extern crate futures;
extern crate tokio_buf;
use futures::Async::*; use futures::Async::*;
use std::io::Cursor; use std::io::Cursor;
use tokio_buf::{util, BufStream}; use tokio_buf::{util, BufStream};
#[macro_use]
mod support; mod support;
type Buf = Cursor<&'static [u8]>; type Buf = Cursor<&'static [u8]>;
-6
View File
@@ -1,16 +1,10 @@
#![cfg(feature = "util")] #![cfg(feature = "util")]
extern crate bytes;
extern crate futures;
extern crate tokio_buf;
use futures::Async::*; use futures::Async::*;
use futures::Future; use futures::Future;
use tokio_buf::{BufStream, BufStreamExt}; use tokio_buf::{BufStream, BufStreamExt};
#[macro_use]
mod support; mod support;
use support::*; use support::*;
#[test] #[test]
-2
View File
@@ -1,5 +1,3 @@
extern crate tokio_buf;
use tokio_buf::SizeHint; use tokio_buf::SizeHint;
#[test] #[test]
-6
View File
@@ -1,15 +1,9 @@
extern crate bytes;
extern crate futures;
extern crate tokio_buf;
extern crate tokio_mock_task;
use futures::sync::mpsc; use futures::sync::mpsc;
use futures::Async::*; use futures::Async::*;
use std::io::Cursor; use std::io::Cursor;
use tokio_buf::{util, BufStream}; use tokio_buf::{util, BufStream};
use tokio_mock_task::MockTask; use tokio_mock_task::MockTask;
#[macro_use]
mod support; mod support;
type Buf = Cursor<&'static [u8]>; type Buf = Cursor<&'static [u8]>;
-5
View File
@@ -1,12 +1,7 @@
extern crate bytes;
extern crate futures;
extern crate tokio_buf;
use futures::Async::*; use futures::Async::*;
use std::fmt; use std::fmt;
use tokio_buf::BufStream; use tokio_buf::BufStream;
#[macro_use]
mod support; mod support;
fn test_hello_world<B>(mut bs: B) fn test_hello_world<B>(mut bs: B)
+3 -4
View File
@@ -1,9 +1,5 @@
#![allow(unused)] #![allow(unused)]
extern crate bytes;
extern crate futures;
extern crate tokio_buf;
use bytes::Buf; use bytes::Buf;
use futures::Async::*; use futures::Async::*;
use futures::Poll; use futures::Poll;
@@ -12,6 +8,7 @@ use tokio_buf::{BufStream, SizeHint};
use std::collections::VecDeque; use std::collections::VecDeque;
use std::io::Cursor; use std::io::Cursor;
#[macro_export]
macro_rules! assert_buf_eq { macro_rules! assert_buf_eq {
($actual:expr, $expect:expr) => {{ ($actual:expr, $expect:expr) => {{
use bytes::Buf; use bytes::Buf;
@@ -27,6 +24,7 @@ macro_rules! assert_buf_eq {
}}; }};
} }
#[macro_export]
macro_rules! assert_none { macro_rules! assert_none {
($actual:expr) => { ($actual:expr) => {
match $actual { match $actual {
@@ -36,6 +34,7 @@ macro_rules! assert_none {
}; };
} }
#[macro_export]
macro_rules! assert_not_ready { macro_rules! assert_not_ready {
($actual:expr) => { ($actual:expr) => {
match $actual { match $actual {
+5 -3
View File
@@ -7,8 +7,9 @@ name = "tokio-codec"
# - Cargo.toml # - Cargo.toml
# - README.md # - README.md
# - Update CHANGELOG.md. # - Update CHANGELOG.md.
# - Create "v0.1.x" git tag. # - Create "v0.2.x" git tag.
version = "0.1.1" version = "0.2.0"
edition = "2018"
authors = ["Carl Lerche <[email protected]>", "Bryan Burgers <[email protected]>"] authors = ["Carl Lerche <[email protected]>", "Bryan Burgers <[email protected]>"]
license = "MIT" license = "MIT"
repository = "https://github.com/tokio-rs/tokio" repository = "https://github.com/tokio-rs/tokio"
@@ -18,8 +19,9 @@ description = """
Utilities for encoding and decoding frames. Utilities for encoding and decoding frames.
""" """
categories = ["asynchronous"] categories = ["asynchronous"]
publish = false
[dependencies] [dependencies]
tokio-io = "0.1.7" tokio-io = { version = "0.2.0", path = "../tokio-io" }
bytes = "0.4.7" bytes = "0.4.7"
futures = "0.1.18" futures = "0.1.18"
-15
View File
@@ -4,21 +4,6 @@ Utilities for encoding and decoding frames.
[Documentation](https://docs.rs/tokio-codec) [Documentation](https://docs.rs/tokio-codec)
## Usage
First, add this to your `Cargo.toml`:
```toml
[dependencies]
tokio-codec = "0.1"
```
Next, add this to your crate:
```rust
extern crate tokio_codec;
```
You can find extensive documentation and examples about how to use this crate You can find extensive documentation and examples about how to use this crate
online at [https://tokio.rs](https://tokio.rs). The [API online at [https://tokio.rs](https://tokio.rs). The [API
documentation](https://docs.rs/tokio-codec) is also a great place to get started documentation](https://docs.rs/tokio-codec) is also a great place to get started
+5 -7
View File
@@ -1,5 +1,7 @@
#![deny(missing_docs, missing_debug_implementations, warnings)]
#![doc(html_root_url = "https://docs.rs/tokio-codec/0.1.1")] #![doc(html_root_url = "https://docs.rs/tokio-codec/0.1.1")]
#![deny(missing_docs, missing_debug_implementations, rust_2018_idioms)]
#![cfg_attr(test, deny(warnings))]
#![doc(test(no_crate_inject, attr(deny(rust_2018_idioms))))]
//! Utilities for encoding and decoding frames. //! Utilities for encoding and decoding frames.
//! //!
@@ -13,13 +15,9 @@
//! [`Stream`]: # //! [`Stream`]: #
//! [transports]: # //! [transports]: #
extern crate bytes;
extern crate tokio_io;
mod bytes_codec; mod bytes_codec;
mod lines_codec; mod lines_codec;
pub use crate::bytes_codec::BytesCodec;
pub use crate::lines_codec::LinesCodec;
pub use tokio_io::_tokio_codec::{Decoder, Encoder, Framed, FramedParts, FramedRead, FramedWrite}; pub use tokio_io::_tokio_codec::{Decoder, Encoder, Framed, FramedParts, FramedRead, FramedWrite};
pub use bytes_codec::BytesCodec;
pub use lines_codec::LinesCodec;
+1 -2
View File
@@ -1,5 +1,4 @@
extern crate bytes; #![deny(warnings, rust_2018_idioms)]
extern crate tokio_codec;
use bytes::{BufMut, Bytes, BytesMut}; use bytes::{BufMut, Bytes, BytesMut};
use tokio_codec::{BytesCodec, Decoder, Encoder, LinesCodec}; use tokio_codec::{BytesCodec, Decoder, Encoder, LinesCodec};
+1 -4
View File
@@ -1,7 +1,4 @@
extern crate bytes; #![deny(warnings, rust_2018_idioms)]
extern crate futures;
extern crate tokio_codec;
extern crate tokio_io;
use bytes::{Buf, BufMut, BytesMut, IntoBuf}; use bytes::{Buf, BufMut, BytesMut, IntoBuf};
use futures::{Future, Stream}; use futures::{Future, Stream};
+3 -8
View File
@@ -1,17 +1,12 @@
extern crate bytes; #![deny(warnings, rust_2018_idioms)]
extern crate futures;
extern crate tokio_codec;
extern crate tokio_io;
use tokio_codec::{Decoder, FramedRead};
use tokio_io::AsyncRead;
use bytes::{Buf, BytesMut, IntoBuf}; use bytes::{Buf, BytesMut, IntoBuf};
use futures::Async::{NotReady, Ready}; use futures::Async::{NotReady, Ready};
use futures::Stream; use futures::Stream;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::io::{self, Read}; use std::io::{self, Read};
use tokio_codec::{Decoder, FramedRead};
use tokio_io::AsyncRead;
macro_rules! mock { macro_rules! mock {
($($x:expr,)*) => {{ ($($x:expr,)*) => {{
+3 -8
View File
@@ -1,16 +1,11 @@
extern crate bytes; #![deny(warnings, rust_2018_idioms)]
extern crate futures;
extern crate tokio_codec;
extern crate tokio_io;
use tokio_codec::{Encoder, FramedWrite};
use tokio_io::AsyncWrite;
use bytes::{BufMut, BytesMut}; use bytes::{BufMut, BytesMut};
use futures::{Poll, Sink}; use futures::{Poll, Sink};
use std::collections::VecDeque; use std::collections::VecDeque;
use std::io::{self, Write}; use std::io::{self, Write};
use tokio_codec::{Encoder, FramedWrite};
use tokio_io::AsyncWrite;
macro_rules! mock { macro_rules! mock {
($($x:expr,)*) => {{ ($($x:expr,)*) => {{
+5 -3
View File
@@ -7,8 +7,9 @@ name = "tokio-current-thread"
# - Cargo.toml # - Cargo.toml
# - README.md # - README.md
# - Update CHANGELOG.md. # - Update CHANGELOG.md.
# - Create "v0.1.x" git tag. # - Create "v0.2.x" git tag.
version = "0.1.6" version = "0.2.0"
edition = "2018"
documentation = "https://docs.rs/tokio-current-thread/0.1.6/tokio_current_thread" documentation = "https://docs.rs/tokio-current-thread/0.1.6/tokio_current_thread"
repository = "https://github.com/tokio-rs/tokio" repository = "https://github.com/tokio-rs/tokio"
homepage = "https://github.com/tokio-rs/tokio" homepage = "https://github.com/tokio-rs/tokio"
@@ -19,7 +20,8 @@ Single threaded executor which manage many tasks concurrently on the current thr
""" """
keywords = ["futures", "tokio"] keywords = ["futures", "tokio"]
categories = ["concurrency", "asynchronous"] categories = ["concurrency", "asynchronous"]
publish = false
[dependencies] [dependencies]
tokio-executor = "0.1.7" tokio-executor = { version = "0.2.0", path = "../tokio-executor" }
futures = "0.1.19" futures = "0.1.19"
+35 -31
View File
@@ -1,5 +1,7 @@
#![doc(html_root_url = "https://docs.rs/tokio-current-thread/0.1.6")] #![doc(html_root_url = "https://docs.rs/tokio-current-thread/0.1.6")]
#![deny(warnings, missing_docs, missing_debug_implementations)] #![deny(missing_docs, missing_debug_implementations, rust_2018_idioms)]
#![cfg_attr(test, deny(warnings))]
#![doc(test(no_crate_inject, attr(deny(rust_2018_idioms))))]
//! A single-threaded executor which executes tasks on the same thread from which //! A single-threaded executor which executes tasks on the same thread from which
//! they are spawned. //! they are spawned.
@@ -25,19 +27,11 @@
//! [`block_on_all`]: fn.block_on_all.html //! [`block_on_all`]: fn.block_on_all.html
//! [executor module]: https://docs.rs/tokio/0.1/tokio/executor/index.html //! [executor module]: https://docs.rs/tokio/0.1/tokio/executor/index.html
extern crate futures;
extern crate tokio_executor;
mod scheduler; mod scheduler;
use self::scheduler::Scheduler; use crate::scheduler::Scheduler;
use tokio_executor::park::{Park, ParkThread, Unpark};
use tokio_executor::{Enter, SpawnError};
use futures::future::{ExecuteError, ExecuteErrorKind, Executor}; use futures::future::{ExecuteError, ExecuteErrorKind, Executor};
use futures::{executor, Async, Future}; use futures::{executor, Async, Future};
use std::cell::Cell; use std::cell::Cell;
use std::error::Error; use std::error::Error;
use std::fmt; use std::fmt;
@@ -45,6 +39,8 @@ use std::rc::Rc;
use std::sync::{atomic, mpsc, Arc}; use std::sync::{atomic, mpsc, Arc};
use std::thread; use std::thread;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use tokio_executor::park::{Park, ParkThread, Unpark};
use tokio_executor::{Enter, SpawnError};
/// Executes tasks on the current thread /// Executes tasks on the current thread
pub struct CurrentThread<P: Park = ParkThread> { pub struct CurrentThread<P: Park = ParkThread> {
@@ -64,7 +60,7 @@ pub struct CurrentThread<P: Park = ParkThread> {
spawn_handle: Handle, spawn_handle: Handle,
/// Receiver for futures spawned from other threads /// Receiver for futures spawned from other threads
spawn_receiver: mpsc::Receiver<Box<Future<Item = (), Error = ()> + Send + 'static>>, spawn_receiver: mpsc::Receiver<Box<dyn Future<Item = (), Error = ()> + Send + 'static>>,
/// The thread-local ID assigned to this executor. /// The thread-local ID assigned to this executor.
id: u64, id: u64,
@@ -97,7 +93,7 @@ impl Turn {
} }
/// A `CurrentThread` instance bound to a supplied execution context. /// A `CurrentThread` instance bound to a supplied execution context.
pub struct Entered<'a, P: Park + 'a> { pub struct Entered<'a, P: Park> {
executor: &'a mut CurrentThread<P>, executor: &'a mut CurrentThread<P>,
enter: &'a mut Enter, enter: &'a mut Enter,
} }
@@ -109,7 +105,7 @@ pub struct RunError {
} }
impl fmt::Display for RunError { impl fmt::Display for RunError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "{}", self.description()) write!(fmt, "{}", self.description())
} }
} }
@@ -127,7 +123,7 @@ pub struct RunTimeoutError {
} }
impl fmt::Display for RunTimeoutError { impl fmt::Display for RunTimeoutError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "{}", self.description()) write!(fmt, "{}", self.description())
} }
} }
@@ -149,7 +145,7 @@ pub struct TurnError {
} }
impl fmt::Display for TurnError { impl fmt::Display for TurnError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "{}", self.description()) write!(fmt, "{}", self.description())
} }
} }
@@ -167,7 +163,7 @@ pub struct BlockError<T> {
} }
impl<T> fmt::Display for BlockError<T> { impl<T> fmt::Display for BlockError<T> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "Block error") write!(fmt, "Block error")
} }
} }
@@ -179,18 +175,22 @@ impl<T: fmt::Debug> Error for BlockError<T> {
} }
/// This is mostly split out to make the borrow checker happy. /// This is mostly split out to make the borrow checker happy.
struct Borrow<'a, U: 'a> { struct Borrow<'a, U> {
id: u64, id: u64,
scheduler: &'a mut Scheduler<U>, scheduler: &'a mut Scheduler<U>,
num_futures: &'a atomic::AtomicUsize, num_futures: &'a atomic::AtomicUsize,
} }
trait SpawnLocal { trait SpawnLocal {
fn spawn_local(&mut self, future: Box<Future<Item = (), Error = ()>>, already_counted: bool); fn spawn_local(
&mut self,
future: Box<dyn Future<Item = (), Error = ()>>,
already_counted: bool,
);
} }
struct CurrentRunner { struct CurrentRunner {
spawn: Cell<Option<*mut SpawnLocal>>, spawn: Cell<Option<*mut dyn SpawnLocal>>,
id: Cell<Option<u64>>, id: Cell<Option<u64>>,
} }
@@ -386,7 +386,7 @@ impl<P: Park> CurrentThread<P> {
&mut self.park &mut self.park
} }
fn borrow(&mut self) -> Borrow<P::Unpark> { fn borrow(&mut self) -> Borrow<'_, P::Unpark> {
Borrow { Borrow {
id: self.id, id: self.id,
scheduler: &mut self.scheduler, scheduler: &mut self.scheduler,
@@ -424,7 +424,7 @@ impl<P: Park> Drop for CurrentThread<P> {
impl tokio_executor::Executor for CurrentThread { impl tokio_executor::Executor for CurrentThread {
fn spawn( fn spawn(
&mut self, &mut self,
future: Box<Future<Item = (), Error = ()> + Send>, future: Box<dyn Future<Item = (), Error = ()> + Send>,
) -> Result<(), SpawnError> { ) -> Result<(), SpawnError> {
self.borrow().spawn_local(future, false); self.borrow().spawn_local(future, false);
Ok(()) Ok(())
@@ -442,7 +442,7 @@ where
} }
impl<P: Park> fmt::Debug for CurrentThread<P> { impl<P: Park> fmt::Debug for CurrentThread<P> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("CurrentThread") fmt.debug_struct("CurrentThread")
.field("scheduler", &self.scheduler) .field("scheduler", &self.scheduler)
.field( .field(
@@ -616,7 +616,7 @@ impl<'a, P: Park> Entered<'a, P> {
} }
impl<'a, P: Park> fmt::Debug for Entered<'a, P> { impl<'a, P: Park> fmt::Debug for Entered<'a, P> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("Entered") fmt.debug_struct("Entered")
.field("executor", &self.executor) .field("executor", &self.executor)
.field("enter", &self.enter) .field("enter", &self.enter)
@@ -629,7 +629,7 @@ impl<'a, P: Park> fmt::Debug for Entered<'a, P> {
/// Handle to spawn a future on the corresponding `CurrentThread` instance /// Handle to spawn a future on the corresponding `CurrentThread` instance
#[derive(Clone)] #[derive(Clone)]
pub struct Handle { pub struct Handle {
sender: mpsc::Sender<Box<Future<Item = (), Error = ()> + Send + 'static>>, sender: mpsc::Sender<Box<dyn Future<Item = (), Error = ()> + Send + 'static>>,
num_futures: Arc<atomic::AtomicUsize>, num_futures: Arc<atomic::AtomicUsize>,
shut_down: Cell<bool>, shut_down: Cell<bool>,
notify: executor::NotifyHandle, notify: executor::NotifyHandle,
@@ -641,7 +641,7 @@ pub struct Handle {
// Manual implementation because the Sender does not implement Debug // Manual implementation because the Sender does not implement Debug
impl fmt::Debug for Handle { impl fmt::Debug for Handle {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("Handle") fmt.debug_struct("Handle")
.field("shut_down", &self.shut_down.get()) .field("shut_down", &self.shut_down.get())
.finish() .finish()
@@ -731,7 +731,7 @@ impl TaskExecutor {
/// Spawn a future onto the current `CurrentThread` instance. /// Spawn a future onto the current `CurrentThread` instance.
pub fn spawn_local( pub fn spawn_local(
&mut self, &mut self,
future: Box<Future<Item = (), Error = ()>>, future: Box<dyn Future<Item = (), Error = ()>>,
) -> Result<(), SpawnError> { ) -> Result<(), SpawnError> {
CURRENT.with(|current| match current.spawn.get() { CURRENT.with(|current| match current.spawn.get() {
Some(spawn) => { Some(spawn) => {
@@ -746,7 +746,7 @@ impl TaskExecutor {
impl tokio_executor::Executor for TaskExecutor { impl tokio_executor::Executor for TaskExecutor {
fn spawn( fn spawn(
&mut self, &mut self,
future: Box<Future<Item = (), Error = ()> + Send>, future: Box<dyn Future<Item = (), Error = ()> + Send>,
) -> Result<(), SpawnError> { ) -> Result<(), SpawnError> {
self.spawn_local(future) self.spawn_local(future)
} }
@@ -791,7 +791,11 @@ impl<'a, U: Unpark> Borrow<'a, U> {
} }
impl<'a, U: Unpark> SpawnLocal for Borrow<'a, U> { impl<'a, U: Unpark> SpawnLocal for Borrow<'a, U> {
fn spawn_local(&mut self, future: Box<Future<Item = (), Error = ()>>, already_counted: bool) { fn spawn_local(
&mut self,
future: Box<dyn Future<Item = (), Error = ()>>,
already_counted: bool,
) {
if !already_counted { if !already_counted {
// NOTE: we have a borrow of the Runtime, so we know that it isn't shut down. // NOTE: we have a borrow of the Runtime, so we know that it isn't shut down.
// NOTE: += 2 since LSB is the shutdown bit // NOTE: += 2 since LSB is the shutdown bit
@@ -804,7 +808,7 @@ impl<'a, U: Unpark> SpawnLocal for Borrow<'a, U> {
// ===== impl CurrentRunner ===== // ===== impl CurrentRunner =====
impl CurrentRunner { impl CurrentRunner {
fn set_spawn<F, R>(&self, spawn: &mut SpawnLocal, f: F) -> R fn set_spawn<F, R>(&self, spawn: &mut dyn SpawnLocal, f: F) -> R
where where
F: FnOnce() -> R, F: FnOnce() -> R,
{ {
@@ -819,14 +823,14 @@ impl CurrentRunner {
let _reset = Reset(self); let _reset = Reset(self);
let spawn = unsafe { hide_lt(spawn as *mut SpawnLocal) }; let spawn = unsafe { hide_lt(spawn as *mut dyn SpawnLocal) };
self.spawn.set(Some(spawn)); self.spawn.set(Some(spawn));
f() f()
} }
} }
unsafe fn hide_lt<'a>(p: *mut (SpawnLocal + 'a)) -> *mut (SpawnLocal + 'static) { unsafe fn hide_lt<'a>(p: *mut (dyn SpawnLocal + 'a)) -> *mut (dyn SpawnLocal + 'static) {
use std::mem; use std::mem;
mem::transmute(p) mem::transmute(p)
} }
+14 -16
View File
@@ -1,10 +1,6 @@
use super::Borrow; use crate::Borrow;
use tokio_executor::park::Unpark;
use tokio_executor::Enter;
use futures::executor::{self, NotifyHandle, Spawn, UnsafeNotify}; use futures::executor::{self, NotifyHandle, Spawn, UnsafeNotify};
use futures::{Async, Future}; use futures::{Async, Future};
use std::cell::UnsafeCell; use std::cell::UnsafeCell;
use std::fmt::{self, Debug}; use std::fmt::{self, Debug};
use std::marker::PhantomData; use std::marker::PhantomData;
@@ -15,6 +11,8 @@ use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicUsize};
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use std::thread; use std::thread;
use std::usize; use std::usize;
use tokio_executor::park::Unpark;
use tokio_executor::Enter;
/// A generic task-aware scheduler. /// A generic task-aware scheduler.
/// ///
@@ -24,7 +22,7 @@ pub struct Scheduler<U> {
nodes: List<U>, nodes: List<U>,
} }
pub struct Notify<'a, U: 'a>(&'a Arc<Node<U>>); pub struct Notify<'a, U>(&'a Arc<Node<U>>);
// A linked-list of nodes // A linked-list of nodes
struct List<U> { struct List<U> {
@@ -125,10 +123,10 @@ enum Dequeue<U> {
} }
/// Wraps a spawned boxed future /// Wraps a spawned boxed future
struct Task(Spawn<Box<Future<Item = (), Error = ()>>>); struct Task(Spawn<Box<dyn Future<Item = (), Error = ()>>>);
/// A task that is scheduled. `turn` must be called /// A task that is scheduled. `turn` must be called
pub struct Scheduled<'a, U: 'a> { pub struct Scheduled<'a, U> {
task: &'a mut Task, task: &'a mut Task,
notify: &'a Notify<'a, U>, notify: &'a Notify<'a, U>,
done: &'a mut bool, done: &'a mut bool,
@@ -171,7 +169,7 @@ where
self.inner.clone().into() self.inner.clone().into()
} }
pub fn schedule(&mut self, item: Box<Future<Item = (), Error = ()>>) { pub fn schedule(&mut self, item: Box<dyn Future<Item = (), Error = ()>>) {
// Get the current scheduler tick // Get the current scheduler tick
let tick_num = self.inner.tick_num.load(SeqCst); let tick_num = self.inner.tick_num.load(SeqCst);
@@ -259,7 +257,7 @@ where
// assume is is complete (will return Ready or panic), in // assume is is complete (will return Ready or panic), in
// which case we'll want to discard it regardless. // which case we'll want to discard it regardless.
// //
struct Bomb<'a, U: Unpark + 'a> { struct Bomb<'a, U: Unpark> {
borrow: &'a mut Borrow<'a, U>, borrow: &'a mut Borrow<'a, U>,
enter: &'a mut Enter, enter: &'a mut Enter,
node: Option<Arc<Node<U>>>, node: Option<Arc<Node<U>>>,
@@ -359,13 +357,13 @@ impl<'a, U: Unpark> Scheduled<'a, U> {
} }
impl Task { impl Task {
pub fn new(future: Box<Future<Item = (), Error = ()> + 'static>) -> Self { pub fn new(future: Box<dyn Future<Item = (), Error = ()> + 'static>) -> Self {
Task(executor::spawn(future)) Task(executor::spawn(future))
} }
} }
impl fmt::Debug for Task { impl fmt::Debug for Task {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("Task").finish() fmt.debug_struct("Task").finish()
} }
} }
@@ -399,7 +397,7 @@ fn release_node<U>(node: Arc<Node<U>>) {
} }
impl<U> Debug for Scheduler<U> { impl<U> Debug for Scheduler<U> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "Scheduler {{ ... }}") write!(fmt, "Scheduler {{ ... }}")
} }
} }
@@ -639,7 +637,7 @@ impl<'a, U> Clone for Notify<'a, U> {
} }
impl<'a, U> fmt::Debug for Notify<'a, U> { impl<'a, U> fmt::Debug for Notify<'a, U> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("Notify").finish() fmt.debug_struct("Notify").finish()
} }
} }
@@ -687,8 +685,8 @@ unsafe impl<U: Unpark> UnsafeNotify for ArcNode<U> {
} }
} }
unsafe fn hide_lt<U: Unpark>(p: *mut ArcNode<U>) -> *mut UnsafeNotify { unsafe fn hide_lt<U: Unpark>(p: *mut ArcNode<U>) -> *mut dyn UnsafeNotify {
mem::transmute(p as *mut UnsafeNotify) mem::transmute(p as *mut dyn UnsafeNotify)
} }
impl<U: Unpark> Node<U> { impl<U: Unpark> Node<U> {
+22 -26
View File
@@ -1,28 +1,24 @@
extern crate futures; #![deny(warnings, rust_2018_idioms)]
extern crate tokio_current_thread;
extern crate tokio_executor;
use tokio_current_thread::{block_on_all, CurrentThread};
use futures::future::{self, lazy};
// This is not actually unused --- we need this trait to be in scope for
// the tests that sue TaskExecutor::current().execute(). The compiler
// doesn't realise that.
#[allow(unused_imports)]
use futures::future::Executor;
use futures::prelude::*;
use futures::sync::oneshot;
use futures::task;
use std::any::Any; use std::any::Any;
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::rc::Rc; use std::rc::Rc;
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
use tokio_current_thread::{block_on_all, CurrentThread};
use futures::future::{self, lazy};
use futures::task;
// This is not actually unused --- we need this trait to be in scope for
// the tests that sue TaskExecutor::current().execute(). The compiler
// doesn't realise that.
#[allow(unused_imports)]
use futures::future::Executor as _futures_Executor;
use futures::prelude::*;
use futures::sync::oneshot;
mod from_block_on_all { mod from_block_on_all {
use super::*; use super::*;
fn test<F: Fn(Box<Future<Item = (), Error = ()>>) + 'static>(spawn: F) { fn test<F: Fn(Box<dyn Future<Item = (), Error = ()>>) + 'static>(spawn: F) {
let cnt = Rc::new(Cell::new(0)); let cnt = Rc::new(Cell::new(0));
let c = cnt.clone(); let c = cnt.clone();
@@ -102,7 +98,7 @@ fn spawn_many() {
mod does_not_set_global_executor_by_default { mod does_not_set_global_executor_by_default {
use super::*; use super::*;
fn test<F: Fn(Box<Future<Item = (), Error = ()> + Send>) -> Result<(), E> + 'static, E>( fn test<F: Fn(Box<dyn Future<Item = (), Error = ()> + Send>) -> Result<(), E> + 'static, E>(
spawn: F, spawn: F,
) { ) {
block_on_all(lazy(|| { block_on_all(lazy(|| {
@@ -127,7 +123,7 @@ mod does_not_set_global_executor_by_default {
mod from_block_on_future { mod from_block_on_future {
use super::*; use super::*;
fn test<F: Fn(Box<Future<Item = (), Error = ()>>)>(spawn: F) { fn test<F: Fn(Box<dyn Future<Item = (), Error = ()>>)>(spawn: F) {
let cnt = Rc::new(Cell::new(0)); let cnt = Rc::new(Cell::new(0));
let mut tokio_current_thread = CurrentThread::new(); let mut tokio_current_thread = CurrentThread::new();
@@ -181,8 +177,8 @@ mod outstanding_tasks_are_dropped_when_executor_is_dropped {
fn test<F, G>(spawn: F, dotspawn: G) fn test<F, G>(spawn: F, dotspawn: G)
where where
F: Fn(Box<Future<Item = (), Error = ()>>) + 'static, F: Fn(Box<dyn Future<Item = (), Error = ()>>) + 'static,
G: Fn(&mut CurrentThread, Box<Future<Item = (), Error = ()>>), G: Fn(&mut CurrentThread, Box<dyn Future<Item = (), Error = ()>>),
{ {
let mut rc = Rc::new(()); let mut rc = Rc::new(());
@@ -383,8 +379,8 @@ mod and_turn {
fn test<F, G>(spawn: F, dotspawn: G) fn test<F, G>(spawn: F, dotspawn: G)
where where
F: Fn(Box<Future<Item = (), Error = ()>>) + 'static, F: Fn(Box<dyn Future<Item = (), Error = ()>>) + 'static,
G: Fn(&mut CurrentThread, Box<Future<Item = (), Error = ()>>), G: Fn(&mut CurrentThread, Box<dyn Future<Item = (), Error = ()>>),
{ {
let cnt = Rc::new(Cell::new(0)); let cnt = Rc::new(Cell::new(0));
let c = cnt.clone(); let c = cnt.clone();
@@ -459,7 +455,7 @@ mod in_drop {
} }
struct MyFuture { struct MyFuture {
_data: Box<Any>, _data: Box<dyn Any>,
} }
impl Future for MyFuture { impl Future for MyFuture {
@@ -473,8 +469,8 @@ mod in_drop {
fn test<F, G>(spawn: F, dotspawn: G) fn test<F, G>(spawn: F, dotspawn: G)
where where
F: Fn(Box<Future<Item = (), Error = ()>>) + 'static, F: Fn(Box<dyn Future<Item = (), Error = ()>>) + 'static,
G: Fn(&mut CurrentThread, Box<Future<Item = (), Error = ()>>), G: Fn(&mut CurrentThread, Box<dyn Future<Item = (), Error = ()>>),
{ {
let mut tokio_current_thread = CurrentThread::new(); let mut tokio_current_thread = CurrentThread::new();
@@ -827,7 +823,7 @@ fn spawn_from_executor_with_handle() {
Ok::<_, ()>(()) Ok::<_, ()>(())
})); }));
current_thread.run(); current_thread.run().unwrap();
rx.wait().unwrap(); rx.wait().unwrap();
} }
+5 -3
View File
@@ -7,8 +7,9 @@ name = "tokio-executor"
# - Cargo.toml # - Cargo.toml
# - README.md # - README.md
# - Update CHANGELOG.md. # - Update CHANGELOG.md.
# - Create "v0.1.x" git tag. # - Create "v0.2.x" git tag.
version = "0.1.7" version = "0.2.0"
edition = "2018"
documentation = "https://docs.rs/tokio-executor/0.1.7/tokio_executor" documentation = "https://docs.rs/tokio-executor/0.1.7/tokio_executor"
repository = "https://github.com/tokio-rs/tokio" repository = "https://github.com/tokio-rs/tokio"
homepage = "https://github.com/tokio-rs/tokio" homepage = "https://github.com/tokio-rs/tokio"
@@ -19,10 +20,11 @@ Future execution primitives
""" """
keywords = ["futures", "tokio"] keywords = ["futures", "tokio"]
categories = ["concurrency", "asynchronous"] categories = ["concurrency", "asynchronous"]
publish = false
[dependencies] [dependencies]
crossbeam-utils = "0.6.2" crossbeam-utils = "0.6.2"
futures = "0.1.19" futures = "0.1.19"
[dev-dependencies] [dev-dependencies]
tokio = "0.1.18" tokio = { version = "0.2.0", path = "../tokio" }
+5 -6
View File
@@ -1,17 +1,16 @@
use futures::{self, Future};
use std::cell::Cell; use std::cell::Cell;
use std::error::Error; use std::error::Error;
use std::fmt; use std::fmt;
use std::prelude::v1::*; use std::prelude::v1::*;
use futures::{self, Future};
thread_local!(static ENTERED: Cell<bool> = Cell::new(false)); thread_local!(static ENTERED: Cell<bool> = Cell::new(false));
/// Represents an executor context. /// Represents an executor context.
/// ///
/// For more details, see [`enter` documentation](fn.enter.html) /// For more details, see [`enter` documentation](fn.enter.html)
pub struct Enter { pub struct Enter {
on_exit: Vec<Box<Callback>>, on_exit: Vec<Box<dyn Callback>>,
permanent: bool, permanent: bool,
} }
@@ -22,7 +21,7 @@ pub struct EnterError {
} }
impl fmt::Debug for EnterError { impl fmt::Debug for EnterError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("EnterError") f.debug_struct("EnterError")
.field("reason", &self.description()) .field("reason", &self.description())
.finish() .finish()
@@ -30,7 +29,7 @@ impl fmt::Debug for EnterError {
} }
impl fmt::Display for EnterError { impl fmt::Display for EnterError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "{}", self.description()) write!(fmt, "{}", self.description())
} }
} }
@@ -94,7 +93,7 @@ impl Enter {
} }
impl fmt::Debug for Enter { impl fmt::Debug for Enter {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Enter").finish() f.debug_struct("Enter").finish()
} }
} }
+1 -1
View File
@@ -38,7 +38,7 @@ impl SpawnError {
} }
impl fmt::Display for SpawnError { impl fmt::Display for SpawnError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "{}", self.description()) write!(fmt, "{}", self.description())
} }
} }
+11 -18
View File
@@ -1,5 +1,5 @@
use crate::SpawnError;
use futures::Future; use futures::Future;
use SpawnError;
/// A value that executes futures. /// A value that executes futures.
/// ///
@@ -48,17 +48,15 @@ use SpawnError;
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # extern crate futures; /// use tokio_executor::Executor;
/// # extern crate tokio_executor;
/// # use tokio_executor::Executor;
/// # fn docs(my_executor: &mut Executor) {
/// use futures::future::lazy; /// use futures::future::lazy;
///
/// # fn docs(my_executor: &mut dyn Executor) {
/// my_executor.spawn(Box::new(lazy(|| { /// my_executor.spawn(Box::new(lazy(|| {
/// println!("running on the executor"); /// println!("running on the executor");
/// Ok(()) /// Ok(())
/// }))).unwrap(); /// }))).unwrap();
/// # } /// # }
/// # fn main() {}
/// ``` /// ```
/// ///
/// [`spawn`]: #tymethod.spawn /// [`spawn`]: #tymethod.spawn
@@ -80,21 +78,19 @@ pub trait Executor {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # extern crate futures; /// use tokio_executor::Executor;
/// # extern crate tokio_executor;
/// # use tokio_executor::Executor;
/// # fn docs(my_executor: &mut Executor) {
/// use futures::future::lazy; /// use futures::future::lazy;
///
/// # fn docs(my_executor: &mut dyn Executor) {
/// my_executor.spawn(Box::new(lazy(|| { /// my_executor.spawn(Box::new(lazy(|| {
/// println!("running on the executor"); /// println!("running on the executor");
/// Ok(()) /// Ok(())
/// }))).unwrap(); /// }))).unwrap();
/// # } /// # }
/// # fn main() {}
/// ``` /// ```
fn spawn( fn spawn(
&mut self, &mut self,
future: Box<Future<Item = (), Error = ()> + Send>, future: Box<dyn Future<Item = (), Error = ()> + Send>,
) -> Result<(), SpawnError>; ) -> Result<(), SpawnError>;
/// Provides a best effort **hint** to whether or not `spawn` will succeed. /// Provides a best effort **hint** to whether or not `spawn` will succeed.
@@ -115,12 +111,10 @@ pub trait Executor {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # extern crate futures; /// use tokio_executor::Executor;
/// # extern crate tokio_executor;
/// # use tokio_executor::Executor;
/// # fn docs(my_executor: &mut Executor) {
/// use futures::future::lazy; /// use futures::future::lazy;
/// ///
/// # fn docs(my_executor: &mut dyn Executor) {
/// if my_executor.status().is_ok() { /// if my_executor.status().is_ok() {
/// my_executor.spawn(Box::new(lazy(|| { /// my_executor.spawn(Box::new(lazy(|| {
/// println!("running on the executor"); /// println!("running on the executor");
@@ -130,7 +124,6 @@ pub trait Executor {
/// println!("the executor is not in a good state"); /// println!("the executor is not in a good state");
/// } /// }
/// # } /// # }
/// # fn main() {}
/// ``` /// ```
fn status(&self) -> Result<(), SpawnError> { fn status(&self) -> Result<(), SpawnError> {
Ok(()) Ok(())
@@ -140,7 +133,7 @@ pub trait Executor {
impl<E: Executor + ?Sized> Executor for Box<E> { impl<E: Executor + ?Sized> Executor for Box<E> {
fn spawn( fn spawn(
&mut self, &mut self,
future: Box<Future<Item = (), Error = ()> + Send>, future: Box<dyn Future<Item = (), Error = ()> + Send>,
) -> Result<(), SpawnError> { ) -> Result<(), SpawnError> {
(**self).spawn(future) (**self).spawn(future)
} }
+6 -13
View File
@@ -1,7 +1,5 @@
use super::{Enter, Executor, SpawnError}; use super::{Enter, Executor, SpawnError};
use futures::{future, Future}; use futures::{future, Future};
use std::cell::Cell; use std::cell::Cell;
/// Executes futures on the default executor for the current execution context. /// Executes futures on the default executor for the current execution context.
@@ -37,7 +35,7 @@ impl DefaultExecutor {
} }
#[inline] #[inline]
fn with_current<F: FnOnce(&mut Executor) -> R, R>(f: F) -> Option<R> { fn with_current<F: FnOnce(&mut dyn Executor) -> R, R>(f: F) -> Option<R> {
EXECUTOR.with( EXECUTOR.with(
|current_executor| match current_executor.replace(State::Active) { |current_executor| match current_executor.replace(State::Active) {
State::Ready(executor_ptr) => { State::Ready(executor_ptr) => {
@@ -57,7 +55,7 @@ enum State {
// default executor not defined // default executor not defined
Empty, Empty,
// default executor is defined and ready to be used // default executor is defined and ready to be used
Ready(*mut Executor), Ready(*mut dyn Executor),
// default executor is currently active (used to detect recursive calls) // default executor is currently active (used to detect recursive calls)
Active, Active,
} }
@@ -72,7 +70,7 @@ thread_local! {
impl super::Executor for DefaultExecutor { impl super::Executor for DefaultExecutor {
fn spawn( fn spawn(
&mut self, &mut self,
future: Box<Future<Item = (), Error = ()> + Send>, future: Box<dyn Future<Item = (), Error = ()> + Send>,
) -> Result<(), SpawnError> { ) -> Result<(), SpawnError> {
DefaultExecutor::with_current(|executor| executor.spawn(future)) DefaultExecutor::with_current(|executor| executor.spawn(future))
.unwrap_or_else(|| Err(SpawnError::shutdown())) .unwrap_or_else(|| Err(SpawnError::shutdown()))
@@ -144,19 +142,14 @@ where
/// ///
/// # Examples /// # Examples
/// ///
/// ```rust /// ```no_run
/// # extern crate futures; /// use tokio_executor::spawn;
/// # extern crate tokio_executor;
/// # use tokio_executor::spawn;
/// # pub fn dox() {
/// use futures::future::lazy; /// use futures::future::lazy;
/// ///
/// spawn(lazy(|| { /// spawn(lazy(|| {
/// println!("running on the default executor"); /// println!("running on the default executor");
/// Ok(()) /// Ok(())
/// })); /// }));
/// # }
/// # pub fn main() {}
/// ``` /// ```
pub fn spawn<T>(future: T) pub fn spawn<T>(future: T)
where where
@@ -210,7 +203,7 @@ where
}) })
} }
unsafe fn hide_lt<'a>(p: *mut (Executor + 'a)) -> *mut (Executor + 'static) { unsafe fn hide_lt<'a>(p: *mut (dyn Executor + 'a)) -> *mut (dyn Executor + 'static) {
use std::mem; use std::mem;
mem::transmute(p) mem::transmute(p)
} }
+8 -9
View File
@@ -1,5 +1,7 @@
#![deny(missing_docs, missing_debug_implementations, warnings)]
#![doc(html_root_url = "https://docs.rs/tokio-executor/0.1.7")] #![doc(html_root_url = "https://docs.rs/tokio-executor/0.1.7")]
#![deny(missing_docs, missing_debug_implementations, rust_2018_idioms)]
#![cfg_attr(test, deny(warnings))]
#![doc(test(no_crate_inject, attr(deny(rust_2018_idioms))))]
//! Task execution related traits and utilities. //! Task execution related traits and utilities.
//! //!
@@ -51,9 +53,6 @@
//! [`Park`]: park/index.html //! [`Park`]: park/index.html
//! [`Future::poll`]: https://docs.rs/futures/0.1/futures/future/trait.Future.html#tymethod.poll //! [`Future::poll`]: https://docs.rs/futures/0.1/futures/future/trait.Future.html#tymethod.poll
extern crate crossbeam_utils;
extern crate futures;
mod enter; mod enter;
mod error; mod error;
mod executor; mod executor;
@@ -61,8 +60,8 @@ mod global;
pub mod park; pub mod park;
mod typed; mod typed;
pub use enter::{enter, Enter, EnterError}; pub use crate::enter::{enter, Enter, EnterError};
pub use error::SpawnError; pub use crate::error::SpawnError;
pub use executor::Executor; pub use crate::executor::Executor;
pub use global::{spawn, with_default, DefaultExecutor}; pub use crate::global::{spawn, with_default, DefaultExecutor};
pub use typed::TypedExecutor; pub use crate::typed::TypedExecutor;
+3 -4
View File
@@ -44,13 +44,12 @@
//! [up]: trait.Unpark.html //! [up]: trait.Unpark.html
//! [mio]: https://docs.rs/mio/0.6/mio/struct.Poll.html //! [mio]: https://docs.rs/mio/0.6/mio/struct.Poll.html
use crossbeam_utils::sync::{Parker, Unparker};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use crossbeam_utils::sync::{Parker, Unparker};
/// Block the current thread. /// Block the current thread.
/// ///
/// See [module documentation][mod] for more details. /// See [module documentation][mod] for more details.
@@ -128,13 +127,13 @@ pub trait Unpark: Sync + Send + 'static {
fn unpark(&self); fn unpark(&self);
} }
impl Unpark for Box<Unpark> { impl Unpark for Box<dyn Unpark> {
fn unpark(&self) { fn unpark(&self) {
(**self).unpark() (**self).unpark()
} }
} }
impl Unpark for Arc<Unpark> { impl Unpark for Arc<dyn Unpark> {
fn unpark(&self) { fn unpark(&self) {
(**self).unpark() (**self).unpark()
} }
+7 -17
View File
@@ -1,4 +1,4 @@
use SpawnError; use crate::SpawnError;
/// A value that spawns futures of a specific type. /// A value that spawns futures of a specific type.
/// ///
@@ -21,11 +21,7 @@ use SpawnError;
/// task is spawned. /// task is spawned.
/// ///
/// ```rust /// ```rust
/// #[macro_use] /// use futures::{try_ready, Future, Stream, Poll};
/// extern crate futures;
/// extern crate tokio;
///
/// use futures::{Future, Stream, Poll};
/// use tokio::executor::TypedExecutor; /// use tokio::executor::TypedExecutor;
/// use tokio::sync::oneshot; /// use tokio::sync::oneshot;
/// ///
@@ -69,7 +65,6 @@ use SpawnError;
/// Ok(().into()) /// Ok(().into())
/// } /// }
/// } /// }
/// # pub fn main() {}
/// ``` /// ```
/// ///
/// By doing this, the `drain` fn can accept a stream that is `!Send` as long as /// By doing this, the `drain` fn can accept a stream that is `!Send` as long as
@@ -90,10 +85,8 @@ pub trait TypedExecutor<T> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # extern crate futures; /// use tokio_executor::TypedExecutor;
/// # extern crate tokio_executor; /// use futures::{Future, Poll};
/// # use tokio_executor::TypedExecutor;
/// # use futures::{Future, Poll};
/// fn example<T>(my_executor: &mut T) /// fn example<T>(my_executor: &mut T)
/// where /// where
/// T: TypedExecutor<MyFuture>, /// T: TypedExecutor<MyFuture>,
@@ -112,7 +105,6 @@ pub trait TypedExecutor<T> {
/// Ok(().into()) /// Ok(().into())
/// } /// }
/// } /// }
/// # fn main() {}
/// ``` /// ```
fn spawn(&mut self, future: T) -> Result<(), SpawnError>; fn spawn(&mut self, future: T) -> Result<(), SpawnError>;
@@ -134,10 +126,9 @@ pub trait TypedExecutor<T> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # extern crate futures; /// use tokio_executor::TypedExecutor;
/// # extern crate tokio_executor; /// use futures::{Future, Poll};
/// # use tokio_executor::TypedExecutor; ///
/// # use futures::{Future, Poll};
/// fn example<T>(my_executor: &mut T) /// fn example<T>(my_executor: &mut T)
/// where /// where
/// T: TypedExecutor<MyFuture>, /// T: TypedExecutor<MyFuture>,
@@ -160,7 +151,6 @@ pub trait TypedExecutor<T> {
/// Ok(().into()) /// Ok(().into())
/// } /// }
/// } /// }
/// # fn main() {}
/// ``` /// ```
fn status(&self) -> Result<(), SpawnError> { fn status(&self) -> Result<(), SpawnError> {
Ok(()) Ok(())
+4 -5
View File
@@ -1,8 +1,7 @@
extern crate futures; #![deny(warnings, rust_2018_idioms)]
extern crate tokio_executor;
use futures::{future::lazy, Future}; use futures::{self, future::lazy, Future};
use tokio_executor::DefaultExecutor; use tokio_executor::{self, DefaultExecutor};
mod out_of_executor_context { mod out_of_executor_context {
use super::*; use super::*;
@@ -10,7 +9,7 @@ mod out_of_executor_context {
fn test<F, E>(spawn: F) fn test<F, E>(spawn: F)
where where
F: Fn(Box<Future<Item = (), Error = ()> + Send>) -> Result<(), E>, F: Fn(Box<dyn Future<Item = (), Error = ()> + Send>) -> Result<(), E>,
{ {
let res = spawn(Box::new(lazy(|| Ok(())))); let res = spawn(Box::new(lazy(|| Ok(()))));
assert!(res.is_err()); assert!(res.is_err());
+8 -7
View File
@@ -7,8 +7,9 @@ name = "tokio-fs"
# - Cargo.toml # - Cargo.toml
# - README.md # - README.md
# - Update CHANGELOG.md. # - Update CHANGELOG.md.
# - Create "v0.1.x" git tag. # - Create "v0.2.x" git tag.
version = "0.1.6" version = "0.2.0"
edition = "2018"
authors = ["Carl Lerche <[email protected]>"] authors = ["Carl Lerche <[email protected]>"]
license = "MIT" license = "MIT"
readme = "README.md" readme = "README.md"
@@ -20,16 +21,16 @@ Filesystem API for Tokio.
""" """
keywords = ["tokio", "futures", "fs", "file", "async"] keywords = ["tokio", "futures", "fs", "file", "async"]
categories = ["asynchronous", "network-programming", "filesystem"] categories = ["asynchronous", "network-programming", "filesystem"]
publish = false
[dependencies] [dependencies]
futures = "0.1.21" futures = "0.1.21"
tokio-threadpool = "0.1.3" tokio-threadpool = { version = "0.2.0", path = "../tokio-threadpool" }
tokio-io = "0.1.6" tokio-io = { version = "0.2.0", path = "../tokio-io" }
[dev-dependencies] [dev-dependencies]
rand = "0.6" rand = "0.6"
tempfile = "3" tempfile = "3"
tempdir = "0.3" tempdir = "0.3"
tokio-io = "0.1.6" tokio-codec = { version = "0.2.0", path = "../tokio-codec" }
tokio-codec = "0.1.0" tokio = { version = "0.2.0", path = "../tokio" }
tokio = "0.1.7"
+1 -6
View File
@@ -1,11 +1,6 @@
//! Echo everything received on STDIN to STDOUT. //! Echo everything received on STDIN to STDOUT.
#![deny(deprecated, warnings)] #![deny(deprecated, warnings)]
extern crate futures;
extern crate tokio_codec;
extern crate tokio_fs;
extern crate tokio_threadpool;
use tokio_codec::{FramedRead, FramedWrite, LinesCodec}; use tokio_codec::{FramedRead, FramedWrite, LinesCodec};
use tokio_fs::{stderr, stdin, stdout}; use tokio_fs::{stderr, stdin, stdout};
use tokio_threadpool::Builder; use tokio_threadpool::Builder;
@@ -14,7 +9,7 @@ use futures::{Future, Sink, Stream};
use std::io; use std::io;
pub fn main() -> Result<(), Box<std::error::Error>> { pub fn main() -> Result<(), Box<dyn std::error::Error>> {
let pool = Builder::new().pool_size(1).build(); let pool = Builder::new().pool_size(1).build();
pool.spawn({ pool.spawn({
+2 -3
View File
@@ -1,9 +1,8 @@
use futures::{Future, Poll};
use std::fs; use std::fs;
use std::io; use std::io;
use std::path::Path; use std::path::Path;
use futures::{Future, Poll};
/// Creates a new, empty directory at the provided path /// Creates a new, empty directory at the provided path
/// ///
/// This is an async version of [`std::fs::create_dir`][std] /// This is an async version of [`std::fs::create_dir`][std]
@@ -39,6 +38,6 @@ where
type Error = io::Error; type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::create_dir(&self.path)) crate::blocking_io(|| fs::create_dir(&self.path))
} }
} }
+2 -3
View File
@@ -1,9 +1,8 @@
use futures::{Future, Poll};
use std::fs; use std::fs;
use std::io; use std::io;
use std::path::Path; use std::path::Path;
use futures::{Future, Poll};
/// Recursively create a directory and all of its parent components if they /// Recursively create a directory and all of its parent components if they
/// are missing. /// are missing.
/// ///
@@ -40,6 +39,6 @@ where
type Error = io::Error; type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::create_dir_all(&self.path)) crate::blocking_io(|| fs::create_dir_all(&self.path))
} }
} }
-2
View File
@@ -1,7 +1,5 @@
use super::File; use super::File;
use futures::{Future, Poll}; use futures::{Future, Poll};
use std::io; use std::io;
/// Future returned by `File::try_clone`. /// Future returned by `File::try_clone`.
+2 -4
View File
@@ -1,7 +1,5 @@
use super::File; use super::File;
use futures::{try_ready, Future, Poll};
use futures::{Future, Poll};
use std::fs::File as StdFile; use std::fs::File as StdFile;
use std::io; use std::io;
use std::path::Path; use std::path::Path;
@@ -29,7 +27,7 @@ where
type Error = io::Error; type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let std = try_ready!(::blocking_io(|| StdFile::create(&self.path))); let std = try_ready!(crate::blocking_io(|| StdFile::create(&self.path)));
let file = File::from_std(std); let file = File::from_std(std);
Ok(file.into()) Ok(file.into())
+2 -4
View File
@@ -1,7 +1,5 @@
use super::File; use super::File;
use futures::{try_ready, Future, Poll};
use futures::{Future, Poll};
use std::fs::File as StdFile; use std::fs::File as StdFile;
use std::fs::Metadata; use std::fs::Metadata;
use std::io; use std::io;
@@ -29,7 +27,7 @@ impl Future for MetadataFuture {
type Error = io::Error; type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let metadata = try_ready!(::blocking_io(|| StdFile::metadata(self.std()))); let metadata = try_ready!(crate::blocking_io(|| StdFile::metadata(self.std())));
let file = self.file.take().expect(POLL_AFTER_RESOLVE); let file = self.file.take().expect(POLL_AFTER_RESOLVE);
Ok((file, metadata).into()) Ok((file, metadata).into())
+148 -194
View File
@@ -16,13 +16,11 @@ pub use self::open::OpenFuture;
pub use self::open_options::OpenOptions; pub use self::open_options::OpenOptions;
pub use self::seek::SeekFuture; pub use self::seek::SeekFuture;
use tokio_io::{AsyncRead, AsyncWrite};
use futures::Poll; use futures::Poll;
use std::fs::{File as StdFile, Metadata, Permissions}; use std::fs::{File as StdFile, Metadata, Permissions};
use std::io::{self, Read, Seek, Write}; use std::io::{self, Read, Seek, Write};
use std::path::Path; use std::path::Path;
use tokio_io::{AsyncRead, AsyncWrite};
/// A reference to an open file on the filesystem. /// A reference to an open file on the filesystem.
/// ///
@@ -42,39 +40,32 @@ use std::path::Path;
/// Create a new file and asynchronously write bytes to it: /// Create a new file and asynchronously write bytes to it:
/// ///
/// ```no_run /// ```no_run
/// extern crate tokio;
///
/// use tokio::prelude::{AsyncWrite, Future}; /// use tokio::prelude::{AsyncWrite, Future};
/// ///
/// fn main() { /// let task = tokio::fs::File::create("foo.txt")
/// let task = tokio::fs::File::create("foo.txt") /// .and_then(|mut file| file.poll_write(b"hello, world!"))
/// .and_then(|mut file| file.poll_write(b"hello, world!")) /// .map(|res| {
/// .map(|res| { /// println!("{:?}", res);
/// println!("{:?}", res); /// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// ///
/// tokio::run(task); /// tokio::run(task);
/// }
/// ``` /// ```
/// ///
/// Read the contents of a file into a buffer /// Read the contents of a file into a buffer
/// ///
/// ```no_run /// ```no_run
/// extern crate tokio;
///
/// use tokio::prelude::{AsyncRead, Future}; /// use tokio::prelude::{AsyncRead, Future};
/// ///
/// fn main() { /// let task = tokio::fs::File::open("foo.txt")
/// let task = tokio::fs::File::open("foo.txt") /// .and_then(|mut file| {
/// .and_then(|mut file| { /// let mut contents = vec![];
/// let mut contents = vec![]; /// file.read_buf(&mut contents)
/// file.read_buf(&mut contents) /// .map(|res| {
/// .map(|res| { /// println!("{:?}", res);
/// println!("{:?}", res); /// })
/// }) /// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// }).map_err(|err| eprintln!("IO error: {:?}", err)); ///
/// tokio::run(task); /// tokio::run(task);
/// }
/// ``` /// ```
#[derive(Debug)] #[derive(Debug)]
pub struct File { pub struct File {
@@ -98,18 +89,17 @@ impl File {
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::Future; /// use tokio::prelude::Future;
/// fn main() { ///
/// let task = tokio::fs::File::open("foo.txt").and_then(|file| { /// let task = tokio::fs::File::open("foo.txt").and_then(|file| {
/// // do something with the file ... /// // do something with the file ...
/// file.metadata().map(|md| println!("{:?}", md)) /// file.metadata().map(|md| println!("{:?}", md))
/// }).map_err(|e| { /// }).map_err(|e| {
/// // handle errors /// // handle errors
/// eprintln!("IO error: {:?}", e); /// eprintln!("IO error: {:?}", e);
/// }); /// });
/// tokio::run(task); ///
/// } /// tokio::run(task);
/// ``` /// ```
pub fn open<P>(path: P) -> OpenFuture<P> pub fn open<P>(path: P) -> OpenFuture<P>
where where
@@ -137,19 +127,18 @@ impl File {
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::Future; /// use tokio::prelude::Future;
/// fn main() { ///
/// let task = tokio::fs::File::create("foo.txt") /// let task = tokio::fs::File::create("foo.txt")
/// .and_then(|file| { /// .and_then(|file| {
/// // do something with the created file ... /// // do something with the created file ...
/// file.metadata().map(|md| println!("{:?}", md)) /// file.metadata().map(|md| println!("{:?}", md))
/// }).map_err(|e| { /// }).map_err(|e| {
/// // handle errors /// // handle errors
/// eprintln!("IO error: {:?}", e); /// eprintln!("IO error: {:?}", e);
/// }); /// });
/// tokio::run(task); ///
/// } /// tokio::run(task);
/// ``` /// ```
pub fn create<P>(path: P) -> CreateFuture<P> pub fn create<P>(path: P) -> CreateFuture<P>
where where
@@ -165,13 +154,10 @@ impl File {
/// ///
/// Examples /// Examples
/// ```no_run /// ```no_run
/// # extern crate tokio;
/// use std::fs::File; /// use std::fs::File;
/// ///
/// fn main() { /// let std_file = File::open("foo.txt").unwrap();
/// let std_file = File::open("foo.txt").unwrap(); /// let file = tokio::fs::File::from_std(std_file);
/// let file = tokio::fs::File::from_std(std_file);
/// }
/// ``` /// ```
pub fn from_std(std: StdFile) -> File { pub fn from_std(std: StdFile) -> File {
File { std: Some(std) } File { std: Some(std) }
@@ -193,23 +179,20 @@ impl File {
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::Future; /// use tokio::prelude::Future;
/// use std::io::SeekFrom; /// use std::io::SeekFrom;
/// ///
/// fn main() { /// let task = tokio::fs::File::open("foo.txt")
/// let task = tokio::fs::File::open("foo.txt") /// // move cursor 6 bytes from the start of the file
/// // move cursor 6 bytes from the start of the file /// .and_then(|mut file| file.poll_seek(SeekFrom::Start(6)))
/// .and_then(|mut file| file.poll_seek(SeekFrom::Start(6))) /// .map(|res| {
/// .map(|res| { /// println!("{:?}", res);
/// println!("{:?}", res); /// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// ///
/// tokio::run(task); /// tokio::run(task);
/// }
/// ``` /// ```
pub fn poll_seek(&mut self, pos: io::SeekFrom) -> Poll<u64, io::Error> { pub fn poll_seek(&mut self, pos: io::SeekFrom) -> Poll<u64, io::Error> {
::blocking_io(|| self.std().seek(pos)) crate::blocking_io(|| self.std().seek(pos))
} }
/// Seek to an offset, in bytes, in a stream. /// Seek to an offset, in bytes, in a stream.
@@ -222,20 +205,17 @@ impl File {
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::Future; /// use tokio::prelude::Future;
/// use std::io::SeekFrom; /// use std::io::SeekFrom;
/// ///
/// fn main() { /// let task = tokio::fs::File::create("foo.txt")
/// let task = tokio::fs::File::create("foo.txt") /// .and_then(|file| file.seek(SeekFrom::Start(6)))
/// .and_then(|file| file.seek(SeekFrom::Start(6))) /// .map(|file| {
/// .map(|file| { /// // handle returned file ..
/// // handle returned file .. /// # println!("{:?}", file);
/// # println!("{:?}", file); /// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// ///
/// tokio::run(task); /// tokio::run(task);
/// }
/// ``` /// ```
pub fn seek(self, pos: io::SeekFrom) -> SeekFuture { pub fn seek(self, pos: io::SeekFrom) -> SeekFuture {
SeekFuture::new(self, pos) SeekFuture::new(self, pos)
@@ -249,25 +229,22 @@ impl File {
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::{AsyncWrite, Future}; /// use tokio::prelude::{AsyncWrite, Future};
/// ///
/// fn main() { /// let task = tokio::fs::File::create("foo.txt")
/// let task = tokio::fs::File::create("foo.txt") /// .and_then(|mut file| {
/// .and_then(|mut file| { /// file.poll_write(b"hello, world!")?;
/// file.poll_write(b"hello, world!")?; /// file.poll_sync_all()
/// file.poll_sync_all() /// })
/// }) /// .map(|res| {
/// .map(|res| { /// // handle returned result ..
/// // handle returned result .. /// # println!("{:?}", res);
/// # println!("{:?}", res); /// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// ///
/// tokio::run(task); /// tokio::run(task);
/// }
/// ``` /// ```
pub fn poll_sync_all(&mut self) -> Poll<(), io::Error> { pub fn poll_sync_all(&mut self) -> Poll<(), io::Error> {
::blocking_io(|| self.std().sync_all()) crate::blocking_io(|| self.std().sync_all())
} }
/// This function is similar to `poll_sync_all`, except that it may not /// This function is similar to `poll_sync_all`, except that it may not
@@ -282,25 +259,22 @@ impl File {
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::{AsyncWrite, Future}; /// use tokio::prelude::{AsyncWrite, Future};
/// ///
/// fn main() { /// let task = tokio::fs::File::create("foo.txt")
/// let task = tokio::fs::File::create("foo.txt") /// .and_then(|mut file| {
/// .and_then(|mut file| { /// file.poll_write(b"hello, world!")?;
/// file.poll_write(b"hello, world!")?; /// file.poll_sync_data()
/// file.poll_sync_data() /// })
/// }) /// .map(|res| {
/// .map(|res| { /// // handle returned result ..
/// // handle returned result .. /// # println!("{:?}", res);
/// # println!("{:?}", res); /// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// ///
/// tokio::run(task); /// tokio::run(task);
/// }
/// ``` /// ```
pub fn poll_sync_data(&mut self) -> Poll<(), io::Error> { pub fn poll_sync_data(&mut self) -> Poll<(), io::Error> {
::blocking_io(|| self.std().sync_data()) crate::blocking_io(|| self.std().sync_data())
} }
/// Truncates or extends the underlying file, updating the size of this file to become size. /// Truncates or extends the underlying file, updating the size of this file to become size.
@@ -318,24 +292,21 @@ impl File {
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::Future; /// use tokio::prelude::Future;
/// ///
/// fn main() { /// let task = tokio::fs::File::create("foo.txt")
/// let task = tokio::fs::File::create("foo.txt") /// .and_then(|mut file| {
/// .and_then(|mut file| { /// file.poll_set_len(10)
/// file.poll_set_len(10) /// })
/// }) /// .map(|res| {
/// .map(|res| { /// // handle returned result ..
/// // handle returned result .. /// # println!("{:?}", res);
/// # println!("{:?}", res); /// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// ///
/// tokio::run(task); /// tokio::run(task);
/// }
/// ``` /// ```
pub fn poll_set_len(&mut self, size: u64) -> Poll<(), io::Error> { pub fn poll_set_len(&mut self, size: u64) -> Poll<(), io::Error> {
::blocking_io(|| self.std().set_len(size)) crate::blocking_io(|| self.std().set_len(size))
} }
/// Queries metadata about the underlying file. /// Queries metadata about the underlying file.
@@ -343,18 +314,15 @@ impl File {
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::Future; /// use tokio::prelude::Future;
/// ///
/// fn main() { /// let task = tokio::fs::File::create("foo.txt")
/// let task = tokio::fs::File::create("foo.txt") /// .and_then(|file| file.metadata())
/// .and_then(|file| file.metadata()) /// .map(|metadata| {
/// .map(|metadata| { /// println!("{:?}", metadata);
/// println!("{:?}", metadata); /// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// ///
/// tokio::run(task); /// tokio::run(task);
/// }
/// ``` /// ```
pub fn metadata(self) -> MetadataFuture { pub fn metadata(self) -> MetadataFuture {
MetadataFuture::new(self) MetadataFuture::new(self)
@@ -365,22 +333,19 @@ impl File {
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::Future; /// use tokio::prelude::Future;
/// ///
/// fn main() { /// let task = tokio::fs::File::create("foo.txt")
/// let task = tokio::fs::File::create("foo.txt") /// .and_then(|mut file| file.poll_metadata())
/// .and_then(|mut file| file.poll_metadata()) /// .map(|metadata| {
/// .map(|metadata| { /// // metadata is of type Async::Ready<Metadata>
/// // metadata is of type Async::Ready<Metadata> /// println!("{:?}", metadata);
/// println!("{:?}", metadata); /// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// ///
/// tokio::run(task); /// tokio::run(task);
/// }
/// ``` /// ```
pub fn poll_metadata(&mut self) -> Poll<Metadata, io::Error> { pub fn poll_metadata(&mut self) -> Poll<Metadata, io::Error> {
::blocking_io(|| self.std().metadata()) crate::blocking_io(|| self.std().metadata())
} }
/// Create a new `File` instance that shares the same underlying file handle /// Create a new `File` instance that shares the same underlying file handle
@@ -390,22 +355,19 @@ impl File {
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::Future; /// use tokio::prelude::Future;
/// ///
/// fn main() { /// let task = tokio::fs::File::create("foo.txt")
/// let task = tokio::fs::File::create("foo.txt") /// .and_then(|mut file| file.poll_try_clone())
/// .and_then(|mut file| file.poll_try_clone()) /// .map(|clone| {
/// .map(|clone| { /// // do something with the clone
/// // do something with the clone /// # println!("{:?}", clone);
/// # println!("{:?}", clone); /// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// ///
/// tokio::run(task); /// tokio::run(task);
/// }
/// ``` /// ```
pub fn poll_try_clone(&mut self) -> Poll<File, io::Error> { pub fn poll_try_clone(&mut self) -> Poll<File, io::Error> {
::blocking_io(|| { crate::blocking_io(|| {
let std = self.std().try_clone()?; let std = self.std().try_clone()?;
Ok(File::from_std(std)) Ok(File::from_std(std))
}) })
@@ -416,28 +378,26 @@ impl File {
/// File instances simultaneously. /// File instances simultaneously.
/// ///
/// # Examples /// # Examples
///
/// ```no_run /// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::Future; /// use tokio::prelude::Future;
/// ///
/// fn main() { /// let task = tokio::fs::File::create("foo.txt")
/// let task = tokio::fs::File::create("foo.txt") /// .and_then(|file| {
/// .and_then(|file| { /// file.try_clone()
/// file.try_clone() /// .map(|(file, clone)| {
/// .map(|(file, clone)| { /// // do something with the file and the clone
/// // do something with the file and the clone /// # println!("{:?} {:?}", file, clone);
/// # println!("{:?} {:?}", file, clone); /// })
/// }) /// .map_err(|(file, err)| {
/// .map_err(|(file, err)| { /// // you get the original file back if there's an error
/// // you get the original file back if there's an error /// # println!("{:?}", file);
/// # println!("{:?}", file); /// err
/// err /// })
/// }) /// })
/// }) /// .map_err(|err| eprintln!("IO error: {:?}", err));
/// .map_err(|err| eprintln!("IO error: {:?}", err));
/// ///
/// tokio::run(task); /// tokio::run(task);
/// }
/// ``` /// ```
pub fn try_clone(self) -> CloneFuture { pub fn try_clone(self) -> CloneFuture {
CloneFuture::new(self) CloneFuture::new(self)
@@ -462,26 +422,23 @@ impl File {
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::Future; /// use tokio::prelude::Future;
/// ///
/// fn main() { /// let task = tokio::fs::File::create("foo.txt")
/// let task = tokio::fs::File::create("foo.txt") /// .and_then(|file| file.metadata())
/// .and_then(|file| file.metadata()) /// .map(|(mut file, metadata)| {
/// .map(|(mut file, metadata)| { /// let mut perms = metadata.permissions();
/// let mut perms = metadata.permissions(); /// perms.set_readonly(true);
/// perms.set_readonly(true); /// match file.poll_set_permissions(perms) {
/// match file.poll_set_permissions(perms) { /// Err(e) => eprintln!("{}", e),
/// Err(e) => eprintln!("{}", e), /// _ => println!("permissions set!"),
/// _ => println!("permissions set!"), /// }
/// } /// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// ///
/// tokio::run(task); /// tokio::run(task);
/// }
/// ``` /// ```
pub fn poll_set_permissions(&mut self, perm: Permissions) -> Poll<(), io::Error> { pub fn poll_set_permissions(&mut self, perm: Permissions) -> Poll<(), io::Error> {
::blocking_io(|| self.std().set_permissions(perm)) crate::blocking_io(|| self.std().set_permissions(perm))
} }
/// Destructures the `tokio_fs::File` into a [`std::fs::File`][std]. /// Destructures the `tokio_fs::File` into a [`std::fs::File`][std].
@@ -495,19 +452,16 @@ impl File {
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::Future; /// use tokio::prelude::Future;
/// ///
/// fn main() { /// let task = tokio::fs::File::create("foo.txt")
/// let task = tokio::fs::File::create("foo.txt") /// .map(|file| {
/// .map(|file| { /// let std_file = file.into_std();
/// let std_file = file.into_std(); /// // do something with the std::fs::File
/// // do something with the std::fs::File /// # println!("{:?}", std_file);
/// # println!("{:?}", std_file); /// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// }).map_err(|err| eprintln!("IO error: {:?}", err));
/// ///
/// tokio::run(task); /// tokio::run(task);
/// }
/// ``` /// ```
pub fn into_std(mut self) -> StdFile { pub fn into_std(mut self) -> StdFile {
self.std.take().expect("`File` instance already shutdown") self.std.take().expect("`File` instance already shutdown")
@@ -520,7 +474,7 @@ impl File {
impl Read for File { impl Read for File {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
::would_block(|| self.std().read(buf)) crate::would_block(|| self.std().read(buf))
} }
} }
@@ -532,17 +486,17 @@ impl AsyncRead for File {
impl Write for File { impl Write for File {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
::would_block(|| self.std().write(buf)) crate::would_block(|| self.std().write(buf))
} }
fn flush(&mut self) -> io::Result<()> { fn flush(&mut self) -> io::Result<()> {
::would_block(|| self.std().flush()) crate::would_block(|| self.std().flush())
} }
} }
impl AsyncWrite for File { impl AsyncWrite for File {
fn shutdown(&mut self) -> Poll<(), io::Error> { fn shutdown(&mut self) -> Poll<(), io::Error> {
::blocking_io(|| { crate::blocking_io(|| {
self.std = None; self.std = None;
Ok(()) Ok(())
}) })
+2 -4
View File
@@ -1,7 +1,5 @@
use super::File; use super::File;
use futures::{try_ready, Future, Poll};
use futures::{Future, Poll};
use std::fs::OpenOptions as StdOpenOptions; use std::fs::OpenOptions as StdOpenOptions;
use std::io; use std::io;
use std::path::Path; use std::path::Path;
@@ -30,7 +28,7 @@ where
type Error = io::Error; type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let std = try_ready!(::blocking_io(|| self.options.open(&self.path))); let std = try_ready!(crate::blocking_io(|| self.options.open(&self.path)));
let file = File::from_std(std); let file = File::from_std(std);
Ok(file.into()) Ok(file.into())
-1
View File
@@ -1,5 +1,4 @@
use super::OpenFuture; use super::OpenFuture;
use std::convert::From; use std::convert::From;
use std::fs::OpenOptions as StdOpenOptions; use std::fs::OpenOptions as StdOpenOptions;
use std::path::Path; use std::path::Path;
+1 -3
View File
@@ -1,7 +1,5 @@
use super::File; use super::File;
use futures::{try_ready, Future, Poll};
use futures::{Future, Poll};
use std::io; use std::io;
/// Future returned by `File::seek`. /// Future returned by `File::seek`.
+2 -3
View File
@@ -1,9 +1,8 @@
use futures::{Future, Poll};
use std::fs; use std::fs;
use std::io; use std::io;
use std::path::Path; use std::path::Path;
use futures::{Future, Poll};
/// Creates a new hard link on the filesystem. /// Creates a new hard link on the filesystem.
/// ///
/// The `dst` path will be a link pointing to the `src` path. Note that systems /// The `dst` path will be a link pointing to the `src` path. Note that systems
@@ -46,6 +45,6 @@ where
type Error = io::Error; type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::hard_link(&self.src, &self.dst)) crate::blocking_io(|| fs::hard_link(&self.src, &self.dst))
} }
} }
+21 -25
View File
@@ -1,5 +1,7 @@
#![deny(missing_docs, missing_debug_implementations, warnings)]
#![doc(html_root_url = "https://docs.rs/tokio-fs/0.1.6")] #![doc(html_root_url = "https://docs.rs/tokio-fs/0.1.6")]
#![deny(missing_docs, missing_debug_implementations, rust_2018_idioms)]
#![cfg_attr(test, deny(warnings))]
#![doc(test(no_crate_inject, attr(deny(rust_2018_idioms))))]
//! Asynchronous file and standard stream adaptation. //! Asynchronous file and standard stream adaptation.
//! //!
@@ -28,11 +30,6 @@
//! [`AsyncRead`]: https://docs.rs/tokio-io/0.1/tokio_io/trait.AsyncRead.html //! [`AsyncRead`]: https://docs.rs/tokio-io/0.1/tokio_io/trait.AsyncRead.html
//! [tokio-threadpool]: https://docs.rs/tokio-threadpool/0.1/tokio_threadpool //! [tokio-threadpool]: https://docs.rs/tokio-threadpool/0.1/tokio_threadpool
#[macro_use]
extern crate futures;
extern crate tokio_io;
extern crate tokio_threadpool;
mod create_dir; mod create_dir;
mod create_dir_all; mod create_dir_all;
pub mod file; pub mod file;
@@ -52,28 +49,27 @@ mod stdout;
mod symlink_metadata; mod symlink_metadata;
mod write; mod write;
pub use create_dir::{create_dir, CreateDirFuture}; pub use crate::create_dir::{create_dir, CreateDirFuture};
pub use create_dir_all::{create_dir_all, CreateDirAllFuture}; pub use crate::create_dir_all::{create_dir_all, CreateDirAllFuture};
pub use file::File; pub use crate::file::File;
pub use file::OpenOptions; pub use crate::file::OpenOptions;
pub use hard_link::{hard_link, HardLinkFuture}; pub use crate::hard_link::{hard_link, HardLinkFuture};
pub use metadata::{metadata, MetadataFuture}; pub use crate::metadata::{metadata, MetadataFuture};
pub use read::{read, ReadFile}; pub use crate::read::{read, ReadFile};
pub use read_dir::{read_dir, DirEntry, ReadDir, ReadDirFuture}; pub use crate::read_dir::{read_dir, DirEntry, ReadDir, ReadDirFuture};
pub use read_link::{read_link, ReadLinkFuture}; pub use crate::read_link::{read_link, ReadLinkFuture};
pub use remove_dir::{remove_dir, RemoveDirFuture}; pub use crate::remove_dir::{remove_dir, RemoveDirFuture};
pub use remove_file::{remove_file, RemoveFileFuture}; pub use crate::remove_file::{remove_file, RemoveFileFuture};
pub use rename::{rename, RenameFuture}; pub use crate::rename::{rename, RenameFuture};
pub use set_permissions::{set_permissions, SetPermissionsFuture}; pub use crate::set_permissions::{set_permissions, SetPermissionsFuture};
pub use stderr::{stderr, Stderr}; pub use crate::stderr::{stderr, Stderr};
pub use stdin::{stdin, Stdin}; pub use crate::stdin::{stdin, Stdin};
pub use stdout::{stdout, Stdout}; pub use crate::stdout::{stdout, Stdout};
pub use symlink_metadata::{symlink_metadata, SymlinkMetadataFuture}; pub use crate::symlink_metadata::{symlink_metadata, SymlinkMetadataFuture};
pub use write::{write, WriteFile}; pub use crate::write::{write, WriteFile};
use futures::Async::*; use futures::Async::*;
use futures::Poll; use futures::Poll;
use std::io; use std::io;
use std::io::ErrorKind::{Other, WouldBlock}; use std::io::ErrorKind::{Other, WouldBlock};
-2
View File
@@ -1,7 +1,5 @@
use super::blocking_io; use super::blocking_io;
use futures::{Future, Poll}; use futures::{Future, Poll};
use std::fs::{self, Metadata}; use std::fs::{self, Metadata};
use std::io; use std::io;
use std::path::Path; use std::path::Path;
+2 -3
View File
@@ -1,11 +1,10 @@
//! Unix-specific extensions to primitives in the `tokio_fs` module. //! Unix-specific extensions to primitives in the `tokio_fs` module.
use futures::{Future, Poll};
use std::io; use std::io;
use std::os::unix::fs; use std::os::unix::fs;
use std::path::Path; use std::path::Path;
use futures::{Future, Poll};
/// Creates a new symbolic link on the filesystem. /// Creates a new symbolic link on the filesystem.
/// ///
/// The `dst` path will be a symbolic link pointing to the `src` path. /// The `dst` path will be a symbolic link pointing to the `src` path.
@@ -47,6 +46,6 @@ where
type Error = io::Error; type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::symlink(&self.src, &self.dst)) crate::blocking_io(|| fs::symlink(&self.src, &self.dst))
} }
} }
+2 -3
View File
@@ -1,9 +1,8 @@
use futures::{Future, Poll};
use std::io; use std::io;
use std::os::windows::fs; use std::os::windows::fs;
use std::path::Path; use std::path::Path;
use futures::{Future, Poll};
/// Creates a new directory symlink on the filesystem. /// Creates a new directory symlink on the filesystem.
/// ///
/// The `dst` path will be a directory symbolic link pointing to the `src` /// The `dst` path will be a directory symbolic link pointing to the `src`
@@ -46,6 +45,6 @@ where
type Error = io::Error; type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::symlink_dir(&self.src, &self.dst)) crate::blocking_io(|| fs::symlink_dir(&self.src, &self.dst))
} }
} }
+2 -3
View File
@@ -1,9 +1,8 @@
use futures::{Future, Poll};
use std::io; use std::io;
use std::os::windows::fs; use std::os::windows::fs;
use std::path::Path; use std::path::Path;
use futures::{Future, Poll};
/// Creates a new file symbolic link on the filesystem. /// Creates a new file symbolic link on the filesystem.
/// ///
/// The `dst` path will be a file symbolic link pointing to the `src` /// The `dst` path will be a file symbolic link pointing to the `src`
@@ -46,6 +45,6 @@ where
type Error = io::Error; type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::symlink_file(&self.src, &self.dst)) crate::blocking_io(|| fs::symlink_file(&self.src, &self.dst))
} }
} }
+12 -13
View File
@@ -1,7 +1,7 @@
use futures::{Async, Future, Poll}; use crate::{file, File};
use futures::{try_ready, Async, Future, Poll};
use std::{io, mem, path::Path}; use std::{io, mem, path::Path};
use tokio_io; use tokio_io;
use {file, File};
/// Creates a future which will open a file for reading and read the entire /// Creates a future which will open a file for reading and read the entire
/// contents into a buffer and return said buffer. /// contents into a buffer and return said buffer.
@@ -11,18 +11,17 @@ use {file, File};
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::Future; /// use tokio::prelude::Future;
/// fn main() { ///
/// let task = tokio::fs::read("foo.txt").map(|data| { /// let task = tokio::fs::read("foo.txt").map(|data| {
/// // do something with the contents of the file ... /// // do something with the contents of the file ...
/// println!("foo.txt contains {} bytes", data.len()); /// println!("foo.txt contains {} bytes", data.len());
/// }).map_err(|e| { /// }).map_err(|e| {
/// // handle errors /// // handle errors
/// eprintln!("IO error: {:?}", e); /// eprintln!("IO error: {:?}", e);
/// }); /// });
/// tokio::run(task); ///
/// } /// tokio::run(task);
/// ``` /// ```
pub fn read<P>(path: P) -> ReadFile<P> pub fn read<P>(path: P) -> ReadFile<P>
where where
+37 -54
View File
@@ -1,3 +1,4 @@
use futures::{Future, Poll, Stream};
use std::ffi::OsString; use std::ffi::OsString;
use std::fs::{self, DirEntry as StdDirEntry, FileType, Metadata, ReadDir as StdReadDir}; use std::fs::{self, DirEntry as StdDirEntry, FileType, Metadata, ReadDir as StdReadDir};
use std::io; use std::io;
@@ -5,8 +6,6 @@ use std::io;
use std::os::unix::fs::DirEntryExt; use std::os::unix::fs::DirEntryExt;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use futures::{Future, Poll, Stream};
/// Returns a stream over the entries within a directory. /// Returns a stream over the entries within a directory.
/// ///
/// This is an async version of [`std::fs::read_dir`][std] /// This is an async version of [`std::fs::read_dir`][std]
@@ -45,7 +44,7 @@ where
type Error = io::Error; type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, io::Error> { fn poll(&mut self) -> Poll<Self::Item, io::Error> {
::blocking_io(|| Ok(ReadDir(fs::read_dir(&self.path)?))) crate::blocking_io(|| Ok(ReadDir(fs::read_dir(&self.path)?)))
} }
} }
@@ -73,7 +72,7 @@ impl Stream for ReadDir {
type Error = io::Error; type Error = io::Error;
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> { fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
::blocking_io(|| match self.0.next() { crate::blocking_io(|| match self.0.next() {
Some(Err(err)) => Err(err), Some(Err(err)) => Err(err),
Some(Ok(item)) => Ok(Some(DirEntry(item))), Some(Ok(item)) => Ok(Some(DirEntry(item))),
None => Ok(None), None => Ok(None),
@@ -112,18 +111,14 @@ impl DirEntry {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # extern crate futures;
/// # extern crate tokio;
/// # extern crate tokio_fs;
/// use futures::{Future, Stream}; /// use futures::{Future, Stream};
/// ///
/// fn main() { /// let fut = tokio_fs::read_dir(".").flatten_stream().for_each(|dir| {
/// let fut = tokio_fs::read_dir(".").flatten_stream().for_each(|dir| { /// println!("{:?}", dir.path());
/// println!("{:?}", dir.path()); /// Ok(())
/// Ok(()) /// }).map_err(|err| { eprintln!("Error: {:?}", err); () });
/// }).map_err(|err| { eprintln!("Error: {:?}", err); () }); ///
/// tokio::run(fut); /// tokio::run(fut);
/// }
/// ``` /// ```
/// ///
/// This prints output like: /// This prints output like:
@@ -145,19 +140,15 @@ impl DirEntry {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # extern crate futures;
/// # extern crate tokio;
/// # extern crate tokio_fs;
/// use futures::{Future, Stream}; /// use futures::{Future, Stream};
/// ///
/// fn main() { /// let fut = tokio_fs::read_dir(".").flatten_stream().for_each(|dir| {
/// let fut = tokio_fs::read_dir(".").flatten_stream().for_each(|dir| { /// // Here, `dir` is a `DirEntry`.
/// // Here, `dir` is a `DirEntry`. /// println!("{:?}", dir.file_name());
/// println!("{:?}", dir.file_name()); /// Ok(())
/// Ok(()) /// }).map_err(|err| { eprintln!("Error: {:?}", err); () });
/// }).map_err(|err| { eprintln!("Error: {:?}", err); () }); ///
/// tokio::run(fut); /// tokio::run(fut);
/// }
/// ``` /// ```
pub fn file_name(&self) -> OsString { pub fn file_name(&self) -> OsString {
self.0.file_name() self.0.file_name()
@@ -177,25 +168,21 @@ impl DirEntry {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # extern crate futures;
/// # extern crate tokio;
/// # extern crate tokio_fs;
/// use futures::{Future, Stream}; /// use futures::{Future, Stream};
/// use futures::future::poll_fn; /// use futures::future::poll_fn;
/// ///
/// fn main() { /// let fut = tokio_fs::read_dir(".").flatten_stream().for_each(|dir| {
/// let fut = tokio_fs::read_dir(".").flatten_stream().for_each(|dir| { /// // Here, `dir` is a `DirEntry`.
/// // Here, `dir` is a `DirEntry`. /// let path = dir.path();
/// let path = dir.path(); /// poll_fn(move || dir.poll_metadata()).map(move |metadata| {
/// poll_fn(move || dir.poll_metadata()).map(move |metadata| { /// println!("{:?}: {:?}", path, metadata.permissions());
/// println!("{:?}: {:?}", path, metadata.permissions()); /// })
/// }) /// }).map_err(|err| { eprintln!("Error: {:?}", err); () });
/// }).map_err(|err| { eprintln!("Error: {:?}", err); () }); ///
/// tokio::run(fut); /// tokio::run(fut);
/// }
/// ``` /// ```
pub fn poll_metadata(&self) -> Poll<Metadata, io::Error> { pub fn poll_metadata(&self) -> Poll<Metadata, io::Error> {
::blocking_io(|| self.0.metadata()) crate::blocking_io(|| self.0.metadata())
} }
/// Return the file type for the file that this entry points at. /// Return the file type for the file that this entry points at.
@@ -212,26 +199,22 @@ impl DirEntry {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # extern crate futures;
/// # extern crate tokio;
/// # extern crate tokio_fs;
/// use futures::{Future, Stream}; /// use futures::{Future, Stream};
/// use futures::future::poll_fn; /// use futures::future::poll_fn;
/// ///
/// fn main() { /// let fut = tokio_fs::read_dir(".").flatten_stream().for_each(|dir| {
/// let fut = tokio_fs::read_dir(".").flatten_stream().for_each(|dir| { /// // Here, `dir` is a `DirEntry`.
/// // Here, `dir` is a `DirEntry`. /// let path = dir.path();
/// let path = dir.path(); /// poll_fn(move || dir.poll_file_type()).map(move |file_type| {
/// poll_fn(move || dir.poll_file_type()).map(move |file_type| { /// // Now let's show our entry's file type!
/// // Now let's show our entry's file type! /// println!("{:?}: {:?}", path, file_type);
/// println!("{:?}: {:?}", path, file_type); /// })
/// }) /// }).map_err(|err| { eprintln!("Error: {:?}", err); () });
/// }).map_err(|err| { eprintln!("Error: {:?}", err); () }); ///
/// tokio::run(fut); /// tokio::run(fut);
/// }
/// ``` /// ```
pub fn poll_file_type(&self) -> Poll<FileType, io::Error> { pub fn poll_file_type(&self) -> Poll<FileType, io::Error> {
::blocking_io(|| self.0.file_type()) crate::blocking_io(|| self.0.file_type())
} }
} }
+2 -3
View File
@@ -1,9 +1,8 @@
use futures::{Future, Poll};
use std::fs; use std::fs;
use std::io; use std::io;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use futures::{Future, Poll};
/// Reads a symbolic link, returning the file that the link points to. /// Reads a symbolic link, returning the file that the link points to.
/// ///
/// This is an async version of [`std::fs::read_link`][std] /// This is an async version of [`std::fs::read_link`][std]
@@ -39,6 +38,6 @@ where
type Error = io::Error; type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::read_link(&self.path)) crate::blocking_io(|| fs::read_link(&self.path))
} }
} }
+2 -3
View File
@@ -1,9 +1,8 @@
use futures::{Future, Poll};
use std::fs; use std::fs;
use std::io; use std::io;
use std::path::Path; use std::path::Path;
use futures::{Future, Poll};
/// Removes an existing, empty directory. /// Removes an existing, empty directory.
/// ///
/// This is an async version of [`std::fs::remove_dir`][std] /// This is an async version of [`std::fs::remove_dir`][std]
@@ -39,6 +38,6 @@ where
type Error = io::Error; type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::remove_dir(&self.path)) crate::blocking_io(|| fs::remove_dir(&self.path))
} }
} }
+2 -3
View File
@@ -1,9 +1,8 @@
use futures::{Future, Poll};
use std::fs; use std::fs;
use std::io; use std::io;
use std::path::Path; use std::path::Path;
use futures::{Future, Poll};
/// Removes a file from the filesystem. /// Removes a file from the filesystem.
/// ///
/// Note that there is no /// Note that there is no
@@ -43,6 +42,6 @@ where
type Error = io::Error; type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::remove_file(&self.path)) crate::blocking_io(|| fs::remove_file(&self.path))
} }
} }
+2 -3
View File
@@ -1,9 +1,8 @@
use futures::{Future, Poll};
use std::fs; use std::fs;
use std::io; use std::io;
use std::path::Path; use std::path::Path;
use futures::{Future, Poll};
/// Rename a file or directory to a new name, replacing the original file if /// Rename a file or directory to a new name, replacing the original file if
/// `to` already exists. /// `to` already exists.
/// ///
@@ -46,6 +45,6 @@ where
type Error = io::Error; type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::rename(&self.from, &self.to)) crate::blocking_io(|| fs::rename(&self.from, &self.to))
} }
} }
+2 -3
View File
@@ -1,9 +1,8 @@
use futures::{Future, Poll};
use std::fs; use std::fs;
use std::io; use std::io;
use std::path::Path; use std::path::Path;
use futures::{Future, Poll};
/// Changes the permissions found on a file or a directory. /// Changes the permissions found on a file or a directory.
/// ///
/// This is an async version of [`std::fs::set_permissions`][std] /// This is an async version of [`std::fs::set_permissions`][std]
@@ -43,6 +42,6 @@ where
type Error = io::Error; type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
::blocking_io(|| fs::set_permissions(&self.path, self.perm.clone())) crate::blocking_io(|| fs::set_permissions(&self.path, self.perm.clone()))
} }
} }
+3 -5
View File
@@ -1,8 +1,6 @@
use tokio_io::AsyncWrite;
use futures::Poll; use futures::Poll;
use std::io::{self, Stderr as StdStderr, Write}; use std::io::{self, Stderr as StdStderr, Write};
use tokio_io::AsyncWrite;
/// A handle to the standard error stream of a process. /// A handle to the standard error stream of a process.
/// ///
@@ -29,11 +27,11 @@ pub fn stderr() -> Stderr {
impl Write for Stderr { impl Write for Stderr {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
::would_block(|| self.std.write(buf)) crate::would_block(|| self.std.write(buf))
} }
fn flush(&mut self) -> io::Result<()> { fn flush(&mut self) -> io::Result<()> {
::would_block(|| self.std.flush()) crate::would_block(|| self.std.flush())
} }
} }
+2 -3
View File
@@ -1,6 +1,5 @@
use tokio_io::AsyncRead;
use std::io::{self, Read, Stdin as StdStdin}; use std::io::{self, Read, Stdin as StdStdin};
use tokio_io::AsyncRead;
/// A handle to the standard input stream of a process. /// A handle to the standard input stream of a process.
/// ///
@@ -33,7 +32,7 @@ pub fn stdin() -> Stdin {
impl Read for Stdin { impl Read for Stdin {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
::would_block(|| self.std.read(buf)) crate::would_block(|| self.std.read(buf))
} }
} }
+3 -5
View File
@@ -1,8 +1,6 @@
use tokio_io::AsyncWrite;
use futures::Poll; use futures::Poll;
use std::io::{self, Stdout as StdStdout, Write}; use std::io::{self, Stdout as StdStdout, Write};
use tokio_io::AsyncWrite;
/// A handle to the standard output stream of a process. /// A handle to the standard output stream of a process.
/// ///
@@ -29,11 +27,11 @@ pub fn stdout() -> Stdout {
impl Write for Stdout { impl Write for Stdout {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
::would_block(|| self.std.write(buf)) crate::would_block(|| self.std.write(buf))
} }
fn flush(&mut self) -> io::Result<()> { fn flush(&mut self) -> io::Result<()> {
::would_block(|| self.std.flush()) crate::would_block(|| self.std.flush())
} }
} }
-2
View File
@@ -1,7 +1,5 @@
use super::blocking_io; use super::blocking_io;
use futures::{Future, Poll}; use futures::{Future, Poll};
use std::fs::{self, Metadata}; use std::fs::{self, Metadata};
use std::io; use std::io;
use std::path::Path; use std::path::Path;
+14 -15
View File
@@ -1,7 +1,7 @@
use futures::{Async, Future, Poll}; use crate::{file, File};
use futures::{try_ready, Async, Future, Poll};
use std::{fmt, io, mem, path::Path}; use std::{fmt, io, mem, path::Path};
use tokio_io; use tokio_io;
use {file, File};
/// Creates a future that will open a file for writing and write the entire /// Creates a future that will open a file for writing and write the entire
/// contents of `contents` to it. /// contents of `contents` to it.
@@ -11,20 +11,19 @@ use {file, File};
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # extern crate tokio;
/// use tokio::prelude::Future; /// use tokio::prelude::Future;
/// fn main() { ///
/// let buffer = b"Hello world!"; /// let buffer = b"Hello world!";
/// let task = tokio::fs::write("foo.txt", buffer).map(|data| { /// let task = tokio::fs::write("foo.txt", buffer).map(|data| {
/// // `data` has now been written to foo.txt. The buffer is being /// // `data` has now been written to foo.txt. The buffer is being
/// // returned so it can be used for other things. /// // returned so it can be used for other things.
/// println!("foo.txt now had {} bytes written to it", data.len()); /// println!("foo.txt now had {} bytes written to it", data.len());
/// }).map_err(|e| { /// }).map_err(|e| {
/// // handle errors /// // handle errors
/// eprintln!("IO error: {:?}", e); /// eprintln!("IO error: {:?}", e);
/// }); /// });
/// tokio::run(task); ///
/// } /// tokio::run(task);
/// ``` /// ```
pub fn write<P, C: AsRef<[u8]>>(path: P, contents: C) -> WriteFile<P, C> pub fn write<P, C: AsRef<[u8]>>(path: P, contents: C) -> WriteFile<P, C>
where where
+1 -3
View File
@@ -1,6 +1,4 @@
extern crate futures; #![deny(warnings, rust_2018_idioms)]
extern crate tempdir;
extern crate tokio_fs;
use futures::{Future, Stream}; use futures::{Future, Stream};
use std::fs; use std::fs;
+4 -10
View File
@@ -1,19 +1,13 @@
extern crate futures; #![deny(warnings, rust_2018_idioms)]
extern crate rand;
extern crate tempfile;
extern crate tokio_fs;
extern crate tokio_io;
use tokio_fs::*;
use tokio_io::io;
use futures::future::poll_fn; use futures::future::poll_fn;
use futures::Future; use futures::Future;
use rand::{distributions, thread_rng, Rng}; use rand::{distributions, thread_rng, Rng};
use tempfile::Builder as TmpBuilder;
use std::fs; use std::fs;
use std::io::SeekFrom; use std::io::SeekFrom;
use tempfile::Builder as TmpBuilder;
use tokio_fs::*;
use tokio_io::io;
mod pool; mod pool;
+3 -4
View File
@@ -1,8 +1,5 @@
extern crate futures; #![deny(warnings, rust_2018_idioms)]
extern crate tempdir;
extern crate tokio_fs;
use futures::Future;
use std::fs; use std::fs;
use std::io::prelude::*; use std::io::prelude::*;
use std::io::BufReader; use std::io::BufReader;
@@ -38,6 +35,8 @@ fn test_hard_link() {
#[cfg(unix)] #[cfg(unix)]
#[test] #[test]
fn test_symlink() { fn test_symlink() {
use futures::Future;
let dir = TempDir::new("base").unwrap(); let dir = TempDir::new("base").unwrap();
let src = dir.path().join("src.txt"); let src = dir.path().join("src.txt");
let dst = dir.path().join("dst.txt"); let dst = dir.path().join("dst.txt");
+2 -2
View File
@@ -1,5 +1,5 @@
extern crate futures; use futures;
extern crate tokio_threadpool; use tokio_threadpool;
use self::tokio_threadpool::Builder; use self::tokio_threadpool::Builder;
use futures::sync::oneshot; use futures::sync::oneshot;
+5 -3
View File
@@ -3,7 +3,8 @@ name = "tokio-futures"
# When releasing to crates.io: # When releasing to crates.io:
# - Update html_root_url. # - Update html_root_url.
version = "0.1.0" version = "0.2.0"
edition = "2018"
authors = ["Carl Lerche <[email protected]>"] authors = ["Carl Lerche <[email protected]>"]
license = "MIT" license = "MIT"
repository = "https://github.com/tokio-rs/tokio" repository = "https://github.com/tokio-rs/tokio"
@@ -13,6 +14,7 @@ description = """
Experimental std::future::Future and async/await support for Tokio Experimental std::future::Future and async/await support for Tokio
""" """
categories = ["asynchronous"] categories = ["asynchronous"]
publish = false
[features] [features]
# This feature comes with no promise of stability. Things will # This feature comes with no promise of stability. Things will
@@ -21,9 +23,9 @@ async-await-preview = ["futures/nightly"]
[dependencies] [dependencies]
futures = "0.1.23" futures = "0.1.23"
tokio-io = "0.1.7" tokio-io = { version = "0.2.0", path = "../tokio-io" }
[dev-dependencies] [dev-dependencies]
bytes = "0.4.9" bytes = "0.4.9"
hyper = "0.12.8" hyper = "0.12.8"
tokio = { version = "0.1.8", path = "../tokio" } tokio = { version = "0.2.0", path = "../tokio" }
+2 -7
View File
@@ -18,19 +18,14 @@ Add this to your `Cargo.toml`:
edition = "2018" edition = "2018"
# In the `[dependencies]` section # In the `[dependencies]` section
tokio = {version = "0.1.15", features = ["async-await-preview"]} tokio = {version = "0.2.0", features = ["async-await-preview"]}
``` ```
Then, get started. In your application, add: Then, get started. In your application, add:
```rust ```rust
// The nightly features that are commonly needed with async / await // The nightly features that are commonly needed with async / await
#![feature(await_macro, async_await)] #![feature(async_await)]
// This pulls in the `tokio-futures` crate. While Rust 2018 doesn't require
// `extern crate`, we need to pull in the macros.
#[macro_use]
extern crate tokio;
fn main() { fn main() {
// And we are async... // And we are async...
@@ -1,16 +1,15 @@
/// Wait for a future to complete. /// Wait for a future to complete.
#[macro_export] #[macro_export]
macro_rules! await { macro_rules! async_wait {
($e:expr) => {{ ($e:expr) => {{
#[allow(unused_imports)] #[allow(unused_imports)]
use $crate::compat::backward::IntoAwaitable as IntoAwaitableBackward; use $crate::compat::backward::IntoAwaitable as IntoAwaitableBackward;
#[allow(unused_imports)] #[allow(unused_imports)]
use $crate::compat::forward::IntoAwaitable as IntoAwaitableForward; use $crate::compat::forward::IntoAwaitable as IntoAwaitableForward;
use $crate::std_await;
#[allow(unused_mut)] #[allow(unused_mut)]
let mut e = $e; let mut e = $e;
let e = e.into_awaitable(); let e = e.into_awaitable();
std_await!(e) e.await
}}; }};
} }
+1 -1
View File
@@ -55,7 +55,7 @@ where
{ {
type Output = Result<T::Item, T::Error>; type Output = Result<T::Item, T::Error>;
fn poll(mut self: Pin<&mut Self>, _context: &mut Context) -> StdPoll<Self::Output> { fn poll(mut self: Pin<&mut Self>, _context: &mut Context<'_>) -> StdPoll<Self::Output> {
use futures::Async::{NotReady, Ready}; use futures::Async::{NotReady, Ready};
// TODO: wire in cx // TODO: wire in cx
+1 -1
View File
@@ -30,7 +30,7 @@ where
impl<T: std::future::Future> std::future::Future for Map<T> { impl<T: std::future::Future> std::future::Future for Map<T> {
type Output = Result<T::Output, ()>; type Output = Result<T::Output, ()>;
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> { fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match self.future().poll(cx) { match self.future().poll(cx) {
Poll::Ready(v) => Poll::Ready(Ok(v)), Poll::Ready(v) => Poll::Ready(Ok(v)),
Poll::Pending => Poll::Pending, Poll::Pending => Poll::Pending,
+3 -4
View File
@@ -1,13 +1,12 @@
use tokio_io::AsyncWrite;
use std::future::Future; use std::future::Future;
use std::io; use std::io;
use std::pin::Pin; use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use tokio_io::AsyncWrite;
/// A future used to fully flush an I/O object. /// A future used to fully flush an I/O object.
#[derive(Debug)] #[derive(Debug)]
pub struct Flush<'a, T: ?Sized + 'a> { pub struct Flush<'a, T: ?Sized> {
writer: &'a mut T, writer: &'a mut T,
} }
@@ -23,7 +22,7 @@ impl<'a, T: AsyncWrite + ?Sized> Flush<'a, T> {
impl<'a, T: AsyncWrite + ?Sized> Future for Flush<'a, T> { impl<'a, T: AsyncWrite + ?Sized> Future for Flush<'a, T> {
type Output = io::Result<()>; type Output = io::Result<()>;
fn poll(mut self: Pin<&mut Self>, _context: &mut Context) -> Poll<Self::Output> { fn poll(mut self: Pin<&mut Self>, _context: &mut Context<'_>) -> Poll<Self::Output> {
use crate::compat::forward::convert_poll; use crate::compat::forward::convert_poll;
convert_poll(self.writer.poll_flush()) convert_poll(self.writer.poll_flush())
} }
+15 -15
View File
@@ -25,7 +25,7 @@ pub trait AsyncReadExt: AsyncRead {
/// # Examples /// # Examples
/// ///
/// ```edition2018 /// ```edition2018
/// #![feature(async_await, await_macro)] /// #![feature(async_await)]
/// tokio::run_async(async { /// tokio::run_async(async {
/// // The extension trait can also be imported with /// // The extension trait can also be imported with
/// // `use tokio::prelude::*`. /// // `use tokio::prelude::*`.
@@ -35,7 +35,7 @@ pub trait AsyncReadExt: AsyncRead {
/// let mut reader = Cursor::new([1, 2, 3, 4]); /// let mut reader = Cursor::new([1, 2, 3, 4]);
/// let mut output = [0u8; 5]; /// let mut output = [0u8; 5];
/// ///
/// let bytes = await!(reader.read_async(&mut output[..])).unwrap(); /// let bytes = reader.read_async(&mut output[..]).await.unwrap();
/// ///
/// // This is only guaranteed to be 4 because `&[u8]` is a synchronous /// // This is only guaranteed to be 4 because `&[u8]` is a synchronous
/// // reader. In a real system you could get anywhere from 1 to /// // reader. In a real system you could get anywhere from 1 to
@@ -59,7 +59,7 @@ pub trait AsyncReadExt: AsyncRead {
/// # Examples /// # Examples
/// ///
/// ```edition2018 /// ```edition2018
/// #![feature(async_await, await_macro)] /// #![feature(async_await)]
/// tokio::run_async(async { /// tokio::run_async(async {
/// // The extension trait can also be imported with /// // The extension trait can also be imported with
/// // `use tokio::prelude::*`. /// // `use tokio::prelude::*`.
@@ -69,7 +69,7 @@ pub trait AsyncReadExt: AsyncRead {
/// let mut reader = Cursor::new([1, 2, 3, 4]); /// let mut reader = Cursor::new([1, 2, 3, 4]);
/// let mut output = [0u8; 4]; /// let mut output = [0u8; 4];
/// ///
/// await!(reader.read_exact_async(&mut output)).unwrap(); /// reader.read_exact_async(&mut output).await.unwrap();
/// ///
/// assert_eq!(output, [1, 2, 3, 4]); /// assert_eq!(output, [1, 2, 3, 4]);
/// }); /// });
@@ -78,7 +78,7 @@ pub trait AsyncReadExt: AsyncRead {
/// ## EOF is hit before `buf` is filled /// ## EOF is hit before `buf` is filled
/// ///
/// ```edition2018 /// ```edition2018
/// #![feature(async_await, await_macro)] /// #![feature(async_await)]
/// tokio::run_async(async { /// tokio::run_async(async {
/// // The extension trait can also be imported with /// // The extension trait can also be imported with
/// // `use tokio::prelude::*`. /// // `use tokio::prelude::*`.
@@ -88,7 +88,7 @@ pub trait AsyncReadExt: AsyncRead {
/// let mut reader = Cursor::new([1, 2, 3, 4]); /// let mut reader = Cursor::new([1, 2, 3, 4]);
/// let mut output = [0u8; 5]; /// let mut output = [0u8; 5];
/// ///
/// let result = await!(reader.read_exact_async(&mut output)); /// let result = reader.read_exact_async(&mut output).await;
/// ///
/// assert_eq!(result.unwrap_err().kind(), io::ErrorKind::UnexpectedEof); /// assert_eq!(result.unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
/// }); /// });
@@ -110,7 +110,7 @@ pub trait AsyncWriteExt: AsyncWrite {
/// # Examples /// # Examples
/// ///
/// ```edition2018 /// ```edition2018
/// #![feature(async_await, await_macro)] /// #![feature(async_await)]
/// tokio::run_async(async { /// tokio::run_async(async {
/// // The extension trait can also be imported with /// // The extension trait can also be imported with
/// // `use tokio::prelude::*`. /// // `use tokio::prelude::*`.
@@ -120,7 +120,7 @@ pub trait AsyncWriteExt: AsyncWrite {
/// let mut buf = [0u8; 5]; /// let mut buf = [0u8; 5];
/// let mut writer = Cursor::new(&mut buf[..]); /// let mut writer = Cursor::new(&mut buf[..]);
/// ///
/// let n = await!(writer.write_async(&[1, 2, 3, 4])).unwrap(); /// let n = writer.write_async(&[1, 2, 3, 4]).await.unwrap();
/// ///
/// assert_eq!(writer.into_inner()[..n], [1, 2, 3, 4, 0][..n]); /// assert_eq!(writer.into_inner()[..n], [1, 2, 3, 4, 0][..n]);
/// }); /// });
@@ -139,7 +139,7 @@ pub trait AsyncWriteExt: AsyncWrite {
/// # Examples /// # Examples
/// ///
/// ```edition2018 /// ```edition2018
/// #![feature(async_await, await_macro)] /// #![feature(async_await)]
/// tokio::run_async(async { /// tokio::run_async(async {
/// // The extension trait can also be imported with /// // The extension trait can also be imported with
/// // `use tokio::prelude::*`. /// // `use tokio::prelude::*`.
@@ -149,7 +149,7 @@ pub trait AsyncWriteExt: AsyncWrite {
/// let mut buf = [0u8; 5]; /// let mut buf = [0u8; 5];
/// let mut writer = Cursor::new(&mut buf[..]); /// let mut writer = Cursor::new(&mut buf[..]);
/// ///
/// await!(writer.write_all_async(&[1, 2, 3, 4])).unwrap(); /// writer.write_all_async(&[1, 2, 3, 4]).await.unwrap();
/// ///
/// assert_eq!(writer.into_inner(), [1, 2, 3, 4, 0]); /// assert_eq!(writer.into_inner(), [1, 2, 3, 4, 0]);
/// }); /// });
@@ -163,7 +163,7 @@ pub trait AsyncWriteExt: AsyncWrite {
/// # Examples /// # Examples
/// ///
/// ```edition2018 /// ```edition2018
/// #![feature(async_await, await_macro)] /// #![feature(async_await)]
/// tokio::run_async(async { /// tokio::run_async(async {
/// // The extension trait can also be imported with /// // The extension trait can also be imported with
/// // `use tokio::prelude::*`. /// // `use tokio::prelude::*`.
@@ -175,15 +175,15 @@ pub trait AsyncWriteExt: AsyncWrite {
/// { /// {
/// let mut writer = Cursor::new(&mut output[..]); /// let mut writer = Cursor::new(&mut output[..]);
/// let mut buffered = BufWriter::new(writer); /// let mut buffered = BufWriter::new(writer);
/// await!(buffered.write_all_async(&[1, 2])).unwrap(); /// buffered.write_all_async(&[1, 2]).await.unwrap();
/// await!(buffered.write_all_async(&[3, 4])).unwrap(); /// buffered.write_all_async(&[3, 4]).await.unwrap();
/// await!(buffered.flush_async()).unwrap(); /// buffered.flush_async().await.unwrap();
/// } /// }
/// ///
/// assert_eq!(output, [1, 2, 3, 4, 0]); /// assert_eq!(output, [1, 2, 3, 4, 0]);
/// }); /// });
/// ``` /// ```
fn flush_async<'a>(&mut self) -> Flush<Self> { fn flush_async<'a>(&mut self) -> Flush<'_, Self> {
Flush::new(self) Flush::new(self)
} }
} }
+4 -6
View File
@@ -1,14 +1,12 @@
use tokio_io::AsyncRead;
use std::future::Future; use std::future::Future;
use std::task::{self, Poll};
use std::io; use std::io;
use std::pin::Pin; use std::pin::Pin;
use std::task::{self, Poll};
use tokio_io::AsyncRead;
/// A future which can be used to read bytes. /// A future which can be used to read bytes.
#[derive(Debug)] #[derive(Debug)]
pub struct Read<'a, T: ?Sized + 'a> { pub struct Read<'a, T: ?Sized> {
reader: &'a mut T, reader: &'a mut T,
buf: &'a mut [u8], buf: &'a mut [u8],
} }
@@ -25,7 +23,7 @@ impl<'a, T: AsyncRead + ?Sized> Read<'a, T> {
impl<'a, T: AsyncRead + ?Sized> Future for Read<'a, T> { impl<'a, T: AsyncRead + ?Sized> Future for Read<'a, T> {
type Output = io::Result<usize>; type Output = io::Result<usize>;
fn poll(mut self: Pin<&mut Self>, _context: &mut task::Context) -> Poll<Self::Output> { fn poll(mut self: Pin<&mut Self>, _context: &mut task::Context<'_>) -> Poll<Self::Output> {
use crate::compat::forward::convert_poll; use crate::compat::forward::convert_poll;
let this = &mut *self; let this = &mut *self;
+4 -6
View File
@@ -1,15 +1,13 @@
use tokio_io::AsyncRead;
use std::future::Future; use std::future::Future;
use std::task::{self, Poll};
use std::io; use std::io;
use std::mem; use std::mem;
use std::pin::Pin; use std::pin::Pin;
use std::task::{self, Poll};
use tokio_io::AsyncRead;
/// A future which can be used to read exactly enough bytes to fill a buffer. /// A future which can be used to read exactly enough bytes to fill a buffer.
#[derive(Debug)] #[derive(Debug)]
pub struct ReadExact<'a, T: ?Sized + 'a> { pub struct ReadExact<'a, T: ?Sized> {
reader: &'a mut T, reader: &'a mut T,
buf: &'a mut [u8], buf: &'a mut [u8],
} }
@@ -30,7 +28,7 @@ fn eof() -> io::Error {
impl<'a, T: AsyncRead + ?Sized> Future for ReadExact<'a, T> { impl<'a, T: AsyncRead + ?Sized> Future for ReadExact<'a, T> {
type Output = io::Result<()>; type Output = io::Result<()>;
fn poll(mut self: Pin<&mut Self>, _context: &mut task::Context) -> Poll<Self::Output> { fn poll(mut self: Pin<&mut Self>, _context: &mut task::Context<'_>) -> Poll<Self::Output> {
use crate::compat::forward::convert_poll; use crate::compat::forward::convert_poll;
let this = &mut *self; let this = &mut *self;
+4 -6
View File
@@ -1,14 +1,12 @@
use tokio_io::AsyncWrite;
use std::future::Future; use std::future::Future;
use std::task::{self, Poll};
use std::io; use std::io;
use std::pin::Pin; use std::pin::Pin;
use std::task::{self, Poll};
use tokio_io::AsyncWrite;
/// A future used to write data. /// A future used to write data.
#[derive(Debug)] #[derive(Debug)]
pub struct Write<'a, T: 'a + ?Sized> { pub struct Write<'a, T: ?Sized> {
writer: &'a mut T, writer: &'a mut T,
buf: &'a [u8], buf: &'a [u8],
} }
@@ -25,7 +23,7 @@ impl<'a, T: AsyncWrite + ?Sized> Write<'a, T> {
impl<'a, T: AsyncWrite + ?Sized> Future for Write<'a, T> { impl<'a, T: AsyncWrite + ?Sized> Future for Write<'a, T> {
type Output = io::Result<usize>; type Output = io::Result<usize>;
fn poll(mut self: Pin<&mut Self>, _context: &mut task::Context) -> Poll<io::Result<usize>> { fn poll(mut self: Pin<&mut Self>, _context: &mut task::Context<'_>) -> Poll<io::Result<usize>> {
use crate::compat::forward::convert_poll; use crate::compat::forward::convert_poll;
let this = &mut *self; let this = &mut *self;
+4 -6
View File
@@ -1,15 +1,13 @@
use tokio_io::AsyncWrite;
use std::future::Future; use std::future::Future;
use std::task::{self, Poll};
use std::io; use std::io;
use std::mem; use std::mem;
use std::pin::Pin; use std::pin::Pin;
use std::task::{self, Poll};
use tokio_io::AsyncWrite;
/// A future used to write the entire contents of a buffer. /// A future used to write the entire contents of a buffer.
#[derive(Debug)] #[derive(Debug)]
pub struct WriteAll<'a, T: ?Sized + 'a> { pub struct WriteAll<'a, T: ?Sized> {
writer: &'a mut T, writer: &'a mut T,
buf: &'a [u8], buf: &'a [u8],
} }
@@ -30,7 +28,7 @@ fn zero_write() -> io::Error {
impl<'a, T: AsyncWrite + ?Sized> Future for WriteAll<'a, T> { impl<'a, T: AsyncWrite + ?Sized> Future for WriteAll<'a, T> {
type Output = io::Result<()>; type Output = io::Result<()>;
fn poll(mut self: Pin<&mut Self>, _context: &mut task::Context) -> Poll<io::Result<()>> { fn poll(mut self: Pin<&mut Self>, _context: &mut task::Context<'_>) -> Poll<io::Result<()>> {
use crate::compat::forward::convert_poll; use crate::compat::forward::convert_poll;
let this = &mut *self; let this = &mut *self;
+4 -11
View File
@@ -1,14 +1,12 @@
#![cfg(feature = "async-await-preview")] #![cfg(feature = "async-await-preview")]
#![feature(await_macro)] #![feature(async_await, await_macro)]
#![doc(html_root_url = "https://docs.rs/tokio-futures/0.1.0")] #![doc(html_root_url = "https://docs.rs/tokio-futures/0.1.0")]
#![deny(missing_docs, missing_debug_implementations)] #![deny(missing_docs, missing_debug_implementations, rust_2018_idioms)]
#![cfg_attr(test, deny(warnings))] #![cfg_attr(test, deny(warnings))]
#![doc(test(no_crate_inject, attr(deny(rust_2018_idioms))))]
//! A preview of Tokio w/ `async` / `await` support. //! A preview of Tokio w/ `async` / `await` support.
extern crate futures;
extern crate tokio_io;
/// Extracts the successful type of a `Poll<Result<T, E>>`. /// Extracts the successful type of a `Poll<Result<T, E>>`.
/// ///
/// This macro bakes in propagation of `Pending` and `Err` signals by returning early. /// This macro bakes in propagation of `Pending` and `Err` signals by returning early.
@@ -23,13 +21,8 @@ macro_rules! try_ready {
} }
#[macro_use] #[macro_use]
mod await; mod async_wait;
pub mod compat; pub mod compat;
pub mod io; pub mod io;
pub mod sink; pub mod sink;
pub mod stream; pub mod stream;
// Rename the `await` macro in `std`. This is used by the redefined
// `await` macro in this crate.
#[doc(hidden)]
pub use std::await as std_await;
+1 -1
View File
@@ -13,7 +13,7 @@ pub trait SinkExt: Sink {
/// Note that, **because of the flushing requirement, it is usually better /// Note that, **because of the flushing requirement, it is usually better
/// to batch together items to send via `send_all`, rather than flushing /// to batch together items to send via `send_all`, rather than flushing
/// between each item.** /// between each item.**
fn send_async(&mut self, item: Self::SinkItem) -> Send<Self> fn send_async(&mut self, item: Self::SinkItem) -> Send<'_, Self>
where where
Self: Sized + Unpin, Self: Sized + Unpin,
{ {
+3 -5
View File
@@ -1,14 +1,12 @@
use futures::Sink; use futures::Sink;
use std::future::Future; use std::future::Future;
use std::task::{self, Poll};
use std::pin::Pin; use std::pin::Pin;
use std::task::{self, Poll};
/// Future for the `SinkExt::send_async` combinator, which sends a value to a /// Future for the `SinkExt::send_async` combinator, which sends a value to a
/// sink and then waits until the sink has fully flushed. /// sink and then waits until the sink has fully flushed.
#[derive(Debug)] #[derive(Debug)]
pub struct Send<'a, T: Sink + 'a + ?Sized> { pub struct Send<'a, T: Sink + ?Sized> {
sink: &'a mut T, sink: &'a mut T,
item: Option<T::SinkItem>, item: Option<T::SinkItem>,
} }
@@ -27,7 +25,7 @@ impl<'a, T: Sink + Unpin + ?Sized> Send<'a, T> {
impl<T: Sink + Unpin + ?Sized> Future for Send<'_, T> { impl<T: Sink + Unpin + ?Sized> Future for Send<'_, T> {
type Output = Result<(), T::SinkError>; type Output = Result<(), T::SinkError>;
fn poll(mut self: Pin<&mut Self>, _context: &mut task::Context) -> Poll<Self::Output> { fn poll(mut self: Pin<&mut Self>, _context: &mut task::Context<'_>) -> Poll<Self::Output> {
use crate::compat::forward::convert_poll; use crate::compat::forward::convert_poll;
use futures::AsyncSink::{NotReady, Ready}; use futures::AsyncSink::{NotReady, Ready};

Some files were not shown because too many files have changed in this diff Show More