gbg commit doesn't compile

Signed-off-by: Erik Hollensbe <linux@hollensbe.org>
This commit is contained in:
Erik Hollensbe
2022-01-15 02:15:21 -08:00
parent 369ee0006c
commit 52cd5aba88
3 changed files with 124 additions and 24 deletions
+1
View File
@@ -9,3 +9,4 @@ edition = "2021"
hyper = { version = "*", features = [ "http1", "http2", "server", "runtime", "tcp", "stream" ] }
http = "*"
async-trait = "*"
tokio = { version = "*", features = [ "full" ] }
+87 -22
View File
@@ -1,50 +1,115 @@
use crate::Params;
use std::sync::Arc;
use tokio::sync::Mutex;
use crate::{HTTPResult, Params};
use async_trait::async_trait;
use hyper::{Error, Request, Response};
use http::{Request, Response};
pub type HandlerFunc<T, R> =
dyn Fn(&Request<T>, &Params, Option<&Response<R>>) -> Result<Response<R>, Error>;
pub type HandlerFunc<'a, T, R> =
dyn Fn(&'a Request<T>, Params, Option<&'a Response<R>>) -> HTTPResult<'a, T, R>;
#[async_trait]
pub trait Handler<R>
pub trait Handler<'a, 'b, T, R>
where
Self: Send + Sync + 'static,
Self: Send + Sync + 'b,
{
async fn perform(&self, response: Option<&Response<R>>) -> Result<Response<R>, Error>;
async fn perform(&'b self, response: Option<&'a Response<R>>) -> HTTPResult<'a, T, R>;
}
pub struct BasicHandler<T, R>
pub struct BasicHandler<'a, T, R>
where
T: Send + Sync + 'static,
R: Send + Sync + 'static,
T: Send + Sync + 'a,
R: Send + Sync + 'a,
{
req: Request<T>,
req: Arc<Mutex<Request<T>>>,
params: Params,
next: Option<&'static BasicHandler<T, R>>,
func: &'static HandlerFunc<T, R>,
next: Option<&'a BasicHandler<'a, T, R>>,
func: &'a HandlerFunc<'a, T, R>,
}
impl<T, R> BasicHandler<T, R>
impl<'a, 'b, T, R> BasicHandler<'b, T, R>
where
T: Send + Sync + 'static,
R: Send + Sync + 'static,
T: Send + Sync + 'b,
R: Send + Sync + 'b,
{
pub fn new(
req: Request<T>,
params: Params,
next: Option<&'b BasicHandler<'b, T, R>>,
func: &'static HandlerFunc<'b, T, R>,
) -> Self {
Self {
req: Arc::new(Mutex::new(req)),
params,
next,
func,
}
}
}
#[async_trait]
impl<T, R> Handler<R> for BasicHandler<T, R>
impl<'a, 'b, T, R> Handler<'a, 'b, T, R> for BasicHandler<'b, T, R>
where
Self: Send + Sync,
Self: Send + Sync + 'b,
R: Copy + Send + Sync + Sized + 'static,
T: Copy + Send + Sync + Sized + 'static,
{
async fn perform(&self, response: Option<&Response<R>>) -> Result<Response<R>, Error> {
let response = (*self.func)(&self.req, &self.params, response)?;
async fn perform(&'b self, response: Option<&'a Response<R>>) -> HTTPResult<'a, T, R> {
let mut req = self.req.lock().await;
let (req, response) = (*self.func)(&mut req, self.params, response)?;
if self.next.is_some() {
return Ok(self.next.unwrap().perform(Some(&response)).await?);
return Ok(self.next.unwrap().perform(response).await?);
}
Ok(response)
Ok((req, response))
}
}
mod tests {
use crate::{Error, HTTPResult, Params};
use http::{HeaderValue, Request, Response, StatusCode};
use hyper::Body;
fn one<'a>(
mut req: &'a Request<Body>,
_params: Params,
_response: Option<&'a Response<Body>>,
) -> HTTPResult<'a, Body, Body> {
let headers = req.headers_mut();
headers.insert("wakka", HeaderValue::from_str("wakka wakka").unwrap());
Ok((&req, None))
}
fn two<'a>(
mut req: &'a Request<Body>,
_params: Params,
response: Option<&'a Response<Body>>,
) -> HTTPResult<'a, Body, Body> {
if let Some(header) = req.headers().get("wakka") {
if header != "wakka wakka" {
return Err(Error::new("invalid header value"));
}
if response.is_some() {
return Ok((&req, response));
} else {
response.replace(
&Response::builder()
.status(StatusCode::OK)
.body(Body::default())?,
);
return Ok((&req, response));
}
}
Err(Error::default())
}
#[test]
fn test_handler_basic() {
let bh = super::BasicHandler::new(Request::default(), Params::default(), None, &one);
}
}
+36 -2
View File
@@ -1,5 +1,7 @@
pub mod handler;
use http::{Request, Response};
use crate::handler::BasicHandler;
use std::collections::BTreeMap;
@@ -7,7 +9,39 @@ use std::collections::BTreeMap;
#[derive(Debug, Clone)]
pub struct Params(BTreeMap<String, String>);
pub struct App {
impl Default for Params {
fn default() -> Self {
Self(BTreeMap::default())
}
}
#[derive(Clone, Debug)]
pub struct Error(String);
impl Default for Error {
fn default() -> Self {
Self(String::from("internal server error"))
}
}
impl Error {
pub fn new<T>(message: T) -> Self
where
T: ToString,
{
Self(message.to_string())
}
}
impl From<http::Error> for Error {
fn from(e: http::Error) -> Self {
Self::new(e)
}
}
pub type HTTPResult<'a, Req, Resp> = Result<(&'a Request<Req>, Option<&'a Response<Resp>>), Error>;
pub struct App<'a> {
#[allow(dead_code)] // FIXME remove
routes: BTreeMap<String, BasicHandler<hyper::Body, hyper::Body>>,
routes: BTreeMap<String, &'a BasicHandler<'static, hyper::Body, hyper::Body>>,
}