From 6e2ed7612750a007d537be97274c8f0c62ac172a Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Wed, 24 Aug 2016 23:46:23 -0700 Subject: [PATCH] Add Never type versions of Finished and Failed --- src/lib.rs | 6 ++++- src/never.rs | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/all.rs | 20 ++++++++++++++++ 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 202523d5fe..1e843c0ea1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -174,18 +174,22 @@ pub use poll::{Poll, Async}; // Primitive futures mod done; mod empty; +#[cfg(not(feature = "never"))] mod failed; +#[cfg(not(feature = "never"))] mod finished; mod lazy; #[cfg(feature = "never")] mod never; pub use done::{done, Done}; pub use empty::{empty, Empty}; +#[cfg(not(feature = "never"))] pub use failed::{failed, Failed}; +#[cfg(not(feature = "never"))] pub use finished::{finished, Finished}; pub use lazy::{lazy, Lazy}; #[cfg(feature = "never")] -pub use never::{never, Never}; +pub use never::{never, Never, failed, Failed, finished, Finished}; // combinators mod and_then; diff --git a/src/never.rs b/src/never.rs index ef73dfd781..dfcb665e96 100644 --- a/src/never.rs +++ b/src/never.rs @@ -3,6 +3,7 @@ use {Future, Poll}; /// A future which is never resolved. /// /// This future can be created with the `empty` function. +#[derive(Copy, Clone)] pub struct Never {} /// Creates a future which never resolves, representing a computation that never @@ -23,3 +24,68 @@ impl Future for Never { Poll::NotReady } } + +/// A future representing a finished but erroneous computation. +/// +/// Created by the `failed` function. +pub struct Failed { + e: Option, +} + +/// Creates a "leaf future" from an immediate value of a failed computation. +/// +/// The returned future is similar to `done` where it will immediately run a +/// scheduled callback with the provided value. +/// +/// # Examples +/// +/// ``` +/// use futures::*; +/// +/// let future_of_err_1 = failed::(1); +/// ``` +pub fn failed(e: E) -> impl Future { + Failed { e: Some(e) }.map(|x| x) +} + +impl Future for Failed { + type Item = !; + type Error = E; + + fn poll(&mut self) -> Poll { + Poll::Err(self.e.take().expect("cannot poll Failed twice")) + } +} + +/// A future representing a finished successful computation. +/// +/// Created by the `finished` function. +pub struct Finished { + t: Option, +} + +/// Creates a "leaf future" from an immediate value of a finished and +/// successful computation. +/// +/// The returned future is similar to `done` where it will immediately run a +/// scheduled callback with the provided value. +/// +/// # Examples +/// +/// ``` +/// use futures::*; +/// +/// let future_of_1 = finished::(1); +/// ``` +pub fn finished(t: T) -> impl Future { + Finished { t: Some(t) }.map_err(|x| x) +} + +impl Future for Finished { + type Item = T; + type Error = !; + + fn poll(&mut self) -> Poll { + Poll::Ok(self.t.take().expect("cannot poll Finished twice")) + } +} diff --git a/tests/all.rs b/tests/all.rs index ac78647e52..5f09046428 100644 --- a/tests/all.rs +++ b/tests/all.rs @@ -106,6 +106,7 @@ fn test_finished() { assert_done(|| failed(1), err(1)); } +#[cfg(not(feature = "never"))] #[test] fn flatten() { fn finished(a: T) -> Finished { @@ -124,6 +125,25 @@ fn flatten() { assert_empty(|| empty::().map(finished).flatten()); } +#[cfg(feature = "never")] +#[test] +fn flatten() { + fn finished(a: T) -> impl Future { + futures::finished(a) + } + fn failed(b: E) -> impl Future { + futures::failed(b) + } + + assert_done(|| finished(finished(1)).flatten(), ok(1)); + assert_done(|| finished(failed(1)).flatten(), err(1)); + assert_done(|| failed(1u32).map(finished).flatten(), err(1)); + assert_done(|| futures::finished::<_, u8>(futures::finished::<_, u32>(1)) + .flatten(), ok(1)); + assert_empty(|| finished(empty::()).flatten()); + assert_empty(|| empty::().map(finished).flatten()); +} + #[test] fn smoke_oneshot() { assert_done(|| {