Cannot move out of a captured variable in an FnMut closure

I am starting to lose my sanity. I am trying to run a server with hyper, where I have a Arc<Config> Object, that I want to have present in each request handler.

I am really sorry to post the whole file here, but I really do not know how to proceed here. No matter what I do with moves and clones, the compiler is never satisfied. This should be no problem in my opinion. The Config object behind the Arc can live as long as necessary and can be cloned and moved as often as the compiler needs. But I do not know how to achieve it...

use std::convert::Infallible;
use std::sync::Arc;

use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Request, Response, Server};

pub struct RestServer {
    config: Arc<Config>,
}

impl RestServer {
    pub fn new(config: Arc<Config>) -> Self {
        Self { config }
    }

    pub async fn run(self) -> Result<()> {
        println!(
            "Listening for rest requests on {}",
            self.config.rest_interface.to_string()
        );

        let config = self.config.clone();

        let make_svc = make_service_fn(move |_conn| async move {
            let config = config.clone();
            Ok::<_, Infallible>(service_fn(move |req: Request<Body>| {
                rest_service(req, config.clone())
            }))
        });

        Server::bind(&self.config.rest_interface)
            .serve(make_svc)
            .await?;

        Ok(())
    }
}

async fn rest_service(
    req: Request<Body>,
    config: Arc<ReporterConfig>,
) -> std::result::Result<Response<Body>, Infallible> {
    let full_body = hyper::body::to_bytes(req.into_body()).await.unwrap();

    Ok::<_, Infallible>(Response::new(Body::from(
        handler::handle_request(&full_body, config).await,
    )))
}

Does turning

move |_conn| async move {
    let config = config.clone();
    Ok::<_, Infallible>(service_fn(move |req: Request<Body>| {
        rest_service(req, config.clone())
    }))
}

into

move |_conn| {
    let config = config.clone();
    async move {
        Ok::<_, Infallible>(service_fn(move |req: Request<Body>| {
            rest_service(req, config.clone())
        }))
    }
}

help perhaps?

2 Likes

Yes, that was it. Thanks a lot!

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.