mirror of
https://github.com/tokio-rs/axum.git
synced 2025-03-19 21:49:04 +01:00
* add `#[derive(FromRef)]` * tests * don't support skipping fields probably wouldn't work at all since the whole state likely needs `Clone` * UI tests * changelog * changelog link * revert hello-world example, used for testing * Re-export `#[derive(FromRef)]` * Don't need to return `Result` * use `collect` instead of quoting the iterator * Mention it in axum's changelog
39 lines
994 B
Rust
39 lines
994 B
Rust
use proc_macro2::{Ident, TokenStream};
|
|
use quote::quote_spanned;
|
|
use syn::{spanned::Spanned, Field, ItemStruct};
|
|
|
|
pub(crate) fn expand(item: ItemStruct) -> TokenStream {
|
|
item.fields
|
|
.iter()
|
|
.enumerate()
|
|
.map(|(idx, field)| expand_field(&item.ident, idx, field))
|
|
.collect()
|
|
}
|
|
|
|
fn expand_field(state: &Ident, idx: usize, field: &Field) -> TokenStream {
|
|
let field_ty = &field.ty;
|
|
let span = field.ty.span();
|
|
|
|
let body = if let Some(field_ident) = &field.ident {
|
|
quote_spanned! {span=> state.#field_ident.clone() }
|
|
} else {
|
|
let idx = syn::Index {
|
|
index: idx as _,
|
|
span: field.span(),
|
|
};
|
|
quote_spanned! {span=> state.#idx.clone() }
|
|
};
|
|
|
|
quote_spanned! {span=>
|
|
impl ::axum::extract::FromRef<#state> for #field_ty {
|
|
fn from_ref(state: &#state) -> Self {
|
|
#body
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn ui() {
|
|
crate::run_ui_tests("from_ref");
|
|
}
|