nuclear 0.0.10

[WIP] a web framework for humans
Documentation
use nuclear::error::StatusError;
use nuclear::functional::{ref_handler, ref_middleware};
use nuclear::prelude::{Handler, Request, Response, Result};
use nuclear::router::{SimpleRouter, SimpleRouterExt};

use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;

struct App {
    count: AtomicUsize,
}

impl App {
    fn new() -> Self {
        Self {
            count: AtomicUsize::new(0),
        }
    }

    fn into_handler(self) -> impl Handler {
        let get_hello: _ = ref_handler(Self::get_hello);
        let get_world: _ = ref_handler(Self::get_world);
        let not_found: _ = ref_handler(Self::not_found);
        let recover: _ = ref_middleware(Self::recover);

        let mut router: SimpleRouter = SimpleRouter::new();

        router.at("/hello/:name").get(get_hello.boxed());
        router.at("/world").get(get_world.boxed());
        router.set_default(not_found.boxed());

        router.wrap(recover).with_state(Arc::new(self))
    }

    async fn get_hello(&self, req: Request) -> String {
        let name = req.expect_param("name");
        format!("GET /hello/{}", name)
    }

    async fn get_world(&self, _: Request) -> String {
        let count = self.count.fetch_add(1, Ordering::Relaxed) + 1;
        format!("GET /world => {}", count)
    }

    async fn not_found(&self, _: Request) -> Result<Response> {
        Err(StatusError::NOT_FOUND.into())
    }

    async fn recover(&self, req: Request, next: &dyn Handler) -> Result<Response> {
        match next.handle(req).await {
            Err(err) => {
                eprintln!("Error: {:?}", err);
                Ok(Response::text("Oops"))
            }
            ret => ret,
        }
    }
}

#[tokio::main]
async fn main() -> Result<()> {
    let h = App::new().into_handler();
    h.into_server().run("127.0.0.1:8080").await
}