Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion futures-sink/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
42 changes: 42 additions & 0 deletions futures-sink/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<A, B> Sink for Either<A, B>
where A: Sink,
B: Sink<SinkItem=<A as Sink>::SinkItem,
SinkError=<A as Sink>::SinkError>
{
type SinkItem = <A as Sink>::SinkItem;
type SinkError = <A as Sink>::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;

Expand Down
2 changes: 1 addition & 1 deletion futures-util/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
66 changes: 65 additions & 1 deletion futures-util/src/future/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,17 +509,49 @@ pub trait FutureExt: Future {
/// assert_eq!(x, block_on(future).unwrap());
/// # }
/// ```
#[deprecated(note = "use `left_future` instead")]
fn left<B>(self) -> Either<Self, B>
where B: Future<Item = Self::Item, Error = Self::Error>,
Self: Sized
{
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<B>(self) -> Either<Self, B>
where B: Future<Item = Self::Item, Error = Self::Error>,
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
Expand All @@ -540,13 +572,45 @@ pub trait FutureExt: Future {
/// assert_eq!(x, block_on(future).unwrap());
/// # }
/// ```
#[deprecated(note = "use `right_future` instead")]
fn right<A>(self) -> Either<A, Self>
where A: Future<Item = Self::Item, Error = Self::Error>,
Self: Sized,
{
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<A>(self) -> Either<A, Self>
where A: Future<Item = Self::Item, Error = Self::Error>,
Self: Sized,
{
Either::Right(self)
}

/// Convert this future into a single element stream.
///
/// The returned stream contains single success if this future resolves to
Expand Down
25 changes: 25 additions & 0 deletions futures-util/src/sink/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

use futures_core::{Stream, IntoFuture};
use futures_sink::Sink;
use super::future::Either;

mod close;
mod fanout;
Expand Down Expand Up @@ -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<B>(self) -> Either<Self, B>
where B: Sink<SinkItem = Self::SinkItem, SinkError = Self::SinkError>,
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<B>(self) -> Either<B, Self>
where B: Sink<SinkItem = Self::SinkItem, SinkError = Self::SinkError>,
Self: Sized
{
Either::Right(self)
}
}
27 changes: 26 additions & 1 deletion futures-util/src/stream/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<B>(self) -> Either<Self, B>
where B: Stream<Item = Self::Item, Error = Self::Error>,
Self: Sized
Expand All @@ -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<B>(self) -> Either<B, Self>
where B: Stream<Item = Self::Item, Error = Self::Error>,
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<B>(self) -> Either<Self, B>
where B: Stream<Item = Self::Item, Error = Self::Error>,
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<B>(self) -> Either<B, Self>
where B: Stream<Item = Self::Item, Error = Self::Error>,
Self: Sized
{
Either::Right(self)
}
}
11 changes: 11 additions & 0 deletions futures/tests/sink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ use futures::sink::SinkErrInto;
mod support;
use support::*;

#[test]
fn either_sink() {
let mut s = if true {
Vec::<i32>::new().left_sink()
} else {
VecDeque::<i32>::new().right_sink()
};

s.start_send(0).unwrap();
}

#[test]
fn vec_sink() {
let mut v = Vec::new();
Expand Down