Seems like there should be a trivial function to lift Error
into an appropriate future? Something like this:
fn lift_io<F, A, B, C>(a: io::Result<A>, f: F) -> IoFuture<B>
where F: FnOnce(A) -> C,
C: Future<Item = B, Error = io::Error> + Send + 'static,
B: Send + 'static
{
match a {
Ok(x) => f(x).boxed(),
Err(err) => failed(err).boxed(),
}
}
Also, it feels like I should be able to drop the Send + 'static
bounds... Maybe if I holler @alexcrichton?
You can certainly do this! An easy way might be:
futures::done(result).and_then(my_closure)
That is, you can convert any Result<T, E>
into a Future<Item=T, Error=E>
easily through the futures::done
method, and then once you've done that you can chain on further computations like and_then
.
The Send + 'static
bounds here are actually required by the return type, IoFuture
. This is an alias around Box<Future<...> + Send + 'static>
which is where those requirements come from. This is part of the difficulty of returning futures where if you return a trait object you have to define the Send
-ness or 'static
-ness up front.
If you were to return a concrete type (e.g. AndThen<Done<A, io::Error>, F>
) then you wouldn't require either Send
or 'static
. Additionally, if you were to use impl Future
you also wouldn't require the bounds. You also optionally have the ability to return a non-Send
trait object or even a non-'static
one depending on what you'd like to do in this situation.
Lemme know if any of that's confusing though, I may need to update the "returning futures" section of the tutorial in light of recent changes with the futures library
3 Likes
That's perfect actually. I've just been trying to figure out how to make my own version of Done
(which of course, given what I wrote above, is more like DoneAndThen
, so it would have taken me quite a while to realise that error in design). Times like this I'm a little sad about the lack of something like Hoogle --- I knew exactly what type the thing had to have, but finding it in the documentation was too much for my weekend brain
As far as documentation goes, some code with realistic error handling, alternating between layers of io and futures, would be a nice addition. I have a Haskell background so naturally I knew to try to look for something like liftIO
that would push things up the transformer stack, but that pattern might be a bit weird to other people. And even then I'm not sure that's actually the idiomatic way to proceed here!
Hi Alex, you said
Additionally, if you were to use impl Future you also wouldn’t require the bounds
could you please give a simple sample?
I saw your another post on Make methods -> impl Future · Issue #657 · rust-lang/futures-rs · GitHub
you said methods -> impl Future was not a good idea
The answers on this thread seem deprecated. What is the alternative to futures::done
now?
futures::future::ready(value)
or async move { value }
2 Likes
This topic was automatically closed after 91 days. New replies are no longer allowed.