novel 0.4.2

my web framework.
Documentation
use std::fmt;
use std::sync::Arc;
use std::collections::HashMap;
use std::time::Duration;

use hyper::Server as HyperServer;
use futures_cpupool::CpuPool;

use crate::{Context, Handler, Protocol, Catcher};
use crate::http::{self, StatusCode, Request, Response, Mime};
use crate::http::headers::SET_COOKIE;
use crate::catcher;

use std::net::{SocketAddr, ToSocketAddrs};
use futures::{future, Future};
/// A settings struct containing a set of timeouts which can be applied to a server.
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct Timeouts {
    /// Controls the timeout for keep alive connections.
    ///
    /// The default is `Some(Duration::from_secs(5))`.
    ///
    /// NOTE: Setting this to None will have the effect of turning off keep alive.
    pub keep_alive: Option<Duration>,
}

impl Default for Timeouts {
    fn default() -> Self {
        Timeouts {
            keep_alive: Some(Duration::from_secs(5)),
        }
    }
}

/// The main `Novel` type: used to mount routes and catchers and launch the
/// application.
pub struct Server<H: Handler> {
    pub handler: Arc<H>,
    pub config: Arc<ServerConfig>
}
pub struct ServerConfig{
    pub timeouts: Timeouts,

    /// Cpu pool to run synchronus requests on.
    ///
    /// Defaults to `num_cpus`.  Note that reading/writing to the client is
    /// handled asyncronusly in a single thread.
    pub pool: CpuPool,

    /// Protocol of the incoming requests
    ///
    /// This is automatically set by the `http` and `https` functions, but
    /// can be set if you are manually constructing the hyper `http` instance.
    pub protocol: Protocol,

    /// Default host address to use when none is provided
    ///
    /// When set, this provides a default host for any requests that don't
    /// provide one.  When unset, any request without a host specified
    /// will fail.
    pub local_addr: Option<SocketAddr>,

    pub catchers: Arc<Vec<Box<dyn Catcher>>>,
    pub media_types: Arc<HashMap<String, Mime>>,
}
impl ServerConfig {
    pub fn new()->ServerConfig{
        ServerConfig{
            protocol: Protocol::http(),
            local_addr: None,
            timeouts: Timeouts::default(),
            pool: CpuPool::new_num_cpus(),
            catchers: Arc::new(catcher::defaults::get()),
            media_types: Arc::new(http::media_type::defaults::get()),
        }
    }
}

impl Default for ServerConfig {
    fn default() -> Self {
        ServerConfig::new()
    }
}

impl<H: Handler> Server<H> {
    pub fn new(handler: H)->Server<H>{
        let config = ServerConfig::default();
        Server{
            handler: Arc::new(handler),
            config: Arc::new(config),
        }
    }

    pub fn with_config(handler: H, config: ServerConfig)->Server<H> {
        Server{
            handler: Arc::new(handler),
            config: Arc::new(config),
        }
    }

    pub fn serve<A>(mut self, addr: A) where A: ToSocketAddrs{
        let addr: SocketAddr = addr.to_socket_addrs().unwrap().next().unwrap();
        Arc::get_mut(&mut self.config).unwrap().local_addr = Some(addr);
        let server = HyperServer::bind(&addr)
            .tcp_keepalive(self.config.timeouts.keep_alive)
            .serve(self).map_err(|e| eprintln!("server error: {}", e));
        println!("Server running: {}", addr);
        hyper::rt::run(server);
    }
}
impl<H: Handler> hyper::service::NewService for Server<H> {
    type ReqBody = hyper::body::Body;
    type ResBody = hyper::body::Body;
    type Error = hyper::Error;
    type Service = HyperHandler<H>;
    type InitError = hyper::Error;
    type Future = future::FutureResult<Self::Service, Self::InitError>;

    fn new_service(&self) -> Self::Future {
        future::ok(HyperHandler {
            handler: self.handler.clone(),
            server_config: self.config.clone(),
         })
    }
}
pub struct HyperHandler<H: Handler> {
    handler: Arc<H>,
    server_config: Arc<ServerConfig>,
}

impl<H: Handler> hyper::service::Service for HyperHandler<H>{
    type ReqBody = hyper::body::Body;
    type ResBody = hyper::body::Body;
    type Error = hyper::Error;
    type Future = Box<dyn Future<Item = hyper::Response<Self::ResBody>, Error = Self::Error> + Send>;
    
    fn call(&mut self, req: hyper::Request<Self::ReqBody>) -> Self::Future {
        let handler = self.handler.clone();
        let sconfig = self.server_config.clone();

        let pool = sconfig.pool.clone();
        let local_addr = sconfig.local_addr.clone();
        let protocol = sconfig.protocol.clone();
        let catchers = sconfig.catchers.clone();
        Box::new(pool.spawn_fn(move || {
            let mut ctx = Context::new(sconfig, Request::from_hyper(req, local_addr, &protocol).unwrap(), Response::new());
            handler.handle(&mut ctx);
            if !ctx.is_commited() {
                ctx.commit();
            }
            let mut response = hyper::Response::<hyper::Body>::new(hyper::Body::empty());

           if let None = ctx.response.status{
                if ctx.response.body_writers.len() == 0 {
                    ctx.response.status = Some(StatusCode::NOT_FOUND);
                }else {
                    ctx.response.status = Some(StatusCode::OK);
                }
            }
            let status = ctx.response.status.unwrap();
            if ctx.response.body_writers.len() == 0 && (status.as_str().starts_with('4') || status.as_str().starts_with('5')) {
                for catcher in &*catchers {
                    if catcher.catch(&ctx.request, &mut ctx.response){
                        break;
                    }
                }
            }
            for cookie in ctx.cookies.delta() {
                if let Ok(hv) = cookie.encoded().to_string().parse(){
                    response.headers_mut().append(SET_COOKIE, hv);
                }
            }
            ctx.response.write_back(&mut response, ctx.request.method().clone());
            future::ok(response)
        }))
    }
}