use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use crate::handler::BoxHandler;
use crate::types::BoxMiddleware;
use crate::types::Request;
use crate::types::Response;
pub mod api_key_auth;
pub mod basic_auth;
pub mod bearer_auth;
pub mod body_limit;
pub mod csrf;
pub mod jwt_auth;
pub mod request_id;
pub mod security_headers;
pub mod session;
pub mod upload_progress;
#[doc(alias = "middleware")]
pub trait IntoMiddleware {
fn into_middleware(
self,
) -> impl Fn(Request, Next) -> Pin<Box<dyn Future<Output = Response> + Send + 'static>>
+ Clone
+ Send
+ Sync
+ 'static;
}
#[doc(alias = "next")]
pub struct Next {
pub global_middlewares: Arc<Vec<BoxMiddleware>>,
pub route_middlewares: Arc<Vec<BoxMiddleware>>,
pub index: usize,
pub endpoint: BoxHandler,
}
impl std::fmt::Debug for Next {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Next")
.field(
"middlewares_remaining",
&(self.global_middlewares.len() + self.route_middlewares.len()).saturating_sub(self.index),
)
.finish_non_exhaustive()
}
}
impl Clone for Next {
fn clone(&self) -> Self {
Self {
global_middlewares: Arc::clone(&self.global_middlewares),
route_middlewares: Arc::clone(&self.route_middlewares),
index: self.index,
endpoint: self.endpoint.clone(),
}
}
}
impl Next {
pub async fn run(mut self, req: Request) -> Response {
let mw = if let Some(mw) = self.global_middlewares.get(self.index) {
Some(mw.clone())
} else {
self
.route_middlewares
.get(self.index.saturating_sub(self.global_middlewares.len()))
.cloned()
};
if let Some(mw) = mw {
self.index += 1;
mw(req, self).await
} else {
self.endpoint.call(req).await
}
}
}