use http::Method;
use std::collections::HashMap;
use crate::capture::Captures;
use crate::parser::Parser;
use crate::router::Router;
pub struct HttpRouter<T> {
router: Router<HashMap<Method, T>>,
}
macro_rules! http_delegate {
($name:ident, $method:expr, $smethod:expr) => {
#[inline(always)]
#[doc = "Registers a handler for the `"]
#[doc = $smethod]
#[doc = "` HTTP method."]
pub fn $name(&mut self, path: &str, t: T) {
self.insert($method, path, t)
}
};
}
impl<T> HttpRouter<T> {
pub fn new(parsers: Vec<Box<dyn Parser>>) -> Self {
Self {
router: Router::new(parsers),
}
}
http_delegate!(connect, Method::CONNECT, "CONNECT");
http_delegate!(delete, Method::DELETE, "DELETE");
http_delegate!(get, Method::GET, "GET");
http_delegate!(head, Method::HEAD, "HEAD");
http_delegate!(options, Method::OPTIONS, "OPTIONS");
http_delegate!(patch, Method::PATCH, "PATCH");
http_delegate!(post, Method::POST, "POST");
http_delegate!(put, Method::PUT, "PUT");
http_delegate!(trace, Method::TRACE, "TRACE");
fn insert(&mut self, method: Method, path: &str, t: T) {
self.router.update(path, |node| {
let mut map = node.unwrap_or_default();
if !map.contains_key(&method) {
map.reserve(1);
}
map.insert(method, t);
map
});
}
pub fn handler<'a>(&'a self, method: &Method, path: &str) -> Option<(&'a T, Captures<'a>)> {
self.router.lookup(path).and_then(|(node, captures)| {
node.get(method).map(|handler| (handler, captures))
})
}
}