use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Request, Response, Server, StatusCode};
use usher::capture::find_capture;
use usher::http::HttpRouter;
use usher::prelude::*;
use std::sync::Arc;
type Callee =
Box<dyn Fn(Request<Body>, Vec<(&str, (usize, usize))>) -> Response<Body> + Send + Sync>;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let addr = ([127, 0, 0, 1], 3000).into();
let mut router: HttpRouter<Callee> =
HttpRouter::new(vec![Box::new(DynamicParser), Box::new(StaticParser)]);
router.get(
"/:name",
Box::new(|req, params| {
let path = req.uri().path();
let name = find_capture(path, ¶ms, "name").unwrap();
Response::new(format!("Hello, {}!\n", name).into())
}),
);
let router = Arc::new(router);
let server = make_service_fn(move |_conn| {
let router = router.clone();
async {
let server = service_fn(move |req: Request<Body>| {
let router = router.clone();
async move {
let method = req.method();
let path = req.uri().path();
let response = match router.handler(method, path) {
Some((handler, captures)) => handler(req, captures),
None => {
let mut response = Response::new(Body::empty());
*response.status_mut() = StatusCode::NOT_FOUND;
response
}
};
Ok::<_, hyper::Error>(response)
}
});
Ok::<_, hyper::Error>(server)
}
});
println!("Listening on http://{}", addr);
Server::bind(&addr).serve(server).await?;
Ok(())
}