Why the trait is missing in my middleware

43 views Asked by At

I implemented a middleware layer for my GRPC server in Rust like this:

use std::{
    pin::Pin,
    task::{Context, Poll},
};
use tonic::transport::Body;
use tonic::{body::BoxBody, Request};
use tower_layer::Layer;
use tower_service::Service;

#[derive(Debug, Clone, Default)]
pub struct MiddlewareLayer;

impl<S> Layer<S> for MiddlewareLayer {
    type Service = Middleware<S>;

    fn layer(&self, service: S) -> Self::Service {
        Middleware { service }
    }
}

#[derive(Debug, Clone)]
pub struct Middleware<S> {
    service: S,
}

type BoxFuture<'a, T> = Pin<Box<dyn std::future::Future<Output = T> + Send + 'a>>;

impl<S> Service<Request<Body>> for Middleware<S>
where
    S: Service<Request<Body>, Response = tonic::Response<BoxBody>> + Clone + Send + 'static,
    S::Future: Send + 'static,
{
    type Response = S::Response;
    type Error = S::Error;
    type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;

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

    fn call(&mut self, req: Request<Body>) -> Self::Future {
        println!("Request body: {:?}", req);

        //self.service.call(req)
        let clone = self.service.clone();
        let mut service = std::mem::replace(&mut self.service, clone);

        Box::pin(async move {
            println!("Before");
            let response = service.call(req).await?;
            println!("After");

            Ok(response)
        })
    }
}

I then add this middleware to my server:

let layer = tower::ServiceBuilder::new()
    .layer(MiddlewareLayer::default())
    .into_inner();

Server::builder()
    .layer(layer)
    .add_service(PermissionServiceServer::new(permission_service))
    .add_service(reflection)
    .serve(server_address)
    .await?;

However, when I try to run my program I get this error message, which is driving my crazy by now, because I have no idea how to solve it:

error[E0277]: the trait bound `Middleware<Routes>: Service<request::Request<tonic::transport::Body>>` is not satisfied
  --> src/main.rs:96:10
   |
96 |         .serve(server_address)
   |          ^^^^^ the trait `Service<request::Request<tonic::transport::Body>>` is not implemented for `Middleware<Routes>`
   |
   = help: the trait `Service<tonic::Request<tonic::transport::Body>>` is implemented for `Middleware<S>`
0

There are 0 answers