-
Notifications
You must be signed in to change notification settings - Fork 626
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
Cannot ergonomically match between diverging futures #683
Comments
Hey @mqudsi, did you know that you can use In your case, this could look like: use futures::future::Either;
// ...
match err {
ErrorCode::CanHandleWithAsync => Either::A(async_error_handler()
.map_err(|_| ErrorCode::CannotHandle)),
ErrorCode::CanHandleWithSync => Either::B(future::result(sync_error_handler())),
ErrorCode::CannotHandle => Either::B(future::err(ErrorCode::CannotHandle)),
} For more complex state-machine patterns, you can also check out the |
You can also use |
@srijs I didn't. Thank you for that tidbit. @Thomasdezeeuw |
Thanks for the report! Unfortunately there's not really much we can do about this I think. This is sort of what happens I believe when you mix a statically compiled language with the generics-based implementation of futures. That being said though this is something that async/await is directly targeted at solving. Conditional branches, multiple returns, etc, are far more ergonomic with async/await. |
I'm trying to come up with a good issue that describes the various type incompatibility problems I've run into with
futures-rs
in the past. This is a very simple and contrived use case, but I think it demonstrates the basic problem.I don't think there's an ergonomic way of handling a case where, depending on the result of one action the called futures undergo different transforms that arrive at the same result.
Here's the code (git repo here: https://git.neosmart.net/mqudsi/futuretest/src/branch/futures-rs-683)
which returns the following compiler error:
Normally, my workaround would be to use
future::result()
to force parallel construction of the futures, but since in this case two of the error cases can be resolved immediately but the third requires the evaluation of another future, the end result is trying to compare a single-level future (FutureResult<_, ErrorCode>
) with a multi-level future (MapErr<FutureResult<_, ErrorCode>>
), which obviously causes the type error above.In terms of solutions that would make this more ergonomic, what comes to my mind is if the return type of all the future transforms were unified as members of an enum wrapped in an opaque struct rather than unified via implementation of a shared trait (especially since
impl trait
is pretty useless as it currently stands). I'm sure there's a catch there and it's not as simple as I'm thinking it is, but there has to be a better way than this. In its current state, futures-rs becomes very hard to use when dealing with what is essentially a state machine (which is ironic since rust itself is particularly well suited for state machine composition with its powerful pattern matching) as the different responses each trigger the evaluation of differing futures.The text was updated successfully, but these errors were encountered: