How to Write Tower-Style Middleware in Rust

Tower-style middleware in Rust is implemented by creating a struct that wraps a service and implements the `Service` trait to intercept requests before and after they reach the inner service.

How to Write Tower-Style Middleware in Rust

Tower-style middleware in Rust is implemented by creating a struct that wraps a service and implements the Service trait to intercept requests before and after they reach the inner service.

use tower::{Service, ServiceExt};
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};

struct MyMiddleware<S> {
    inner: S,
}

// Define a concrete future type to wrap the inner service's future
struct MyFuture<F> {
    inner: F,
}

impl<F> Future for MyFuture<F>
where
    F: Future,
{
    type Output = F::Output;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        Pin::new(&mut self.inner).poll(cx)
    }
}

impl<S, Req> Service<Req> for MyMiddleware<S>
where
    S: Service<Req>,
{
    type Response = S::Response;
    type Error = S::Error;
    // Use the concrete struct defined above
    type Future = MyFuture<S::Future>;

    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
        self.inner.poll_ready(cx)
    }

    fn call(&mut self, req: Req) -> Self::Future {
        // Pre-processing logic here
        let future = self.inner.call(req);
        // Wrap the future in our concrete type
        MyFuture { inner: future }
    }
}