Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

An adapter for Option<impl Future> for select! macro #2583

Closed
MOZGIII opened this issue Jun 2, 2020 · 3 comments
Closed

An adapter for Option<impl Future> for select! macro #2583

MOZGIII opened this issue Jun 2, 2020 · 3 comments
Labels
A-tokio Area: The main tokio crate C-feature-request Category: A feature request.

Comments

@MOZGIII
Copy link
Contributor

MOZGIII commented Jun 2, 2020

Is your feature request related to a problem? Please describe.

Using select! macro with Option<T> where T: Future is not ergonomic:

let val: Option<BoxFuture<'static, ()>> = None;
select! {
    _ = val.expect("crash here"), if val.is_some() => {}
}

Describe the solution you'd like

Would be great if we provide a simple adapter for the Option<T> where T: Future, outlined with pseudocode below:

impl Option<T>
where
     T: Future
{
    fn unwrap_future(self) -> (FutureLike<T>, bool) {
        match self {
            Some(fut) => (fut, true),
            None => (Box::pin(async { panic!("polling None future) }), false),
         }
     }
}

This would really be something like a OptionExt trait, but you get the idea.

With this, we can do it more elegantly, and without an error:

let val: Option<BoxFuture<'static, ()>> = None;
let (selectable, should_select) = val.unwrap_future();
select! {
    _ = selectable, if should_select => {}
}

Describe alternatives you've considered

Altering the select! macro to support Options would be an alternative, but it's more involving.

Additional context

None

@MOZGIII MOZGIII added A-tokio Area: The main tokio crate C-feature-request Category: A feature request. labels Jun 2, 2020
@MOZGIII
Copy link
Contributor Author

MOZGIII commented Jun 3, 2020

Note this is different from futures::future::OptionFuture.

@Darksonn
Copy link
Contributor

Darksonn commented Jun 3, 2020

One way to do it today is the following:

let val: Option<BoxFuture<'static, ()>> = None;
select! {
    _ = async { val.expect("crash here").await }, if val.is_some() => {}
}

This makes use of the fact that async blocks are lazy.

@MOZGIII
Copy link
Contributor Author

MOZGIII commented Jun 9, 2020

Turns out what I want here can just be acheived with futures::future::OptionFuture. The FusedFuture abstraction provides is_terminated, and it works great with both tokio and futures select macros.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio Area: The main tokio crate C-feature-request Category: A feature request.
Projects
None yet
Development

No branches or pull requests

2 participants