1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
extern crate iron; extern crate regex; use std::collections::HashMap; use iron::method::Method; use iron::{status, Handler, Request, Response, IronResult}; use regex::{Regex, Captures}; type RouteHandler = fn(&mut Request, Captures) -> IronResult<Response>; type NotFoundHandler = fn(&mut Request) -> IronResult<Response>; type Routes = HashMap<Method, Vec<(Regex, RouteHandler)>>; pub struct Router { routes: Routes, not_found: NotFoundHandler, } impl Handler for Router { fn handle(&self, req: &mut Request) -> IronResult<Response> { let url = ["/", &req.url.path().join("/")].concat(); let routes = self.routes.get(&req.method).unwrap(); match routes.clone().into_iter().find(|ref x| x.0.is_match(&url)) { Some((re, handler)) => { let captures = re.captures(&url).unwrap(); handler(req, captures) } None => (self.not_found)(req) } } } pub struct RouterBuilder { pub routes: Routes, pub not_found: Option<NotFoundHandler> } impl RouterBuilder { pub fn new() -> RouterBuilder { let mut routes = HashMap::new(); routes.insert(Method::Get, Vec::new()); routes.insert(Method::Post, Vec::new()); routes.insert(Method::Put, Vec::new()); routes.insert(Method::Delete, Vec::new()); RouterBuilder { routes: routes, not_found: None } } fn route(&mut self, method: Method, pattern: &str, handler: RouteHandler) -> &mut RouterBuilder { let pattern = [r"\A", pattern, r"\z"].join(""); let re = Regex::new(&pattern).unwrap(); self.routes.get_mut(&method).unwrap().push((re, handler)); self } pub fn get(&mut self, pattern: &str, handler: RouteHandler) -> &mut RouterBuilder { self.route(Method::Get, pattern, handler) } pub fn post(&mut self, pattern: &str, handler: RouteHandler) -> &mut RouterBuilder { self.route(Method::Post, pattern, handler) } pub fn put(&mut self, pattern: &str, handler: RouteHandler) -> &mut RouterBuilder { self.route(Method::Put, pattern, handler) } pub fn delete(&mut self, pattern: &str, handler: RouteHandler) -> &mut RouterBuilder { self.route(Method::Delete, pattern, handler) } pub fn not_found(&mut self, handler: NotFoundHandler) -> &mut RouterBuilder { self.not_found = Some(handler); self } pub fn finalize(self) -> Router { Router { routes: self.routes, not_found: self.not_found.unwrap_or_else(|| default_not_found) } } } fn default_not_found(_: &mut Request) -> IronResult<Response> { Ok(Response::with((status::NotFound))) } #[cfg(test)] mod tests { #[test] fn it_works() { assert_eq!(2 + 2, 4); } }