summaryrefslogtreecommitdiffstats
path: root/third_party/rust/futures-0.1.31/src/future/select.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/futures-0.1.31/src/future/select.rs')
-rw-r--r--third_party/rust/futures-0.1.31/src/future/select.rs86
1 files changed, 86 insertions, 0 deletions
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(),
+ }
+ }
+}