How to create a Future from a Result containing a Future?

Probably what one usually wants is to deal with the Err case immediately rather than waiting until the future is .awaited, so that might explain why a function like this doesn't already exist. However, if you do need it, it's pretty simple to write using async and .await:

fn transpose_flatten<T, U, E>(result: Result<T, E>) -> impl Future<Output = Result<U, E>>
where
    T: Future<Output = Result<U, E>>,
{
    async {                          // when polled,
        match result {
            Ok(good) => good.await,  // defer to the inner Future if it exists
            Err(bad) => Err(bad),    // otherwise return the error immediately
        }
    }
}

Or the same thing using async fn (which is not always quite the same thing, but in this case it seems to be):

async fn transpose_flatten<T, U, E>(result: Result<T, E>) -> Result<U, E>
where
    T: Future<Output = Result<U, E>>,
{
    match result {
        Ok(good) => good.await,
        Err(bad) => Err(bad),
    }
}

Since the Err value is returned from the enclosing async block or function, you can use ? syntax to make it even shorter:

async fn transpose_flatten<T, U, E>(result: Result<T, E>) -> Result<U, E>
where
    T: Future<Output = Result<U, E>>,
{
    result?.await
}

I called this function transpose_flatten because to me transpose sounds like it should take a Result<Future<Output = U>, _>. This function flattens two layers of Result (the one passed to the function and the one returned from the future).

Tags:

Future

Rust