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 .await
ed, 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).