Borrow Problem with actix

I have probably a simple problem (which I can not solve). My code is as follows:

async fn debug_post(req: HttpRequest, body: web::Bytes, param: String) -> impl Responder {
    info!("{}", param);

    match String::from_utf8(body.to_vec()) {
        Ok(text) => {
            info!("{}->{}", req.path(), text);
            web::Json(Result {
                result: RESULT_OK.to_string(),
            })
        }
        Err(e) => {
            error!("{}->{}", req.path(), e);
            web::Json(Result {
                result: RESULT_ERR.to_string(),
            })
        }
    }
}
...
let hrx_ok: String = String::from_utf8_lossy(include_bytes!("assets/hrx_response_ok.xml")).to_string();
...
   match HttpServer::new(|| {
        App::new()
            .route("/", web::post().to(accept_hrx))
            //.route("/debug", web::post().to(debug_post))
            .route(
                "/debug",
                web::post().to(|body: web::Bytes, req: HttpRequest| debug_post(req, body, hrx_ok.clone())),
            )
            .route("/resend-all", web::get().to(resend_hrx))
    })
    .bind(listen)
    {
        Ok(server) => server.run().await,
        Err(e) => {
            error!("{:?}", e.to_string());
            Ok(())
        }
    }

When I compile it, I get the following error:

error[E0597]: `hrx_ok` does not live long enough
  --> hrx_proxy\src\main.rs:87:91
   |
81 |     match HttpServer::new(|| {
   |                           -- value captured here
...
87 |                 web::post().to(|body: web::Bytes, req: HttpRequest| debug_post(req, body, hrx_ok.clone())),
   |                 --------------------------------------------------------------------------^^^^^^----------
   |                 |                                                                         |
   |                 |                                                                         borrowed value does not live long enough
   |                 argument requires that `hrx_ok` is borrowed for `'static`
...
99 | }
   | - `hrx_ok` dropped here while still borrowed

error: aborting due to previous error; 2 warnings emitted

For more information about this error, try `rustc --explain E0597`.

Do you see a simple solution for this?

Thank you for any help in advance,

Maciej

Try adding move to the closure that the error came from.

1 Like

Could you give me an advice how to do it?

I tried:

web::post().to(move |body: web::Bytes, req: HttpRequest| debug_post(req, body, hrx_ok.clone())),

but then I get a new error:

75 |     let hrx_ok: String = String::from_utf8_lossy(include_bytes!("assets/hrx_response_ok.xml")).to_string();
   |         ------ captured outer variable
...
87 |                 web::post().to(move |body: web::Bytes, req: HttpRequest| debug_post(req, body, hrx_ok.clone())),
   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                       ------
   |                                |                                                               |
   |                                |                                                               move occurs because `hrx_ok` has type `std::string::String`, which does not implement the `Copy` trait
   |                                |                                                               move occurs due to use in closure
   |                                move out of `hrx_ok` occurs here

Finally I have found a solution, exactly as suggested by Alice:

Example:

fn main() -> io::Result<()> {
        let schema = std::sync::Arc::new(create_schema());
        HttpServer::new(move || {
            App::new()
                .data(schema.clone())
                .service(web::resource("/graphql").route(web::post().to_async(graphql)))
                .service(web::resource("/graphiql").route(web::get().to(graphiql)))
        })
        .bind("localhost:8080")?
        .run()
    }

seen here: How to Build Powerful GraphQL Servers with Rust (freecodecamp.org)

Thank you very much !