Skip to content

Commit 0c08606

Browse files
authored
Merge pull request #972 from cramertj/either-fix
Either fixes
2 parents b8369e2 + a814d7b commit 0c08606

File tree

7 files changed

+172
-4
lines changed

7 files changed

+172
-4
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/future/mod.rs

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,17 +509,49 @@ pub trait FutureExt: Future {
509509
/// assert_eq!(x, block_on(future).unwrap());
510510
/// # }
511511
/// ```
512+
#[deprecated(note = "use `left_future` instead")]
512513
fn left<B>(self) -> Either<Self, B>
513514
where B: Future<Item = Self::Item, Error = Self::Error>,
514515
Self: Sized
515516
{
516517
Either::Left(self)
517518
}
518519

520+
/// Wrap this future in an `Either` future, making it the left-hand variant
521+
/// of that `Either`.
522+
///
523+
/// This can be used in combination with the `right_future` method to write `if`
524+
/// statements that evaluate to different futures in different branches.
525+
///
526+
/// # Examples
527+
///
528+
/// ```
529+
/// # extern crate futures;
530+
/// use futures::executor::block_on;
531+
/// use futures::future::*;
532+
///
533+
/// # fn main() {
534+
/// let x = 6;
535+
/// let future = if x < 10 {
536+
/// ok::<_, bool>(x).left_future()
537+
/// } else {
538+
/// empty().right_future()
539+
/// };
540+
///
541+
/// assert_eq!(x, block_on(future).unwrap());
542+
/// # }
543+
/// ```
544+
fn left_future<B>(self) -> Either<Self, B>
545+
where B: Future<Item = Self::Item, Error = Self::Error>,
546+
Self: Sized
547+
{
548+
Either::Left(self)
549+
}
550+
519551
/// Wrap this future in an `Either` future, making it the right-hand variant
520552
/// of that `Either`.
521553
///
522-
/// This can be used in combination with the `left` method to write `if`
554+
/// This can be used in combination with the `left_future` method to write `if`
523555
/// statements that evaluate to different futures in different branches.
524556
///
525557
/// # Examples
@@ -540,13 +572,45 @@ pub trait FutureExt: Future {
540572
/// assert_eq!(x, block_on(future).unwrap());
541573
/// # }
542574
/// ```
575+
#[deprecated(note = "use `right_future` instead")]
543576
fn right<A>(self) -> Either<A, Self>
544577
where A: Future<Item = Self::Item, Error = Self::Error>,
545578
Self: Sized,
546579
{
547580
Either::Right(self)
548581
}
549582

583+
/// Wrap this future in an `Either` future, making it the right-hand variant
584+
/// of that `Either`.
585+
///
586+
/// This can be used in combination with the `left_future` method to write `if`
587+
/// statements that evaluate to different futures in different branches.
588+
///
589+
/// # Examples
590+
///
591+
/// ```
592+
/// # extern crate futures;
593+
/// use futures::executor::block_on;
594+
/// use futures::future::*;
595+
///
596+
/// # fn main() {
597+
/// let x = 6;
598+
/// let future = if x < 10 {
599+
/// ok::<_, bool>(x).left_future()
600+
/// } else {
601+
/// empty().right_future()
602+
/// };
603+
///
604+
/// assert_eq!(x, block_on(future).unwrap());
605+
/// # }
606+
/// ```
607+
fn right_future<A>(self) -> Either<A, Self>
608+
where A: Future<Item = Self::Item, Error = Self::Error>,
609+
Self: Sized,
610+
{
611+
Either::Right(self)
612+
}
613+
550614
/// Convert this future into a single element stream.
551615
///
552616
/// The returned stream contains single success if this future resolves to

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-util/src/stream/mod.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -962,12 +962,12 @@ pub trait StreamExt: Stream {
962962
recover::new(self, f)
963963
}
964964

965-
966965
/// Wrap this stream in an `Either` stream, making it the left-hand variant
967966
/// of that `Either`.
968967
///
969968
/// This can be used in combination with the `right` method to write `if`
970969
/// statements that evaluate to different streams in different branches.
970+
#[deprecated(note = "use `left_stream` instead")]
971971
fn left<B>(self) -> Either<Self, B>
972972
where B: Stream<Item = Self::Item, Error = Self::Error>,
973973
Self: Sized
@@ -980,10 +980,35 @@ pub trait StreamExt: Stream {
980980
///
981981
/// This can be used in combination with the `left` method to write `if`
982982
/// statements that evaluate to different streams in different branches.
983+
#[deprecated(note = "use `right_stream` instead")]
983984
fn right<B>(self) -> Either<B, Self>
984985
where B: Stream<Item = Self::Item, Error = Self::Error>,
985986
Self: Sized
986987
{
987988
Either::Right(self)
988989
}
990+
991+
/// Wrap this stream in an `Either` stream, making it the left-hand variant
992+
/// of that `Either`.
993+
///
994+
/// This can be used in combination with the `right_stream` method to write `if`
995+
/// statements that evaluate to different streams in different branches.
996+
fn left_stream<B>(self) -> Either<Self, B>
997+
where B: Stream<Item = Self::Item, Error = Self::Error>,
998+
Self: Sized
999+
{
1000+
Either::Left(self)
1001+
}
1002+
1003+
/// Wrap this stream in an `Either` stream, making it the right-hand variant
1004+
/// of that `Either`.
1005+
///
1006+
/// This can be used in combination with the `left_stream` method to write `if`
1007+
/// statements that evaluate to different streams in different branches.
1008+
fn right_stream<B>(self) -> Either<B, Self>
1009+
where B: Stream<Item = Self::Item, Error = Self::Error>,
1010+
Self: Sized
1011+
{
1012+
Either::Right(self)
1013+
}
9891014
}

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)