Add type safe state extractor (#1155)

* begin threading the state through

* Pass state to extractors

* make state extractor work

* make sure nesting with different states work

* impl Service for MethodRouter<()>

* Fix some of axum-macro's tests

* Implement more traits for `State`

* Update examples to use `State`

* consistent naming of request body param

* swap type params

* Default the state param to ()

* fix docs references

* Docs and handler state refactoring

* docs clean ups

* more consistent naming

* when does MethodRouter implement Service?

* add missing docs

* use `Router`'s default state type param

* changelog

* don't use default type param for FromRequest and RequestParts

probably safer for library authors so you don't accidentally forget

* fix examples

* minor docs tweaks

* clarify how to convert handlers into services

* group methods in one impl block

* make sure merged `MethodRouter`s can access state

* fix docs link

* test merge with same state type

* Document how to access state from middleware

* Port cookie extractors to use state to extract keys (#1250)

* Updates ECOSYSTEM with a new sample project (#1252)

* Avoid unhelpful compiler suggestion (#1251)

* fix docs typo

* document how library authors should access state

* Add `RequestParts::with_state`

* fix example

* apply suggestions from review

* add relevant changes to axum-extra and axum-core changelogs

* Add `route_service_with_tsr`

* fix trybuild expectations

* make sure `SpaRouter` works with routers that have state

* Change order of type params on FromRequest and RequestParts

* reverse order of `RequestParts::with_state` args to match type params

* Add `FromRef` trait (#1268)

* Add `FromRef` trait

* Remove unnecessary type params

* format

* fix docs link

* format examples

* Avoid unnecessary `MethodRouter`

* apply suggestions from review

Co-authored-by: Dani Pardo <[email protected]>
Co-authored-by: Jonas Platte <[email protected]>
This commit is contained in:
David Pedersen
2022-08-17 15:13:31 +00:00
committed by GitHub
co-authored by Dani Pardo Jonas Platte
parent 90dbd52ee4
commit 423308de3c
132 changed files with 2404 additions and 1126 deletions
+19 -16
View File
@@ -218,16 +218,17 @@ fn impl_struct_by_extracting_each_field(
Ok(quote! {
#[::axum::async_trait]
#[automatically_derived]
impl<B> ::axum::extract::FromRequest<B> for #ident
impl<S, B> ::axum::extract::FromRequest<S, B> for #ident
where
B: ::axum::body::HttpBody + ::std::marker::Send + 'static,
B::Data: ::std::marker::Send,
B::Error: ::std::convert::Into<::axum::BoxError>,
S: Send,
{
type Rejection = #rejection_ident;
async fn from_request(
req: &mut ::axum::extract::RequestParts<B>,
req: &mut ::axum::extract::RequestParts<S, B>,
) -> ::std::result::Result<Self, Self::Rejection> {
::std::result::Result::Ok(Self {
#(#extract_fields)*
@@ -422,7 +423,7 @@ fn extract_each_field_rejection(
Ok(quote_spanned! {ty_span=>
#[allow(non_camel_case_types)]
#variant_name(<#extractor_ty as ::axum::extract::FromRequest<::axum::body::Body>>::Rejection),
#variant_name(<#extractor_ty as ::axum::extract::FromRequest<(), ::axum::body::Body>>::Rejection),
})
})
.collect::<syn::Result<Vec<_>>>()?;
@@ -609,26 +610,26 @@ fn impl_struct_by_extracting_all_at_once(
quote! { #rejection }
} else {
quote! {
<#path<Self> as ::axum::extract::FromRequest<B>>::Rejection
<#path<Self> as ::axum::extract::FromRequest<S, B>>::Rejection
}
};
let rejection_bound = rejection.as_ref().map(|rejection| {
if generic_ident.is_some() {
quote! {
#rejection: ::std::convert::From<<#path<T> as ::axum::extract::FromRequest<B>>::Rejection>,
#rejection: ::std::convert::From<<#path<T> as ::axum::extract::FromRequest<S, B>>::Rejection>,
}
} else {
quote! {
#rejection: ::std::convert::From<<#path<Self> as ::axum::extract::FromRequest<B>>::Rejection>,
#rejection: ::std::convert::From<<#path<Self> as ::axum::extract::FromRequest<S, B>>::Rejection>,
}
}
}).unwrap_or_default();
let impl_generics = if generic_ident.is_some() {
quote! { B, T }
quote! { S, B, T }
} else {
quote! { B }
quote! { S, B }
};
let type_generics = generic_ident
@@ -653,18 +654,19 @@ fn impl_struct_by_extracting_all_at_once(
Ok(quote_spanned! {path_span=>
#[::axum::async_trait]
#[automatically_derived]
impl<#impl_generics> ::axum::extract::FromRequest<B> for #ident #type_generics
impl<#impl_generics> ::axum::extract::FromRequest<S, B> for #ident #type_generics
where
#path<#via_type_generics>: ::axum::extract::FromRequest<B>,
#path<#via_type_generics>: ::axum::extract::FromRequest<S, B>,
#rejection_bound
B: ::std::marker::Send,
S: ::std::marker::Send,
{
type Rejection = #associated_rejection_type;
async fn from_request(
req: &mut ::axum::extract::RequestParts<B>,
req: &mut ::axum::extract::RequestParts<S, B>,
) -> ::std::result::Result<Self, Self::Rejection> {
::axum::extract::FromRequest::<B>::from_request(req)
::axum::extract::FromRequest::<S, B>::from_request(req)
.await
.map(|#path(value)| #value_to_self)
.map_err(::std::convert::From::from)
@@ -709,7 +711,7 @@ fn impl_enum_by_extracting_all_at_once(
quote! { #rejection }
} else {
quote! {
<#path<Self> as ::axum::extract::FromRequest<B>>::Rejection
<#path<Self> as ::axum::extract::FromRequest<S, B>>::Rejection
}
};
@@ -718,18 +720,19 @@ fn impl_enum_by_extracting_all_at_once(
Ok(quote_spanned! {path_span=>
#[::axum::async_trait]
#[automatically_derived]
impl<B> ::axum::extract::FromRequest<B> for #ident
impl<S, B> ::axum::extract::FromRequest<S, B> for #ident
where
B: ::axum::body::HttpBody + ::std::marker::Send + 'static,
B::Data: ::std::marker::Send,
B::Error: ::std::convert::Into<::axum::BoxError>,
S: ::std::marker::Send,
{
type Rejection = #associated_rejection_type;
async fn from_request(
req: &mut ::axum::extract::RequestParts<B>,
req: &mut ::axum::extract::RequestParts<S, B>,
) -> ::std::result::Result<Self, Self::Rejection> {
::axum::extract::FromRequest::<B>::from_request(req)
::axum::extract::FromRequest::<S, B>::from_request(req)
.await
.map(|#path(inner)| inner)
.map_err(::std::convert::From::from)