From fb5741bc6f7965cb60350d8d08e446fbe4c7c01f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Jane=C5=BEi=C4=8D?= Date: Wed, 22 May 2024 22:41:07 +0200 Subject: [PATCH] feat(server): basic framework for views Create library entrypoint (`src/lib.rs`) and prepare a very basic framework for registering functions with endpoints. --- src/lib.rs | 1 + src/main.rs | 3 --- src/server.rs | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 src/lib.rs delete mode 100644 src/main.rs create mode 100644 src/server.rs diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..74f47ad --- /dev/null +++ b/src/lib.rs @@ -0,0 +1 @@ +pub mod server; diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index e7a11a9..0000000 --- a/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/src/server.rs b/src/server.rs new file mode 100644 index 0000000..29ed9bd --- /dev/null +++ b/src/server.rs @@ -0,0 +1,59 @@ +use hyper::service::Service; +use hyper::Method; +use hyper::{body::Incoming, Request, Response}; +use std::future::Future; +use std::pin::Pin; + +pub trait Handler: Send + Sync + 'static { + fn invoke(&self, request: Request) -> Response; +} + +impl Handler for F +where + F: Fn(Request) -> Response, +{ + fn invoke(&self, request: Request) -> Response { + (self)(request) + } +} + +struct RouterPath { + method: Method, + path: &'static str, + f: Box, +} + +#[derive(Default)] +pub struct Router { + paths: Vec, +} + +impl Router { + pub fn register(&mut self, method: Method, path: &'static str, f: Box) { + self.paths.push(RouterPath { method, path, f }) + } +} + +impl Service> for &Router { + type Response = Response; + type Error = hyper::Error; + type Future = Pin> + Send>>; + + fn call(&self, req: Request) -> Self::Future { + fn default_response(_req: Request) -> Result, hyper::Error> { + Ok(Response::builder().body("default".to_string()).unwrap()) + } + + let res_fn = self + .paths + .iter() + .find(|rp| (&rp.method, rp.path) == (req.method(), req.uri().path())); + + let res = match res_fn { + None => default_response(req), + Some(x) => Ok(x.f.invoke(req)), + }; + + Box::pin(async { res }) + } +}