I am trying to use something like the following to create routes for types that implement a trait:
trait HasPayload {
type Payload: DeserializeOwned;
}
async fn handler_doesnt_work<T: HasPayload>(Json(payload): Json<T::Payload>) -> impl IntoResponse {
/* ... */
}
async fn handler_works<T: HasPayload>() -> impl IntoResponse {
/* ... */
}
fn router<T: HasPayload>() -> Router {
Router::new()
.route("/works", get(handler_works::<T>))
.route("/doesnt_work", post(handler_doesnt_work::<T>))
}
However handler_doesnt_work doesn't satisfy the trait bounds. Why is this, and how can I fix or work around it? #[axum::debug_handler] says it doesn't support generic functions
the trait `Handler<_, _>` is not implemented for fn item `fn(Json<<T as HasPayload>::Payload>) -> ... {handler_doesnt_work::<...>}`
I had to add the Send constraint to the Payload associated type, and the 'static lifetime to the generic parameter passed to the handler in order to conform to the existing implementations for the Handler trait:
trait HasPayload {
type Payload: DeserializeOwned + Send;
}
async fn handler_doesnt_work<T: HasPayload>(Json(payload): Json<T::Payload>) -> impl IntoResponse {}
async fn handler_works<T: HasPayload>() -> impl IntoResponse {}
fn router<T: HasPayload + 'static>() -> Router {
Router::new()
.route("/works", get(handler_works::<T>))
.route("/doesnt_work", post(handler_doesnt_work::<T>))
}
3 Likes