Skip to content

Commit

Permalink
Use our own either type
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Apr 16, 2019
1 parent 845c71e commit d03065e
Show file tree
Hide file tree
Showing 11 changed files with 170 additions and 176 deletions.
3 changes: 1 addition & 2 deletions futures-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@ name = "futures_core"

[features]
default = ["std"]
std = ["alloc", "either/use_std"]
std = ["alloc"]
nightly = []
cfg-target-has-atomic = []
alloc = []

[dependencies]
either = { version = "1.4", default-features = false, optional = true }

[dev-dependencies]
futures-preview = { path = "../futures", version = "=0.3.0-alpha.14" }
20 changes: 0 additions & 20 deletions futures-core/src/stream/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ use core::ops;
use core::pin::Pin;
use core::task::{Context, Poll};

#[cfg(feature = "either")]
use either::Either;

mod stream_obj;
pub use self::stream_obj::{StreamObj,LocalStreamObj,UnsafeStreamObj};

Expand Down Expand Up @@ -84,23 +81,6 @@ where
}
}

#[cfg(feature = "either")]
impl<A, B> Stream for Either<A, B>
where A: Stream,
B: Stream<Item = A::Item>
{
type Item = A::Item;

fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<A::Item>> {
unsafe {
match Pin::get_unchecked_mut(self) {
Either::Left(a) => Pin::new_unchecked(a).poll_next(cx),
Either::Right(b) => Pin::new_unchecked(b).poll_next(cx),
}
}
}
}

/// A `Stream` or `TryStream` which tracks whether or not the underlying stream
/// should no longer be polled.
///
Expand Down
3 changes: 1 addition & 2 deletions futures-sink/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@ The asynchronous `Sink` trait for the futures-rs library.
name = "futures_sink"

[features]
std = ["alloc", "either/use_std", "futures-core-preview/std", "futures-channel-preview/std"]
std = ["alloc", "futures-core-preview/std", "futures-channel-preview/std"]
default = ["std"]
nightly = ["futures-core-preview/nightly"]
alloc = ["futures-core-preview/alloc"]

