There should be a way to make a Future<Item=Vec<Result<T, E>>, Error=!> from a Vec<Future<Item=T, Error=E>>. I've got a first try:
fn collect_futures<F>(
futures: Vec<F>,
) -> Box<Future<Item = Vec<Result<F::Item, F::Error>>, Error = !>>
where
F: 'static + Future,
<F as Future>::Item: 'static,
<F as Future>::Error: 'static,
{
Box::new(loop_fn((futures, vec![]), |(futures, mut done)| {
select_all(futures).then(|r| {
let (r, rest) = match r {
Ok((r, _, rest)) => (Ok(r), rest),
Err((r, _, rest)) => (Err(r), rest),
};
done.push(r);
if rest.len() == 0 {
Ok(Loop::Break(done))
} else {
Ok(Loop::Continue((rest, done)))
}
})
}))
}
This still needs improvement:
collect_futures(vec![ok(1), ok(2)]) might return vec![Ok(2), Ok(1)])Box'static bounds should be removed.This can, of course, wait until ! is stabilized (or get added as a #[cfg(feature = "nightly")]), or a dependency on void could be added in the short-term.
@remexre would something like this work perhaps?
stream::futures_unordered(futures)
.then(|x| Ok(x))
.collect()
Well, now I just feel silly :P
Most helpful comment
@remexre would something like this work perhaps?