diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /third_party/rust/futures-0.1.31/src/future | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/futures-0.1.31/src/future')
28 files changed, 3059 insertions, 0 deletions
diff --git a/third_party/rust/futures-0.1.31/src/future/and_then.rs b/third_party/rust/futures-0.1.31/src/future/and_then.rs new file mode 100644 index 0000000000..2e5b6aa16e --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/and_then.rs @@ -0,0 +1,38 @@ +use {Future, IntoFuture, Poll}; +use super::chain::Chain; + +/// Future for the `and_then` combinator, chaining a computation onto the end of +/// another future which completes successfully. +/// +/// This is created by the `Future::and_then` method. +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct AndThen<A, B, F> where A: Future, B: IntoFuture { + state: Chain<A, B::Future, F>, +} + +pub fn new<A, B, F>(future: A, f: F) -> AndThen<A, B, F> + where A: Future, + B: IntoFuture, +{ + AndThen { + state: Chain::new(future, f), + } +} + +impl<A, B, F> Future for AndThen<A, B, F> + where A: Future, + B: IntoFuture<Error=A::Error>, + F: FnOnce(A::Item) -> B, +{ + type Item = B::Item; + type Error = B::Error; + + fn poll(&mut self) -> Poll<B::Item, B::Error> { + self.state.poll(|result, f| { + result.map(|e| { + Err(f(e).into_future()) + }) + }) + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/catch_unwind.rs b/third_party/rust/futures-0.1.31/src/future/catch_unwind.rs new file mode 100644 index 0000000000..f87f118185 --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/catch_unwind.rs @@ -0,0 +1,51 @@ +use std::prelude::v1::*; +use std::any::Any; +use std::panic::{catch_unwind, UnwindSafe, AssertUnwindSafe}; + +use {Future, Poll, Async}; + +/// Future for the `catch_unwind` combinator. +/// +/// This is created by the `Future::catch_unwind` method. +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct CatchUnwind<F> where F: Future { + future: Option<F>, +} + +pub fn new<F>(future: F) -> CatchUnwind<F> + where F: Future + UnwindSafe, +{ + CatchUnwind { + future: Some(future), + } +} + +impl<F> Future for CatchUnwind<F> + where F: Future + UnwindSafe, +{ + type Item = Result<F::Item, F::Error>; + type Error = Box<Any + Send>; + + fn poll(&mut self) -> Poll<Self::Item, Self::Error> { + let mut future = self.future.take().expect("cannot poll twice"); + let (res, future) = catch_unwind(|| (future.poll(), future))?; + match res { + Ok(Async::NotReady) => { + self.future = Some(future); + Ok(Async::NotReady) + } + Ok(Async::Ready(t)) => Ok(Async::Ready(Ok(t))), + Err(e) => Ok(Async::Ready(Err(e))), + } + } +} + +impl<F: Future> Future for AssertUnwindSafe<F> { + type Item = F::Item; + type Error = F::Error; + + fn poll(&mut self) -> Poll<F::Item, F::Error> { + self.0.poll() + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/chain.rs b/third_party/rust/futures-0.1.31/src/future/chain.rs new file mode 100644 index 0000000000..1bf5cd639c --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/chain.rs @@ -0,0 +1,48 @@ +use core::mem; + +use {Future, Poll, Async}; + +#[derive(Debug)] +pub enum Chain<A, B, C> where A: Future { + First(A, C), + Second(B), + Done, +} + +impl<A, B, C> Chain<A, B, C> + where A: Future, + B: Future, +{ + pub fn new(a: A, c: C) -> Chain<A, B, C> { + Chain::First(a, c) + } + + pub fn poll<F>(&mut self, f: F) -> Poll<B::Item, B::Error> + where F: FnOnce(Result<A::Item, A::Error>, C) + -> Result<Result<B::Item, B>, B::Error>, + { + let a_result = match *self { + Chain::First(ref mut a, _) => { + match a.poll() { + Ok(Async::NotReady) => return Ok(Async::NotReady), + Ok(Async::Ready(t)) => Ok(t), + Err(e) => Err(e), + } + } + Chain::Second(ref mut b) => return b.poll(), + Chain::Done => panic!("cannot poll a chained future twice"), + }; + let data = match mem::replace(self, Chain::Done) { + Chain::First(_, c) => c, + _ => panic!(), + }; + match f(a_result, data)? { + Ok(e) => Ok(Async::Ready(e)), + Err(mut b) => { + let ret = b.poll(); + *self = Chain::Second(b); + ret + } + } + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/either.rs b/third_party/rust/futures-0.1.31/src/future/either.rs new file mode 100644 index 0000000000..253f26784c --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/either.rs @@ -0,0 +1,54 @@ +use {Future, Poll, Stream}; + +/// Combines two different futures yielding the same item and error +/// types into a single type. +#[derive(Debug)] +pub enum Either<A, B> { + /// First branch of the type + A(A), + /// Second branch of the type + B(B), +} + +impl<T, A, B> Either<(T, A), (T, B)> { + /// Splits out the homogeneous type from an either of tuples. + /// + /// This method is typically useful when combined with the `Future::select2` + /// combinator. + pub fn split(self) -> (T, Either<A, B>) { + match self { + Either::A((a, b)) => (a, Either::A(b)), + Either::B((a, b)) => (a, Either::B(b)), + } + } +} + +impl<A, B> Future for Either<A, B> + where A: Future, + B: Future<Item = A::Item, Error = A::Error> +{ + type Item = A::Item; + type Error = A::Error; + + fn poll(&mut self) -> Poll<A::Item, A::Error> { + match *self { + Either::A(ref mut a) => a.poll(), + Either::B(ref mut b) => b.poll(), + } + } +} + +impl<A, B> Stream for Either<A, B> + where A: Stream, + B: Stream<Item = A::Item, Error = A::Error> +{ + type Item = A::Item; + type Error = A::Error; + + fn poll(&mut self) -> Poll<Option<A::Item>, A::Error> { + match *self { + Either::A(ref mut a) => a.poll(), + Either::B(ref mut b) => b.poll(), + } + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/empty.rs b/third_party/rust/futures-0.1.31/src/future/empty.rs new file mode 100644 index 0000000000..fbb56b26fd --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/empty.rs @@ -0,0 +1,31 @@ +//! Definition of the Empty combinator, a future that's never ready. + +use core::marker; + +use {Future, Poll, Async}; + +/// A future which is never resolved. +/// +/// This future can be created with the `empty` function. +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct Empty<T, E> { + _data: marker::PhantomData<(T, E)>, +} + +/// Creates a future which never resolves, representing a computation that never +/// finishes. +/// +/// The returned future will forever return `Async::NotReady`. +pub fn empty<T, E>() -> Empty<T, E> { + Empty { _data: marker::PhantomData } +} + +impl<T, E> Future for Empty<T, E> { + type Item = T; + type Error = E; + + fn poll(&mut self) -> Poll<T, E> { + Ok(Async::NotReady) + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/flatten.rs b/third_party/rust/futures-0.1.31/src/future/flatten.rs new file mode 100644 index 0000000000..bfe286975c --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/flatten.rs @@ -0,0 +1,49 @@ +use {Future, IntoFuture, Poll}; +use core::fmt; +use super::chain::Chain; + +/// Future for the `flatten` combinator, flattening a future-of-a-future to get just +/// the result of the final future. +/// +/// This is created by the `Future::flatten` method. +#[must_use = "futures do nothing unless polled"] +pub struct Flatten<A> where A: Future, A::Item: IntoFuture { + state: Chain<A, <A::Item as IntoFuture>::Future, ()>, +} + +impl<A> fmt::Debug for Flatten<A> + where A: Future + fmt::Debug, + A::Item: IntoFuture, + <<A as IntoFuture>::Item as IntoFuture>::Future: fmt::Debug, +{ + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("Flatten") + .field("state", &self.state) + .finish() + } +} + +pub fn new<A>(future: A) -> Flatten<A> + where A: Future, + A::Item: IntoFuture, +{ + Flatten { + state: Chain::new(future, ()), + } +} + +impl<A> Future for Flatten<A> + where A: Future, + A::Item: IntoFuture, + <<A as Future>::Item as IntoFuture>::Error: From<<A as Future>::Error> +{ + type Item = <<A as Future>::Item as IntoFuture>::Item; + type Error = <<A as Future>::Item as IntoFuture>::Error; + + fn poll(&mut self) -> Poll<Self::Item, Self::Error> { + self.state.poll(|a, ()| { + let future = a?.into_future(); + Ok(Err(future)) + }) + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/flatten_stream.rs b/third_party/rust/futures-0.1.31/src/future/flatten_stream.rs new file mode 100644 index 0000000000..7bf3b9ca79 --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/flatten_stream.rs @@ -0,0 +1,99 @@ +use {Async, Future, Poll}; +use core::fmt; +use stream::Stream; + +/// Future for the `flatten_stream` combinator, flattening a +/// future-of-a-stream to get just the result of the final stream as a stream. +/// +/// This is created by the `Future::flatten_stream` method. +#[must_use = "streams do nothing unless polled"] +pub struct FlattenStream<F> + where F: Future, + <F as Future>::Item: Stream<Error=F::Error>, +{ + state: State<F> +} + +impl<F> fmt::Debug for FlattenStream<F> + where F: Future + fmt::Debug, + <F as Future>::Item: Stream<Error=F::Error> + fmt::Debug, +{ + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("FlattenStream") + .field("state", &self.state) + .finish() + } +} + +pub fn new<F>(f: F) -> FlattenStream<F> + where F: Future, + <F as Future>::Item: Stream<Error=F::Error>, +{ + FlattenStream { + state: State::Future(f) + } +} + +#[derive(Debug)] +enum State<F> + where F: Future, + <F as Future>::Item: Stream<Error=F::Error>, +{ + // future is not yet called or called and not ready + Future(F), + // future resolved to Stream + Stream(F::Item), + // EOF after future resolved to error + Eof, + // after EOF after future resolved to error + Done, +} + +impl<F> Stream for FlattenStream<F> + where F: Future, + <F as Future>::Item: Stream<Error=F::Error>, +{ + type Item = <F::Item as Stream>::Item; + type Error = <F::Item as Stream>::Error; + + fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> { + loop { + let (next_state, ret_opt) = match self.state { + State::Future(ref mut f) => { + match f.poll() { + Ok(Async::NotReady) => { + // State is not changed, early return. + return Ok(Async::NotReady) + }, + Ok(Async::Ready(stream)) => { + // Future resolved to stream. + // We do not return, but poll that + // stream in the next loop iteration. + (State::Stream(stream), None) + } + Err(e) => { + (State::Eof, Some(Err(e))) + } + } + } + State::Stream(ref mut s) => { + // Just forward call to the stream, + // do not track its state. + return s.poll(); + } + State::Eof => { + (State::Done, Some(Ok(Async::Ready(None)))) + } + State::Done => { + panic!("poll called after eof"); + } + }; + + self.state = next_state; + if let Some(ret) = ret_opt { + return ret; + } + } + } +} + diff --git a/third_party/rust/futures-0.1.31/src/future/from_err.rs b/third_party/rust/futures-0.1.31/src/future/from_err.rs new file mode 100644 index 0000000000..97e35d7cc7 --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/from_err.rs @@ -0,0 +1,35 @@ +use core::marker::PhantomData; + +use {Future, Poll, Async}; + +/// Future for the `from_err` combinator, changing the error type of a future. +/// +/// This is created by the `Future::from_err` method. +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct FromErr<A, E> where A: Future { + future: A, + f: PhantomData<E> +} + +pub fn new<A, E>(future: A) -> FromErr<A, E> + where A: Future +{ + FromErr { + future: future, + f: PhantomData + } +} + +impl<A:Future, E:From<A::Error>> Future for FromErr<A, E> { + type Item = A::Item; + type Error = E; + + fn poll(&mut self) -> Poll<A::Item, E> { + let e = match self.future.poll() { + Ok(Async::NotReady) => return Ok(Async::NotReady), + other => other, + }; + e.map_err(From::from) + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/fuse.rs b/third_party/rust/futures-0.1.31/src/future/fuse.rs new file mode 100644 index 0000000000..05ad3d5afa --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/fuse.rs @@ -0,0 +1,49 @@ +use {Future, Poll, Async}; + +/// A future which "fuses" a future once it's been resolved. +/// +/// Normally futures can behave unpredictable once they're used after a future +/// has been resolved, but `Fuse` is always defined to return `Async::NotReady` +/// from `poll` after it has resolved successfully or returned an error. +/// +/// This is created by the `Future::fuse` method. +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct Fuse<A: Future> { + future: Option<A>, +} + +pub fn new<A: Future>(f: A) -> Fuse<A> { + Fuse { + future: Some(f), + } +} + +impl<A: Future> Fuse<A> { + /// Returns whether the underlying future has finished or not. + /// + /// If this method returns `true`, then all future calls to `poll` + /// are guaranteed to return `Ok(Async::NotReady)`. If this returns + /// false, then the underlying future has not been driven to + /// completion. + pub fn is_done(&self) -> bool { + self.future.is_none() + } +} + +impl<A: Future> Future for Fuse<A> { + type Item = A::Item; + type Error = A::Error; + + fn poll(&mut self) -> Poll<A::Item, A::Error> { + let res = self.future.as_mut().map(|f| f.poll()); + match res.unwrap_or(Ok(Async::NotReady)) { + res @ Ok(Async::Ready(_)) | + res @ Err(_) => { + self.future = None; + res + } + Ok(Async::NotReady) => Ok(Async::NotReady) + } + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/inspect.rs b/third_party/rust/futures-0.1.31/src/future/inspect.rs new file mode 100644 index 0000000000..59fcd78638 --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/inspect.rs @@ -0,0 +1,40 @@ +use {Future, Poll, Async}; + +/// Do something with the item of a future, passing it on. +/// +/// This is created by the `Future::inspect` method. +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct Inspect<A, F> where A: Future { + future: A, + f: Option<F>, +} + +pub fn new<A, F>(future: A, f: F) -> Inspect<A, F> + where A: Future, + F: FnOnce(&A::Item), +{ + Inspect { + future: future, + f: Some(f), + } +} + +impl<A, F> Future for Inspect<A, F> + where A: Future, + F: FnOnce(&A::Item), +{ + type Item = A::Item; + type Error = A::Error; + + fn poll(&mut self) -> Poll<A::Item, A::Error> { + match self.future.poll() { + Ok(Async::NotReady) => Ok(Async::NotReady), + Ok(Async::Ready(e)) => { + (self.f.take().expect("cannot poll Inspect twice"))(&e); + Ok(Async::Ready(e)) + }, + Err(e) => Err(e), + } + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/into_stream.rs b/third_party/rust/futures-0.1.31/src/future/into_stream.rs new file mode 100644 index 0000000000..6e299e6a21 --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/into_stream.rs @@ -0,0 +1,36 @@ +use {Async, Poll}; +use Future; +use stream::Stream; + +/// Future that forwards one element from the underlying future +/// (whether it is success of error) and emits EOF after that. +#[derive(Debug)] +pub struct IntoStream<F: Future> { + future: Option<F> +} + +pub fn new<F: Future>(future: F) -> IntoStream<F> { + IntoStream { + future: Some(future) + } +} + +impl<F: Future> Stream for IntoStream<F> { + type Item = F::Item; + type Error = F::Error; + + fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> { + let ret = match self.future { + None => return Ok(Async::Ready(None)), + Some(ref mut future) => { + match future.poll() { + Ok(Async::NotReady) => return Ok(Async::NotReady), + Err(e) => Err(e), + Ok(Async::Ready(r)) => Ok(r), + } + } + }; + self.future = None; + ret.map(|r| Async::Ready(Some(r))) + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/join.rs b/third_party/rust/futures-0.1.31/src/future/join.rs new file mode 100644 index 0000000000..452121200b --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/join.rs @@ -0,0 +1,172 @@ +#![allow(non_snake_case)] + +use core::fmt; +use core::mem; + +use {Future, Poll, IntoFuture, Async}; + +macro_rules! generate { + ($( + $(#[$doc:meta])* + ($Join:ident, $new:ident, <A, $($B:ident),*>), + )*) => ($( + $(#[$doc])* + #[must_use = "futures do nothing unless polled"] + pub struct $Join<A, $($B),*> + where A: Future, + $($B: Future<Error=A::Error>),* + { + a: MaybeDone<A>, + $($B: MaybeDone<$B>,)* + } + + impl<A, $($B),*> fmt::Debug for $Join<A, $($B),*> + where A: Future + fmt::Debug, + A::Item: fmt::Debug, + $( + $B: Future<Error=A::Error> + fmt::Debug, + $B::Item: fmt::Debug + ),* + { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct(stringify!($Join)) + .field("a", &self.a) + $(.field(stringify!($B), &self.$B))* + .finish() + } + } + + pub fn $new<A, $($B),*>(a: A, $($B: $B),*) -> $Join<A, $($B),*> + where A: Future, + $($B: Future<Error=A::Error>),* + { + $Join { + a: MaybeDone::NotYet(a), + $($B: MaybeDone::NotYet($B)),* + } + } + + impl<A, $($B),*> $Join<A, $($B),*> + where A: Future, + $($B: Future<Error=A::Error>),* + { + fn erase(&mut self) { + self.a = MaybeDone::Gone; + $(self.$B = MaybeDone::Gone;)* + } + } + + impl<A, $($B),*> Future for $Join<A, $($B),*> + where A: Future, + $($B: Future<Error=A::Error>),* + { + type Item = (A::Item, $($B::Item),*); + type Error = A::Error; + + fn poll(&mut self) -> Poll<Self::Item, Self::Error> { + let mut all_done = match self.a.poll() { + Ok(done) => done, + Err(e) => { + self.erase(); + return Err(e) + } + }; + $( + all_done = match self.$B.poll() { + Ok(done) => all_done && done, + Err(e) => { + self.erase(); + return Err(e) + } + }; + )* + + if all_done { + Ok(Async::Ready((self.a.take(), $(self.$B.take()),*))) + } else { + Ok(Async::NotReady) + } + } + } + + impl<A, $($B),*> IntoFuture for (A, $($B),*) + where A: IntoFuture, + $( + $B: IntoFuture<Error=A::Error> + ),* + { + type Future = $Join<A::Future, $($B::Future),*>; + type Item = (A::Item, $($B::Item),*); + type Error = A::Error; + + fn into_future(self) -> Self::Future { + match self { + (a, $($B),+) => { + $new( + IntoFuture::into_future(a), + $(IntoFuture::into_future($B)),+ + ) + } + } + } + } + + )*) +} + +generate! { + /// Future for the `join` combinator, waiting for two futures to + /// complete. + /// + /// This is created by the `Future::join` method. + (Join, new, <A, B>), + + /// Future for the `join3` combinator, waiting for three futures to + /// complete. + /// + /// This is created by the `Future::join3` method. + (Join3, new3, <A, B, C>), + + /// Future for the `join4` combinator, waiting for four futures to + /// complete. + /// + /// This is created by the `Future::join4` method. + (Join4, new4, <A, B, C, D>), + + /// Future for the `join5` combinator, waiting for five futures to + /// complete. + /// + /// This is created by the `Future::join5` method. + (Join5, new5, <A, B, C, D, E>), +} + +#[derive(Debug)] +enum MaybeDone<A: Future> { + NotYet(A), + Done(A::Item), + Gone, +} + +impl<A: Future> MaybeDone<A> { + fn poll(&mut self) -> Result<bool, A::Error> { + let res = match *self { + MaybeDone::NotYet(ref mut a) => a.poll()?, + MaybeDone::Done(_) => return Ok(true), + MaybeDone::Gone => panic!("cannot poll Join twice"), + }; + match res { + Async::Ready(res) => { + *self = MaybeDone::Done(res); + Ok(true) + } + Async::NotReady => Ok(false), + } + } + + fn take(&mut self) -> A::Item { + match mem::replace(self, MaybeDone::Gone) { + MaybeDone::Done(a) => a, + _ => panic!(), + } + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/join_all.rs b/third_party/rust/futures-0.1.31/src/future/join_all.rs new file mode 100644 index 0000000000..398a7a4736 --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/join_all.rs @@ -0,0 +1,136 @@ +//! Definition of the `JoinAll` combinator, waiting for all of a list of futures +//! to finish. + +use std::prelude::v1::*; + +use std::fmt; +use std::mem; + +use {Future, IntoFuture, Poll, Async}; + +#[derive(Debug)] +enum ElemState<T> where T: Future { + Pending(T), + Done(T::Item), +} + +/// A future which takes a list of futures and resolves with a vector of the +/// completed values. +/// +/// This future is created with the `join_all` method. +#[must_use = "futures do nothing unless polled"] +pub struct JoinAll<I> + where I: IntoIterator, + I::Item: IntoFuture, +{ + elems: Vec<ElemState<<I::Item as IntoFuture>::Future>>, +} + +impl<I> fmt::Debug for JoinAll<I> + where I: IntoIterator, + I::Item: IntoFuture, + <<I as IntoIterator>::Item as IntoFuture>::Future: fmt::Debug, + <<I as IntoIterator>::Item as IntoFuture>::Item: fmt::Debug, +{ + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("JoinAll") + .field("elems", &self.elems) + .finish() + } +} + +/// Creates a future which represents a collection of the results of the futures +/// given. +/// +/// The returned future will drive execution for all of its underlying futures, +/// collecting the results into a destination `Vec<T>` in the same order as they +/// were provided. If any future returns an error then all other futures will be +/// canceled and an error will be returned immediately. If all futures complete +/// successfully, however, then the returned future will succeed with a `Vec` of +/// all the successful results. +/// +/// # Examples +/// +/// ``` +/// use futures::future::*; +/// +/// let f = join_all(vec![ +/// ok::<u32, u32>(1), +/// ok::<u32, u32>(2), +/// ok::<u32, u32>(3), +/// ]); +/// let f = f.map(|x| { +/// assert_eq!(x, [1, 2, 3]); +/// }); +/// +/// let f = join_all(vec![ +/// Box::new(ok::<u32, u32>(1)), +/// Box::new(err::<u32, u32>(2)), +/// Box::new(ok::<u32, u32>(3)), +/// ]); +/// let f = f.then(|x| { +/// assert_eq!(x, Err(2)); +/// x +/// }); +/// ``` +pub fn join_all<I>(i: I) -> JoinAll<I> + where I: IntoIterator, + I::Item: IntoFuture, +{ + let elems = i.into_iter().map(|f| { + ElemState::Pending(f.into_future()) + }).collect(); + JoinAll { elems: elems } +} + +impl<I> Future for JoinAll<I> + where I: IntoIterator, + I::Item: IntoFuture, +{ + type Item = Vec<<I::Item as IntoFuture>::Item>; + type Error = <I::Item as IntoFuture>::Error; + + + fn poll(&mut self) -> Poll<Self::Item, Self::Error> { + let mut all_done = true; + + for idx in 0 .. self.elems.len() { + let done_val = match self.elems[idx] { + ElemState::Pending(ref mut t) => { + match t.poll() { + Ok(Async::Ready(v)) => Ok(v), + Ok(Async::NotReady) => { + all_done = false; + continue + } + Err(e) => Err(e), + } + } + ElemState::Done(ref mut _v) => continue, + }; + + match done_val { + Ok(v) => self.elems[idx] = ElemState::Done(v), + Err(e) => { + // On completion drop all our associated resources + // ASAP. + self.elems = Vec::new(); + return Err(e) + } + } + } + + if all_done { + let elems = mem::replace(&mut self.elems, Vec::new()); + let result = elems.into_iter().map(|e| { + match e { + ElemState::Done(t) => t, + _ => unreachable!(), + } + }).collect(); + Ok(Async::Ready(result)) + } else { + Ok(Async::NotReady) + } + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/lazy.rs b/third_party/rust/futures-0.1.31/src/future/lazy.rs new file mode 100644 index 0000000000..2f310337b6 --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/lazy.rs @@ -0,0 +1,84 @@ +//! Definition of the Lazy combinator, deferring execution of a function until +//! the future is polled. + +use core::mem; + +use {Future, IntoFuture, Poll}; + +/// A future which defers creation of the actual future until a callback is +/// scheduled. +/// +/// This is created by the `lazy` function. +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct Lazy<F, R: IntoFuture> { + inner: _Lazy<F, R::Future>, +} + +#[derive(Debug)] +enum _Lazy<F, R> { + First(F), + Second(R), + Moved, +} + +/// Creates a new future which will eventually be the same as the one created +/// by the closure provided. +/// +/// The provided closure is only run once the future has a callback scheduled +/// on it, otherwise the callback never runs. Once run, however, this future is +/// the same as the one the closure creates. +/// +/// # Examples +/// +/// ``` +/// use futures::future::*; +/// +/// let a = lazy(|| ok::<u32, u32>(1)); +/// +/// let b = lazy(|| -> FutureResult<u32, u32> { +/// panic!("oh no!") +/// }); +/// drop(b); // closure is never run +/// ``` +pub fn lazy<F, R>(f: F) -> Lazy<F, R> + where F: FnOnce() -> R, + R: IntoFuture +{ + Lazy { + inner: _Lazy::First(f), + } +} + +impl<F, R> Lazy<F, R> + where F: FnOnce() -> R, + R: IntoFuture, +{ + fn get(&mut self) -> &mut R::Future { + match self.inner { + _Lazy::First(_) => {} + _Lazy::Second(ref mut f) => return f, + _Lazy::Moved => panic!(), // can only happen if `f()` panics + } + match mem::replace(&mut self.inner, _Lazy::Moved) { + _Lazy::First(f) => self.inner = _Lazy::Second(f().into_future()), + _ => panic!(), // we already found First + } + match self.inner { + _Lazy::Second(ref mut f) => f, + _ => panic!(), // we just stored Second + } + } +} + +impl<F, R> Future for Lazy<F, R> + where F: FnOnce() -> R, + R: IntoFuture, +{ + type Item = R::Item; + type Error = R::Error; + + fn poll(&mut self) -> Poll<R::Item, R::Error> { + self.get().poll() + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/loop_fn.rs b/third_party/rust/futures-0.1.31/src/future/loop_fn.rs new file mode 100644 index 0000000000..299a0383c2 --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/loop_fn.rs @@ -0,0 +1,99 @@ +//! Definition of the `LoopFn` combinator, implementing `Future` loops. + +use {Async, Future, IntoFuture, Poll}; + +/// The status of a `loop_fn` loop. +#[derive(Debug)] +pub enum Loop<T, S> { + /// Indicates that the loop has completed with output `T`. + Break(T), + + /// Indicates that the loop function should be called again with input + /// state `S`. + Continue(S), +} + +/// A future implementing a tail-recursive loop. +/// +/// Created by the `loop_fn` function. +#[derive(Debug)] +pub struct LoopFn<A, F> where A: IntoFuture { + future: A::Future, + func: F, +} + +/// Creates a new future implementing a tail-recursive loop. +/// +/// The loop function is immediately called with `initial_state` and should +/// return a value that can be converted to a future. On successful completion, +/// this future should output a `Loop<T, S>` to indicate the status of the +/// loop. +/// +/// `Loop::Break(T)` halts the loop and completes the future with output `T`. +/// +/// `Loop::Continue(S)` reinvokes the loop function with state `S`. The returned +/// future will be subsequently polled for a new `Loop<T, S>` value. +/// +/// # Examples +/// +/// ``` +/// use futures::future::{ok, loop_fn, Future, FutureResult, Loop}; +/// use std::io::Error; +/// +/// struct Client { +/// ping_count: u8, +/// } +/// +/// impl Client { +/// fn new() -> Self { +/// Client { ping_count: 0 } +/// } +/// +/// fn send_ping(self) -> FutureResult<Self, Error> { +/// ok(Client { ping_count: self.ping_count + 1 }) +/// } +/// +/// fn receive_pong(self) -> FutureResult<(Self, bool), Error> { +/// let done = self.ping_count >= 5; +/// ok((self, done)) +/// } +/// } +/// +/// let ping_til_done = loop_fn(Client::new(), |client| { +/// client.send_ping() +/// .and_then(|client| client.receive_pong()) +/// .and_then(|(client, done)| { +/// if done { +/// Ok(Loop::Break(client)) +/// } else { +/// Ok(Loop::Continue(client)) +/// } +/// }) +/// }); +/// ``` +pub fn loop_fn<S, T, A, F>(initial_state: S, mut func: F) -> LoopFn<A, F> + where F: FnMut(S) -> A, + A: IntoFuture<Item = Loop<T, S>>, +{ + LoopFn { + future: func(initial_state).into_future(), + func: func, + } +} + +impl<S, T, A, F> Future for LoopFn<A, F> + where F: FnMut(S) -> A, + A: IntoFuture<Item = Loop<T, S>>, +{ + type Item = T; + type Error = A::Error; + + fn poll(&mut self) -> Poll<Self::Item, Self::Error> { + loop { + match try_ready!(self.future.poll()) { + Loop::Break(x) => return Ok(Async::Ready(x)), + Loop::Continue(s) => self.future = (self.func)(s).into_future(), + } + } + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/map.rs b/third_party/rust/futures-0.1.31/src/future/map.rs new file mode 100644 index 0000000000..4b1f4cd7d4 --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/map.rs @@ -0,0 +1,38 @@ +use {Future, Poll, Async}; + +/// Future for the `map` combinator, changing the type of a future. +/// +/// This is created by the `Future::map` method. +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct Map<A, F> where A: Future { + future: A, + f: Option<F>, +} + +pub fn new<A, F>(future: A, f: F) -> Map<A, F> + where A: Future, +{ + Map { + future: future, + f: Some(f), + } +} + +impl<U, A, F> Future for Map<A, F> + where A: Future, + F: FnOnce(A::Item) -> U, +{ + type Item = U; + type Error = A::Error; + + fn poll(&mut self) -> Poll<U, A::Error> { + let e = match self.future.poll() { + Ok(Async::NotReady) => return Ok(Async::NotReady), + Ok(Async::Ready(e)) => Ok(e), + Err(e) => Err(e), + }; + e.map(self.f.take().expect("cannot poll Map twice")) + .map(Async::Ready) + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/map_err.rs b/third_party/rust/futures-0.1.31/src/future/map_err.rs new file mode 100644 index 0000000000..4ea12f4586 --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/map_err.rs @@ -0,0 +1,36 @@ +use {Future, Poll, Async}; + +/// Future for the `map_err` combinator, changing the error type of a future. +/// +/// This is created by the `Future::map_err` method. +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct MapErr<A, F> where A: Future { + future: A, + f: Option<F>, +} + +pub fn new<A, F>(future: A, f: F) -> MapErr<A, F> + where A: Future +{ + MapErr { + future: future, + f: Some(f), + } +} + +impl<U, A, F> Future for MapErr<A, F> + where A: Future, + F: FnOnce(A::Error) -> U, +{ + type Item = A::Item; + type Error = U; + + fn poll(&mut self) -> Poll<A::Item, U> { + let e = match self.future.poll() { + Ok(Async::NotReady) => return Ok(Async::NotReady), + other => other, + }; + e.map_err(self.f.take().expect("cannot poll MapErr twice")) + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/mod.rs b/third_party/rust/futures-0.1.31/src/future/mod.rs new file mode 100644 index 0000000000..9867765902 --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/mod.rs @@ -0,0 +1,1171 @@ +//! Futures +//! +//! This module contains the `Future` trait and a number of adaptors for this +//! trait. See the crate docs, and the docs for `Future`, for full detail. + +use core::fmt; +use core::result; + +// Primitive futures +mod empty; +mod lazy; +mod poll_fn; +#[path = "result.rs"] +mod result_; +mod loop_fn; +mod option; +pub use self::empty::{empty, Empty}; +pub use self::lazy::{lazy, Lazy}; +pub use self::poll_fn::{poll_fn, PollFn}; +pub use self::result_::{result, ok, err, FutureResult}; +pub use self::loop_fn::{loop_fn, Loop, LoopFn}; + +#[doc(hidden)] +#[deprecated(since = "0.1.4", note = "use `ok` instead")] +#[cfg(feature = "with-deprecated")] +pub use self::{ok as finished, Ok as Finished}; +#[doc(hidden)] +#[deprecated(since = "0.1.4", note = "use `err` instead")] +#[cfg(feature = "with-deprecated")] +pub use self::{err as failed, Err as Failed}; +#[doc(hidden)] +#[deprecated(since = "0.1.4", note = "use `result` instead")] +#[cfg(feature = "with-deprecated")] +pub use self::{result as done, FutureResult as Done}; +#[doc(hidden)] +#[deprecated(since = "0.1.7", note = "use `FutureResult` instead")] +#[cfg(feature = "with-deprecated")] +pub use self::{FutureResult as Ok}; +#[doc(hidden)] +#[deprecated(since = "0.1.7", note = "use `FutureResult` instead")] +#[cfg(feature = "with-deprecated")] +pub use self::{FutureResult as Err}; + +// combinators +mod and_then; +mod flatten; +mod flatten_stream; +mod fuse; +mod into_stream; +mod join; +mod map; +mod map_err; +mod from_err; +mod or_else; +mod select; +mod select2; +mod then; +mod either; +mod inspect; + +// impl details +mod chain; + +pub use self::and_then::AndThen; +pub use self::flatten::Flatten; +pub use self::flatten_stream::FlattenStream; +pub use self::fuse::Fuse; +pub use self::into_stream::IntoStream; +pub use self::join::{Join, Join3, Join4, Join5}; +pub use self::map::Map; +pub use self::map_err::MapErr; +pub use self::from_err::FromErr; +pub use self::or_else::OrElse; +pub use self::select::{Select, SelectNext}; +pub use self::select2::Select2; +pub use self::then::Then; +pub use self::either::Either; +pub use self::inspect::Inspect; + +if_std! { + mod catch_unwind; + mod join_all; + mod select_all; + mod select_ok; + mod shared; + pub use self::catch_unwind::CatchUnwind; + pub use self::join_all::{join_all, JoinAll}; + pub use self::select_all::{SelectAll, SelectAllNext, select_all}; + pub use self::select_ok::{SelectOk, select_ok}; + pub use self::shared::{Shared, SharedItem, SharedError}; + + #[doc(hidden)] + #[deprecated(since = "0.1.4", note = "use join_all instead")] + #[cfg(feature = "with-deprecated")] + pub use self::join_all::join_all as collect; + #[doc(hidden)] + #[deprecated(since = "0.1.4", note = "use JoinAll instead")] + #[cfg(feature = "with-deprecated")] + pub use self::join_all::JoinAll as Collect; + + /// A type alias for `Box<Future + Send>` + #[doc(hidden)] + #[deprecated(note = "removed without replacement, recommended to use a \ + local extension trait or function if needed, more \ + details in https://github.com/rust-lang-nursery/futures-rs/issues/228")] + pub type BoxFuture<T, E> = ::std::boxed::Box<Future<Item = T, Error = E> + Send>; + + impl<F: ?Sized + Future> Future for ::std::boxed::Box<F> { + type Item = F::Item; + type Error = F::Error; + + fn poll(&mut self) -> Poll<Self::Item, Self::Error> { + (**self).poll() + } + } +} + +use {Poll, stream}; + +/// Trait for types which are a placeholder of a value that may become +/// available at some later point in time. +/// +/// In addition to the documentation here you can also find more information +/// about futures [online] at [https://tokio.rs](https://tokio.rs) +/// +/// [online]: https://tokio.rs/docs/getting-started/futures/ +/// +/// Futures are used to provide a sentinel through which a value can be +/// referenced. They crucially allow chaining and composing operations through +/// consumption which allows expressing entire trees of computation as one +/// sentinel value. +/// +/// The ergonomics and implementation of the `Future` trait are very similar to +/// the `Iterator` trait in that there is just one methods you need +/// to implement, but you get a whole lot of others for free as a result. +/// +/// # The `poll` method +/// +/// The core method of future, `poll`, is used to attempt to generate the value +/// of a `Future`. This method *does not block* but is allowed to inform the +/// caller that the value is not ready yet. Implementations of `poll` may +/// themselves do work to generate the value, but it's guaranteed that this will +/// never block the calling thread. +/// +/// A key aspect of this method is that if the value is not yet available the +/// current task is scheduled to receive a notification when it's later ready to +/// be made available. This follows what's typically known as a "readiness" or +/// "pull" model where values are pulled out of futures on demand, and +/// otherwise a task is notified when a value might be ready to get pulled out. +/// +/// The `poll` method is not intended to be called in general, but rather is +/// typically called in the context of a "task" which drives a future to +/// completion. For more information on this see the `task` module. +/// +/// More information about the details of `poll` and the nitty-gritty of tasks +/// can be [found online at tokio.rs][poll-dox]. +/// +/// [poll-dox]: https://tokio.rs/docs/going-deeper-futures/futures-model/ +/// +/// # Combinators +/// +/// Like iterators, futures provide a large number of combinators to work with +/// futures to express computations in a much more natural method than +/// scheduling a number of callbacks. For example the `map` method can change +/// a `Future<Item=T>` to a `Future<Item=U>` or an `and_then` combinator could +/// create a future after the first one is done and only be resolved when the +/// second is done. +/// +/// Combinators act very similarly to the methods on the `Iterator` trait itself +/// or those on `Option` and `Result`. Like with iterators, the combinators are +/// zero-cost and don't impose any extra layers of indirection you wouldn't +/// otherwise have to write down. +/// +/// More information about combinators can be found [on tokio.rs]. +/// +/// [on tokio.rs]: https://tokio.rs/docs/going-deeper-futures/futures-mechanics/ +#[must_use = "futures do nothing unless polled"] +pub trait Future { + /// The type of value that this future will resolved with if it is + /// successful. + type Item; + + /// The type of error that this future will resolve with if it fails in a + /// normal fashion. + type Error; + + /// Query this future to see if its value has become available, registering + /// interest if it is not. + /// + /// This function will check the internal state of the future and assess + /// whether the value is ready to be produced. Implementers of this function + /// should ensure that a call to this **never blocks** as event loops may + /// not work properly otherwise. + /// + /// When a future is not ready yet, the `Async::NotReady` value will be + /// returned. In this situation the future will *also* register interest of + /// the current task in the value being produced. This is done by calling + /// `task::park` to retrieve a handle to the current `Task`. When the future + /// is then ready to make progress (e.g. it should be `poll`ed again) the + /// `unpark` method is called on the `Task`. + /// + /// More information about the details of `poll` and the nitty-gritty of + /// tasks can be [found online at tokio.rs][poll-dox]. + /// + /// [poll-dox]: https://tokio.rs/docs/going-deeper-futures/futures-model/ + /// + /// # Runtime characteristics + /// + /// This function, `poll`, is the primary method for 'making progress' + /// within a tree of futures. For example this method will be called + /// repeatedly as the internal state machine makes its various transitions. + /// Executors are responsible for ensuring that this function is called in + /// the right location (e.g. always on an I/O thread or not). Unless it is + /// otherwise arranged to be so, it should be ensured that **implementations + /// of this function finish very quickly**. + /// + /// Returning quickly prevents unnecessarily clogging up threads and/or + /// event loops while a `poll` function call, for example, takes up compute + /// resources to perform some expensive computation. If it is known ahead + /// of time that a call to `poll` may end up taking awhile, the work should + /// be offloaded to a thread pool (or something similar) to ensure that + /// `poll` can return quickly. + /// + /// Note that the `poll` function is not called repeatedly in a loop for + /// futures typically, but only whenever the future itself is ready. If + /// you're familiar with the `poll(2)` or `select(2)` syscalls on Unix + /// it's worth noting that futures typically do *not* suffer the same + /// problems of "all wakeups must poll all events". Futures have enough + /// support for only polling futures which cause a wakeup. + /// + /// # Return value + /// + /// This function returns `Async::NotReady` if the future is not ready yet, + /// `Err` if the future is finished but resolved to an error, or + /// `Async::Ready` with the result of this future if it's finished + /// successfully. Once a future has finished it is considered a contract + /// error to continue polling the future. + /// + /// If `NotReady` is returned, then the future will internally register + /// interest in the value being produced for the current task (through + /// `task::park`). In other words, the current task will receive a + /// notification (through the `unpark` method) once the value is ready to be + /// produced or the future can make progress. + /// + /// Note that if `NotReady` is returned it only means that *this* task will + /// receive a notification. Historical calls to `poll` with different tasks + /// will not receive notifications. In other words, implementers of the + /// `Future` trait need not store a queue of tasks to notify, but only the + /// last task that called this method. Alternatively callers of this method + /// can only rely on the most recent task which call `poll` being notified + /// when a future is ready. + /// + /// # Panics + /// + /// Once a future has completed (returned `Ready` or `Err` from `poll`), + /// then any future calls to `poll` may panic, block forever, or otherwise + /// cause wrong behavior. The `Future` trait itself provides no guarantees + /// about the behavior of `poll` after a future has completed. + /// + /// Callers who may call `poll` too many times may want to consider using + /// the `fuse` adaptor which defines the behavior of `poll`, but comes with + /// a little bit of extra cost. + /// + /// Additionally, calls to `poll` must always be made from within the + /// context of a task. If a current task is not set then this method will + /// likely panic. + /// + /// # Errors + /// + /// This future may have failed to finish the computation, in which case + /// the `Err` variant will be returned with an appropriate payload of an + /// error. + fn poll(&mut self) -> Poll<Self::Item, Self::Error>; + + /// Block the current thread until this future is resolved. + /// + /// This method will consume ownership of this future, driving it to + /// completion via `poll` and blocking the current thread while it's waiting + /// for the value to become available. Once the future is resolved the + /// result of this future is returned. + /// + /// > **Note:** This method is not appropriate to call on event loops or + /// > similar I/O situations because it will prevent the event + /// > loop from making progress (this blocks the thread). This + /// > method should only be called when it's guaranteed that the + /// > blocking work associated with this future will be completed + /// > by another thread. + /// + /// This method is only available when the `use_std` feature of this + /// library is activated, and it is activated by default. + /// + /// # Panics + /// + /// This function does not attempt to catch panics. If the `poll` function + /// of this future panics, panics will be propagated to the caller. + #[cfg(feature = "use_std")] + fn wait(self) -> result::Result<Self::Item, Self::Error> + where Self: Sized + { + ::executor::spawn(self).wait_future() + } + + /// Convenience function for turning this future into a trait object which + /// is also `Send`. + /// + /// This simply avoids the need to write `Box::new` and can often help with + /// type inference as well by always returning a trait object. Note that + /// this method requires the `Send` bound and returns a `BoxFuture`, which + /// also encodes this. If you'd like to create a `Box<Future>` without the + /// `Send` bound, then the `Box::new` function can be used instead. + /// + /// This method is only available when the `use_std` feature of this + /// library is activated, and it is activated by default. + /// + /// # Examples + /// + /// ``` + /// use futures::prelude::*; + /// use futures::future::{BoxFuture, result}; + /// + /// let a: BoxFuture<i32, i32> = result(Ok(1)).boxed(); + /// ``` + #[cfg(feature = "use_std")] + #[doc(hidden)] + #[deprecated(note = "removed without replacement, recommended to use a \ + local extension trait or function if needed, more \ + details in https://github.com/rust-lang-nursery/futures-rs/issues/228")] + #[allow(deprecated)] + fn boxed(self) -> BoxFuture<Self::Item, Self::Error> + where Self: Sized + Send + 'static + { + ::std::boxed::Box::new(self) + } + + /// Map this future's result to a different type, returning a new future of + /// the resulting type. + /// + /// This function is similar to the `Option::map` or `Iterator::map` where + /// it will change the type of the underlying future. This is useful to + /// chain along a computation once a future has been resolved. + /// + /// The closure provided will only be called if this future is resolved + /// successfully. If this future returns an error, panics, or is dropped, + /// then the closure provided will never be invoked. + /// + /// Note that this function consumes the receiving future and returns a + /// wrapped version of it, similar to the existing `map` methods in the + /// standard library. + /// + /// # Examples + /// + /// ``` + /// use futures::prelude::*; + /// use futures::future; + /// + /// let future = future::ok::<u32, u32>(1); + /// let new_future = future.map(|x| x + 3); + /// assert_eq!(new_future.wait(), Ok(4)); + /// ``` + /// + /// Calling `map` on an errored `Future` has no effect: + /// + /// ``` + /// use futures::prelude::*; + /// use futures::future; + /// + /// let future = future::err::<u32, u32>(1); + /// let new_future = future.map(|x| x + 3); + /// assert_eq!(new_future.wait(), Err(1)); + /// ``` + fn map<F, U>(self, f: F) -> Map<Self, F> + where F: FnOnce(Self::Item) -> U, + Self: Sized, + { + assert_future::<U, Self::Error, _>(map::new(self, f)) + } + + /// Map this future's error to a different error, returning a new future. + /// + /// This function is similar to the `Result::map_err` where it will change + /// the error type of the underlying future. This is useful for example to + /// ensure that futures have the same error type when used with combinators + /// like `select` and `join`. + /// + /// The closure provided will only be called if this future is resolved + /// with an error. If this future returns a success, panics, or is + /// dropped, then the closure provided will never be invoked. + /// + /// Note that this function consumes the receiving future and returns a + /// wrapped version of it. + /// + /// # Examples + /// + /// ``` + /// use futures::future::*; + /// + /// let future = err::<u32, u32>(1); + /// let new_future = future.map_err(|x| x + 3); + /// assert_eq!(new_future.wait(), Err(4)); + /// ``` + /// + /// Calling `map_err` on a successful `Future` has no effect: + /// + /// ``` + /// use futures::future::*; + /// + /// let future = ok::<u32, u32>(1); + /// let new_future = future.map_err(|x| x + 3); + /// assert_eq!(new_future.wait(), Ok(1)); + /// ``` + fn map_err<F, E>(self, f: F) -> MapErr<Self, F> + where F: FnOnce(Self::Error) -> E, + Self: Sized, + { + assert_future::<Self::Item, E, _>(map_err::new(self, f)) + } + + + + /// Map this future's error to any error implementing `From` for + /// this future's `Error`, returning a new future. + /// + /// This function does for futures what `try!` does for `Result`, + /// by letting the compiler infer the type of the resulting error. + /// Just as `map_err` above, this is useful for example to ensure + /// that futures have the same error type when used with + /// combinators like `select` and `join`. + /// + /// Note that this function consumes the receiving future and returns a + /// wrapped version of it. + /// + /// # Examples + /// + /// ``` + /// use futures::prelude::*; + /// use futures::future; + /// + /// let future_with_err_u8 = future::err::<(), u8>(1); + /// let future_with_err_u32 = future_with_err_u8.from_err::<u32>(); + /// ``` + fn from_err<E:From<Self::Error>>(self) -> FromErr<Self, E> + where Self: Sized, + { + assert_future::<Self::Item, E, _>(from_err::new(self)) + } + + /// Chain on a computation for when a future finished, passing the result of + /// the future to the provided closure `f`. + /// + /// This function can be used to ensure a computation runs regardless of + /// the conclusion of the future. The closure provided will be yielded a + /// `Result` once the future is complete. + /// + /// The returned value of the closure must implement the `IntoFuture` trait + /// and can represent some more work to be done before the composed future + /// is finished. Note that the `Result` type implements the `IntoFuture` + /// trait so it is possible to simply alter the `Result` yielded to the + /// closure and return it. + /// + /// If this future is dropped or panics then the closure `f` will not be + /// run. + /// + /// Note that this function consumes the receiving future and returns a + /// wrapped version of it. + /// + /// # Examples + /// + /// ``` + /// use futures::prelude::*; + /// use futures::future; + /// + /// let future_of_1 = future::ok::<u32, u32>(1); + /// let future_of_4 = future_of_1.then(|x| { + /// x.map(|y| y + 3) + /// }); + /// + /// let future_of_err_1 = future::err::<u32, u32>(1); + /// let future_of_4 = future_of_err_1.then(|x| { + /// match x { + /// Ok(_) => panic!("expected an error"), + /// Err(y) => future::ok::<u32, u32>(y + 3), + /// } + /// }); + /// ``` + fn then<F, B>(self, f: F) -> Then<Self, B, F> + where F: FnOnce(result::Result<Self::Item, Self::Error>) -> B, + B: IntoFuture, + Self: Sized, + { + assert_future::<B::Item, B::Error, _>(then::new(self, f)) + } + + /// Execute another future after this one has resolved successfully. + /// + /// This function can be used to chain two futures together and ensure that + /// the final future isn't resolved until both have finished. The closure + /// provided is yielded the successful result of this future and returns + /// another value which can be converted into a future. + /// + /// Note that because `Result` implements the `IntoFuture` trait this method + /// can also be useful for chaining fallible and serial computations onto + /// the end of one future. + /// + /// If this future is dropped, panics, or completes with an error then the + /// provided closure `f` is never called. + /// + /// Note that this function consumes the receiving future and returns a + /// wrapped version of it. + /// + /// # Examples + /// + /// ``` + /// use futures::prelude::*; + /// use futures::future::{self, FutureResult}; + /// + /// let future_of_1 = future::ok::<u32, u32>(1); + /// let future_of_4 = future_of_1.and_then(|x| { + /// Ok(x + 3) + /// }); + /// + /// let future_of_err_1 = future::err::<u32, u32>(1); + /// future_of_err_1.and_then(|_| -> FutureResult<u32, u32> { + /// panic!("should not be called in case of an error"); + /// }); + /// ``` + fn and_then<F, B>(self, f: F) -> AndThen<Self, B, F> + where F: FnOnce(Self::Item) -> B, + B: IntoFuture<Error = Self::Error>, + Self: Sized, + { + assert_future::<B::Item, Self::Error, _>(and_then::new(self, f)) + } + + /// Execute another future if this one resolves with an error. + /// + /// Return a future that passes along this future's value if it succeeds, + /// and otherwise passes the error to the closure `f` and waits for the + /// future it returns. The closure may also simply return a value that can + /// be converted into a future. + /// + /// Note that because `Result` implements the `IntoFuture` trait this method + /// can also be useful for chaining together fallback computations, where + /// when one fails, the next is attempted. + /// + /// If this future is dropped, panics, or completes successfully then the + /// provided closure `f` is never called. + /// + /// Note that this function consumes the receiving future and returns a + /// wrapped version of it. + /// + /// # Examples + /// + /// ``` + /// use futures::prelude::*; + /// use futures::future::{self, FutureResult}; + /// + /// let future_of_err_1 = future::err::<u32, u32>(1); + /// let future_of_4 = future_of_err_1.or_else(|x| -> Result<u32, u32> { + /// Ok(x + 3) + /// }); + /// + /// let future_of_1 = future::ok::<u32, u32>(1); + /// future_of_1.or_else(|_| -> FutureResult<u32, u32> { + /// panic!("should not be called in case of success"); + /// }); + /// ``` + fn or_else<F, B>(self, f: F) -> OrElse<Self, B, F> + where F: FnOnce(Self::Error) -> B, + B: IntoFuture<Item = Self::Item>, + Self: Sized, + { + assert_future::<Self::Item, B::Error, _>(or_else::new(self, f)) + } + + /// Waits for either one of two futures to complete. + /// + /// This function will return a new future which awaits for either this or + /// the `other` future to complete. The returned future will finish with + /// both the value resolved and a future representing the completion of the + /// other work. Both futures must have the same item and error type. + /// + /// Note that this function consumes the receiving futures and returns a + /// wrapped version of them. + /// + /// # Examples + /// + /// ```no_run + /// use futures::prelude::*; + /// use futures::future; + /// use std::thread; + /// use std::time; + /// + /// let future1 = future::lazy(|| { + /// thread::sleep(time::Duration::from_secs(5)); + /// future::ok::<char, ()>('a') + /// }); + /// + /// let future2 = future::lazy(|| { + /// thread::sleep(time::Duration::from_secs(3)); + /// future::ok::<char, ()>('b') + /// }); + /// + /// let (value, last_future) = future1.select(future2).wait().ok().unwrap(); + /// assert_eq!(value, 'a'); + /// assert_eq!(last_future.wait().unwrap(), 'b'); + /// ``` + /// + /// A poor-man's `join` implemented on top of `select`: + /// + /// ``` + /// use futures::prelude::*; + /// use futures::future; + /// + /// fn join<A>(a: A, b: A) -> Box<Future<Item=(u32, u32), Error=u32>> + /// where A: Future<Item = u32, Error = u32> + 'static, + /// { + /// Box::new(a.select(b).then(|res| -> Box<Future<Item=_, Error=_>> { + /// match res { + /// Ok((a, b)) => Box::new(b.map(move |b| (a, b))), + /// Err((a, _)) => Box::new(future::err(a)), + /// } + /// })) + /// } + /// ``` + fn select<B>(self, other: B) -> Select<Self, B::Future> + where B: IntoFuture<Item=Self::Item, Error=Self::Error>, + Self: Sized, + { + let f = select::new(self, other.into_future()); + assert_future::<(Self::Item, SelectNext<Self, B::Future>), + (Self::Error, SelectNext<Self, B::Future>), _>(f) + } + + /// Waits for either one of two differently-typed futures to complete. + /// + /// This function will return a new future which awaits for either this or + /// the `other` future to complete. The returned future will finish with + /// both the value resolved and a future representing the completion of the + /// other work. + /// + /// Note that this function consumes the receiving futures and returns a + /// wrapped version of them. + /// + /// Also note that if both this and the second future have the same + /// success/error type you can use the `Either::split` method to + /// conveniently extract out the value at the end. + /// + /// # Examples + /// + /// ``` + /// use futures::prelude::*; + /// use futures::future::{self, Either}; + /// + /// // A poor-man's join implemented on top of select2 + /// + /// fn join<A, B, E>(a: A, b: B) -> Box<Future<Item=(A::Item, B::Item), Error=E>> + /// where A: Future<Error = E> + 'static, + /// B: Future<Error = E> + 'static, + /// E: 'static, + /// { + /// Box::new(a.select2(b).then(|res| -> Box<Future<Item=_, Error=_>> { + /// match res { + /// Ok(Either::A((x, b))) => Box::new(b.map(move |y| (x, y))), + /// Ok(Either::B((y, a))) => Box::new(a.map(move |x| (x, y))), + /// Err(Either::A((e, _))) => Box::new(future::err(e)), + /// Err(Either::B((e, _))) => Box::new(future::err(e)), + /// } + /// })) + /// } + /// ``` + fn select2<B>(self, other: B) -> Select2<Self, B::Future> + where B: IntoFuture, Self: Sized + { + select2::new(self, other.into_future()) + } + + /// Joins the result of two futures, waiting for them both to complete. + /// + /// This function will return a new future which awaits both this and the + /// `other` future to complete. The returned future will finish with a tuple + /// of both results. + /// + /// Both futures must have the same error type, and if either finishes with + /// an error then the other will be dropped and that error will be + /// returned. + /// + /// Note that this function consumes the receiving future and returns a + /// wrapped version of it. + /// + /// # Examples + /// + /// ``` + /// use futures::prelude::*; + /// use futures::future; + /// + /// let a = future::ok::<u32, u32>(1); + /// let b = future::ok::<u32, u32>(2); + /// let pair = a.join(b); + /// + /// assert_eq!(pair.wait(), Ok((1, 2))); + /// ``` + /// + /// If one or both of the joined `Future`s is errored, the resulting + /// `Future` will be errored: + /// + /// ``` + /// use futures::prelude::*; + /// use futures::future; + /// + /// let a = future::ok::<u32, u32>(1); + /// let b = future::err::<u32, u32>(2); + /// let pair = a.join(b); + /// + /// assert_eq!(pair.wait(), Err(2)); + /// ``` + fn join<B>(self, other: B) -> Join<Self, B::Future> + where B: IntoFuture<Error=Self::Error>, + Self: Sized, + { + let f = join::new(self, other.into_future()); + assert_future::<(Self::Item, B::Item), Self::Error, _>(f) + } + + /// Same as `join`, but with more futures. + fn join3<B, C>(self, b: B, c: C) -> Join3<Self, B::Future, C::Future> + where B: IntoFuture<Error=Self::Error>, + C: IntoFuture<Error=Self::Error>, + Self: Sized, + { + join::new3(self, b.into_future(), c.into_future()) + } + + /// Same as `join`, but with more futures. + fn join4<B, C, D>(self, b: B, c: C, d: D) + -> Join4<Self, B::Future, C::Future, D::Future> + where B: IntoFuture<Error=Self::Error>, + C: IntoFuture<Error=Self::Error>, + D: IntoFuture<Error=Self::Error>, + Self: Sized, + { + join::new4(self, b.into_future(), c.into_future(), d.into_future()) + } + + /// Same as `join`, but with more futures. + fn join5<B, C, D, E>(self, b: B, c: C, d: D, e: E) + -> Join5<Self, B::Future, C::Future, D::Future, E::Future> + where B: IntoFuture<Error=Self::Error>, + C: IntoFuture<Error=Self::Error>, + D: IntoFuture<Error=Self::Error>, + E: IntoFuture<Error=Self::Error>, + Self: Sized, + { + join::new5(self, b.into_future(), c.into_future(), d.into_future(), + e.into_future()) + } + + /// Convert this future into a single element stream. + /// + /// The returned stream contains single success if this future resolves to + /// success or single error if this future resolves into error. + /// + /// # Examples + /// + /// ``` + /// use futures::prelude::*; + /// use futures::future; + /// + /// let future = future::ok::<_, bool>(17); + /// let mut stream = future.into_stream(); + /// assert_eq!(Ok(Async::Ready(Some(17))), stream.poll()); + /// assert_eq!(Ok(Async::Ready(None)), stream.poll()); + /// + /// let future = future::err::<bool, _>(19); + /// let mut stream = future.into_stream(); + /// assert_eq!(Err(19), stream.poll()); + /// assert_eq!(Ok(Async::Ready(None)), stream.poll()); + /// ``` + fn into_stream(self) -> IntoStream<Self> + where Self: Sized + { + into_stream::new(self) + } + + /// Flatten the execution of this future when the successful result of this + /// future is itself another future. + /// + /// This can be useful when combining futures together to flatten the + /// computation out the final result. This method can only be called + /// when the successful result of this future itself implements the + /// `IntoFuture` trait and the error can be created from this future's error + /// type. + /// + /// This method is roughly equivalent to `self.and_then(|x| x)`. + /// + /// Note that this function consumes the receiving future and returns a + /// wrapped version of it. + /// + /// # Examples + /// + /// ``` + /// use futures::prelude::*; + /// use futures::future; + /// + /// let nested_future = future::ok::<_, u32>(future::ok::<u32, u32>(1)); + /// let future = nested_future.flatten(); + /// assert_eq!(future.wait(), Ok(1)); + /// ``` + /// + /// Calling `flatten` on an errored `Future`, or if the inner `Future` is + /// errored, will result in an errored `Future`: + /// + /// ``` + /// use futures::prelude::*; + /// use futures::future; + /// + /// let nested_future = future::ok::<_, u32>(future::err::<u32, u32>(1)); + /// let future = nested_future.flatten(); + /// assert_eq!(future.wait(), Err(1)); + /// ``` + fn flatten(self) -> Flatten<Self> + where Self::Item: IntoFuture, + <<Self as Future>::Item as IntoFuture>::Error: + From<<Self as Future>::Error>, + Self: Sized + { + let f = flatten::new(self); + assert_future::<<<Self as Future>::Item as IntoFuture>::Item, + <<Self as Future>::Item as IntoFuture>::Error, + _>(f) + } + + /// Flatten the execution of this future when the successful result of this + /// future is a stream. + /// + /// This can be useful when stream initialization is deferred, and it is + /// convenient to work with that stream as if stream was available at the + /// call site. + /// + /// Note that this function consumes this future and returns a wrapped + /// version of it. + /// + /// # Examples + /// + /// ``` + /// use futures::prelude::*; + /// use futures::future; + /// use futures::stream; + /// + /// let stream_items = vec![17, 18, 19]; + /// let future_of_a_stream = future::ok::<_, bool>(stream::iter_ok(stream_items)); + /// + /// let stream = future_of_a_stream.flatten_stream(); + /// + /// let mut iter = stream.wait(); + /// assert_eq!(Ok(17), iter.next().unwrap()); + /// assert_eq!(Ok(18), iter.next().unwrap()); + /// assert_eq!(Ok(19), iter.next().unwrap()); + /// assert_eq!(None, iter.next()); + /// ``` + fn flatten_stream(self) -> FlattenStream<Self> + where <Self as Future>::Item: stream::Stream<Error=Self::Error>, + Self: Sized + { + flatten_stream::new(self) + } + + /// Fuse a future such that `poll` will never again be called once it has + /// completed. + /// + /// Currently once a future has returned `Ready` or `Err` from + /// `poll` any further calls could exhibit bad behavior such as blocking + /// forever, panicking, never returning, etc. If it is known that `poll` + /// may be called too often then this method can be used to ensure that it + /// has defined semantics. + /// + /// Once a future has been `fuse`d and it returns a completion from `poll`, + /// then it will forever return `NotReady` from `poll` again (never + /// resolve). This, unlike the trait's `poll` method, is guaranteed. + /// + /// This combinator will drop this future as soon as it's been completed to + /// ensure resources are reclaimed as soon as possible. + /// + /// # Examples + /// + /// ```rust + /// use futures::prelude::*; + /// use futures::future; + /// + /// let mut future = future::ok::<i32, u32>(2); + /// assert_eq!(future.poll(), Ok(Async::Ready(2))); + /// + /// // Normally, a call such as this would panic: + /// //future.poll(); + /// + /// // This, however, is guaranteed to not panic + /// let mut future = future::ok::<i32, u32>(2).fuse(); + /// assert_eq!(future.poll(), Ok(Async::Ready(2))); + /// assert_eq!(future.poll(), Ok(Async::NotReady)); + /// ``` + fn fuse(self) -> Fuse<Self> + where Self: Sized + { + let f = fuse::new(self); + assert_future::<Self::Item, Self::Error, _>(f) + } + + /// Do something with the item of a future, passing it on. + /// + /// When using futures, you'll often chain several of them together. + /// While working on such code, you might want to check out what's happening at + /// various parts in the pipeline. To do that, insert a call to inspect(). + /// + /// # Examples + /// + /// ``` + /// use futures::prelude::*; + /// use futures::future; + /// + /// let future = future::ok::<u32, u32>(1); + /// let new_future = future.inspect(|&x| println!("about to resolve: {}", x)); + /// assert_eq!(new_future.wait(), Ok(1)); + /// ``` + fn inspect<F>(self, f: F) -> Inspect<Self, F> + where F: FnOnce(&Self::Item) -> (), + Self: Sized, + { + assert_future::<Self::Item, Self::Error, _>(inspect::new(self, f)) + } + + /// Catches unwinding panics while polling the future. + /// + /// In general, panics within a future can propagate all the way out to the + /// task level. This combinator makes it possible to halt unwinding within + /// the future itself. It's most commonly used within task executors. It's + /// not recommended to use this for error handling. + /// + /// Note that this method requires the `UnwindSafe` bound from the standard + /// library. This isn't always applied automatically, and the standard + /// library provides an `AssertUnwindSafe` wrapper type to apply it + /// after-the fact. To assist using this method, the `Future` trait is also + /// implemented for `AssertUnwindSafe<F>` where `F` implements `Future`. + /// + /// This method is only available when the `use_std` feature of this + /// library is activated, and it is activated by default. + /// + /// # Examples + /// + /// ```rust + /// use futures::prelude::*; + /// use futures::future::{self, FutureResult}; + /// + /// let mut future = future::ok::<i32, u32>(2); + /// assert!(future.catch_unwind().wait().is_ok()); + /// + /// let mut future = future::lazy(|| -> FutureResult<i32, u32> { + /// panic!(); + /// future::ok::<i32, u32>(2) + /// }); + /// assert!(future.catch_unwind().wait().is_err()); + /// ``` + #[cfg(feature = "use_std")] + fn catch_unwind(self) -> CatchUnwind<Self> + where Self: Sized + ::std::panic::UnwindSafe + { + catch_unwind::new(self) + } + + /// Create a cloneable handle to this future where all handles will resolve + /// to the same result. + /// + /// The shared() method provides a method to convert any future into a + /// cloneable future. It enables a future to be polled by multiple threads. + /// + /// The returned `Shared` future resolves successfully with + /// `SharedItem<Self::Item>` or erroneously with `SharedError<Self::Error>`. + /// Both `SharedItem` and `SharedError` implements `Deref` to allow shared + /// access to the underlying result. Ownership of `Self::Item` and + /// `Self::Error` cannot currently be reclaimed. + /// + /// This method is only available when the `use_std` feature of this + /// library is activated, and it is activated by default. + /// + /// # Examples + /// + /// ``` + /// use futures::prelude::*; + /// use futures::future; + /// + /// let future = future::ok::<_, bool>(6); + /// let shared1 = future.shared(); + /// let shared2 = shared1.clone(); + /// assert_eq!(6, *shared1.wait().unwrap()); + /// assert_eq!(6, *shared2.wait().unwrap()); + /// ``` + /// + /// ``` + /// use std::thread; + /// use futures::prelude::*; + /// use futures::future; + /// + /// let future = future::ok::<_, bool>(6); + /// let shared1 = future.shared(); + /// let shared2 = shared1.clone(); + /// let join_handle = thread::spawn(move || { + /// assert_eq!(6, *shared2.wait().unwrap()); + /// }); + /// assert_eq!(6, *shared1.wait().unwrap()); + /// join_handle.join().unwrap(); + /// ``` + #[cfg(feature = "use_std")] + fn shared(self) -> Shared<Self> + where Self: Sized + { + shared::new(self) + } +} + +impl<'a, F: ?Sized + Future> Future for &'a mut F { + type Item = F::Item; + type Error = F::Error; + + fn poll(&mut self) -> Poll<Self::Item, Self::Error> { + (**self).poll() + } +} + +// Just a helper function to ensure the futures we're returning all have the +// right implementations. +fn assert_future<A, B, F>(t: F) -> F + where F: Future<Item=A, Error=B>, +{ + t +} + +/// Class of types which can be converted into a future. +/// +/// This trait is very similar to the `IntoIterator` trait and is intended to be +/// used in a very similar fashion. +pub trait IntoFuture { + /// The future that this type can be converted into. + type Future: Future<Item=Self::Item, Error=Self::Error>; + + /// The item that the future may resolve with. + type Item; + /// The error that the future may resolve with. + type Error; + + /// Consumes this object and produces a future. + fn into_future(self) -> Self::Future; +} + +impl<F: Future> IntoFuture for F { + type Future = F; + type Item = F::Item; + type Error = F::Error; + + fn into_future(self) -> F { + self + } +} + +impl<T, E> IntoFuture for result::Result<T, E> { + type Future = FutureResult<T, E>; + type Item = T; + type Error = E; + + fn into_future(self) -> FutureResult<T, E> { + result(self) + } +} + +/// Asynchronous conversion from a type `T`. +/// +/// This trait is analogous to `std::convert::From`, adapted to asynchronous +/// computation. +pub trait FutureFrom<T>: Sized { + /// The future for the conversion. + type Future: Future<Item=Self, Error=Self::Error>; + + /// Possible errors during conversion. + type Error; + + /// Consume the given value, beginning the conversion. + fn future_from(T) -> Self::Future; +} + +/// A trait for types which can spawn fresh futures. +/// +/// This trait is typically implemented for "executors", or those types which +/// can execute futures to completion. Futures passed to `Spawn::spawn` +/// typically get turned into a *task* and are then driven to completion. +/// +/// On spawn, the executor takes ownership of the future and becomes responsible +/// to call `Future::poll()` whenever a readiness notification is raised. +pub trait Executor<F: Future<Item = (), Error = ()>> { + /// Spawns a future to run on this `Executor`, typically in the + /// "background". + /// + /// This function will return immediately, and schedule the future `future` + /// to run on `self`. The details of scheduling and execution are left to + /// the implementations of `Executor`, but this is typically a primary point + /// for injecting concurrency in a futures-based system. Futures spawned + /// through this `execute` function tend to run concurrently while they're + /// waiting on events. + /// + /// # Errors + /// + /// Implementers of this trait are allowed to reject accepting this future + /// as well. This can happen for various reason such as: + /// + /// * The executor is shut down + /// * The executor has run out of capacity to execute futures + /// + /// The decision is left to the caller how to work with this form of error. + /// The error returned transfers ownership of the future back to the caller. + fn execute(&self, future: F) -> Result<(), ExecuteError<F>>; +} + +/// Errors returned from the `Spawn::spawn` function. +pub struct ExecuteError<F> { + future: F, + kind: ExecuteErrorKind, +} + +/// Kinds of errors that can be returned from the `Execute::spawn` function. +/// +/// Executors which may not always be able to accept a future may return one of +/// these errors, indicating why it was unable to spawn a future. +#[derive(Debug, Copy, Clone, PartialEq)] +pub enum ExecuteErrorKind { + /// This executor has shut down and will no longer accept new futures to + /// spawn. + Shutdown, + + /// This executor has no more capacity to run more futures. Other futures + /// need to finish before this executor can accept another. + NoCapacity, + + #[doc(hidden)] + __Nonexhaustive, +} + +impl<F> ExecuteError<F> { + /// Create a new `ExecuteError` + pub fn new(kind: ExecuteErrorKind, future: F) -> ExecuteError<F> { + ExecuteError { + future: future, + kind: kind, + } + } + + /// Returns the associated reason for the error + pub fn kind(&self) -> ExecuteErrorKind { + self.kind + } + + /// Consumes self and returns the original future that was spawned. + pub fn into_future(self) -> F { + self.future + } +} + +impl<F> fmt::Debug for ExecuteError<F> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.kind { + ExecuteErrorKind::Shutdown => "executor has shut down".fmt(f), + ExecuteErrorKind::NoCapacity => "executor has no more capacity".fmt(f), + ExecuteErrorKind::__Nonexhaustive => panic!(), + } + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/option.rs b/third_party/rust/futures-0.1.31/src/future/option.rs new file mode 100644 index 0000000000..1b204d376a --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/option.rs @@ -0,0 +1,15 @@ +//! Definition of the `Option` (optional step) combinator + +use {Future, Poll, Async}; + +impl<F, T, E> Future for Option<F> where F: Future<Item=T, Error=E> { + type Item = Option<T>; + type Error = E; + + fn poll(&mut self) -> Poll<Option<T>, E> { + match *self { + None => Ok(Async::Ready(None)), + Some(ref mut x) => x.poll().map(|x| x.map(Some)), + } + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/or_else.rs b/third_party/rust/futures-0.1.31/src/future/or_else.rs new file mode 100644 index 0000000000..bc134137af --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/or_else.rs @@ -0,0 +1,39 @@ +use {Future, IntoFuture, Poll}; +use super::chain::Chain; + +/// Future for the `or_else` combinator, chaining a computation onto the end of +/// a future which fails with an error. +/// +/// This is created by the `Future::or_else` method. +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct OrElse<A, B, F> where A: Future, B: IntoFuture { + state: Chain<A, B::Future, F>, +} + +pub fn new<A, B, F>(future: A, f: F) -> OrElse<A, B, F> + where A: Future, + B: IntoFuture<Item=A::Item>, +{ + OrElse { + state: Chain::new(future, f), + } +} + +impl<A, B, F> Future for OrElse<A, B, F> + where A: Future, + B: IntoFuture<Item=A::Item>, + F: FnOnce(A::Error) -> B, +{ + type Item = B::Item; + type Error = B::Error; + + fn poll(&mut self) -> Poll<B::Item, B::Error> { + self.state.poll(|a, f| { + match a { + Ok(item) => Ok(Ok(item)), + Err(e) => Ok(Err(f(e).into_future())) + } + }) + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/poll_fn.rs b/third_party/rust/futures-0.1.31/src/future/poll_fn.rs new file mode 100644 index 0000000000..d96bf2f98d --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/poll_fn.rs @@ -0,0 +1,45 @@ +//! Definition of the `PollFn` adapter combinator + +use {Future, Poll}; + +/// A future which adapts a function returning `Poll`. +/// +/// Created by the `poll_fn` function. +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct PollFn<F> { + inner: F, +} + +/// Creates a new future wrapping around a function returning `Poll`. +/// +/// Polling the returned future delegates to the wrapped function. +/// +/// # Examples +/// +/// ``` +/// use futures::future::poll_fn; +/// use futures::{Async, Poll}; +/// +/// fn read_line() -> Poll<String, std::io::Error> { +/// Ok(Async::Ready("Hello, World!".into())) +/// } +/// +/// let read_future = poll_fn(read_line); +/// ``` +pub fn poll_fn<T, E, F>(f: F) -> PollFn<F> + where F: FnMut() -> ::Poll<T, E> +{ + PollFn { inner: f } +} + +impl<T, E, F> Future for PollFn<F> + where F: FnMut() -> Poll<T, E> +{ + type Item = T; + type Error = E; + + fn poll(&mut self) -> Poll<T, E> { + (self.inner)() + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/result.rs b/third_party/rust/futures-0.1.31/src/future/result.rs new file mode 100644 index 0000000000..5c44a63e1f --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/result.rs @@ -0,0 +1,81 @@ +//! Definition of the `Result` (immediately finished) combinator + +use core::result; + +use {Future, Poll, Async}; + +/// A future representing a value that is immediately ready. +/// +/// Created by the `result` function. +#[derive(Debug, Clone)] +#[must_use = "futures do nothing unless polled"] +// TODO: rename this to `Result` on the next major version +pub struct FutureResult<T, E> { + inner: Option<result::Result<T, E>>, +} + +/// Creates a new "leaf future" which will resolve with the given result. +/// +/// The returned future represents a computation which is finished immediately. +/// This can be useful with the `finished` and `failed` base future types to +/// convert an immediate value to a future to interoperate elsewhere. +/// +/// # Examples +/// +/// ``` +/// use futures::future::*; +/// +/// let future_of_1 = result::<u32, u32>(Ok(1)); +/// let future_of_err_2 = result::<u32, u32>(Err(2)); +/// ``` +pub fn result<T, E>(r: result::Result<T, E>) -> FutureResult<T, E> { + FutureResult { inner: Some(r) } +} + +/// Creates a "leaf future" from an immediate value of a finished and +/// successful computation. +/// +/// The returned future is similar to `result` where it will immediately run a +/// scheduled callback with the provided value. +/// +/// # Examples +/// +/// ``` +/// use futures::future::*; +/// +/// let future_of_1 = ok::<u32, u32>(1); +/// ``` +pub fn ok<T, E>(t: T) -> FutureResult<T, E> { + result(Ok(t)) +} + +/// Creates a "leaf future" from an immediate value of a failed computation. +/// +/// The returned future is similar to `result` where it will immediately run a +/// scheduled callback with the provided value. +/// +/// # Examples +/// +/// ``` +/// use futures::future::*; +/// +/// let future_of_err_1 = err::<u32, u32>(1); +/// ``` +pub fn err<T, E>(e: E) -> FutureResult<T, E> { + result(Err(e)) +} + +impl<T, E> Future for FutureResult<T, E> { + type Item = T; + type Error = E; + + fn poll(&mut self) -> Poll<T, E> { + self.inner.take().expect("cannot poll Result twice").map(Async::Ready) + } +} + +impl<T, E> From<Result<T, E>> for FutureResult<T, E> { + fn from(r: Result<T, E>) -> Self { + result(r) + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/select.rs b/third_party/rust/futures-0.1.31/src/future/select.rs new file mode 100644 index 0000000000..c48e1c0a1e --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/select.rs @@ -0,0 +1,86 @@ +use {Future, Poll, Async}; + +/// Future for the `select` combinator, waiting for one of two futures to +/// complete. +/// +/// This is created by the `Future::select` method. +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct Select<A, B> where A: Future, B: Future<Item=A::Item, Error=A::Error> { + inner: Option<(A, B)>, +} + +/// Future yielded as the second result in a `Select` future. +/// +/// This sentinel future represents the completion of the second future to a +/// `select` which finished second. +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct SelectNext<A, B> where A: Future, B: Future<Item=A::Item, Error=A::Error> { + inner: OneOf<A, B>, +} + +#[derive(Debug)] +enum OneOf<A, B> where A: Future, B: Future { + A(A), + B(B), +} + +pub fn new<A, B>(a: A, b: B) -> Select<A, B> + where A: Future, + B: Future<Item=A::Item, Error=A::Error> +{ + Select { + inner: Some((a, b)), + } +} + +impl<A, B> Future for Select<A, B> + where A: Future, + B: Future<Item=A::Item, Error=A::Error>, +{ + type Item = (A::Item, SelectNext<A, B>); + type Error = (A::Error, SelectNext<A, B>); + + fn poll(&mut self) -> Poll<Self::Item, Self::Error> { + let (ret, is_a) = match self.inner { + Some((ref mut a, ref mut b)) => { + match a.poll() { + Err(a) => (Err(a), true), + Ok(Async::Ready(a)) => (Ok(a), true), + Ok(Async::NotReady) => { + match b.poll() { + Err(a) => (Err(a), false), + Ok(Async::Ready(a)) => (Ok(a), false), + Ok(Async::NotReady) => return Ok(Async::NotReady), + } + } + } + } + None => panic!("cannot poll select twice"), + }; + + let (a, b) = self.inner.take().unwrap(); + let next = if is_a {OneOf::B(b)} else {OneOf::A(a)}; + let next = SelectNext { inner: next }; + match ret { + Ok(a) => Ok(Async::Ready((a, next))), + Err(e) => Err((e, next)), + } + } +} + +impl<A, B> Future for SelectNext<A, B> + where A: Future, + B: Future<Item=A::Item, Error=A::Error>, +{ + type Item = A::Item; + type Error = A::Error; + + fn poll(&mut self) -> Poll<Self::Item, Self::Error> { + match self.inner { + OneOf::A(ref mut a) => a.poll(), + OneOf::B(ref mut b) => b.poll(), + } + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/select2.rs b/third_party/rust/futures-0.1.31/src/future/select2.rs new file mode 100644 index 0000000000..073f67be4a --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/select2.rs @@ -0,0 +1,39 @@ +use {Future, Poll, Async}; +use future::Either; + +/// Future for the `select2` combinator, waiting for one of two differently-typed +/// futures to complete. +/// +/// This is created by the [`Future::select2`] method. +/// +/// [`Future::select2`]: trait.Future.html#method.select2 +#[must_use = "futures do nothing unless polled"] +#[derive(Debug)] +pub struct Select2<A, B> { + inner: Option<(A, B)>, +} + +pub fn new<A, B>(a: A, b: B) -> Select2<A, B> { + Select2 { inner: Some((a, b)) } +} + +impl<A, B> Future for Select2<A, B> where A: Future, B: Future { + type Item = Either<(A::Item, B), (B::Item, A)>; + type Error = Either<(A::Error, B), (B::Error, A)>; + + fn poll(&mut self) -> Poll<Self::Item, Self::Error> { + let (mut a, mut b) = self.inner.take().expect("cannot poll Select2 twice"); + match a.poll() { + Err(e) => Err(Either::A((e, b))), + Ok(Async::Ready(x)) => Ok(Async::Ready(Either::A((x, b)))), + Ok(Async::NotReady) => match b.poll() { + Err(e) => Err(Either::B((e, a))), + Ok(Async::Ready(x)) => Ok(Async::Ready(Either::B((x, a)))), + Ok(Async::NotReady) => { + self.inner = Some((a, b)); + Ok(Async::NotReady) + } + } + } + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/select_all.rs b/third_party/rust/futures-0.1.31/src/future/select_all.rs new file mode 100644 index 0000000000..1fbc98693b --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/select_all.rs @@ -0,0 +1,71 @@ +//! Definition of the `SelectAll`, finding the first future in a list that +//! finishes. + +use std::mem; +use std::prelude::v1::*; + +use {Future, IntoFuture, Poll, Async}; + +/// Future for the `select_all` combinator, waiting for one of any of a list of +/// futures to complete. +/// +/// This is created by the `select_all` function. +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct SelectAll<A> where A: Future { + inner: Vec<A>, +} + +#[doc(hidden)] +pub type SelectAllNext<A> = A; + +/// Creates a new future which will select over a list of futures. +/// +/// The returned future will wait for any future within `iter` to be ready. Upon +/// completion or failure the item resolved will be returned, along with the +/// index of the future that was ready and the list of all the remaining +/// futures. +/// +/// # Panics +/// +/// This function will panic if the iterator specified contains no items. +pub fn select_all<I>(iter: I) -> SelectAll<<I::Item as IntoFuture>::Future> + where I: IntoIterator, + I::Item: IntoFuture, +{ + let ret = SelectAll { + inner: iter.into_iter() + .map(|a| a.into_future()) + .collect(), + }; + assert!(ret.inner.len() > 0); + ret +} + +impl<A> Future for SelectAll<A> + where A: Future, +{ + type Item = (A::Item, usize, Vec<A>); + type Error = (A::Error, usize, Vec<A>); + + fn poll(&mut self) -> Poll<Self::Item, Self::Error> { + let item = self.inner.iter_mut().enumerate().filter_map(|(i, f)| { + match f.poll() { + Ok(Async::NotReady) => None, + Ok(Async::Ready(e)) => Some((i, Ok(e))), + Err(e) => Some((i, Err(e))), + } + }).next(); + match item { + Some((idx, res)) => { + self.inner.remove(idx); + let rest = mem::replace(&mut self.inner, Vec::new()); + match res { + Ok(e) => Ok(Async::Ready((e, idx, rest))), + Err(e) => Err((e, idx, rest)), + } + } + None => Ok(Async::NotReady), + } + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/select_ok.rs b/third_party/rust/futures-0.1.31/src/future/select_ok.rs new file mode 100644 index 0000000000..f122a0ea30 --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/select_ok.rs @@ -0,0 +1,81 @@ +//! Definition of the `SelectOk` combinator, finding the first successful future +//! in a list. + +use std::mem; +use std::prelude::v1::*; + +use {Future, IntoFuture, Poll, Async}; + +/// Future for the `select_ok` combinator, waiting for one of any of a list of +/// futures to successfully complete. Unlike `select_all`, this future ignores all +/// but the last error, if there are any. +/// +/// This is created by the `select_ok` function. +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct SelectOk<A> where A: Future { + inner: Vec<A>, +} + +/// Creates a new future which will select the first successful future over a list of futures. +/// +/// The returned future will wait for any future within `iter` to be ready and Ok. Unlike +/// `select_all`, this will only return the first successful completion, or the last +/// failure. This is useful in contexts where any success is desired and failures +/// are ignored, unless all the futures fail. +/// +/// # Panics +/// +/// This function will panic if the iterator specified contains no items. +pub fn select_ok<I>(iter: I) -> SelectOk<<I::Item as IntoFuture>::Future> + where I: IntoIterator, + I::Item: IntoFuture, +{ + let ret = SelectOk { + inner: iter.into_iter() + .map(|a| a.into_future()) + .collect(), + }; + assert!(ret.inner.len() > 0); + ret +} + +impl<A> Future for SelectOk<A> where A: Future { + type Item = (A::Item, Vec<A>); + type Error = A::Error; + + fn poll(&mut self) -> Poll<Self::Item, Self::Error> { + // loop until we've either exhausted all errors, a success was hit, or nothing is ready + loop { + let item = self.inner.iter_mut().enumerate().filter_map(|(i, f)| { + match f.poll() { + Ok(Async::NotReady) => None, + Ok(Async::Ready(e)) => Some((i, Ok(e))), + Err(e) => Some((i, Err(e))), + } + }).next(); + + match item { + Some((idx, res)) => { + // always remove Ok or Err, if it's not the last Err continue looping + drop(self.inner.remove(idx)); + match res { + Ok(e) => { + let rest = mem::replace(&mut self.inner, Vec::new()); + return Ok(Async::Ready((e, rest))) + }, + Err(e) => { + if self.inner.is_empty() { + return Err(e) + } + }, + } + } + None => { + // based on the filter above, nothing is ready, return + return Ok(Async::NotReady) + }, + } + } + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/shared.rs b/third_party/rust/futures-0.1.31/src/future/shared.rs new file mode 100644 index 0000000000..e3b6d2fca7 --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/shared.rs @@ -0,0 +1,300 @@ +//! Definition of the Shared combinator, a future that is cloneable, +//! and can be polled in multiple threads. +//! +//! # Examples +//! +//! ``` +//! use futures::future::*; +//! +//! let future = ok::<_, bool>(6); +//! let shared1 = future.shared(); +//! let shared2 = shared1.clone(); +//! assert_eq!(6, *shared1.wait().unwrap()); +//! assert_eq!(6, *shared2.wait().unwrap()); +//! ``` + +use {Future, Poll, Async}; +use task::{self, Task}; +use executor::{self, Notify, Spawn}; + +use std::{error, fmt, mem, ops}; +use std::cell::UnsafeCell; +use std::sync::{Arc, Mutex}; +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering::SeqCst; +use std::collections::HashMap; + +/// A future that is cloneable and can be polled in multiple threads. +/// Use `Future::shared()` method to convert any future into a `Shared` future. +#[must_use = "futures do nothing unless polled"] +pub struct Shared<F: Future> { + inner: Arc<Inner<F>>, + waiter: usize, +} + +impl<F> fmt::Debug for Shared<F> + where F: Future + fmt::Debug, + F::Item: fmt::Debug, + F::Error: fmt::Debug, +{ + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("Shared") + .field("inner", &self.inner) + .field("waiter", &self.waiter) + .finish() + } +} + +struct Inner<F: Future> { + next_clone_id: AtomicUsize, + future: UnsafeCell<Option<Spawn<F>>>, + result: UnsafeCell<Option<Result<SharedItem<F::Item>, SharedError<F::Error>>>>, + notifier: Arc<Notifier>, +} + +struct Notifier { + state: AtomicUsize, + waiters: Mutex<HashMap<usize, Task>>, +} + +const IDLE: usize = 0; +const POLLING: usize = 1; +const COMPLETE: usize = 2; +const POISONED: usize = 3; + +pub fn new<F: Future>(future: F) -> Shared<F> { + Shared { + inner: Arc::new(Inner { + next_clone_id: AtomicUsize::new(1), + notifier: Arc::new(Notifier { + state: AtomicUsize::new(IDLE), + waiters: Mutex::new(HashMap::new()), + }), + future: UnsafeCell::new(Some(executor::spawn(future))), + result: UnsafeCell::new(None), + }), + waiter: 0, + } +} + +impl<F> Shared<F> where F: Future { + // TODO: make this private + #[deprecated(since = "0.1.12", note = "use `Future::shared` instead")] + #[cfg(feature = "with-deprecated")] + #[doc(hidden)] + pub fn new(future: F) -> Self { + new(future) + } + + /// If any clone of this `Shared` has completed execution, returns its result immediately + /// without blocking. Otherwise, returns None without triggering the work represented by + /// this `Shared`. + pub fn peek(&self) -> Option<Result<SharedItem<F::Item>, SharedError<F::Error>>> { + match self.inner.notifier.state.load(SeqCst) { + COMPLETE => { + Some(unsafe { self.clone_result() }) + } + POISONED => panic!("inner future panicked during poll"), + _ => None, + } + } + + fn set_waiter(&mut self) { + let mut waiters = self.inner.notifier.waiters.lock().unwrap(); + waiters.insert(self.waiter, task::current()); + } + + unsafe fn clone_result(&self) -> Result<SharedItem<F::Item>, SharedError<F::Error>> { + match *self.inner.result.get() { + Some(Ok(ref item)) => Ok(SharedItem { item: item.item.clone() }), + Some(Err(ref e)) => Err(SharedError { error: e.error.clone() }), + _ => unreachable!(), + } + } + + fn complete(&self) { + unsafe { *self.inner.future.get() = None }; + self.inner.notifier.state.store(COMPLETE, SeqCst); + self.inner.notifier.notify(0); + } +} + +impl<F> Future for Shared<F> + where F: Future +{ + type Item = SharedItem<F::Item>; + type Error = SharedError<F::Error>; + + fn poll(&mut self) -> Poll<Self::Item, Self::Error> { + self.set_waiter(); + + match self.inner.notifier.state.compare_and_swap(IDLE, POLLING, SeqCst) { + IDLE => { + // Lock acquired, fall through + } + POLLING => { + // Another task is currently polling, at this point we just want + // to ensure that our task handle is currently registered + + return Ok(Async::NotReady); + } + COMPLETE => { + return unsafe { self.clone_result().map(Async::Ready) }; + } + POISONED => panic!("inner future panicked during poll"), + _ => unreachable!(), + } + + struct Reset<'a>(&'a AtomicUsize); + + impl<'a> Drop for Reset<'a> { + fn drop(&mut self) { + use std::thread; + + if thread::panicking() { + self.0.store(POISONED, SeqCst); + } + } + } + + let _reset = Reset(&self.inner.notifier.state); + + // Poll the future + let res = unsafe { + (*self.inner.future.get()).as_mut().unwrap() + .poll_future_notify(&self.inner.notifier, 0) + }; + match res { + Ok(Async::NotReady) => { + // Not ready, try to release the handle + match self.inner.notifier.state.compare_and_swap(POLLING, IDLE, SeqCst) { + POLLING => { + // Success + return Ok(Async::NotReady); + } + _ => unreachable!(), + } + + } + Ok(Async::Ready(i)) => { + unsafe { + (*self.inner.result.get()) = Some(Ok(SharedItem { item: Arc::new(i) })); + } + } + Err(e) => { + unsafe { + (*self.inner.result.get()) = Some(Err(SharedError { error: Arc::new(e) })); + } + } + } + + self.complete(); + unsafe { self.clone_result().map(Async::Ready) } + } +} + +impl<F> Clone for Shared<F> where F: Future { + fn clone(&self) -> Self { + let next_clone_id = self.inner.next_clone_id.fetch_add(1, SeqCst); + + Shared { + inner: self.inner.clone(), + waiter: next_clone_id, + } + } +} + +impl<F> Drop for Shared<F> where F: Future { + fn drop(&mut self) { + let mut waiters = self.inner.notifier.waiters.lock().unwrap(); + waiters.remove(&self.waiter); + } +} + +impl Notify for Notifier { + fn notify(&self, _id: usize) { + let waiters = mem::replace(&mut *self.waiters.lock().unwrap(), HashMap::new()); + + for (_, waiter) in waiters { + waiter.notify(); + } + } +} + +// The `F` is synchronized by a lock, so `F` doesn't need +// to be `Sync`. However, its `Item` or `Error` are exposed +// through an `Arc` but not lock, so they must be `Send + Sync`. +unsafe impl<F> Send for Inner<F> + where F: Future + Send, + F::Item: Send + Sync, + F::Error: Send + Sync, +{} + +unsafe impl<F> Sync for Inner<F> + where F: Future + Send, + F::Item: Send + Sync, + F::Error: Send + Sync, +{} + +impl<F> fmt::Debug for Inner<F> + where F: Future + fmt::Debug, + F::Item: fmt::Debug, + F::Error: fmt::Debug, +{ + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("Inner") + .finish() + } +} + +/// A wrapped item of the original future that is cloneable and implements Deref +/// for ease of use. +#[derive(Clone, Debug)] +pub struct SharedItem<T> { + item: Arc<T>, +} + +impl<T> ops::Deref for SharedItem<T> { + type Target = T; + + fn deref(&self) -> &T { + &self.item.as_ref() + } +} + +/// A wrapped error of the original future that is cloneable and implements Deref +/// for ease of use. +#[derive(Clone, Debug)] +pub struct SharedError<E> { + error: Arc<E>, +} + +impl<E> ops::Deref for SharedError<E> { + type Target = E; + + fn deref(&self) -> &E { + &self.error.as_ref() + } +} + +impl<E> fmt::Display for SharedError<E> + where E: fmt::Display, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.error.fmt(f) + } +} + +impl<E> error::Error for SharedError<E> + where E: error::Error, +{ + #[allow(deprecated)] + fn description(&self) -> &str { + self.error.description() + } + + #[allow(deprecated)] + fn cause(&self) -> Option<&error::Error> { + self.error.cause() + } +} diff --git a/third_party/rust/futures-0.1.31/src/future/then.rs b/third_party/rust/futures-0.1.31/src/future/then.rs new file mode 100644 index 0000000000..188fb8fa80 --- /dev/null +++ b/third_party/rust/futures-0.1.31/src/future/then.rs @@ -0,0 +1,36 @@ +use {Future, IntoFuture, Poll}; +use super::chain::Chain; + +/// Future for the `then` combinator, chaining computations on the end of +/// another future regardless of its outcome. +/// +/// This is created by the `Future::then` method. +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct Then<A, B, F> where A: Future, B: IntoFuture { + state: Chain<A, B::Future, F>, +} + +pub fn new<A, B, F>(future: A, f: F) -> Then<A, B, F> + where A: Future, + B: IntoFuture, +{ + Then { + state: Chain::new(future, f), + } +} + +impl<A, B, F> Future for Then<A, B, F> + where A: Future, + B: IntoFuture, + F: FnOnce(Result<A::Item, A::Error>) -> B, +{ + type Item = B::Item; + type Error = B::Error; + + fn poll(&mut self) -> Poll<B::Item, B::Error> { + self.state.poll(|a, f| { + Ok(Err(f(a).into_future())) + }) + } +} |