Futures-rs: "collect" all Futures to a composite

Created on 14 Jan 2018  路  2Comments  路  Source: rust-lang/futures-rs

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:

  • The futures should be in the right order (collect_futures(vec![ok(1), ok(2)]) might return vec![Ok(2), Ok(1)])
  • There should be a specialized return type, not Box
  • The '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.

Most helpful comment

@remexre would something like this work perhaps?

stream::futures_unordered(futures)
    .then(|x| Ok(x))
    .collect()

All 2 comments

@remexre would something like this work perhaps?

stream::futures_unordered(futures)
    .then(|x| Ok(x))
    .collect()

Well, now I just feel silly :P

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sile picture sile  路  5Comments

mqudsi picture mqudsi  路  5Comments

jimblandy picture jimblandy  路  5Comments

jannickj picture jannickj  路  3Comments

Nemo157 picture Nemo157  路  5Comments