loginmanager_codegen/
lib.rs

1//! login_required macros for actix-loginmanager
2//! # Example
3//! ```rust
4//! use actix_loginmanager::login_required;
5//! // define or import `user` which implements `UserMinix` trait.
6//! 
7//! #[login_required(User)]
8//! async fn hello()->impl actix_web::Responder{
9//!     user.is_actived(); //can access user:Rc<User>
10//!     return "hello";
11//! }
12//! 
13//! #[login_required(User, name="user")]
14//! async fn hello()->impl actix_web::Responder{
15//!     user.is_actived(); //can access user:Rc<User>
16//!     return "hello";
17//! }
18//! ```
19
20use proc_macro::TokenStream;
21
22/// inject an argument `UserWrapAuth(UserWrap(user)): UserWrapAuth<User>` into the function.
23/// 
24/// # Syntax
25/// ```text
26/// #[login_required(UserType,name="user")]
27/// ```
28/// 
29/// # Attributes
30/// - `UserType` - Define the variable type.
31/// - `name="user"` - Define the variable name.
32/// 
33/// # Example
34/// ```rust
35/// #[login_required(User)]
36/// async fn hello()->impl actix_web::Responder{
37///     user.is_actived(); //can access user:Rc<User>
38///     return "hello";
39/// }
40/// ```
41#[proc_macro_attribute]
42pub fn login_required(args: TokenStream, item: TokenStream) -> TokenStream {
43    use quote::quote;
44    use syn::{NestedMeta,Lit,Meta};
45    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
46    let mut user = None;
47    let mut name = "user".to_owned();
48    for arg in args{
49        match arg{
50            NestedMeta::Lit(Lit::Str(lit))=> match user{
51                None=>{user = Some(lit.value());},
52                _=>{
53                    return syn::Error::new_spanned(lit,"The user type cannot be defined twice")
54                        .to_compile_error()
55                        .into();
56                }
57            },
58            NestedMeta::Meta(Meta::Path(path))=>match user{
59                None=>{
60                    user = Some(path.segments.first().unwrap().ident.clone().to_string());
61                },
62                _=>{
63                    return syn::Error::new_spanned(path,"The user type cannot be defined twice")
64                        .to_compile_error()
65                        .into();
66                }
67            },
68            NestedMeta::Meta(Meta::NameValue(nv))=>{
69                if &nv.path.segments.first().unwrap().ident.clone().to_string() == "name"{
70                    if let Lit::Str(lit) = nv.lit{
71                        name = lit.value();
72                    }
73                }
74            },
75            _=>{
76
77            }
78        }
79    }
80    if user == None{
81        return syn::Error::new_spanned("#[login_required]", "need user type,Ex:#[login_required(User)]")
82            .to_compile_error()
83            .into();
84    }
85
86    let mut input = syn::parse_macro_input!(item as syn::ItemFn);
87    let attrs = &input.attrs;
88    let vis = &input.vis;
89    let sig = &mut input.sig;
90    let body = &input.block;
91    let param = format!("actix_loginmanager::UserWrapAuth(actix_loginmanager::UserWrap({})): actix_loginmanager::UserWrapAuth<{}>",name,user.unwrap());
92    let param =  syn::parse_str(&param).unwrap();
93    sig.inputs.push(param);
94
95    (quote! {
96        #(#attrs)*
97        #vis #sig {
98            #body
99        }
100    })
101    .into()
102}