Futures / await! and methods on a struct


#1

I’m trying to port some code to use the nightly version of futures using generators and the await! macro. My methods that took self by reference and returned futures obviously no longer work. So I’m trying to convert them to work with self by value instead and change the API to the structs are more “one time use”. Specifically I want to ensure my hyper::Client is reused so the underlying pool of connections is reused.

To that end I’m trying to figure out how something like this could be made to work:

pub struct Search<'a, C: 'a> {
    client: &'a hyper::Client<C>,
    url: &'a str,
}

impl<'a, C: hyper::client::Connect> Search<'a, C> {
    pub fn new(client: &'a hyper::Client<C>, url: &'a str) -> Search<'a, C> {
        Search {
            client: client,
            url: url,
        }
    }

    #[async]
    pub fn run(self) -> Result<String> {
        let res = await!(self.client.get(self.url.parse()?))?;
        let body = await!(res.body().concat2())?;
        something_with_body(&body)
    }
}

Playground version.

But it still fails to compile with type must satisfy the static lifetime.


#2

The current workaround is to use async_block! so you can tie the returned future to the lifetime in your struct:

pub fn run(self) -> impl Future<Item=String, Error=?> + 'a {
    async_block! {
        let res = await!(self.client.get(self.url.parse()?))?;
        let body = await!(res.body().concat2())?;
        something_with_body(&body)
    }
}

There will hopefully be more ergonomic ways to solve this added in the future.


#3

Sweet! That should really be mentioned in the readme :slight_smile: