1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput, Ident};
#[proc_macro_derive(FromRequest)]
pub fn from_request(tokenstream: TokenStream) -> TokenStream {
let abstract_syntax_tree = parse_macro_input!(tokenstream as DeriveInput);
let struct_identifier = abstract_syntax_tree.ident;
let lower_case_identifier = Ident::new(&struct_identifier.to_string().to_lowercase(), struct_identifier.span());
let error = format!("could not extract type \"{}\" from HttpRequest extensions", struct_identifier.to_string());
quote!(
impl actix_web::FromRequest for #struct_identifier {
type Error = actix_web::Error;
type Future = std::future::Ready<Result<Self, Self::Error>>;
fn from_request(req: &actix_web::HttpRequest, _: &mut actix_web::dev::Payload) -> Self::Future {
std::future::ready(
match <actix_web::HttpRequest as actix_web::HttpMessage>::extensions(req).get::<#struct_identifier>() {
Some(#lower_case_identifier) => Ok(#lower_case_identifier.clone()),
None => Err(actix_web::error::ErrorBadRequest(#error))
}
)
}
}
)
.into()
}