Skip to content

Instantly share code, notes, and snippets.

@jbg
Created November 27, 2019 13:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jbg/2eb3f05250f90186bd1ebe0e2449f260 to your computer and use it in GitHub Desktop.
Save jbg/2eb3f05250f90186bd1ebe0e2449f260 to your computer and use it in GitHub Desktop.
use std::future::Future;
use futures::future::{self, Either, FutureExt, Map, Ready};
trait AsyncOption<T> {
fn async_map<U, Fun, Fut>(
self,
f: Fun,
) -> Either<Map<Fut, &'static dyn Fn(Fut::Output) -> Option<U>>, Ready<Option<U>>>
where
Fun: FnOnce(T) -> Fut,
Fut: Future<Output = U>;
}
impl<T> AsyncOption<T> for Option<T> {
fn async_map<U, Fun, Fut>(
self,
f: Fun,
) -> Either<Map<Fut, &'static dyn Fn(Fut::Output) -> Option<U>>, Ready<Option<U>>>
where
Fun: FnOnce(T) -> Fut,
Fut: Future<Output = U>,
{
match self {
Some(v) => Either::Left(f(v).map(&Some)),
None => Either::Right(future::ready(None)),
}
}
}
#[tokio::main]
async fn main() {
let result = Some(37i32).async_map(add_five).await;
println!("{:?}", result); // prints Some(42)
}
async fn add_five(x: i32) -> i32 {
x + 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment