宏路由优化,移除路由手动注册过程

This commit is contained in:
李运家 2024-10-29 09:49:33 +08:00
parent ccb4423476
commit d0ccad5c9f
5 changed files with 40 additions and 54 deletions

View File

@ -1,34 +1,30 @@
use std::sync::Arc;
use axum::Router;
use axum::routing::MethodRouter;
type TypedHandler<S = ()> = fn() -> Vec<(&'static str, MethodRouter<S>)>;
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<S>)`, 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<S>)`, 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::State>) -> Self;
pub trait RouteMethod: Send + Sync + 'static {
fn ge_router(&self, router: Router) -> Router;
}
impl<S> TypedRouter for axum::Router<S>
where
S: Send + Sync + Clone + 'static,
{
type State = S;
fn typed_route(self, handler: TypedHandler<Self::State>) -> 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
}

View File

@ -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)

View File

@ -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<RefreshToken>
) -> ResResult<RefreshTokenResult> {

View File

@ -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)
}

View File

@ -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<Body>| {
let req_id = match request