Skip to content

Commit 2497f4d

Browse files
author
Stjepan Glavina
committed
Merge branch 'master' into poll_next
2 parents 724a9f4 + 06f2569 commit 2497f4d

17 files changed

+491
-55
lines changed

Diff for: .travis.yml

+20-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
language: rust
22

3-
env: RUSTFLAGS="-D warnings"
3+
env:
4+
- RUSTFLAGS="-D warnings"
5+
6+
# Cache the whole `~/.cargo` directory to keep `~/cargo/.crates.toml`.
7+
cache:
8+
directories:
9+
- /home/travis/.cargo
10+
11+
# Don't cache the cargo registry because it's too big.
12+
before_cache:
13+
- rm -rf /home/travis/.cargo/registry
414

515
matrix:
616
fast_finish: true
@@ -35,16 +45,15 @@ matrix:
3545
script:
3646
- cargo doc --features docs
3747

38-
# TODO(yoshuawuyts): re-enable mdbook
39-
# - name: book
40-
# rust: nightly
41-
# os: linux
42-
# before_script:
43-
# - test -x $HOME/.cargo/bin/mdbook || ./ci/install-mdbook.sh
44-
# - cargo build # to find 'extern crate async_std' by `mdbook test`
45-
# script:
46-
# - mdbook build docs
47-
# - mdbook test -L ./target/debug/deps docs
48+
- name: book
49+
rust: nightly
50+
os: linux
51+
before_script:
52+
- test -x $HOME/.cargo/bin/mdbook || ./ci/install-mdbook.sh
53+
- cargo build # to find 'extern crate async_std' by `mdbook test`
54+
script:
55+
- mdbook build docs
56+
- mdbook test -L ./target/debug/deps docs
4857

4958
script:
5059
- cargo check --features unstable --all --benches --bins --examples --tests

Diff for: Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ femme = "1.2.0"
4444
surf = "1.0.2"
4545
tempdir = "0.3.7"
4646

47+
# These are used by the book for examples
48+
futures-channel-preview = "0.3.0-alpha.18"
49+
futures-util-preview = "0.3.0-alpha.18"
50+
4751
[dev-dependencies.futures-preview]
4852
version = "0.3.0-alpha.18"
4953
features = ["std", "nightly", "async-await"]

Diff for: docs/src/tutorial/all_together.md

