use std::{
future::Future,
pin::Pin,
sync::Arc,
task::{Context, Poll},
};
use axum::http::Request;
use tower::{Layer, Service};
use crate::{mail::scope_config, MailConfig};
#[derive(Clone)]
pub struct MailLayer {
config: Arc<MailConfig>,
}
impl MailLayer {
pub fn new(config: MailConfig) -> Self {
Self {
config: Arc::new(config),
}
}
}
impl<S> Layer<S> for MailLayer {
type Service = MailService<S>;
fn layer(&self, inner: S) -> Self::Service {
MailService {
inner,
config: self.config.clone(),
}
}
}
#[derive(Clone)]
pub struct MailService<S> {
inner: S,
config: Arc<MailConfig>,
}
impl<S, ReqBody> Service<Request<ReqBody>> for MailService<S>
where
S: Service<Request<ReqBody>> + Send + Clone + 'static,
S::Future: Send + 'static,
ReqBody: Send + 'static,
{
type Response = S::Response;
type Error = S::Error;
type Future = Pin<Box<dyn Future<Output = Result<S::Response, S::Error>> + Send + 'static>>;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.inner.poll_ready(cx)
}
fn call(&mut self, req: Request<ReqBody>) -> Self::Future {
let config = self.config.clone();
let future = self.inner.call(req);
Box::pin(scope_config(config, future))
}
}