diff --git a/library/src/typed_router.rs b/library/src/typed_router.rs index 34e47c2..c8563c2 100644 --- a/library/src/typed_router.rs +++ b/library/src/typed_router.rs @@ -1,34 +1,30 @@ +use std::sync::Arc; +use axum::Router; use axum::routing::MethodRouter; -type TypedHandler = fn() -> Vec<(&'static str, MethodRouter)>; +pub use inventory::submit; +use crate::task::TaskMethod; -/// A trait that allows typed routes, created with the [`route`] macro to -/// be added to an axum router. -/// -/// Typed handlers are of the form `fn() -> (&'static str, MethodRouter)`, where -/// `S` is the state type. The first element of the tuple is the path, and the second -/// is the method router. -pub trait TypedRouter: Sized { - /// The state type of the router. - type State: Clone + Send + Sync + 'static; - - /// Add a typed route to the router, usually created with the [`route`] macro. - /// - /// Typed handlers are of the form `fn() -> (&'static str, MethodRouter)`, where - /// `S` is the state type. The first element of the tuple is the path, and the second - /// is the method router. - fn typed_route(self, handler: TypedHandler) -> Self; +pub trait RouteMethod: Send + Sync + 'static { + fn ge_router(&self, router: Router) -> Router; } -impl TypedRouter for axum::Router -where - S: Send + Sync + Clone + 'static, -{ - type State = S; - fn typed_route(self, handler: TypedHandler) -> Self { - let routes = handler(); - routes.into_iter().fold(self, |router, (path, method_router)| { - router.route(path, method_router) - }) +inventory::collect!(&'static dyn RouteMethod); + +#[macro_export] +macro_rules! submit_router_method { + ($ty:ident) => { + ::library::task::submit! { + &$ty as &dyn ::library::typed_router::RouteMethod + } + }; +} + +pub fn get_router() -> Router { + let mut router = Router::new(); + for method in inventory::iter::<&dyn RouteMethod> { + // result.push(Arc::new(method.ge_task())); + router = method.ge_router(router); } + router } \ No newline at end of file diff --git a/macro/src/route.rs b/macro/src/route.rs index aa8c246..4b3befa 100644 --- a/macro/src/route.rs +++ b/macro/src/route.rs @@ -125,30 +125,39 @@ pub fn gen_route(attr: TokenStream, item: TokenStream, method: &str) -> TokenStr let RouteArgs { path, methods } = parse_macro_input!(attr as RouteArgs); // 将 method 转换为小写并生成标识符 - let vis = func.vis.clone(); + // let vis = func.vis.clone(); let ident = func.sig.ident.clone(); let mut method_routers = Vec::new(); if methods.is_empty() { let method_name = syn::Ident::new(&method.to_lowercase(), method.span()); method_routers.push(quote! { - (#path, axum::routing::#method_name(#ident)) + (#path, axum::routing::#method_name(#ident::#ident)) }); } else { for method in methods { let method_name = syn::Ident::new(&method.to_lowercase(), method.span()); method_routers.push(quote! { - (#path, axum::routing::#method_name(#ident)) + (#path, axum::routing::#method_name(#ident::#ident)) }); } } let generated = quote! { - #vis fn #ident () -> Vec<(&'static str, axum::routing::method_routing::MethodRouter)> { + #[allow(non_camel_case_types)] + struct #ident; + impl #ident { #func - - vec![#(#method_routers),*] } + impl library::typed_router::RouteMethod for #ident { + fn ge_router(&self, router: axum::Router) -> axum::Router { + let methods = vec![#(#method_routers),*]; + methods.into_iter().fold(router, |router, (path, method_router)| { + router.route(path, method_router) + }) + } + } + ::library::submit_router_method!(#ident); }; TokenStream::from(generated) diff --git a/server/src/controller/account_controller.rs b/server/src/controller/account_controller.rs index 3a9953e..f5133e5 100644 --- a/server/src/controller/account_controller.rs +++ b/server/src/controller/account_controller.rs @@ -24,7 +24,7 @@ pub async fn authenticate_with_password( /// 刷新token #[post("/account/refresh-token")] -pub async fn refresh_token( +pub async fn refresh_account_token( context: Context, JsonBody(refresh_token): JsonBody ) -> ResResult { diff --git a/server/src/controller/mod.rs b/server/src/controller/mod.rs index d05a18f..c8ab81d 100644 --- a/server/src/controller/mod.rs +++ b/server/src/controller/mod.rs @@ -1,22 +1,3 @@ -use axum::Router; -use library::typed_router::TypedRouter; - pub mod account_controller; pub mod feedback_controller; pub mod social_wx_controller; - -pub fn init() -> Router { - Router::new() - // 用户登录、用户管理相关路由 - .typed_route(account_controller::authenticate_google) - .typed_route(account_controller::authenticate_with_password) - .typed_route(account_controller::refresh_token) - // 反馈相关路由 - .typed_route(feedback_controller::add_feedback) - .typed_route(feedback_controller::get_feedback_list_by_page) - .typed_route(feedback_controller::get_feedback_list) - // 微信相关路由 - .typed_route(social_wx_controller::get_wechat_access_token) - .typed_route(social_wx_controller::code_2_session) - .typed_route(social_wx_controller::check_session) -} diff --git a/server/src/lib.rs b/server/src/lib.rs index 2600a88..851af22 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -21,7 +21,7 @@ pub async fn serve() { /// 初始化router,包括router中间件和数据 fn init() -> Router { - let auth: Router = controller::init(); + let auth: Router = library::typed_router::get_router(); let trace_layer = TraceLayer::new_for_http().make_span_with(|request: &Request| { let req_id = match request