Skip to content

Commit

Permalink
Port #[derive(TypedPath)] and #[debug_handler] (#1283)
Browse files Browse the repository at this point in the history
* port #[derive(TypedPath)]

* wip: #[debug_handler]

* fix #[debug_handler]

* don't need itertools

* also require `Send`

* update expected error

* support fully qualified `self`
  • Loading branch information
davidpdrsn authored Aug 21, 2022
1 parent 0b8bfb0 commit bf5675d
Show file tree
Hide file tree
Showing 19 changed files with 178 additions and 182 deletions.
34 changes: 17 additions & 17 deletions axum-extra/src/routing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub use self::resource::Resource;
pub use axum_macros::TypedPath;

#[cfg(feature = "typed-routing")]
pub use self::typed::{FirstElementIs, TypedPath};
pub use self::typed::{SecondElementIs, TypedPath};

#[cfg(feature = "spa")]
pub use self::spa::SpaRouter;
Expand All @@ -41,7 +41,7 @@ pub trait RouterExt<S, B>: sealed::Sealed {
fn typed_get<H, T, P>(self, handler: H) -> Self
where
H: Handler<T, S, B>,
T: FirstElementIs<P> + 'static,
T: SecondElementIs<P> + 'static,
P: TypedPath;

/// Add a typed `DELETE` route to the router.
Expand All @@ -54,7 +54,7 @@ pub trait RouterExt<S, B>: sealed::Sealed {
fn typed_delete<H, T, P>(self, handler: H) -> Self
where
H: Handler<T, S, B>,
T: FirstElementIs<P> + 'static,
T: SecondElementIs<P> + 'static,
P: TypedPath;

/// Add a typed `HEAD` route to the router.
Expand All @@ -67,7 +67,7 @@ pub trait RouterExt<S, B>: sealed::Sealed {
fn typed_head<H, T, P>(self, handler: H) -> Self
where
H: Handler<T, S, B>,
T: FirstElementIs<P> + 'static,
T: SecondElementIs<P> + 'static,
P: TypedPath;

/// Add a typed `OPTIONS` route to the router.
Expand All @@ -80,7 +80,7 @@ pub trait RouterExt<S, B>: sealed::Sealed {
fn typed_options<H, T, P>(self, handler: H) -> Self
where
H: Handler<T, S, B>,
T: FirstElementIs<P> + 'static,
T: SecondElementIs<P> + 'static,
P: TypedPath;

/// Add a typed `PATCH` route to the router.
Expand All @@ -93,7 +93,7 @@ pub trait RouterExt<S, B>: sealed::Sealed {
fn typed_patch<H, T, P>(self, handler: H) -> Self
where
H: Handler<T, S, B>,
T: FirstElementIs<P> + 'static,
T: SecondElementIs<P> + 'static,
P: TypedPath;

/// Add a typed `POST` route to the router.
Expand All @@ -106,7 +106,7 @@ pub trait RouterExt<S, B>: sealed::Sealed {
fn typed_post<H, T, P>(self, handler: H) -> Self
where
H: Handler<T, S, B>,
T: FirstElementIs<P> + 'static,
T: SecondElementIs<P> + 'static,
P: TypedPath;

/// Add a typed `PUT` route to the router.
Expand All @@ -119,7 +119,7 @@ pub trait RouterExt<S, B>: sealed::Sealed {
fn typed_put<H, T, P>(self, handler: H) -> Self
where
H: Handler<T, S, B>,
T: FirstElementIs<P> + 'static,
T: SecondElementIs<P> + 'static,
P: TypedPath;

/// Add a typed `TRACE` route to the router.
Expand All @@ -132,7 +132,7 @@ pub trait RouterExt<S, B>: sealed::Sealed {
fn typed_trace<H, T, P>(self, handler: H) -> Self
where
H: Handler<T, S, B>,
T: FirstElementIs<P> + 'static,
T: SecondElementIs<P> + 'static,
P: TypedPath;

/// Add another route to the router with an additional "trailing slash redirect" route.
Expand Down Expand Up @@ -184,7 +184,7 @@ where
fn typed_get<H, T, P>(self, handler: H) -> Self
where
H: Handler<T, S, B>,
T: FirstElementIs<P> + 'static,
T: SecondElementIs<P> + 'static,
P: TypedPath,
{
self.route(P::PATH, axum::routing::get(handler))
Expand All @@ -194,7 +194,7 @@ where
fn typed_delete<H, T, P>(self, handler: H) -> Self
where
H: Handler<T, S, B>,
T: FirstElementIs<P> + 'static,
T: SecondElementIs<P> + 'static,
P: TypedPath,
{
self.route(P::PATH, axum::routing::delete(handler))
Expand All @@ -204,7 +204,7 @@ where
fn typed_head<H, T, P>(self, handler: H) -> Self
where
H: Handler<T, S, B>,
T: FirstElementIs<P> + 'static,
T: SecondElementIs<P> + 'static,
P: TypedPath,
{
self.route(P::PATH, axum::routing::head(handler))
Expand All @@ -214,7 +214,7 @@ where
fn typed_options<H, T, P>(self, handler: H) -> Self
where
H: Handler<T, S, B>,
T: FirstElementIs<P> + 'static,
T: SecondElementIs<P> + 'static,
P: TypedPath,
{
self.route(P::PATH, axum::routing::options(handler))
Expand All @@ -224,7 +224,7 @@ where
fn typed_patch<H, T, P>(self, handler: H) -> Self
where
H: Handler<T, S, B>,
T: FirstElementIs<P> + 'static,
T: SecondElementIs<P> + 'static,
P: TypedPath,
{
self.route(P::PATH, axum::routing::patch(handler))
Expand All @@ -234,7 +234,7 @@ where
fn typed_post<H, T, P>(self, handler: H) -> Self
where
H: Handler<T, S, B>,
T: FirstElementIs<P> + 'static,
T: SecondElementIs<P> + 'static,
P: TypedPath,
{
self.route(P::PATH, axum::routing::post(handler))
Expand All @@ -244,7 +244,7 @@ where
fn typed_put<H, T, P>(self, handler: H) -> Self
where
H: Handler<T, S, B>,
T: FirstElementIs<P> + 'static,
T: SecondElementIs<P> + 'static,
P: TypedPath,
{
self.route(P::PATH, axum::routing::put(handler))
Expand All @@ -254,7 +254,7 @@ where
fn typed_trace<H, T, P>(self, handler: H) -> Self
where
H: Handler<T, S, B>,
T: FirstElementIs<P> + 'static,
T: SecondElementIs<P> + 'static,
P: TypedPath,
{
self.route(P::PATH, axum::routing::trace(handler))
Expand Down
54 changes: 27 additions & 27 deletions axum-extra/src/routing/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,67 +231,67 @@ pub trait TypedPath: std::fmt::Display {
}
}

/// Utility trait used with [`RouterExt`] to ensure the first element of a tuple type is a
/// Utility trait used with [`RouterExt`] to ensure the second element of a tuple type is a
/// given type.
///
/// If you see it in type errors its most likely because the first argument to your handler doesn't
/// If you see it in type errors its most likely because the second argument to your handler doesn't
/// implement [`TypedPath`].
///
/// You normally shouldn't have to use this trait directly.
///
/// It is sealed such that it cannot be implemented outside this crate.
///
/// [`RouterExt`]: super::RouterExt
pub trait FirstElementIs<P>: Sealed {}
pub trait SecondElementIs<P>: Sealed {}

macro_rules! impl_first_element_is {
macro_rules! impl_second_element_is {
( $($ty:ident),* $(,)? ) => {
impl<P, $($ty,)*> FirstElementIs<P> for (P, $($ty,)*)
impl<M, P, $($ty,)*> SecondElementIs<P> for (M, P, $($ty,)*)
where
P: TypedPath
{}

impl<P, $($ty,)*> Sealed for (P, $($ty,)*)
impl<M, P, $($ty,)*> Sealed for (M, P, $($ty,)*)
where
P: TypedPath
{}

impl<P, $($ty,)*> FirstElementIs<P> for (Option<P>, $($ty,)*)
impl<M, P, $($ty,)*> SecondElementIs<P> for (M, Option<P>, $($ty,)*)
where
P: TypedPath
{}

impl<P, $($ty,)*> Sealed for (Option<P>, $($ty,)*)
impl<M, P, $($ty,)*> Sealed for (M, Option<P>, $($ty,)*)
where
P: TypedPath
{}

impl<P, E, $($ty,)*> FirstElementIs<P> for (Result<P, E>, $($ty,)*)
impl<M, P, E, $($ty,)*> SecondElementIs<P> for (M, Result<P, E>, $($ty,)*)
where
P: TypedPath
{}

impl<P, E, $($ty,)*> Sealed for (Result<P, E>, $($ty,)*)
impl<M, P, E, $($ty,)*> Sealed for (M, Result<P, E>, $($ty,)*)
where
P: TypedPath
{}
};
}

impl_first_element_is!();
impl_first_element_is!(T1);
impl_first_element_is!(T1, T2);
impl_first_element_is!(T1, T2, T3);
impl_first_element_is!(T1, T2, T3, T4);
impl_first_element_is!(T1, T2, T3, T4, T5);
impl_first_element_is!(T1, T2, T3, T4, T5, T6);
impl_first_element_is!(T1, T2, T3, T4, T5, T6, T7);
impl_first_element_is!(T1, T2, T3, T4, T5, T6, T7, T8);
impl_first_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9);
impl_first_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
impl_first_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
impl_first_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
impl_first_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13);
impl_first_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14);
impl_first_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15);
impl_first_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16);
impl_second_element_is!();
impl_second_element_is!(T1);
impl_second_element_is!(T1, T2);
impl_second_element_is!(T1, T2, T3);
impl_second_element_is!(T1, T2, T3, T4);
impl_second_element_is!(T1, T2, T3, T4, T5);
impl_second_element_is!(T1, T2, T3, T4, T5, T6);
impl_second_element_is!(T1, T2, T3, T4, T5, T6, T7);
impl_second_element_is!(T1, T2, T3, T4, T5, T6, T7, T8);
impl_second_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9);
impl_second_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
impl_second_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
impl_second_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
impl_second_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13);
impl_second_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14);
impl_second_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15);
impl_second_element_is!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16);
Loading

0 comments on commit bf5675d

Please sign in to comment.