+4-5
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,16 @@ At this point, we only need to start the broker to get a fully-functioning (in t
44

55
```rust,edition2018
66
# extern crate async_std;
7-
# extern crate futures;
7+
# extern crate futures_channel;
8+
# extern crate futures_util;
89
use async_std::{
910
io::{self, BufReader},
1011
net::{TcpListener, TcpStream, ToSocketAddrs},
1112
prelude::*,
1213
task,
1314
};
14-
use futures::{
15-
channel::mpsc,
16-
SinkExt,
17-
};
15+
use futures_channel::mpsc;
16+
use futures_util::SinkExt;
1817
use std::{
1918
collections::hash_map::{HashMap, Entry},
2019
sync::Arc,

Diff for: docs/src/tutorial/clean_shutdown.md

+8-10
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,16 @@ Let's add waiting to the server:
2222

2323
```rust,edition2018
2424
# extern crate async_std;
25-
# extern crate futures;
25+
# extern crate futures_channel;
26+
# extern crate futures_util;
2627
# use async_std::{
2728
# io::{self, BufReader},
2829
# net::{TcpListener, TcpStream, ToSocketAddrs},
2930
# prelude::*,
3031
# task,
3132
# };
32-
# use futures::{
33-
# channel::mpsc,
34-
# SinkExt,
35-
# };
33+
# use futures_channel::mpsc;
34+
# use futures_util::SinkExt;
3635
# use std::{
3736
# collections::hash_map::{HashMap, Entry},
3837
# sync::Arc,
@@ -156,17 +155,16 @@ And to the broker:
156155

157156
```rust,edition2018
158157
# extern crate async_std;
159-
# extern crate futures;
158+
# extern crate futures_channel;
159+
# extern crate futures_util;
160160
# use async_std::{
161161
# io::{self, BufReader},
162162
# net::{TcpListener, TcpStream, ToSocketAddrs},
163163
# prelude::*,
164164
# task,
165165
# };
166-
# use futures::{
167-
# channel::mpsc,
168-
# SinkExt,
169-
# };
166+
# use futures_channel::mpsc;
167+
# use futures_util::SinkExt;
170168
# use std::{
171169
# collections::hash_map::{HashMap, Entry},
172170
# sync::Arc,

Diff for: docs/src/tutorial/connecting_readers_and_writers.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,16 @@ The order of events "Bob sends message to Alice" and "Alice joins" is determined
1212

1313
```rust,edition2018
1414
# extern crate async_std;
15-
# extern crate futures;
15+
# extern crate futures_channel;
16+
# extern crate futures_util;
1617
# use async_std::{
1718
# io::{Write},
1819
# net::TcpStream,
1920
# prelude::{Future, Stream},
2021
# task,
2122
# };
22-
# use futures::channel::mpsc;
23-
# use futures::sink::SinkExt;
23+
# use futures_channel::mpsc;
24+
# use futures_util::sink::SinkExt;
2425
# use std::sync::Arc;
2526
#
2627
# type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;

Diff for: docs/src/tutorial/handling_disconnection.md

+13-6
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ First, let's add a shutdown channel to the `client`:
1919

2020
```rust,edition2018
2121
# extern crate async_std;
22-
# extern crate futures;
22+
# extern crate futures_channel;
23+
# extern crate futures_util;
2324
# use async_std::net::TcpStream;
24-
# use futures::{channel::mpsc, SinkExt};
25+
# use futures_channel::mpsc;
26+
# use futures_util::SinkExt;
2527
# use std::sync::Arc;
2628
#
2729
# type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
@@ -68,9 +70,11 @@ We use the `select` macro for this purpose:
6870

6971
```rust,edition2018
7072
# extern crate async_std;
71-
# extern crate futures;
73+
# extern crate futures_channel;
74+
# extern crate futures_util;
7275
# use async_std::{io::Write, net::TcpStream};
73-
use futures::{channel::mpsc, select, FutureExt, StreamExt};
76+
use futures_channel::mpsc;
77+
use futures_util::{select, FutureExt, StreamExt};
7478
# use std::sync::Arc;
7579
7680
# type Receiver<T> = mpsc::UnboundedReceiver<T>;
@@ -118,15 +122,18 @@ The final code looks like this:
118122

119123
```rust,edition2018
120124
# extern crate async_std;
121-
# extern crate futures;
125+
# extern crate futures_channel;
126+
# extern crate futures_util;
122127
use async_std::{
123128
io::{BufReader, BufRead, Write},
124129
net::{TcpListener, TcpStream, ToSocketAddrs},
125130
task,
126131
};
127-
use futures::{channel::mpsc, future::Future, select, FutureExt, SinkExt, StreamExt};
132+
use futures_channel::mpsc;
133+
use futures_util::{select, FutureExt, SinkExt, StreamExt};
128134
use std::{
129135
collections::hash_map::{Entry, HashMap},
136+
future::Future,
130137
sync::Arc,
131138
};
132139

Diff for: docs/src/tutorial/implementing_a_client.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ With async, we can just use the `select!` macro.
1616

1717
```rust,edition2018
1818
# extern crate async_std;
19-
# extern crate futures;
19+
# extern crate futures_util;
2020
use async_std::{
2121
io::{stdin, BufRead, BufReader, Write},
2222
net::{TcpStream, ToSocketAddrs},
2323
task,
2424
};
25-
use futures::{select, FutureExt, StreamExt};
25+
use futures_util::{select, FutureExt, StreamExt};
2626
2727
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
2828

Diff for: docs/src/tutorial/sending_messages.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@ if Alice and Charley send two messages to Bob at the same time, Bob will see the
1313

1414
```rust,edition2018
1515
# extern crate async_std;
16-
# extern crate futures;
16+
# extern crate futures_channel;
17+
# extern crate futures_util;
1718
# use async_std::{
1819
# io::Write,
1920
# net::TcpStream,
2021
# prelude::Stream,
2122
# };
22-
use futures::channel::mpsc; // 1
23-
use futures::sink::SinkExt;
23+
use futures_channel::mpsc; // 1
24+
use futures_util::sink::SinkExt;
2425
use std::sync::Arc;
2526
2627
# type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;

Diff for: src/io/buf_read/fill_buf.rs

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use std::pin::Pin;
2+
3+
use futures_io::AsyncBufRead;
4+
5+
use crate::future::Future;
6+
use crate::io;
7+
use crate::task::{Context, Poll};
8+
9+
#[doc(hidden)]
10+
#[allow(missing_debug_implementations)]
11+
pub struct FillBufFuture<'a, R: ?Sized> {
12+
reader: &'a mut R,
13+
}
14+
15+
impl<'a, R: ?Sized> FillBufFuture<'a, R> {
16+
pub(crate) fn new(reader: &'a mut R) -> Self {
17+
Self { reader }
18+
}
19+
}
20+
21+
impl<'a, R: AsyncBufRead + Unpin + ?Sized> Future for FillBufFuture<'a, R> {
22+
type Output = io::Result<&'a [u8]>;
23+
24+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&'a [u8]>> {
25+
let Self { reader } = &mut *self;
26+
let result = Pin::new(reader).poll_fill_buf(cx);
27+
// This is safe because:
28+
// 1. The buffer is valid for the lifetime of the reader.
29+
// 2. Output is unrelated to the wrapper (Self).
30+
result.map_ok(|buf| unsafe { std::mem::transmute::<&'_ [u8], &'a [u8]>(buf) })
31+
}
32+
}

Diff for: src/io/buf_read/mod.rs

+22
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
mod fill_buf;
12
mod lines;
23
mod read_line;
34
mod read_until;
45

6+
use fill_buf::FillBufFuture;
57
pub use lines::Lines;
68
use read_line::ReadLineFuture;
79
use read_until::ReadUntilFuture;
@@ -41,6 +43,26 @@ cfg_if! {
4143
/// [`futures::io::AsyncBufRead`]:
4244
/// https://docs.rs/futures-preview/0.3.0-alpha.17/futures/io/trait.AsyncBufRead.html
4345
pub trait BufRead {
46+
/// Returns the contents of the internal buffer, filling it with more data from the inner
47+
/// reader if it is empty.
48+
///
49+
/// This function is a lower-level call. It needs to be paired with the [`consume`] method to
50+
/// function properly. When calling this method, none of the contents will be "read" in the
51+
/// sense that later calling `read` may return the same contents. As such, [`consume`] must be
52+
/// called with the number of bytes that are consumed from this buffer to ensure that the bytes
53+
/// are never returned twice.
54+
///
55+
/// [`consume`]: #tymethod.consume
56+
///
57+
/// An empty buffer returned indicates that the stream has reached EOF.
58+
// TODO: write a proper doctest with `consume`
59+
fn fill_buf<'a>(&'a mut self) -> ret!('a, FillBufFuture, io::Result<&'a [u8]>)
60+
where
61+
Self: Unpin,
62+
{
63+
FillBufFuture::new(self)
64+
}
65+
4466
/// Reads all bytes into `buf` until the delimiter `byte` or EOF is reached.
4567
///
4668
/// This function will read bytes from the underlying stream until the delimiter or EOF is

Diff for: src/io/write/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ pub trait Write {
127127
/// #
128128
/// # Ok(()) }) }
129129
/// ```
130+
///
131+
/// [`write`]: #tymethod.write
130132
fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> ret!('a, WriteAllFuture, io::Result<()>)
131133
where
132134
Self: Unpin,

Diff for: src/stream/stream/filter_map.rs

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use std::marker::PhantomData;
2+
use std::pin::Pin;
3+
use std::task::{Context, Poll};
4+
5+
/// A stream that both filters and maps.
6+
#[derive(Clone, Debug)]
7+
pub struct FilterMap<S, F, T, B> {
8+
stream: S,
9+
f: F,
10+
__from: PhantomData<T>,
11+
__to: PhantomData<B>,
12+
}
13+
14+
impl<S, F, T, B> FilterMap<S, F, T, B> {
15+
pin_utils::unsafe_pinned!(stream: S);
16+
pin_utils::unsafe_unpinned!(f: F);
17+
18+
pub(crate) fn new(stream: S, f: F) -> Self {
19+
FilterMap {
20+
stream,
21+
f,
22+
__from: PhantomData,
23+
__to: PhantomData,
24+
}
25+
}
26+
}
27+
28+
impl<S, F, B> futures_core::stream::Stream for FilterMap<S, F, S::Item, B>
29+
where
30+
S: futures_core::stream::Stream,
31+
F: FnMut(S::Item) -> Option<B>,
32+
{
33+
type Item = B;
34+
35+
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
36+
let next = futures_core::ready!(self.as_mut().stream().poll_next(cx));
37+
match next {
38+
Some(v) => match (self.as_mut().f())(v) {
39+
Some(b) => Poll::Ready(Some(b)),
40+
None => {
41+
cx.waker().wake_by_ref();
42+
Poll::Pending
43+
}
44+
},
45+
None => Poll::Ready(None),
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)