summaryrefslogtreecommitdiffstats
path: root/smtp/src/resolve_all.rs
diff options
context:
space:
mode:
Diffstat (limited to 'smtp/src/resolve_all.rs')
-rw-r--r--smtp/src/resolve_all.rs81
1 files changed, 81 insertions, 0 deletions
diff --git a/smtp/src/resolve_all.rs b/smtp/src/resolve_all.rs
new file mode 100644
index 0000000..69d3c8b
--- /dev/null
+++ b/smtp/src/resolve_all.rs
@@ -0,0 +1,81 @@
+use std::mem;
+use std::iter::FromIterator;
+
+use futures::{Future, Async, Poll};
+
+pub enum AltFuse<F: Future> {
+ Future(F),
+ Resolved(Result<F::Item, F::Error>)
+}
+
+impl<F> Future for AltFuse<F>
+ where F: Future
+{
+ type Item = ();
+ //TODO[futures/v>=0.2 |rust/! type]: use Never or !
+ type Error = ();
+
+ fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
+ let result = match *self {
+ AltFuse::Resolved(_) => return Ok(Async::Ready(())),
+ AltFuse::Future(ref mut fut) => match fut.poll() {
+ Ok(Async::NotReady) => return Ok(Async::NotReady),
+ Ok(Async::Ready(val)) => Ok(val),
+ Err(err) => Err(err)
+ }
+ };
+
+ *self = AltFuse::Resolved(result);
+ Ok(Async::Ready(()))
+ }
+}
+
+
+pub struct ResolveAll<F>
+ where F: Future
+{
+ all: Vec<AltFuse<F>>
+}
+
+impl<F> Future for ResolveAll<F>
+ where F: Future
+{
+ type Item = Vec<Result<F::Item, F::Error>>;
+ //TODO[futures >= 0.2/rust ! type]: use Never or !
+ type Error = ();
+
+ fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
+ let mut any_not_ready = false;
+ for fut in self.all.iter_mut() {
+ if let Ok(Async::NotReady) = fut.poll() {
+ any_not_ready = true;
+ }
+ }
+ if any_not_ready {
+ Ok(Async::NotReady)
+ } else {
+ let results = mem::replace(&mut self.all, Vec::new())
+ .into_iter().map(|alt_fuse_fut| match alt_fuse_fut {
+ AltFuse::Resolved(res) => res,
+ AltFuse::Future(_) => unreachable!()
+ })
+ .collect();
+ Ok(Async::Ready(results))
+ }
+ }
+}
+
+impl<I> FromIterator<I> for ResolveAll<I>
+ where I: Future
+{
+ fn from_iter<T>(all: T) -> Self
+ where T: IntoIterator<Item = I>
+ {
+ let all = all
+ .into_iter()
+ .map(|fut| AltFuse::Future(fut))
+ .collect();
+
+ ResolveAll { all }
+ }
+} \ No newline at end of file