3

Is there a more idiomatic or prettier way to do an operation like this in rust?

let maybe_output = match maybe_input {
    Some(input) => Some(async_result(input).await?),
    None => None,
};

I tried to use map like this,

let maybe_output = maybe_input.map(|input| async_result(input).await?);

but I cannot use the .await and ? operators inside a lambda that doesn't return a future or a result. I suspect I can do the map and have an Option<Future<Result<_>>>, then sequence out the Future<Result<_>> to be Future<Result<Option<_>>>;

let maybe_output = maybe_input.map(|input|
    async_result(input)
).transpose().await?;

but I don't know if I can call transpose on a Future since it's a trait not a type like Result or Option.

kmdreko
  • 42,554
  • 6
  • 57
  • 106
cheezsteak
  • 2,731
  • 4
  • 26
  • 41
  • 1
    It would be nice if `Option` implemented `Future`, I found a relevant discussion [here](https://internals.rust-lang.org/t/impl-t-future-future-for-option-t/14165) but it doesn't appear it went anywhere. – kmdreko Sep 12 '21 at 20:34

1 Answers1

6

There is OptionFuture in the futures crate:

let maybe_output = OptionFuture::from(maybe_input.map(async_result)).await;

However, I would personally consider the original form more idiomatic. I can immediately understand what the match does, while I'd have to take a second look to know that OptionFuture does what I'd expect.

kmdreko
  • 42,554
  • 6
  • 57
  • 106