Parameter lifetime in async function

Hi, I am pretty new to Rust and do not have a good understanding of the lifetimes. I am currently working on a simple http request function using reqwest but the compiler needs lifetime information from me for the variable body.

I am not sure how to specify this here. body only need to live as long as the function. So what can I tell the compiler?

pub async fn request(url: &str, body: &[u8]) -> result::Result<Vec<u8>> {
  let client = reqwest::Client::new();

  let result = client
    .post(url)
    .body(body)
    .send()
    .await
    .map_err(|err| result::ERR_HTTP)?
    .text()
    .await
    .map_err(|err| result::ERR_HTTP)?;

  let text = format!("{:x?}", result);

  Ok(Vec::from(text.as_bytes()))
}
1 Like

The problem is that body doesn't just need to live that long - something else is requiring that it live longer.

See this error:

error: cannot infer an appropriate lifetime
 --> src/lib.rs:1:33
  |
1 | pub async fn request(url: &str, body: &[u8]) -> Vec<u8> {
  |                                 ^^^^ ...but this borrow...
...
6 |     .body(body)
  |      ---- this return type evaluates to the `'static` lifetime...
  |
note: ...can't outlive the lifetime `'_` as defined on the function body at 1:27
 --> src/lib.rs:1:27
  |
1 | pub async fn request(url: &str, body: &[u8]) -> Vec<u8> {
  |                           ^

The reqwest::RequestBuilder::body function requires that its input live as long as 'static - in other words, that it can hang onto it as long as it wants without any external lifetime bound.

You can't tell rust that body only needs to live as long as this function, because you've already told it (by passing body into RequestBuilder::body) that it needs to live longer.

To fix this, I recommend turning body into an owned String using .to_owned() or .to_string() before passing it into RequestBuilder. That way, you'll be able to accept any lifetime of string, then convert it into something that RequestBuilder can also own as long as it wants. Alternatively, change the function to accept a String argument rather than &str.

1 Like