I am trying to write a simple REST server using hyper:
pub struct APIServer{
port: u16,
memtable: RwLock<Memtable>
}
#[derive(Deserialize, Debug)]
pub struct KeyValuePair {
key : String,
value : String,
}
impl APIServer {
pub fn new(port: u16, path: String) -> Result<APIServer, io::Error> {
let path = Path::new(&path);
let memtable = Memtable::new(path)?;
let server = APIServer {
port: port,
memtable: RwLock::<Memtable>::from(memtable),
};
Ok(server)
}
pub async fn run(&self) {
let addr = SocketAddr::from(([127, 0, 0, 1], self.port));
println!("Listening on {}", addr);
let serve_future = Server::bind(&addr).serve(make_service_fn(|_conn| {
async {
{
Ok::<_, hyper::Error>(service_fn(router))
}
}
}));
// Wait for the server to complete serving or exit with an error.
// If an error occurred, print it to stderr.
if let Err(e) = serve_future.await {
eprintln!("server error: {}", e);
}
}
// Router routes requests to approporiate http handlers.
fn router(&self) -> Box<dyn Fn(Request<Body>) -> Result<Response<Body>, hyper::Error>> {
return Box::new(|req| async move {
let mut response = Response::new(Body::empty());
match (req.method(), req.uri().path()) {
(&Method::GET, "/{key}") => {
handlers::get_value(req)
}
(&Method::POST, "/") => {
handlers::write_key_value_pair(req).await
}
_ => {
*response.status_mut() = StatusCode::NOT_FOUND;
Ok(response)
}
}
});
}
}
The issue is that I would like to use the APIServers
fields inside the the http
handlers (and the router
itself) - i.e. use them as a "service_fn"(1,2), thus, their signature would be fn foo_handler(Request<Body>) -> Result<Response<Body>, hyper::Error:error>
- to resolve this issue I made the router return a closure which contains adheres to the above signature.
But now I am getting the following error:
expected enum `std::result::Result`, found opaque type
note: expected enum `std::result::Result<http::response::Response<hyper::body::body::Body>, hyper::error::Error>`
found opaque type `impl futures::Future`rustc(E0308)
server.rs(58, 31): expected enum `std::result::Result`, found opaque type
In short, how can I use the router and the handlers as methods so that I can pass certain private fields to them? without breaching contract.