Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove B type param: the rest #1778

Merged
merged 3 commits into from
Feb 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion axum-extra/src/routing/spa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ mod tests {

let spa = SpaRouter::new("/assets", "test_files").handle_error(handle_error);

Router::new().merge(spa);
Router::<()>::new().merge(spa);
}

#[allow(dead_code)]
Expand Down
3 changes: 2 additions & 1 deletion axum-macros/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

# Unreleased

- None.
- **breaking:** `#[debug_handler]` no longer accepts a `body = _` argument. The
body type is always `axum::body::Body`

# 0.3.4 (12. February, 2022)

Expand Down
26 changes: 7 additions & 19 deletions axum-macros/src/debug_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,10 @@ use crate::{
};
use proc_macro2::{Span, TokenStream};
use quote::{format_ident, quote, quote_spanned};
use syn::{parse::Parse, parse_quote, spanned::Spanned, FnArg, ItemFn, Token, Type};
use syn::{parse::Parse, spanned::Spanned, FnArg, ItemFn, Token, Type};

pub(crate) fn expand(attr: Attrs, item_fn: ItemFn) -> TokenStream {
let Attrs { body_ty, state_ty } = attr;

let body_ty = body_ty
.map(second)
.unwrap_or_else(|| parse_quote!(axum::body::Body));
let Attrs { state_ty } = attr;

let mut state_ty = state_ty.map(second);

Expand Down Expand Up @@ -48,7 +44,7 @@ pub(crate) fn expand(attr: Attrs, item_fn: ItemFn) -> TokenStream {
let state_ty = state_ty.unwrap_or_else(|| syn::parse_quote!(()));

let check_inputs_impls_from_request =
check_inputs_impls_from_request(&item_fn, &body_ty, state_ty);
check_inputs_impls_from_request(&item_fn, state_ty);
let check_future_send = check_future_send(&item_fn);

quote! {
Expand Down Expand Up @@ -79,20 +75,16 @@ mod kw {
}

pub(crate) struct Attrs {
body_ty: Option<(kw::body, Type)>,
state_ty: Option<(kw::state, Type)>,
}

impl Parse for Attrs {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let mut body_ty = None;
let mut state_ty = None;

while !input.is_empty() {
let lh = input.lookahead1();
if lh.peek(kw::body) {
parse_assignment_attribute(input, &mut body_ty)?;
} else if lh.peek(kw::state) {
if lh.peek(kw::state) {
parse_assignment_attribute(input, &mut state_ty)?;
} else {
return Err(lh.error());
Expand All @@ -101,7 +93,7 @@ impl Parse for Attrs {
let _ = input.parse::<Token![,]>();
}

Ok(Self { body_ty, state_ty })
Ok(Self { state_ty })
}
}

Expand Down Expand Up @@ -174,11 +166,7 @@ fn is_self_pat_type(typed: &syn::PatType) -> bool {
ident == "self"
}

fn check_inputs_impls_from_request(
item_fn: &ItemFn,
body_ty: &Type,
state_ty: Type,
) -> TokenStream {
fn check_inputs_impls_from_request(item_fn: &ItemFn, state_ty: Type) -> TokenStream {
let takes_self = item_fn.sig.inputs.first().map_or(false, |arg| match arg {
FnArg::Receiver(_) => true,
FnArg::Typed(typed) => is_self_pat_type(typed),
Expand Down Expand Up @@ -255,7 +243,7 @@ fn check_inputs_impls_from_request(
}
} else {
quote_spanned! {span=>
#ty: ::axum::extract::FromRequest<#state_ty, #body_ty, M> + Send
#ty: ::axum::extract::FromRequest<#state_ty, M> + Send
}
};

Expand Down
41 changes: 11 additions & 30 deletions axum-macros/src/from_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,6 @@ pub(crate) enum Trait {
}

impl Trait {
fn body_type(&self) -> impl Iterator<Item = Type> {
match self {
Trait::FromRequest => Some(parse_quote!(B)).into_iter(),
Trait::FromRequestParts => None.into_iter(),
}
}

fn via_marker_type(&self) -> Option<Type> {
match self {
Trait::FromRequest => Some(parse_quote!(M)),
Expand Down Expand Up @@ -370,14 +363,12 @@ fn impl_struct_by_extracting_each_field(
quote!(::axum::response::Response)
};

let impl_generics = tr
.body_type()
.chain(state.impl_generics())
let impl_generics = state
.impl_generics()
.collect::<Punctuated<Type, Token![,]>>();

let trait_generics = state
.trait_generics()
.chain(tr.body_type())
.collect::<Punctuated<Type, Token![,]>>();

let state_bounds = state.bounds();
Expand All @@ -388,15 +379,12 @@ fn impl_struct_by_extracting_each_field(
#[automatically_derived]
impl<#impl_generics> ::axum::extract::FromRequest<#trait_generics> for #ident
where
B: ::axum::body::HttpBody + ::std::marker::Send + 'static,
B::Data: ::std::marker::Send,
B::Error: ::std::convert::Into<::axum::BoxError>,
#state_bounds
{
type Rejection = #rejection_ident;

async fn from_request(
mut req: ::axum::http::Request<B>,
mut req: ::axum::http::Request<::axum::body::Body>,
state: &#state,
) -> ::std::result::Result<Self, Self::Rejection> {
#trait_fn_body
Expand Down Expand Up @@ -749,7 +737,7 @@ fn impl_struct_by_extracting_all_at_once(
// struct AppState {}
// ```
//
// we need to implement `impl<B, M> FromRequest<AppState, B, M>` but only for
// we need to implement `impl<M> FromRequest<AppState, M>` but only for
// - `#[derive(FromRequest)]`, not `#[derive(FromRequestParts)]`
// - `State`, not other extractors
//
Expand All @@ -760,16 +748,15 @@ fn impl_struct_by_extracting_all_at_once(
None
};

let impl_generics = tr
.body_type()
.chain(via_marker_type.clone())
let impl_generics = via_marker_type
.iter()
.cloned()
.chain(state.impl_generics())
.chain(generic_ident.is_some().then(|| parse_quote!(T)))
.collect::<Punctuated<Type, Token![,]>>();

let trait_generics = state
.trait_generics()
.chain(tr.body_type())
.chain(via_marker_type)
.collect::<Punctuated<Type, Token![,]>>();

Expand Down Expand Up @@ -828,13 +815,12 @@ fn impl_struct_by_extracting_all_at_once(
where
#via_path<#via_type_generics>: ::axum::extract::FromRequest<#trait_generics>,
#rejection_bound
B: ::std::marker::Send + 'static,
#state_bounds
{
type Rejection = #associated_rejection_type;

async fn from_request(
req: ::axum::http::Request<B>,
req: ::axum::http::Request<::axum::body::Body>,
state: &#state,
) -> ::std::result::Result<Self, Self::Rejection> {
::axum::extract::FromRequest::from_request(req, state)
Expand Down Expand Up @@ -923,14 +909,12 @@ fn impl_enum_by_extracting_all_at_once(

let path_span = path.span();

let impl_generics = tr
.body_type()
.chain(state.impl_generics())
let impl_generics = state
.impl_generics()
.collect::<Punctuated<Type, Token![,]>>();

let trait_generics = state
.trait_generics()
.chain(tr.body_type())
.collect::<Punctuated<Type, Token![,]>>();

let state_bounds = state.bounds();
Expand All @@ -942,15 +926,12 @@ fn impl_enum_by_extracting_all_at_once(
#[automatically_derived]
impl<#impl_generics> ::axum::extract::FromRequest<#trait_generics> for #ident
where
B: ::axum::body::HttpBody + ::std::marker::Send + 'static,
B::Data: ::std::marker::Send,
B::Error: ::std::convert::Into<::axum::BoxError>,
#state_bounds
{
type Rejection = #associated_rejection_type;

async fn from_request(
req: ::axum::http::Request<B>,
req: ::axum::http::Request<::axum::body::Body>,
state: &#state,
) -> ::std::result::Result<Self, Self::Rejection> {
::axum::extract::FromRequest::from_request(req, state)
Expand Down
17 changes: 1 addition & 16 deletions axum-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ use from_request::Trait::{FromRequest, FromRequestParts};
/// ```
/// pub struct ViaExtractor<T>(pub T);
///
/// // impl<T, S, B> FromRequest<S, B> for ViaExtractor<T> { ... }
/// // impl<T, S> FromRequest<S> for ViaExtractor<T> { ... }
/// ```
///
/// More complex via extractors are not supported and require writing a manual implementation.
Expand Down Expand Up @@ -480,21 +480,6 @@ pub fn derive_from_request_parts(item: TokenStream) -> TokenStream {
/// }
/// ```
///
/// # Changing request body type
///
/// By default `#[debug_handler]` assumes your request body type is `axum::body::Body`. This will
/// work for most extractors but, for example, it wont work for `Request<axum::body::BoxBody>`,
/// which only implements `FromRequest<BoxBody>` and _not_ `FromRequest<Body>`.
///
/// To work around that the request body type can be customized like so:
///
/// ```
/// use axum::{body::BoxBody, http::Request, debug_handler};
///
/// #[debug_handler(body = BoxBody)]
/// async fn handler(request: Request<BoxBody>) {}
/// ```
///
/// # Changing state type
///
/// By default `#[debug_handler]` assumes your state type is `()` unless your handler has a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ error[E0277]: the trait bound `bool: FromRequestParts<()>` is not satisfied
<(T1, T2, T3, T4, T5, T6, T7) as FromRequestParts<S>>
<(T1, T2, T3, T4, T5, T6, T7, T8) as FromRequestParts<S>>
and 26 others
= note: required for `bool` to implement `FromRequest<(), Body, axum_core::extract::private::ViaParts>`
= note: required for `bool` to implement `FromRequest<(), axum_core::extract::private::ViaParts>`
note: required by a bound in `__axum_macros_check_handler_0_from_request_check`
--> tests/debug_handler/fail/argument_not_extractor.rs:4:23
|
Expand Down
5 changes: 1 addition & 4 deletions axum-macros/tests/debug_handler/fail/duplicate_args.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use axum_macros::debug_handler;

#[debug_handler(body = BoxBody, body = BoxBody)]
async fn handler() {}

#[debug_handler(state = (), state = ())]
async fn handler_2() {}
async fn handler() {}

fn main() {}
10 changes: 2 additions & 8 deletions axum-macros/tests/debug_handler/fail/duplicate_args.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
error: `body` specified more than once
--> tests/debug_handler/fail/duplicate_args.rs:3:33
|
3 | #[debug_handler(body = BoxBody, body = BoxBody)]
| ^^^^

error: `state` specified more than once
--> tests/debug_handler/fail/duplicate_args.rs:6:29
--> tests/debug_handler/fail/duplicate_args.rs:3:29
|
6 | #[debug_handler(state = (), state = ())]
3 | #[debug_handler(state = (), state = ())]
| ^^^^^
5 changes: 2 additions & 3 deletions axum-macros/tests/debug_handler/fail/extract_self_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@ use axum_macros::debug_handler;
struct A;

#[async_trait]
impl<S, B> FromRequest<S, B> for A
impl<S> FromRequest<S> for A
where
B: Send + 'static,
S: Send + Sync,
{
type Rejection = ();

async fn from_request(_req: Request<B>, _state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(_req: Request<axum::body::Body>, _state: &S) -> Result<Self, Self::Rejection> {
unimplemented!()
}
}
Expand Down
4 changes: 2 additions & 2 deletions axum-macros/tests/debug_handler/fail/extract_self_mut.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: Handlers must only take owned values
--> tests/debug_handler/fail/extract_self_mut.rs:25:22
--> tests/debug_handler/fail/extract_self_mut.rs:24:22
|
25 | async fn handler(&mut self) {}
24 | async fn handler(&mut self) {}
| ^^^^^^^^^
5 changes: 2 additions & 3 deletions axum-macros/tests/debug_handler/fail/extract_self_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@ use axum_macros::debug_handler;
struct A;

#[async_trait]
impl<S, B> FromRequest<S, B> for A
impl<S> FromRequest<S> for A
where
B: Send + 'static,
S: Send + Sync,
{
type Rejection = ();

async fn from_request(_req: Request<B>, _state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(_req: Request<axum::body::Body>, _state: &S) -> Result<Self, Self::Rejection> {
unimplemented!()
}
}
Expand Down
4 changes: 2 additions & 2 deletions axum-macros/tests/debug_handler/fail/extract_self_ref.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: Handlers must only take owned values
--> tests/debug_handler/fail/extract_self_ref.rs:25:22
--> tests/debug_handler/fail/extract_self_ref.rs:24:22
|
25 | async fn handler(&self) {}
24 | async fn handler(&self) {}
| ^^^^^
2 changes: 1 addition & 1 deletion axum-macros/tests/debug_handler/fail/invalid_attrs.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: expected `body` or `state`
error: expected `state`
--> tests/debug_handler/fail/invalid_attrs.rs:3:17
|
3 | #[debug_handler(foo)]
Expand Down

This file was deleted.

10 changes: 4 additions & 6 deletions axum-macros/tests/debug_handler/pass/self_receiver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,25 @@ use axum_macros::debug_handler;
struct A;

#[async_trait]
impl<S, B> FromRequest<S, B> for A
impl<S> FromRequest<S> for A
where
B: Send + 'static,
S: Send + Sync,
{
type Rejection = ();

async fn from_request(_req: Request<B>, _state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(_req: Request<axum::body::Body>, _state: &S) -> Result<Self, Self::Rejection> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No alias yet in this PR? :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not yet. That comes in #1789

unimplemented!()
}
}

#[async_trait]
impl<S, B> FromRequest<S, B> for Box<A>
impl<S> FromRequest<S> for Box<A>
where
B: Send + 'static,
S: Send + Sync,
{
type Rejection = ();

async fn from_request(_req: Request<B>, _state: &S) -> Result<Self, Self::Rejection> {
async fn from_request(_req: Request<axum::body::Body>, _state: &S) -> Result<Self, Self::Rejection> {
unimplemented!()
}
}
Expand Down
Loading