Skip to content

Commit a814d7b

Browse files
committed
Add Sink::{left_sink, right_sink}
1 parent e19e43e commit a814d7b

File tree

5 files changed

+81
-2
lines changed

5 files changed

+81
-2
lines changed

futures-sink/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ The asynchronous `Sink` trait for the futures-rs library.
1111
"""
1212

1313
[features]
14-
std = ["futures-core/std", "futures-channel/std"]
14+
std = ["either/use_std", "futures-core/std", "futures-channel/std"]
1515
default = ["std"]
1616

1717
[dependencies]
18+
either = { version = "1.4", default-features = false, optional = true }
1819
futures-core = { path = "../futures-core", version = "0.2.0", default-features = false }
1920
futures-channel = { path = "../futures-channel", version = "0.2.0", default-features = false }

futures-sink/src/lib.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,48 @@ macro_rules! if_std {
2323

2424
use futures_core::{Poll, task};
2525

26+
#[cfg(feature = "either")]
27+
extern crate either;
28+
#[cfg(feature = "either")]
29+
use either::Either;
30+
#[cfg(feature = "either")]
31+
impl<A, B> Sink for Either<A, B>
32+
where A: Sink,
33+
B: Sink<SinkItem=<A as Sink>::SinkItem,
34+
SinkError=<A as Sink>::SinkError>
35+
{
36+
type SinkItem = <A as Sink>::SinkItem;
37+
type SinkError = <A as Sink>::SinkError;
38+
39+
fn poll_ready(&mut self, cx: &mut task::Context) -> Poll<(), Self::SinkError> {
40+
match *self {
41+
Either::Left(ref mut x) => x.poll_ready(cx),
42+
Either::Right(ref mut x) => x.poll_ready(cx),
43+
}
44+
}
45+
46+
fn start_send(&mut self, item: Self::SinkItem) -> Result<(), Self::SinkError> {
47+
match *self {
48+
Either::Left(ref mut x) => x.start_send(item),
49+
Either::Right(ref mut x) => x.start_send(item),
50+
}
51+
}
52+
53+
fn poll_flush(&mut self, cx: &mut task::Context) -> Poll<(), Self::SinkError> {
54+
match *self {
55+
Either::Left(ref mut x) => x.poll_flush(cx),
56+
Either::Right(ref mut x) => x.poll_flush(cx),
57+
}
58+
}
59+
60+
fn poll_close(&mut self, cx: &mut task::Context) -> Poll<(), Self::SinkError> {
61+
match *self {
62+
Either::Left(ref mut x) => x.poll_close(cx),
63+
Either::Right(ref mut x) => x.poll_close(cx),
64+
}
65+
}
66+
}
67+
2668
if_std! {
2769
mod channel_impls;
2870

futures-util/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Common utilities and extension traits for the futures-rs library.
1212

1313
[features]
1414
std = ["futures-core/std", "futures-io/std", "futures-sink/std", "either/use_std"]
15-
default = ["std", "futures-core/either"]
15+
default = ["std", "futures-core/either", "futures-sink/either"]
1616
bench = []
1717

1818
[dependencies]

futures-util/src/sink/mod.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
66
use futures_core::{Stream, IntoFuture};
77
use futures_sink::Sink;
8+
use super::future::Either;
89

910
mod close;
1011
mod fanout;
@@ -219,4 +220,28 @@ pub trait SinkExt: Sink {
219220
{
220221
send_all::new(self, stream)
221222
}
223+
224+
/// Wrap this sink in an `Either` sink, making it the left-hand variant
225+
/// of that `Either`.
226+
///
227+
/// This can be used in combination with the `right_sink` method to write `if`
228+
/// statements that evaluate to different streams in different branches.
229+
fn left_sink<B>(self) -> Either<Self, B>
230+
where B: Sink<SinkItem = Self::SinkItem, SinkError = Self::SinkError>,
231+
Self: Sized
232+
{
233+
Either::Left(self)
234+
}
235+
236+
/// Wrap this stream in an `Either` stream, making it the right-hand variant
237+
/// of that `Either`.
238+
///
239+
/// This can be used in combination with the `left_sink` method to write `if`
240+
/// statements that evaluate to different streams in different branches.
241+
fn right_sink<B>(self) -> Either<B, Self>
242+
where B: Sink<SinkItem = Self::SinkItem, SinkError = Self::SinkError>,
243+
Self: Sized
244+
{
245+
Either::Right(self)
246+
}
222247
}

futures/tests/sink.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,17 @@ use futures::sink::SinkErrInto;
1818
mod support;
1919
use support::*;
2020

21+
#[test]
22+
fn either_sink() {
23+
let mut s = if true {
24+
Vec::<i32>::new().left_sink()
25+
} else {
26+
VecDeque::<i32>::new().right_sink()
27+
};
28+
29+
s.start_send(0).unwrap();
30+
}
31+
2132
#[test]
2233
fn vec_sink() {
2334
let mut v = Vec::new();

0 commit comments

Comments
 (0)