bare 0.0.1

a bare web framework
use std::old_io::net::ip::IpAddr;
use hyper::net::Fresh;

use hyper::Server as HttpServer;
use { Request, Response, WebResult, status };
use request::HttpRequest;
use response::HttpResponse;

pub struct Service<H> {
    handler: H
}

impl<H: Handler + 'static> Service<H> {
    pub fn new(handler: H) -> Service<H> {
        Service { handler: handler }
    }

    pub fn listen(self, addr: IpAddr, port: u16) {
        HttpServer::http(addr, port).listen(self).unwrap();
    }
}

pub trait Handler: Send + Sync {
    fn call(&self, &Request) -> WebResult<Response>;
}

impl<F> Handler for F where F: Fn(&Request) -> WebResult<Response>, F: Sync + Send {
    fn call(&self, req: &Request) -> WebResult<Response> {
        self(req)
    }
}

impl<H: Handler> ::hyper::server::Handler for Service<H> {
    fn handle(&self, http_req: HttpRequest, mut http_res: HttpResponse<Fresh>) {
        let req = match Request::from_http(http_req) {
            Ok(req) => req,
            Err(_)  => {
                *http_res.status_mut() = status::BadRequest;
                let http_res = match http_res.start() {
                    Ok(res) => res,
                    Err(_) => return,
                };

                // We would like this to work, but can't do anything if it doesn't.
                let _ = http_res.end();
                return;
            }
        };

        // Dispatch the request // from Iron
        // let res = self.handler.call(&mut req).map_err(|e| {
            // self.handler.catch(&mut req, e)
        // });
        let res = self.handler.call(&req);

        match res {
            Ok(res) => res.write_back(http_res),
            Err(e) => {
                // There is no Response, so create one.
                error!("Error handling:\n{:?}\nError was: {}", req, e);
                *http_res.status_mut() = status::BadRequest;

                let http_res = match http_res.start() {
                    Ok(res) => res,
                    Err(_) => return,
                };

                // We would like this to work, but can't do anything if it doesn't.
                let _ = http_res.end();
            }
        }
    }
}