How do I make this code more future-y?
https://play.rust-lang.org/?gist=4ede91865b16e1993862a99df91607e2&version=stable
I know I'm doing something wrong here. My client creates its own core so that I can just block when I make requests.
I don't see how to just return futures without exposing implementation details - I'm trying to write a high level, encapsulated client.
I think maybe the answer is to impl Future for my client, and then lift the Core out of it. But I don't want 'and_then' and things like that, I want 'get_file' etc.
This code is, I think, functional. But it feels incorrect.
Posted Apr 8, 2018, 6:38 PM UTC
78
I've found it useful to write APIs like this in two parts.
It would mean having one "async" API which does not contain the core, and returns futures on every request, then having a "sync" api structure which holds the async API and the core together, and allows making synchronous requests.
In your specific case,
newon the "async" api would probably return some kind ofFuture<AsyncClient>, and the SyncClient would have a blockingnewto match it.Some crates like reqwest have the async part marked as unstable so it can have breaking changes, so that could be an option too. The async API doesn't have to be a public stable one, but if you want people to use it (the async part), it probably should be.
I don't generally think clients exposing Futures should contain their own cores - but it's very inconvenient for synchronous usage if the user always needs to manage a core as well. This is the main reason I'd go with a two-part API.
OK, that makes sense. I guess what I'm struggling with is.. how would I expose a Future<AsyncClient> ?
I guess I'd do something like:
oh... it worked
Yeah, that's what I would do- then just return a
Box<Future<Item=AsyncClient, Error=...>>.In this case I'm using
impl Traitbecause it'll always return the same type.But yeah, cool. This actually works... thank you.