use std::{
future::Future,
pin::Pin,
task::{Context, Poll},
};
use tower::{Layer, Service};
#[derive(Debug, Clone)]
pub struct PanicRecoveryLayer;
impl<S> Layer<S> for PanicRecoveryLayer {
type Service = PanicRecoveryService<S>;
fn layer(&self, inner: S) -> Self::Service {
PanicRecoveryService { inner }
}
}
#[derive(Debug, Clone)]
pub struct PanicRecoveryService<S> {
inner: S,
}
impl<S, B> Service<http::Request<B>> for PanicRecoveryService<S>
where
S: Service<http::Request<B>> + Send + 'static,
S::Future: Send + 'static,
S::Response: Send + 'static,
S::Error: std::fmt::Debug + Send + 'static,
B: Send + 'static,
{
type Response = S::Response;
type Error = S::Error;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::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: http::Request<B>) -> Self::Future {
Box::pin(self.inner.call(req))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_panic_recovery_layer_creation() {
let _ = PanicRecoveryLayer;
}
}