Parameter passing issues in the tonic encapsulation middleware

---------------Original code---------------------

use axum::{extract::Request, http::StatusCode, middleware::Next, response::Response};
use tonic::transport::Server as TServer;

async fn auth(req: Request, next: Next) -> Result<Response, StatusCode> {
    Ok(next.run(req).await)
}

struct GrpcLogic {}
impl GrpcLogic {
    fn new() -> Self {
        Self {}
    }
}
#[tonic::async_trait]
impl xxx for GrpcLogic {
    // ...Implement the service specified in the proto file
}

#[tokio::main]
async fn main() {
    let address = "[::1]:4000".to_string().parse().unwrap();

    // AccountServer # tonic_build is the server-side code generated based on the proto file
    let svc = AccountServer::new(GrpcLogic::new());

    let layer = tower::ServiceBuilder::new()
        .layer(axum::middleware::from_fn(auth))
        .into_inner();

    TServer::builder()
        .layer(layer)
        .add_service(svc)
        .serve(address)
        .await
        .unwrap();
}

---------------Encapsulation code---------------------

use axum::{extract::Request, http::StatusCode, middleware::Next, response::Response};
use axum::{response::IntoResponse, routing::Route};
use std::convert::Infallible;
use tonic::transport::Server as TServer;
use tonic::{body::Body, server::NamedService};
use tower_layer::Layer;
use tower_service::Service;

async fn auth(req: Request, next: Next) -> Result<Response, StatusCode> {
    Ok(next.run(req).await)
}

struct GrpcLogic {}
impl GrpcLogic {
    fn new() -> Self {
        Self {}
    }
}
#[tonic::async_trait]
impl xxx for GrpcLogic {
    // ...Implement the service specified in the proto file
}

#[tokio::main]
async fn main() {
    let layer = tower::ServiceBuilder::new()
        .layer(axum::middleware::from_fn(auth))
        .into_inner();

    GrpcServer::new(AccountServer::new(GrpcLogic::new()))
        .address("[::1]:4000")
        .layer(layer)
        .start()
        .await
}

struct GrpcServer<L, S> {
    address: String,
    layer: Option<L>,
    service: S,
}
impl<L, S> GrpcServer<L, S>
where
    L: Layer<Route> + Clone + Send + Sync + 'static,
    L::Service: Service<Request> + Clone + Send + Sync + 'static,
    <L::Service as Service<Request>>::Response: IntoResponse + 'static,
    <L::Service as Service<Request>>::Error: Into<Infallible> + 'static,
    <L::Service as Service<Request>>::Future: Send + 'static,
    // ---
    S: Service<Request<Body>, Error = Infallible> + NamedService + Clone + Send + Sync + 'static,
    S::Response: axum::response::IntoResponse,
    S::Future: Send + 'static,
{
    fn new(srv: S) -> Self {
        Self {
            address: "[::1]:4000".to_string(),
            layer: None,
            service: srv,
        }
    }

    fn address(mut self, a: &str) -> Self {
        self.address = a.to_string();
        self
    }

    fn layer(mut self, layer: L) -> Self {
        self.layer = Some(layer);
        self
    }

    async fn start(&self) -> Result<(), &str> {
        let address = self.address.parse().unwrap();

        let layer = self.layer.unwrap();

        // let layer = tower::ServiceBuilder::new()
        //     .layer(axum::middleware::from_fn(auth))
        //     .into_inner();

        TServer::builder()
            .layer(layer)
            .add_service(self.service.clone())
            .serve(address)
            .await
            .unwrap();

        Ok(())
    }
}

Problem description: In the encapsulated code, under the start method
Use let layer = self.layer.unwrap(); An error will be reported. The error code is as follows:


error[E0277]: the trait bound `L: Layer<Routes>` is not satisfied
  --> src\transport\grpc\mod.rs:57:14
   |
57 |             .serve(address)
   |              ^^^^^ the trait `Layer<Routes>` is not implemented for `L`
   |
   = note: required for `Stack<L, tower_layer::Identity>` to implement `Layer<Routes>`

Comment out let layer = self.layer.unwrap(); Use tower::ServiceBuilder instead.


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

It's normal. This indicates that there is a problem with self.layer, but we still can't find a solution, so we come to seek help from everyone

the bounds on Router::serve() is very complicated, you must repeat every one of them, but you made some mistakes in doing so:

first of all, you need to fix what seems to be an obvious typo: the type argument to Layer should be tonic::Routes, but you had axum::Route:

-where L: Layer<Route> + ...
+where L: Layer<Routes> + ...

then you just follow the compiler's suggestions (or copy the bounds from Router::serve()):

  • first, the type arguments to Request needs to be tonic::body::Body, but you omitted it, which defaulted to axum::body::Body:

    where
    -    L::Service: Service<Request> +...,
    -    <L::Service as Service<Request>>::...,
    +    L::Service: Service<Request<Body>> + ...,
    +    <L::Service as Service<Request<Body>>>::...,
    
  • then, add an associated type equality constraint for Service::Response:

      = help: consider constraining the associated type `<<L as Layer<Routes>>::Service as Service<axum::http::Request<tonic::body::Body>>>::Response` to `axum::http::Response<_>`
    
    where
    -    L::Service: Service<Request> +...,
    -    <L::Service as Service<Request>>::Response: IntoResponse + 'static,
    +    L::Service: Service<Request<Body>, Response = Response> + ...,
    
  • then, copy the bounds for Service::Error from Router::serve():

    where
    -   <L::Service as Service<Request>>::Error: Into<Infallible> + 'static,
    +   <L::Service as Service<Request<Body>>>::Error: Into<Box<dyn std::error::Error + Send + Sync>> + Send, 
    
  • finally, fixes the borrow error by cloning the layer (or, if the service can only be started once, you can change the receiver type from &self to self):

    -let layer = self.layer.unwrap();
    +let layer = self.layer.clone().unwrap();
    

It still reports an error. Could you provide the complete code of the where clause