[dependencies]
either = { version = "1.4", default-features = false, optional = true }
futures-core-preview = { path = "../futures-core", version = "=0.3.0-alpha.14", default-features = false }
futures-channel-preview = { path = "../futures-channel", version = "=0.3.0-alpha.14", default-features = false }
46 changes: 0 additions & 46 deletions futures-sink/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,49 +229,3 @@ mod if_alloc {

#[cfg(feature = "alloc")]
pub use self::if_alloc::*;

#[cfg(feature = "either")]
use either::Either;
#[cfg(feature = "either")]
impl<A, B, Item> Sink<Item> for Either<A, B>
where A: Sink<Item>,
B: Sink<Item, SinkError=A::SinkError>,
{
type SinkError = A::SinkError;

fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::SinkError>> {
unsafe {
match Pin::get_unchecked_mut(self) {
Either::Left(x) => Pin::new_unchecked(x).poll_ready(cx),
Either::Right(x) => Pin::new_unchecked(x).poll_ready(cx),
}
}
}

fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::SinkError> {
unsafe {
match Pin::get_unchecked_mut(self) {
Either::Left(x) => Pin::new_unchecked(x).start_send(item),
Either::Right(x) => Pin::new_unchecked(x).start_send(item),
}
}
}

fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::SinkError>> {
unsafe {
match Pin::get_unchecked_mut(self) {
Either::Left(x) => Pin::new_unchecked(x).poll_flush(cx),
Either::Right(x) => Pin::new_unchecked(x).poll_flush(cx),
}
}
}

fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::SinkError>> {
unsafe {
match Pin::get_unchecked_mut(self) {
Either::Left(x) => Pin::new_unchecked(x).poll_close(cx),
Either::Right(x) => Pin::new_unchecked(x).poll_close(cx),
}
}
}
}
5 changes: 2 additions & 3 deletions futures-util/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ Common utilities and extension traits for the futures-rs library.
name = "futures_util"

[features]
std = ["alloc", "futures-core-preview/std", "futures-io-preview/std", "futures-sink-preview/std", "futures-select-macro-preview/std", "either/use_std", "rand", "rand_core", "slab"]
default = ["std", "futures-core-preview/either", "futures-sink-preview/either"]
std = ["alloc", "futures-core-preview/std", "futures-io-preview/std", "futures-sink-preview/std", "futures-select-macro-preview/std", "rand", "rand_core", "slab"]
default = ["std"]
compat = ["std", "futures_01"]
io-compat = ["compat", "tokio-io"]
bench = []
Expand All @@ -30,7 +30,6 @@ futures-channel-preview = { path = "../futures-channel", version = "=0.3.0-alpha
futures-io-preview = { path = "../futures-io", version = "=0.3.0-alpha.14", default-features = false }
futures-sink-preview = { path = "../futures-sink", version = "=0.3.0-alpha.14", default-features = false}
futures-select-macro-preview = { path = "../futures-select-macro", version = "=0.3.0-alpha.14", default-features = false }
either = { version = "1.4", default-features = false }
proc-macro-hack = "0.5"
proc-macro-nested = "0.1.2"
rand = { version = "0.6.4", optional = true }
Expand Down
36 changes: 0 additions & 36 deletions futures-util/src/future/disabled/select.rs

This file was deleted.

117 changes: 117 additions & 0 deletions futures-util/src/future/either.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
use core::pin::Pin;
use core::task::{Context, Poll};
use futures_core::future::Future;
use futures_core::stream::Stream;
use futures_sink::Sink;

/// Combines two different futures, streams, or sinks having the same associated types into a single
/// type.
#[derive(Debug, Clone)]
pub enum Either<A, B> {
/// First branch of the type
Left(A),
/// Second branch of the type
Right(B),
}

impl<A, B, T> Either<(T, A), (T, B)> {
/// Factor out a homogeneous type from an either of pairs.
///
/// Here, the homogeneous type is the first element of the pairs.
pub fn factor_first(self) -> (T, Either<A, B>) {
match self {
Either::Left((x, a)) => (x, Either::Left(a)),
Either::Right((x, b)) => (x, Either::Right(b)),
}
}
}

impl<A, B, T> Either<(A, T), (B, T)> {
/// Factor out a homogeneous type from an either of pairs.
///
/// Here, the homogeneous type is the second element of the pairs.
pub fn factor_second(self) -> (Either<A, B>, T) {
match self {
Either::Left((a, x)) => (Either::Left(a), x),
Either::Right((b, x)) => (Either::Right(b), x),
}
}
}

impl<A, B> Future for Either<A, B>
where
A: Future,
B: Future<Output = A::Output>,
{
type Output = A::Output;

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<A::Output> {
unsafe {
match Pin::get_unchecked_mut(self) {
Either::Left(a) => Pin::new_unchecked(a).poll(cx),
Either::Right(b) => Pin::new_unchecked(b).poll(cx),
}
}
}
}

impl<A, B> Stream for Either<A, B>
where
A: Stream,
B: Stream<Item = A::Item>,
{
type Item = A::Item;

fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<A::Item>> {
unsafe {
match Pin::get_unchecked_mut(self) {
Either::Left(a) => Pin::new_unchecked(a).poll_next(cx),
Either::Right(b) => Pin::new_unchecked(b).poll_next(cx),
}
}
}
}

impl<A, B, Item> Sink<Item> for Either<A, B>
where
A: Sink<Item>,
B: Sink<Item, SinkError = A::SinkError>,
{
type SinkError = A::SinkError;

fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::SinkError>> {
unsafe {
match Pin::get_unchecked_mut(self) {
Either::Left(x) => Pin::new_unchecked(x).poll_ready(cx),
Either::Right(x) => Pin::new_unchecked(x).poll_ready(cx),
}
}
}

fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::SinkError> {
unsafe {
match Pin::get_unchecked_mut(self) {
Either::Left(x) => Pin::new_unchecked(x).start_send(item),
Either::Right(x) => Pin::new_unchecked(x).start_send(item),
}
}
}

fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::SinkError>> {
unsafe {
match Pin::get_unchecked_mut(self) {
Either::Left(x) => Pin::new_unchecked(x).poll_flush(cx),
Either::Right(x) => Pin::new_unchecked(x).poll_flush(cx),
}
}
}

fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::SinkError>> {
unsafe {
match Pin::get_unchecked_mut(self) {
Either::Left(x) => Pin::new_unchecked(x).poll_close(cx),
Either::Right(x) => Pin::new_unchecked(x).poll_close(cx),
}
}
}
}
Loading

0 comments on commit d03065e

Please sign in to comment.