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
use std::rc::Rc;
use std::collections::HashMap;
use futures::Future;
use route_recognizer;
use state::Container;

use request::Method;
use super::{Handler, Request, Response, Error};
pub use route_recognizer::Params;


#[derive(Clone)]
pub struct Router {
    rr: Rc<HashMap<Method, route_recognizer::Router<Box<Handler + 'static>>>>,
}

impl Router {
    pub fn new() -> Router {
        Router { rr: Rc::new(HashMap::new()) }
    }

    pub fn get(&mut self, route: &str, handler: Box<Handler + 'static>) {
        let mut rr = Rc::get_mut(&mut self.rr).expect("can't modify router at this point");
        rr.entry(Method::Get)
            .or_insert_with(route_recognizer::Router::new)
            .add(route, handler);
    }

    pub fn mount(&mut self, prefix: &str, handler: Box<Handler + 'static>) {
        let mut rr = Rc::get_mut(&mut self.rr).expect("can't modify router at this point");
        let prefix = if prefix == "/" { "" } else { prefix };

        let path = format!("{}{}", prefix, handler.path());

        rr.entry(handler.method())
            .or_insert_with(route_recognizer::Router::new)
            .add(&path, handler);
    }

    pub fn run(
        &self,
        req: Request,
        state: Container,
    ) -> Result<Box<Future<Item = Response, Error = Error>>, Error> {
        let rr = self.rr.get(req.method()).ok_or(Error::RouterError)?;

        let m = rr.recognize(req.path()).map_err(|_| Error::RouterError)?;
        Ok(m.handler.handle(req, m.params, state))
    }
}