I would like to run something like the following code:
async fn get_user(s: &str) -> Option<User> { /* ... */ }
let user_id = Some("sessiontoken").and_then(|session_token| {
get_user(session_token)
.await // <- error
.map(|user| user.id)
});
But it doesn't work because await can only be used inside async blocks or functions.
If, on the other hand, I use an async block, the closure would return impl Future<Output = Option<_>> which is not allowed because Option::and_then only allows Option as a return type.
The only alternative I know would be to use OptionFuture, create an intermediate variable and .map instead of .and_then.
use futures::future::OptionFuture;
let user: OptionFuture<_> = Some("sessiontoken")
.map(|session_token| {
get_user(session_token)
})
.into();
let user_id = user.await.flatten().map(|user| user.id);
But this is really cumbersome and prevents me from using many functions that would operate on Options, Results or similar, such as Option::and_then.
Is there no better way?
I believe the idiomatic way would be to simply use match:
let user_id = match session_token {
Some(session_token) => get_user("sessiontoken").await.map(|user| user.id),
None => None,
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With