How to specify lifetime of return type equal to lifetime of an argument for async function

I am trying to extract common code from my API handlers, which look like the following:

async fn api_handler(_req: HttpRequest, mut body: web::Payload) -> Result<HttpResponse, Error> {
    let mut bytes = web::BytesMut::new();
    while let Some(item) = body.next().await {
        let item: web::Bytes = item?;
        bytes.extend_from_slice(&item);
    };
    let body = std::str::from_utf8(&bytes)?;

    ....
}

The only way to move this block to a common function is to require one more String construction, like the following:

pub async fn receive_body_as_string(mut body: actix_web::web::Payload) -> Result<String, actix_web::Error> {
    let mut bytes = actix_web::web::BytesMut::new();
    while let Some(item) = body.next().await {
        let item: actix_web::web::Bytes = item?;
        bytes.extend_from_slice(&item);
        if bytes.len() > MAX_MESSAGE_SIZE {
            Err(Error::InvalidBodyTooLarge)?;
        }
    };
    let body = std::str::from_utf8(&bytes)
        .map_err(|_| Error::InvalidBodyUtf8)?;

    let body = String::from(body);
    Ok(body)
}

Is there any way to return body = std::str::from_utf8(&bytes) directly out of the function without wrapping it in a string?

To return the reference, you must take some reference and then make the output reference a view into data referenced by the input reference. So, you could try to replace mut body: actix_web::web::Paypoad with body: &mut actix_web::web::Payload, but I'm not sure if this will help: your return value references bytes, which looks like not referencing the body, but rather building locally based on it.

Yes, I tried this. But then the compiler complains that body does not live long enough after next().await

Well, that's exactly what I was afraid of. You can't return the body as reference, since there's nothing in the function arguments to borrow it from.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.