mirror of
https://github.com/zerotier/ratpack.git
synced 2026-05-22 16:27:23 -07:00
gbg commit doesn't compile
Signed-off-by: Erik Hollensbe <linux@hollensbe.org>
This commit is contained in:
@@ -9,3 +9,4 @@ edition = "2021"
|
||||
hyper = { version = "*", features = [ "http1", "http2", "server", "runtime", "tcp", "stream" ] }
|
||||
http = "*"
|
||||
async-trait = "*"
|
||||
tokio = { version = "*", features = [ "full" ] }
|
||||
|
||||
+87
-22
@@ -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
@@ -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>>,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user