mirror of
https://github.com/tokio-rs/axum.git
synced 2026-08-28 00:00:20 +02:00
Support State with #[derive(FromRequest[Parts])] (#1391)
* Support `State` with `#[derive(FromRequest[Parts])]` Fixes https://github.com/tokio-rs/axum/issues/1314 This makes it possible to extract things via `State` in `#[derive(FromRequet)]`: ```rust struct Foo { state: State<AppState>, } ``` The state can also be inferred in a lot of cases so you only need to write: ```rust struct Foo { // since we're using `State<AppState>` we know the state has to be // `AppState` state: State<AppState>, } ``` Same for ```rust struct Foo { #[from_request(via(State))] state: AppState, } ``` And ```rust struct AppState {} ``` I think I've covered all the edge cases but there are (unsurprisingly) a few. * make sure things can be combined with other extractors * main functions in ui tests don't need to be async * Add test for multiple identicaly state types * Add failing test for multiple states
This commit is contained in:
@@ -7,18 +7,21 @@ use syn::{
|
||||
pub(crate) mod kw {
|
||||
syn::custom_keyword!(via);
|
||||
syn::custom_keyword!(rejection);
|
||||
syn::custom_keyword!(state);
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub(super) struct FromRequestContainerAttrs {
|
||||
pub(super) via: Option<(kw::via, syn::Path)>,
|
||||
pub(super) rejection: Option<(kw::rejection, syn::Path)>,
|
||||
pub(super) state: Option<(kw::state, syn::Type)>,
|
||||
}
|
||||
|
||||
impl Parse for FromRequestContainerAttrs {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
let mut via = None;
|
||||
let mut rejection = None;
|
||||
let mut state = None;
|
||||
|
||||
while !input.is_empty() {
|
||||
let lh = input.lookahead1();
|
||||
@@ -26,6 +29,8 @@ impl Parse for FromRequestContainerAttrs {
|
||||
parse_parenthesized_attribute(input, &mut via)?;
|
||||
} else if lh.peek(kw::rejection) {
|
||||
parse_parenthesized_attribute(input, &mut rejection)?;
|
||||
} else if lh.peek(kw::state) {
|
||||
parse_parenthesized_attribute(input, &mut state)?;
|
||||
} else {
|
||||
return Err(lh.error());
|
||||
}
|
||||
@@ -33,15 +38,24 @@ impl Parse for FromRequestContainerAttrs {
|
||||
let _ = input.parse::<Token![,]>();
|
||||
}
|
||||
|
||||
Ok(Self { via, rejection })
|
||||
Ok(Self {
|
||||
via,
|
||||
rejection,
|
||||
state,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Combine for FromRequestContainerAttrs {
|
||||
fn combine(mut self, other: Self) -> syn::Result<Self> {
|
||||
let Self { via, rejection } = other;
|
||||
let Self {
|
||||
via,
|
||||
rejection,
|
||||
state,
|
||||
} = other;
|
||||
combine_attribute(&mut self.via, via)?;
|
||||
combine_attribute(&mut self.rejection, rejection)?;
|
||||
combine_attribute(&mut self.state, state)?;
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user