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));
}
}