diff --git a/axum-extra/CHANGELOG.md b/axum-extra/CHANGELOG.md index 2dfa296f..ffca0333 100644 --- a/axum-extra/CHANGELOG.md +++ b/axum-extra/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning]. # Unreleased -- None. +- **added:** Implement `TypedPath` for `WithRejection` # 0.9.1 (29. December, 2023) diff --git a/axum-extra/src/extract/with_rejection.rs b/axum-extra/src/extract/with_rejection.rs index 1227a1ab..59541f96 100644 --- a/axum-extra/src/extract/with_rejection.rs +++ b/axum-extra/src/extract/with_rejection.rs @@ -2,10 +2,13 @@ use axum::async_trait; use axum::extract::{FromRequest, FromRequestParts, Request}; use axum::response::IntoResponse; use http::request::Parts; -use std::fmt::Debug; +use std::fmt::{Debug, Display}; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; +#[cfg(feature = "typed-routing")] +use crate::routing::TypedPath; + /// Extractor for customizing extractor rejections /// /// `WithRejection` wraps another extractor and gives you the result. If the @@ -137,6 +140,23 @@ where } } +#[cfg(feature = "typed-routing")] +impl TypedPath for WithRejection +where + E: TypedPath, +{ + const PATH: &'static str = E::PATH; +} + +impl Display for WithRejection +where + E: Display, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + #[cfg(test)] mod tests { use axum::body::Body; diff --git a/axum-extra/src/routing/typed.rs b/axum-extra/src/routing/typed.rs index ef30462a..1f495175 100644 --- a/axum-extra/src/routing/typed.rs +++ b/axum-extra/src/routing/typed.rs @@ -386,7 +386,15 @@ impl_second_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, #[cfg(test)] mod tests { use super::*; - use crate::routing::TypedPath; + use crate::{ + extract::WithRejection, + routing::{RouterExt, TypedPath}, + }; + use axum::{ + extract::rejection::PathRejection, + response::{IntoResponse, Response}, + Router, + }; use serde::Deserialize; #[derive(TypedPath, Deserialize)] @@ -434,4 +442,25 @@ mod tests { assert_eq!(uri, "/users/1?&foo=foo&bar=123&baz=true&qux=1337"); } + + #[allow(dead_code)] // just needs to compile + fn supports_with_rejection() { + async fn handler(_: WithRejection) {} + + struct MyRejection {} + + impl IntoResponse for MyRejection { + fn into_response(self) -> Response { + unimplemented!() + } + } + + impl From for MyRejection { + fn from(_: PathRejection) -> Self { + unimplemented!() + } + } + + let _: Router = Router::new().typed_get(handler); + } }