#[cfg(feature = "cookie")]
mod cookies;
mod state;
mod trace;
#[cfg(feature = "cookie")]
#[cfg_attr(nightly, doc(cfg(feature = "cookie")))]
pub use self::cookies::{CookieExt, CookieMiddleware};
pub use self::state::{State, StateMiddleware};
pub use self::trace::TraceMiddleware;
use crate::{Endpoint, Request, Response};
use std::fmt::Debug;
use std::pin::Pin;
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub(crate) struct PeerAddress(pub(crate) std::net::SocketAddr);
#[derive(Copy, Clone, Debug)]
pub struct Next<'a> {
middleware: &'a [Pin<Box<dyn Middleware>>],
endpoint: Pin<&'a dyn Endpoint>,
}
#[async_trait]
pub trait Middleware: Debug + Send + Sync + 'static {
#[must_use]
async fn apply(
self: Pin<&Self>,
request: Request,
next: Next<'_>,
) -> Result<Response, anyhow::Error>;
}
impl<'a> Next<'a> {
pub(crate) fn new(
middleware: &'a [Pin<Box<dyn Middleware>>],
endpoint: Pin<&'a dyn Endpoint>,
) -> Self {
Next {
middleware,
endpoint,
}
}
pub async fn apply(self, request: Request) -> Result<Response, anyhow::Error> {
if let Some((current, next)) = self.middleware.split_first() {
let new = Next {
middleware: next,
endpoint: self.endpoint,
};
current.as_ref().apply(request, new).await
} else {
self.endpoint.apply(request).await
}
}
}