1

I have a struct Router that, once built, never changes. I want to pass it by reference to several closures:

#![feature(trait_alias)]
use futures::future::{self,Future};
use hyper::{Body, Request,Method,Response};
use hyper::service::{service_fn,make_service_fn};
use hyper::server::conn::AddrStream;

//

#[cfg_attr(rustfmt, rustfmt_skip)]
pub trait RetFut = Future<Item = Response<Body>, Error = hyper::Error>;

#[derive(Debug, Clone)]
pub struct Route {
    pub method: Method,
}

#[derive(Debug, Clone)]
pub struct Router {
    routes: Vec<Route>,
}
impl Router {
    pub fn builder() -> RouterBuilder {
        RouterBuilder::new()
    }

    pub fn handle_req(&self, req: Request<Body>) -> impl RetFut {
        match (req.method(), req.uri().path()) {
            _ => future::ok(Response::new(Body::from("Hello world"))),
        }
    }
}

#[derive(Debug, Default)]
pub struct RouterBuilder {
    routes: Vec<Route>,
}
impl RouterBuilder {
    pub fn new() -> Self {
        RouterBuilder { routes: vec![] }
    }

    pub fn build(self) -> Router {
        Router {
            routes: self.routes,
        }
    }
}



fn main() {
    let addr = "0.0.0.0:8080".parse().unwrap();

    let router: Router = Router::builder().build();

    let make_svc = make_service_fn(move |_socket: &AddrStream| {
        let router_clone = router.clone();
        service_fn(move |req: Request<Body>| {
            router_clone.clone().handle_req(req)
        })
    });

    let server = hyper::Server::bind(&addr)
        .serve(make_svc)
        .map_err(|e| eprintln!("server error: {}", e));

    hyper::rt::run(server);
}

Here I'm passing a clone of the Router for each closure to own, but it seems unnecessary.

Instead, a reference to the Router that lives for the whole duration of the closures would probably be enough.

How can I achieve that here ?

Nicolas Marshall
  • 4,186
  • 9
  • 36
  • 54

0 Answers0