diff --git a/examples/auth-with-state.rs b/examples/auth-with-state.rs
index 73f8340..85ed7e7 100644
--- a/examples/auth-with-state.rs
+++ b/examples/auth-with-state.rs
@@ -4,8 +4,9 @@ async fn validate_authtoken(
req: Request
,
resp: Option>,
_params: Params,
- app: App,
-) -> HTTPResult {
+ app: App,
+ _state: NoState,
+) -> HTTPResult {
let token = req.headers().get("X-AuthToken");
if token.is_none() {
return Err(Error::StatusCode(StatusCode::UNAUTHORIZED));
@@ -24,21 +25,23 @@ async fn validate_authtoken(
return Err(Error::StatusCode(StatusCode::UNAUTHORIZED));
}
- return Ok((req, resp));
+ return Ok((req, resp, NoState {}));
}
async fn hello(
req: Request,
_resp: Option>,
params: Params,
- _app: App,
-) -> HTTPResult {
+ _app: App,
+ _state: NoState,
+) -> HTTPResult {
let name = params.get("name").unwrap();
let bytes = Body::from(format!("hello, {}!\n", name));
return Ok((
req,
Some(Response::builder().status(200).body(bytes).unwrap()),
+ NoState {},
));
}
diff --git a/examples/disk-auth.rs b/examples/disk-auth.rs
index 17794c0..26d478a 100644
--- a/examples/disk-auth.rs
+++ b/examples/disk-auth.rs
@@ -7,8 +7,9 @@ async fn validate_authtoken(
req: Request,
resp: Option>,
_params: Params,
- _app: App<()>,
-) -> HTTPResult {
+ _app: App<(), NoState>,
+ _state: NoState,
+) -> HTTPResult {
let token = req.headers().get("X-AuthToken");
if token.is_none() {
return Err(Error::StatusCode(StatusCode::UNAUTHORIZED));
@@ -28,21 +29,23 @@ async fn validate_authtoken(
return Err(Error::StatusCode(StatusCode::UNAUTHORIZED));
}
- return Ok((req, resp));
+ return Ok((req, resp, NoState {}));
}
async fn hello(
req: Request,
_resp: Option>,
params: Params,
- _app: App<()>,
-) -> HTTPResult {
+ _app: App<(), NoState>,
+ _state: NoState,
+) -> HTTPResult {
let name = params.get("name").unwrap();
let bytes = Body::from(format!("hello, {}!\n", name));
return Ok((
req,
Some(Response::builder().status(200).body(bytes).unwrap()),
+ NoState {},
));
}
diff --git a/examples/hello-world.rs b/examples/hello-world.rs
index 7bc7f59..79fedab 100644
--- a/examples/hello-world.rs
+++ b/examples/hello-world.rs
@@ -4,14 +4,16 @@ async fn hello(
req: Request,
_resp: Option>,
params: Params,
- _app: App<()>,
-) -> HTTPResult {
+ _app: App<(), NoState>,
+ _state: NoState,
+) -> HTTPResult {
let name = params.get("name").unwrap();
let bytes = Body::from(format!("hello, {}!\n", name));
return Ok((
req,
Some(Response::builder().status(200).body(bytes).unwrap()),
+ NoState {},
));
}
diff --git a/examples/log.rs b/examples/log.rs
index b8d9256..5f1c69b 100644
--- a/examples/log.rs
+++ b/examples/log.rs
@@ -5,18 +5,20 @@ async fn log(
req: Request,
resp: Option>,
_params: Params,
- _app: App<()>,
-) -> HTTPResult {
+ _app: App<(), NoState>,
+ _state: NoState,
+) -> HTTPResult {
log::trace!("New request: {}", req.uri().path());
- Ok((req, resp))
+ Ok((req, resp, NoState {}))
}
async fn hello(
req: Request,
_resp: Option>,
params: Params,
- _app: App<()>,
-) -> HTTPResult {
+ _app: App<(), NoState>,
+ _state: NoState,
+) -> HTTPResult {
let name = params.get("name").unwrap();
log::info!("Saying hello to {}", name);
let bytes = Body::from(format!("hello, {}!\n", name));
@@ -24,6 +26,7 @@ async fn hello(
return Ok((
req,
Some(Response::builder().status(200).body(bytes).unwrap()),
+ NoState,
));
}
diff --git a/src/app.rs b/src/app.rs
index ddfc3da..41705ae 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -4,7 +4,7 @@ use http::{Method, Request, Response, StatusCode};
use hyper::{server::conn::Http, service::service_fn, Body};
use tokio::{net::TcpListener, sync::Mutex};
-use crate::{handler::Handler, router::Router, Error, ServerError};
+use crate::{handler::Handler, router::Router, Error, ServerError, TransientState};
/// App is used to define application-level functionality and initialize the server. Routes are
/// typically programmed here.
@@ -49,12 +49,12 @@ use crate::{handler::Handler, router::Router, Error, ServerError};
///
/// Requests are routed through paths to [crate::handler::HandlerFunc]s.
#[derive(Clone)]
-pub struct App {
- router: Router,
+pub struct App {
+ router: Router,
global_state: Option>>,
}
-impl App {
+impl App {
/// Construct a new App with no state; it will be passed to handlers as `App<()>`.
pub fn new() -> Self {
Self {
@@ -84,55 +84,55 @@ impl App {
/// Create a route for a GET request. See App's docs and [crate::handler::Handler] for
/// more information.
- pub fn get(&mut self, path: &str, ch: Handler) {
+ pub fn get(&mut self, path: &str, ch: Handler) {
self.router.add(Method::GET, path.to_string(), ch);
}
/// Create a route for a POST request. See App's docs and [crate::handler::Handler] for
/// more information.
- pub fn post(&mut self, path: &str, ch: Handler) {
+ pub fn post(&mut self, path: &str, ch: Handler) {
self.router.add(Method::POST, path.to_string(), ch);
}
/// Create a route for a DELETE request. See App's docs and [crate::handler::Handler] for
/// more information.
- pub fn delete(&mut self, path: &str, ch: Handler) {
+ pub fn delete(&mut self, path: &str, ch: Handler) {
self.router.add(Method::DELETE, path.to_string(), ch);
}
/// Create a route for a PUT request. See App's docs and [crate::handler::Handler] for
/// more information.
- pub fn put(&mut self, path: &str, ch: Handler) {
+ pub fn put(&mut self, path: &str, ch: Handler) {
self.router.add(Method::PUT, path.to_string(), ch);
}
/// Create a route for an OPTIONS request. See App's docs and
/// [crate::handler::Handler] for more information.
- pub fn options(&mut self, path: &str, ch: Handler) {
+ pub fn options(&mut self, path: &str, ch: Handler) {
self.router.add(Method::OPTIONS, path.to_string(), ch);
}
/// Create a route for a PATCH request. See App's docs and
/// [crate::handler::Handler] for more information.
- pub fn patch(&mut self, path: &str, ch: Handler) {
+ pub fn patch(&mut self, path: &str, ch: Handler) {
self.router.add(Method::PATCH, path.to_string(), ch);
}
/// Create a route for a HEAD request. See App's docs and
/// [crate::handler::Handler] for more information.
- pub fn head(&mut self, path: &str, ch: Handler) {
+ pub fn head(&mut self, path: &str, ch: Handler) {
self.router.add(Method::HEAD, path.to_string(), ch);
}
/// Create a route for a CONNECT request. See App's docs and
/// [crate::handler::Handler] for more information.
- pub fn connect(&mut self, path: &str, ch: Handler) {
+ pub fn connect(&mut self, path: &str, ch: Handler) {
self.router.add(Method::CONNECT, path.to_string(), ch);
}
/// Create a route for a TRACE request. See App's docs and
/// [crate::handler::Handler] for more information.
- pub fn trace(&mut self, path: &str, ch: Handler) {
+ pub fn trace(&mut self, path: &str, ch: Handler) {
self.router.add(Method::TRACE, path.to_string(), ch);
}
diff --git a/src/handler.rs b/src/handler.rs
index bde4a8f..088598e 100644
--- a/src/handler.rs
+++ b/src/handler.rs
@@ -1,6 +1,6 @@
use std::future::Future;
-use crate::{app::App, HTTPResult, PinBox};
+use crate::{app::App, HTTPResult, PinBox, TransientState};
use async_recursion::async_recursion;
use http::{Request, Response};
@@ -18,43 +18,46 @@ use hyper::Body;
/// req: Request,
/// _resp: Option>,
/// params: Params,
-/// _app: App<()>,
-/// ) -> HTTPResult {
+/// _app: App<(), NoState>,
+/// _state: NoState,
+/// ) -> HTTPResult {
/// let name = params.get("name").unwrap();
/// let bytes = Body::from(format!("hello, {}!\n", name));
///
/// return Ok((
/// req,
/// Some(Response::builder().status(200).body(bytes).unwrap()),
+/// NoState{},
/// ));
/// }
/// ```
///
-pub type HandlerFunc = fn(
+pub type HandlerFunc = fn(
req: Request,
response: Option>,
params: crate::Params,
- app: App,
-) -> PinBox + Send>;
+ app: App,
+ state: T,
+) -> PinBox> + Send>;
/// Handler is the structure of the handler. Typically, you will not use this directly, and instead
/// interact with the [crate::compose_handler!] macro. That said, if you wanted to define your own
/// macros or otherwise compose more complicated structures for your handlers, this is available to
/// you.
#[derive(Clone)]
-pub struct Handler {
- handler: HandlerFunc,
- next: Box