huio 0.1.0

HTTP Framework based on Actix-Web
Documentation
use std::{collections::HashMap, future::Future, sync::Arc};

use crate::http::{BoxFuture, Handler, HttpMethod, Middleware, Request, Response};

macro_rules! impl_method {
    ($name:ident, $method:expr) => {
        #[must_use]
        pub fn $name<F, Fut>(self, f: F) -> Self
        where
            F: Fn(Request) -> Fut + Send + Sync + 'static,
            Fut: Future<Output = Response> + Send + 'static,
        {
            self.add_handler($method, f)
        }
    };
}

pub struct Router {
    pub(crate) path: String,
    pub(crate) handlers: HashMap<HttpMethod, Handler>,
    pub(crate) middlewares: Vec<Middleware>,
    pub(crate) children: Vec<Router>,
}

impl Router {
    pub fn new(path: &str) -> Self {
        Self {
            path: path.to_string(),
            handlers: HashMap::new(),
            middlewares: Vec::new(),
            children: Vec::new(),
        }
    }

    #[must_use]
    pub fn middleware(mut self, m: Middleware) -> Self {
        self.middlewares.push(m);
        self
    }

    #[must_use]
    pub fn nest(mut self, child: Router) -> Self {
        self.children.push(child);
        self
    }

    fn add_handler<F, Fut>(mut self, method: HttpMethod, f: F) -> Self
    where
        F: Fn(Request) -> Fut + Send + Sync + 'static,
        Fut: Future<Output = Response> + Send + 'static,
    {
        self.handlers.insert(
            method,
            Arc::new(move |req| Box::pin(f(req)) as BoxFuture<Response>),
        );
        self
    }

    impl_method!(get, HttpMethod::GET);
    impl_method!(post, HttpMethod::POST);
    impl_method!(put, HttpMethod::PUT);
    impl_method!(delete, HttpMethod::DELETE);
    impl_method!(patch, HttpMethod::PATCH);
    impl_method!(head, HttpMethod::HEAD);
    impl_method!(options, HttpMethod::OPTIONS);
}