use std::collections::HashMap;
use http;
use {
box_handler, Body, BodyStream, BoxedHandler, BoxedResponse, Handler, Responder, ResponseBuilder,
};
#[derive(Default)]
pub struct SimpleRouter {
handlers: HashMap<String, BoxedHandler>,
}
impl SimpleRouter {
pub fn new() -> Self {
SimpleRouter::default()
}
pub fn register_handler<S, H, ReqBody>(&mut self, pattern: S, handler: H)
where
S: Into<String>,
H: Handler<ReqBody>,
ReqBody: Body,
{
let pattern = pattern.into();
if self.handlers.contains_key(&pattern) {
panic!("SimpleRouter: Tried to register pattern twice: {}", pattern);
}
self.handlers.insert(pattern, box_handler(handler));
}
pub fn handler(&self, uri: &http::Uri) -> Option<(&String, &BoxedHandler)> {
self.handlers
.iter()
.filter(|&(pattern, _)| uri.path().starts_with(pattern))
.max_by_key(|&(pattern, _)| pattern.len())
}
}
impl Handler<BodyStream> for SimpleRouter {
type Resp = BoxedResponse;
fn handle(&self, req: http::Request<BodyStream>, mut resp: ResponseBuilder) -> BoxedResponse {
match self.handler(req.uri()) {
Some((_, handler)) => handler.handle(req, resp),
None => resp.status(http::StatusCode::NOT_FOUND)
.body(())
.into_response(),
}
}
}