diff --git a/futures-sink/Cargo.toml b/futures-sink/Cargo.toml
index 56b5cad762..72cfd79e24 100644
--- a/futures-sink/Cargo.toml
+++ b/futures-sink/Cargo.toml
@@ -11,9 +11,10 @@ The asynchronous `Sink` trait for the futures-rs library.
"""
[features]
-std = ["futures-core/std", "futures-channel/std"]
+std = ["either/use_std", "futures-core/std", "futures-channel/std"]
default = ["std"]
[dependencies]
+either = { version = "1.4", default-features = false, optional = true }
futures-core = { path = "../futures-core", version = "0.2.0", default-features = false }
futures-channel = { path = "../futures-channel", version = "0.2.0", default-features = false }
diff --git a/futures-sink/src/lib.rs b/futures-sink/src/lib.rs
index 1dc2867023..0da8a92215 100644
--- a/futures-sink/src/lib.rs
+++ b/futures-sink/src/lib.rs
@@ -23,6 +23,48 @@ macro_rules! if_std {
use futures_core::{Poll, task};
+#[cfg(feature = "either")]
+extern crate either;
+#[cfg(feature = "either")]
+use either::Either;
+#[cfg(feature = "either")]
+impl Sink for Either
+ where A: Sink,
+ B: Sink::SinkItem,
+ SinkError=::SinkError>
+{
+ type SinkItem = ::SinkItem;
+ type SinkError = ::SinkError;
+
+ fn poll_ready(&mut self, cx: &mut task::Context) -> Poll<(), Self::SinkError> {
+ match *self {
+ Either::Left(ref mut x) => x.poll_ready(cx),
+ Either::Right(ref mut x) => x.poll_ready(cx),
+ }
+ }
+
+ fn start_send(&mut self, item: Self::SinkItem) -> Result<(), Self::SinkError> {
+ match *self {
+ Either::Left(ref mut x) => x.start_send(item),
+ Either::Right(ref mut x) => x.start_send(item),
+ }
+ }
+
+ fn poll_flush(&mut self, cx: &mut task::Context) -> Poll<(), Self::SinkError> {
+ match *self {
+ Either::Left(ref mut x) => x.poll_flush(cx),
+ Either::Right(ref mut x) => x.poll_flush(cx),
+ }
+ }
+
+ fn poll_close(&mut self, cx: &mut task::Context) -> Poll<(), Self::SinkError> {
+ match *self {
+ Either::Left(ref mut x) => x.poll_close(cx),
+ Either::Right(ref mut x) => x.poll_close(cx),
+ }
+ }
+}
+
if_std! {
mod channel_impls;
diff --git a/futures-util/Cargo.toml b/futures-util/Cargo.toml
index 56f4b927ad..31eab056f0 100644
--- a/futures-util/Cargo.toml
+++ b/futures-util/Cargo.toml
@@ -12,7 +12,7 @@ Common utilities and extension traits for the futures-rs library.
[features]
std = ["futures-core/std", "futures-io/std", "futures-sink/std", "either/use_std"]
-default = ["std", "futures-core/either"]
+default = ["std", "futures-core/either", "futures-sink/either"]
bench = []
[dependencies]
diff --git a/futures-util/src/future/mod.rs b/futures-util/src/future/mod.rs
index ccc2775c9d..121bd8ff48 100644
--- a/futures-util/src/future/mod.rs
+++ b/futures-util/src/future/mod.rs
@@ -509,6 +509,7 @@ pub trait FutureExt: Future {
/// assert_eq!(x, block_on(future).unwrap());
/// # }
/// ```
+ #[deprecated(note = "use `left_future` instead")]
fn left(self) -> Either
where B: Future- ,
Self: Sized
@@ -516,10 +517,41 @@ pub trait FutureExt: Future {
Either::Left(self)
}
+ /// Wrap this future in an `Either` future, making it the left-hand variant
+ /// of that `Either`.
+ ///
+ /// This can be used in combination with the `right_future` method to write `if`
+ /// statements that evaluate to different futures in different branches.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # extern crate futures;
+ /// use futures::executor::block_on;
+ /// use futures::future::*;
+ ///
+ /// # fn main() {
+ /// let x = 6;
+ /// let future = if x < 10 {
+ /// ok::<_, bool>(x).left_future()
+ /// } else {
+ /// empty().right_future()
+ /// };
+ ///
+ /// assert_eq!(x, block_on(future).unwrap());
+ /// # }
+ /// ```
+ fn left_future(self) -> Either
+ where B: Future
- ,
+ Self: Sized
+ {
+ Either::Left(self)
+ }
+
/// Wrap this future in an `Either` future, making it the right-hand variant
/// of that `Either`.
///
- /// This can be used in combination with the `left` method to write `if`
+ /// This can be used in combination with the `left_future` method to write `if`
/// statements that evaluate to different futures in different branches.
///
/// # Examples
@@ -540,6 +572,7 @@ pub trait FutureExt: Future {
/// assert_eq!(x, block_on(future).unwrap());
/// # }
/// ```
+ #[deprecated(note = "use `right_future` instead")]
fn right(self) -> Either
where A: Future
- ,
Self: Sized,
@@ -547,6 +580,37 @@ pub trait FutureExt: Future {
Either::Right(self)
}
+ /// Wrap this future in an `Either` future, making it the right-hand variant
+ /// of that `Either`.
+ ///
+ /// This can be used in combination with the `left_future` method to write `if`
+ /// statements that evaluate to different futures in different branches.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # extern crate futures;
+ /// use futures::executor::block_on;
+ /// use futures::future::*;
+ ///
+ /// # fn main() {
+ /// let x = 6;
+ /// let future = if x < 10 {
+ /// ok::<_, bool>(x).left_future()
+ /// } else {
+ /// empty().right_future()
+ /// };
+ ///
+ /// assert_eq!(x, block_on(future).unwrap());
+ /// # }
+ /// ```
+ fn right_future(self) -> Either
+ where A: Future
- ,
+ Self: Sized,
+ {
+ Either::Right(self)
+ }
+
/// Convert this future into a single element stream.
///
/// The returned stream contains single success if this future resolves to
diff --git a/futures-util/src/sink/mod.rs b/futures-util/src/sink/mod.rs
index 275c748531..9f951c6fc7 100644
--- a/futures-util/src/sink/mod.rs
+++ b/futures-util/src/sink/mod.rs
@@ -5,6 +5,7 @@
use futures_core::{Stream, IntoFuture};
use futures_sink::Sink;
+use super::future::Either;
mod close;
mod fanout;
@@ -219,4 +220,28 @@ pub trait SinkExt: Sink {
{
send_all::new(self, stream)
}
+
+ /// Wrap this sink in an `Either` sink, making it the left-hand variant
+ /// of that `Either`.
+ ///
+ /// This can be used in combination with the `right_sink` method to write `if`
+ /// statements that evaluate to different streams in different branches.
+ fn left_sink(self) -> Either
+ where B: Sink,
+ Self: Sized
+ {
+ Either::Left(self)
+ }
+
+ /// Wrap this stream in an `Either` stream, making it the right-hand variant
+ /// of that `Either`.
+ ///
+ /// This can be used in combination with the `left_sink` method to write `if`
+ /// statements that evaluate to different streams in different branches.
+ fn right_sink(self) -> Either
+ where B: Sink,
+ Self: Sized
+ {
+ Either::Right(self)
+ }
}
diff --git a/futures-util/src/stream/mod.rs b/futures-util/src/stream/mod.rs
index e3c9aaa35c..1a6d65ae89 100644
--- a/futures-util/src/stream/mod.rs
+++ b/futures-util/src/stream/mod.rs
@@ -962,12 +962,12 @@ pub trait StreamExt: Stream {
recover::new(self, f)
}
-
/// Wrap this stream in an `Either` stream, making it the left-hand variant
/// of that `Either`.
///
/// This can be used in combination with the `right` method to write `if`
/// statements that evaluate to different streams in different branches.
+ #[deprecated(note = "use `left_stream` instead")]
fn left(self) -> Either
where B: Stream
- ,
Self: Sized
@@ -980,10 +980,35 @@ pub trait StreamExt: Stream {
///
/// This can be used in combination with the `left` method to write `if`
/// statements that evaluate to different streams in different branches.
+ #[deprecated(note = "use `right_stream` instead")]
fn right(self) -> Either
where B: Stream
- ,
Self: Sized
{
Either::Right(self)
}
+
+ /// Wrap this stream in an `Either` stream, making it the left-hand variant
+ /// of that `Either`.
+ ///
+ /// This can be used in combination with the `right_stream` method to write `if`
+ /// statements that evaluate to different streams in different branches.
+ fn left_stream(self) -> Either
+ where B: Stream
- ,
+ Self: Sized
+ {
+ Either::Left(self)
+ }
+
+ /// Wrap this stream in an `Either` stream, making it the right-hand variant
+ /// of that `Either`.
+ ///
+ /// This can be used in combination with the `left_stream` method to write `if`
+ /// statements that evaluate to different streams in different branches.
+ fn right_stream(self) -> Either
+ where B: Stream
- ,
+ Self: Sized
+ {
+ Either::Right(self)
+ }
}
diff --git a/futures/tests/sink.rs b/futures/tests/sink.rs
index 603633684d..17ec5277ba 100644
--- a/futures/tests/sink.rs
+++ b/futures/tests/sink.rs
@@ -18,6 +18,17 @@ use futures::sink::SinkErrInto;
mod support;
use support::*;
+#[test]
+fn either_sink() {
+ let mut s = if true {
+ Vec::::new().left_sink()
+ } else {
+ VecDeque::::new().right_sink()
+ };
+
+ s.start_send(0).unwrap();
+}
+
#[test]
fn vec_sink() {
let mut v = Vec::new();