SOme Error : i was trying to learn rust by "returns a reference to a captured variable which escapes the closure body"

i am learning from this pdf book "hands-on microservices with rust: build, test, and deploy scalable and reactive microservices with rust 2018"

Code doesn't work so I use google to do some search and I am in problem.
if you find any learning guide of rust by example please share it.
this Book I little older and codes does not work with new rust versions.

use hyper::server::conn::AddrStream;
use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Request, Response, Server, StatusCode};
use std::convert::Infallible;
use std::net::SocketAddr;
use std::sync::{Arc, Mutex};
use slab::Slab;
use hyper::http::Method;
// use serde_json;

const INDEX: &'static str = r#"
<h1>Hi\n</h1>
<p>I love this\n</p>
"#;

type UserId = u64;
#[derive(Debug, Copy, Clone)]
struct UserData;


type UserDb = Arc<Mutex<UserData>>;
type UserDb12 = Arc<Mutex<i32>>;
const USER_PATH: &str = "/user/";

async fn handle(
    context: AppContext,
    addr: SocketAddr,
    req: Request<Body>,
    user_db: &UserDb,
) -> Result<Response<Body>, Infallible> {

    // println!("{:?}", serde_json::from_slice(req.body()));

    // let body = req.body().concat2().wait().unwrap().into_bytes();
    // let s = serde_json::from_slice(&body).unwrap();
    // println!("{:?}",s);
    println!("{:?}", req);


    match (req.method(), req.uri().path()) {
        (&Method::GET, "/") => {
            // Ok(INDEX.into())
            Ok(Response::new(Body::from("<h1>this is rust 4.0</h1>")))
        },
        (&Method::GET, "/love") => {
            // Ok(INDEX.into())
            Ok(Response::new(Body::from("Why do i love you.?")))
        },
        (&Method::GET, "/index") => {
            // Ok(INDEX.into())
            Ok(Response::new(Body::from(INDEX)))
        },
        (method, path) if path.starts_with(USER_PATH) => {
            println!("Unimplemented");
            // Ok(Response::new(Body::from("Not implementd")))
            let user_id = path.trim_start_matches(USER_PATH)
            .parse::<UserId>()
            .ok()
            .map(|x| x as usize);
            // unimplemented!();
            Ok(Response::new(Body::from("user_id")))
        },
        _ => {
            let response = Response::builder()
                .status(StatusCode::NOT_FOUND)
                .body(Body::from("404"))
                .unwrap();
            Ok(response)
        }
    
    }

    // Ok(Response::new(Body::from("this is rust 4.0")))
}

#[derive(Clone)]
#[derive(Debug)]
struct AppContext {
    // Whatever data your application needs can go here
}


#[tokio::main]
async fn main() {
    let context = AppContext {
        // ...
    };
    let ko: &str = "I am here";
    println!("{}", ko);
    // let slab = Slab::new();
    let mut s = 4;
    let user_db = Arc::new(Mutex::new(UserData));
    // A `MakeService` that produces a `Service` to handle each connection.
    let make_service = make_service_fn(move |conn: &AddrStream| {
        let context = context.clone();

        let user_db = user_db.clone();
        let addr = conn.remote_addr();

        let service = service_fn(move |req| {
            handle(context.clone(), addr, req, &user_db)
        });
        async move { Ok::<_, Infallible>(service) }
    });

    // run the server like above...
    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
    let server = Server::bind(&addr).serve(make_service);

    if let Err(e) = server.await {
        eprintln!("server error: {:?}", e);
    }
}

Error

error: captured variable cannot escape `FnMut` closure body
   --> src/main.rs:101:13
    |
97  |         let user_db = user_db.clone();
    |             ------- variable defined here
...
100 |         let service = service_fn(move |req| {
    |                                           - inferred to be a `FnMut` closure
101 |             handle(context.clone(), addr, req, &user_db)
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------^
    |             |                                   |
    |             |                                   variable captured here
    |             returns a reference to a captured variable which escapes the closure body
    |
    = note: `FnMut` closures only have access to their captured variables while they are executing...
    = note: ...therefore, they cannot allow references to captured variables to escape

I didn't dig into hyper to see what exactly is going on, but one way to work around the error is to have handle take a UserDb instead of a &UserDb, and to clone the captured user_db when calling it.

Playground.

sorry didnt work

If you post the new code and error, perhaps someone can try again to help.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.