From 369ee0006cd6f8e94f15de7fc00d549e4737faa9 Mon Sep 17 00:00:00 2001 From: Erik Hollensbe Date: Fri, 14 Jan 2022 23:44:16 -0800 Subject: [PATCH] First stab at a handler framework; a basic chain-of-responsibility pattern This is intended to make middleware a forefront technology. Signed-off-by: Erik Hollensbe --- Cargo.toml | 1 + src/handler.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 19 ++++++++++++------- 3 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 src/handler.rs diff --git a/Cargo.toml b/Cargo.toml index 7bc9c38..1a1995b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,4 @@ edition = "2021" [dependencies] hyper = { version = "*", features = [ "http1", "http2", "server", "runtime", "tcp", "stream" ] } http = "*" +async-trait = "*" diff --git a/src/handler.rs b/src/handler.rs new file mode 100644 index 0000000..03f09ed --- /dev/null +++ b/src/handler.rs @@ -0,0 +1,50 @@ +use crate::Params; + +use async_trait::async_trait; +use hyper::{Error, Request, Response}; + +pub type HandlerFunc = + dyn Fn(&Request, &Params, Option<&Response>) -> Result, Error>; + +#[async_trait] +pub trait Handler +where + Self: Send + Sync + 'static, +{ + async fn perform(&self, response: Option<&Response>) -> Result, Error>; +} + +pub struct BasicHandler +where + T: Send + Sync + 'static, + R: Send + Sync + 'static, +{ + req: Request, + params: Params, + next: Option<&'static BasicHandler>, + func: &'static HandlerFunc, +} + +impl BasicHandler +where + T: Send + Sync + 'static, + R: Send + Sync + 'static, +{ +} + +#[async_trait] +impl Handler for BasicHandler +where + Self: Send + Sync, + R: Copy + Send + Sync + Sized + 'static, + T: Copy + Send + Sync + Sized + 'static, +{ + async fn perform(&self, response: Option<&Response>) -> Result, Error> { + let response = (*self.func)(&self.req, &self.params, response)?; + if self.next.is_some() { + return Ok(self.next.unwrap().perform(Some(&response)).await?); + } + + Ok(response) + } +} diff --git a/src/lib.rs b/src/lib.rs index 1b4a90c..e4901b9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,13 @@ -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - let result = 2 + 2; - assert_eq!(result, 4); - } +pub mod handler; + +use crate::handler::BasicHandler; + +use std::collections::BTreeMap; + +#[derive(Debug, Clone)] +pub struct Params(BTreeMap); + +pub struct App { + #[allow(dead_code)] // FIXME remove + routes: BTreeMap>, }