Skip to content

Commit 812ce0a

Browse files
committed
Use TryStream in Sink::send_all
1 parent 0c165a3 commit 812ce0a

File tree

4 files changed

+46
-25
lines changed

4 files changed

+46
-25
lines changed

futures-util/src/sink/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//! library is activated, and it is activated by default.
88
99
use futures_core::future::Future;
10-
use futures_core::stream::Stream;
10+
use futures_core::stream::{Stream, TryStream};
1111
use crate::future::Either;
1212

1313
#[cfg(feature = "compat")]
@@ -223,7 +223,7 @@ pub trait SinkExt<Item>: Sink<Item> {
223223
&'a mut self,
224224
stream: &'a mut St
225225
) -> SendAll<'a, Self, St>
226-
where St: Stream<Item = Item> + Unpin,
226+
where &'a mut St: TryStream<Ok = Item, Error = Self::Error> + Unpin,
227227
Self: Unpin,
228228
{
229229
SendAll::new(self, stream)

futures-util/src/sink/send_all.rs

+38-18
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,70 @@
1-
use crate::stream::{StreamExt, Fuse};
1+
use crate::stream::{StreamExt, TryStreamExt, Fuse, IntoStream};
2+
use core::fmt;
23
use core::pin::Pin;
34
use futures_core::future::Future;
4-
use futures_core::stream::Stream;
5+
use futures_core::stream::TryStream;
56
use futures_core::task::{Context, Poll};
67
use futures_sink::Sink;
78

89
/// Future for the [`send_all`](super::SinkExt::send_all) method.
910
#[allow(explicit_outlives_requirements)] // https://github.com/rust-lang/rust/issues/60993
10-
#[derive(Debug)]
1111
#[must_use = "futures do nothing unless you `.await` or poll them"]
1212
pub struct SendAll<'a, Si, St>
1313
where
1414
Si: ?Sized,
15-
St: Stream + ?Sized,
15+
St: ?Sized,
16+
&'a mut St: TryStream,
1617
{
1718
sink: &'a mut Si,
18-
stream: Fuse<&'a mut St>,
19-
buffered: Option<St::Item>,
19+
stream: Fuse<IntoStream<&'a mut St>>,
20+
buffered: Option<<&'a mut St as TryStream>::Ok>,
21+
}
22+
23+
impl<'a, Si, St> fmt::Debug for SendAll<'a, Si, St>
24+
where
25+
Si: fmt::Debug + ?Sized,
26+
St: fmt::Debug + ?Sized,
27+
&'a mut St: TryStream,
28+
<&'a mut St as TryStream>::Ok: fmt::Debug,
29+
{
30+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31+
f.debug_struct("SendAll")
32+
.field("sink", &self.sink)
33+
.field("stream", &self.stream)
34+
.field("buffered", &self.buffered)
35+
.finish()
36+
}
2037
}
2138

2239
// Pinning is never projected to any fields
23-
impl<Si, St> Unpin for SendAll<'_, Si, St>
40+
impl<'a, Si, St> Unpin for SendAll<'a, Si, St>
2441
where
2542
Si: Unpin + ?Sized,
26-
St: Stream + Unpin + ?Sized,
43+
St: ?Sized,
44+
&'a mut St: TryStream + Unpin,
2745
{}
2846

29-
impl<'a, Si, St> SendAll<'a, Si, St>
47+
impl<'a, Si, St, Ok, Error> SendAll<'a, Si, St>
3048
where
31-
Si: Sink<St::Item> + Unpin + ?Sized,
32-
St: Stream + Unpin + ?Sized,
49+
Si: Sink<Ok, Error = Error> + Unpin + ?Sized,
50+
St: ?Sized,
51+
&'a mut St: TryStream<Ok = Ok, Error = Error> + Unpin,
3352
{
3453
pub(super) fn new(
3554
sink: &'a mut Si,
3655
stream: &'a mut St,
3756
) -> SendAll<'a, Si, St> {
3857
SendAll {
3958
sink,
40-
stream: stream.fuse(),
59+
stream: stream.into_stream().fuse(),
4160
buffered: None,
4261
}
4362
}
4463

4564
fn try_start_send(
4665
&mut self,
4766
cx: &mut Context<'_>,
48-
item: St::Item,
67+
item: <&'a mut St as TryStream>::Ok,
4968
) -> Poll<Result<(), Si::Error>> {
5069
debug_assert!(self.buffered.is_none());
5170
match Pin::new(&mut self.sink).poll_ready(cx)? {
@@ -60,12 +79,13 @@ where
6079
}
6180
}
6281

63-
impl<Si, St> Future for SendAll<'_, Si, St>
82+
impl<'a, Si, St, Ok, Error> Future for SendAll<'a, Si, St>
6483
where
65-
Si: Sink<St::Item> + Unpin + ?Sized,
66-
St: Stream + Unpin + ?Sized,
84+
Si: Sink<Ok, Error = Error> + Unpin + ?Sized,
85+
St: ?Sized,
86+
&'a mut St: TryStream<Ok = Ok, Error = Error> + Unpin,
6787
{
68-
type Output = Result<(), Si::Error>;
88+
type Output = Result<(), Error>;
6989

7090
fn poll(
7191
mut self: Pin<&mut Self>,
@@ -79,7 +99,7 @@ where
7999
}
80100

81101
loop {
82-
match this.stream.poll_next_unpin(cx) {
102+
match this.stream.try_poll_next_unpin(cx)? {
83103
Poll::Ready(Some(item)) => {
84104
ready!(this.try_start_send(cx, item))?
85105
}

futures/tests/sink.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,13 @@ fn send() {
8686
fn send_all() {
8787
let mut v = Vec::new();
8888

89-
block_on(v.send_all(&mut stream::iter(vec![0, 1]))).unwrap();
89+
block_on(v.send_all(&mut stream::iter(vec![0, 1]).map(Ok))).unwrap();
9090
assert_eq!(v, vec![0, 1]);
9191

92-
block_on(v.send_all(&mut stream::iter(vec![2, 3]))).unwrap();
92+
block_on(v.send_all(&mut stream::iter(vec![2, 3]).map(Ok))).unwrap();
9393
assert_eq!(v, vec![0, 1, 2, 3]);
9494

95-
block_on(v.send_all(&mut stream::iter(vec![4, 5]))).unwrap();
95+
block_on(v.send_all(&mut stream::iter(vec![4, 5]).map(Ok))).unwrap();
9696
assert_eq!(v, vec![0, 1, 2, 3, 4, 5]);
9797
}
9898

@@ -434,7 +434,7 @@ fn fanout_smoke() {
434434
let sink1 = Vec::new();
435435
let sink2 = Vec::new();
436436
let mut sink = sink1.fanout(sink2);
437-
block_on(sink.send_all(&mut stream::iter(vec![1, 2, 3]))).unwrap();
437+
block_on(sink.send_all(&mut stream::iter(vec![1, 2, 3]).map(Ok))).unwrap();
438438
let (sink1, sink2) = sink.into_inner();
439439
assert_eq!(sink1, vec![1, 2, 3]);
440440
assert_eq!(sink2, vec![1, 2, 3]);

futures/tests/split.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ fn test_split() {
6969

7070
let (sink, stream) = join.split();
7171
let join = sink.reunite(stream).expect("test_split: reunite error");
72-
let (mut sink, mut stream) = join.split();
72+
let (mut sink, stream) = join.split();
73+
let mut stream = stream.map(Ok);
7374
block_on(sink.send_all(&mut stream)).unwrap();
7475
}
7576
assert_eq!(dest, vec![10, 20, 30]);

0 commit comments

Comments
 (0)