1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use std::mem;
use {Future, Task, empty, Poll};
use util::Collapsed;
pub struct Select<A, B> where A: Future, B: Future<Item=A::Item, Error=A::Error> {
inner: Option<(Collapsed<A>, Collapsed<B>)>,
}
pub struct SelectNext<A, B> where A: Future, B: Future<Item=A::Item, Error=A::Error> {
inner: OneOf<A, B>,
}
enum OneOf<A, B> where A: Future, B: Future {
A(Collapsed<A>),
B(Collapsed<B>),
}
pub fn new<A, B>(a: A, b: B) -> Select<A, B>
where A: Future,
B: Future<Item=A::Item, Error=A::Error>
{
let a = Collapsed::Start(a);
let b = Collapsed::Start(b);
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, task: &mut Task) -> Poll<Self::Item, Self::Error> {
let (ret, is_a) = match self.inner {
Some((ref mut a, ref mut b)) => {
match a.poll(task) {
Poll::Ok(a) => (Ok(a), true),
Poll::Err(a) => (Err(a), true),
Poll::NotReady => (try_poll!(b.poll(task)), false),
}
}
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) => Poll::Ok((a, next)),
Err(e) => Poll::Err((e, next)),
}
}
fn schedule(&mut self, task: &mut Task) {
match self.inner {
Some((ref mut a, ref mut b)) => {
a.schedule(task);
b.schedule(task);
}
None => task.notify(),
}
}
fn tailcall(&mut self)
-> Option<Box<Future<Item=Self::Item, Error=Self::Error>>> {
if let Some((ref mut a, ref mut b)) = self.inner {
a.collapse();
b.collapse();
}
None
}
}
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, task: &mut Task) -> Poll<Self::Item, Self::Error> {
match self.inner {
OneOf::A(ref mut a) => a.poll(task),
OneOf::B(ref mut b) => b.poll(task),
}
}
fn schedule(&mut self, task: &mut Task) {
match self.inner {
OneOf::A(ref mut a) => a.schedule(task),
OneOf::B(ref mut b) => b.schedule(task),
}
}
fn tailcall(&mut self)
-> Option<Box<Future<Item=Self::Item, Error=Self::Error>>> {
match self.inner {
OneOf::A(ref mut a) => a.collapse(),
OneOf::B(ref mut b) => b.collapse(),
}
match self.inner {
OneOf::A(Collapsed::Tail(ref mut a)) |
OneOf::B(Collapsed::Tail(ref mut a)) => {
Some(mem::replace(a, Box::new(empty())))
}
_ => None,
}
}
}