feat(server): basic framework for views

Create library entrypoint (`src/lib.rs`) and prepare a very basic
framework for registering functions with endpoints.
This commit is contained in:
Matej Janezic 2024-05-22 22:41:07 +02:00
parent aab47577a7
commit fb5741bc6f
Signed by: janezicmatej
GPG Key ID: 4298E230ED37B2C0
3 changed files with 60 additions and 3 deletions

1
src/lib.rs Normal file
View File

@ -0,0 +1 @@
pub mod server;

View File

@ -1,3 +0,0 @@
fn main() {
println!("Hello, world!");
}

59
src/server.rs Normal file
View File

@ -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<Incoming>) -> Response<String>;
}
impl<F: Clone + Send + Sync + 'static> Handler for F
where
F: Fn(Request<Incoming>) -> Response<String>,
{
fn invoke(&self, request: Request<Incoming>) -> Response<String> {
(self)(request)
}
}
struct RouterPath {
method: Method,
path: &'static str,
f: Box<dyn Handler>,
}
#[derive(Default)]
pub struct Router {
paths: Vec<RouterPath>,
}
impl Router {
pub fn register(&mut self, method: Method, path: &'static str, f: Box<dyn Handler>) {
self.paths.push(RouterPath { method, path, f })
}
}
impl Service<Request<Incoming>> for &Router {
type Response = Response<String>;
type Error = hyper::Error;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
fn call(&self, req: Request<Incoming>) -> Self::Future {
fn default_response(_req: Request<Incoming>) -> Result<Response<String>, 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 })
}
}