use std::collections::HashMap;
use std::sync::Arc;
use astra::{Body, Request, Response, ResponseBuilder, Server};
use matchit::Match;
type Router = matchit::Router<fn(Request) -> Response>;
type Params = HashMap<String, String>;
fn home(_: Request) -> Response {
Response::new(Body::new("Welcome!"))
}
fn get_user(req: Request) -> Response {
let params = req.extensions().get::<Params>().unwrap();
let id = params.get("id").unwrap();
Response::new(Body::new(format!("User #{id}")))
}
fn main() {
let router = Arc::new({
let mut router = Router::new();
router.insert("/", home).unwrap();
router.insert("/user/:id", get_user).unwrap();
router
});
Server::bind("localhost:3000")
.serve(move |req, _info| route(router.clone(), req))
.expect("serve failed");
}
fn route(router: Arc<Router>, mut req: Request) -> Response {
match router.at(req.uri().path()) {
Ok(Match { value, params }) => {
let params = params
.iter()
.map(|(k, v)| (k.to_owned(), v.to_owned()))
.collect::<Params>();
req.extensions_mut().insert(params);
(value)(req)
}
Err(_) => ResponseBuilder::new()
.status(404)
.body(Body::empty())
.unwrap(),
}
}