I have a problem with creating a return type for the Axum middleware creation function.
Ex. I have middleware with a signature:
async fn auth_middleware(headers: HeaderMap, request: Request, next: Next) -> Result<Response, StatusCode>
I want to create a function in my crate that returns ready-to-add middleware for Axum, but I cannot figure out the return type of wrapping fn.
pub fn axum_auth_middleware() -> ??? {
axum::middleware::from_fn(auth_middleware)
}
I'm pretty new to Rust and I spent an hour to solve this but I gave up.
Probably the best way is to define a dummy Fn
trait (MyFn
) where Output
can be named and then specify the return type as a FromFnLayer
where the function is impl MyFn<..., Output: Future + ...> + ...
:
use axum::body::Body;
use axum::extract::Request;
use axum::middleware::FromFnLayer;
use axum::middleware::Next;
use axum::response::Response;
use axum::Router;
use http::header::HeaderMap;
use http::status::StatusCode;
use std::future::Future;
async fn auth_middleware(
headers: HeaderMap,
request: Request,
next: Next,
) -> Result<Response, StatusCode> {
todo!();
}
pub trait MyFn<A, B, C>: Fn(A, B, C) -> <Self as MyFn<A, B, C>>::Output {
type Output;
}
impl<F, A, B, C, Out> MyFn<A, B, C> for F
where
F: Fn(A, B, C) -> Out,
{
type Output = Out;
}
pub fn axum_auth_middleware() -> FromFnLayer<
impl MyFn<
HeaderMap,
http::Request<Body>,
Next,
Output: Future<Output = Result<Response<Body>, StatusCode>> + Send + 'static,
> + Clone
+ Copy
+ Send
+ Sync
+ 'static,
(),
(HeaderMap, http::Request<Body>),
> {
axum::middleware::from_fn(auth_middleware)
}
fn main() {
let app = Router::<()>::new().route_layer(axum_auth_middleware());
}