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
use std::sync::Arc;
use std::net::SocketAddr;
use hyper::server::{Http, Service};
use hyper::error::Error;
use futures;
use futures_cpupool::{CpuPool, Builder};
use hyper::StatusCode;

use router::Router;
use context::Context;

pub struct App {
    pub router: Router,
    pub pool: CpuPool,
}

impl App {
    pub fn new() -> App {
        App {
            router: Router::new(),
            pool: Builder::new().create()
        }
    }

    pub fn run(self, addr: &SocketAddr) {
        println!("Starting server on {}...", addr);
        let s = Arc::new(self);
        let http = Http::new().bind(&addr, move || Ok(s.clone())).unwrap();
        http.run().unwrap();
    }
}

impl Service for App {
    type Request = ::Request;
    type Response = ::Response;
    type Error = Error;
    type Future = Box<futures::Future<Item=Self::Response, Error=Self::Error>>;

    fn call(&self, req: ::Request) -> Self::Future {
        for route in self.router.routes.iter() {
            match route.matches_request(&req) {
                Some(params) => {
                    let r = route.clone();
                    return Box::new(self.pool.spawn_fn(move || {
                        let context = Context::new(req, params);
                        return futures::future::ok((r.handler)(context));
                    }))
                },
                None => ()
            }
        }
        let mut notfound = ::Response::new();
        notfound.set_status(StatusCode::NotFound);
        return Box::new(futures::future::ok(notfound));
    }
}