Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Deserializing hyper body into utf8 string: error[E0597]: `bytes` does not live long enough

I want to write a util where I deserialize a given request body into the target type (T):

pub async fn read_json_body<'a, T>(req: &'a mut Request<Body>) -> T where T : Deserialize<'a> {
    let mut body = req.body_mut();
    let bytes = body::to_bytes(body).await.unwrap();
    let body_str = std::str::from_utf8(&*bytes).unwrap();
    serde_json::from_str::<T>(body_str).unwrap()
}

When I try to compile the code, I get the following error:

error[E0597]: `bytes` does not live long enough

21 |     pub async fn read_json_body<'a, T>(req: &'a mut Request<Body>) -> T where T : Deserialize<'a> {
   |                                 -- lifetime `'a` defined here
...
24 |         let body_str = std::str::from_utf8(&*bytes).unwrap();
   |                                              ^^^^^ borrowed value does not live long enough
25 |         serde_json::from_str::<T>(body_str).unwrap()
   |         ----------------------------------- argument requires that `bytes` is borrowed for `'a`
26 |     }
   |     - `bytes` dropped here while still borrowed

I understand that the Deserialize trait requires the lifetime 'a to outlive the deserialization, which is why assign the lifetime to the request reference. However I don’t understand what my options are to fix this error in regard to the lifetime of the bytes object.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

How do I fix this issue?

Requirements:

  • I don’t want to move the request into the scope of the function
  • I don’t want to extract the body from the request outside of the util, the request should be the parameter for the function, not the body

>Solution :

Use an owned version constraining to DeserializeOwned instead:

pub async fn read_json_body<T>(req: &mut Request<Body>) -> T where T : DeserializeOwned {
    let mut body = req.body_mut();
    let bytes = body::to_bytes(body).await.unwrap();
    let body_str = std::String::from_utf8(&*bytes).unwrap();
    serde_json::from_str::<T>(&body_str).unwrap()
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading