添加宏路由(临时提交)
This commit is contained in:
parent
a488c82067
commit
684095231d
@ -18,7 +18,7 @@ i18n = { path = "i18n" }
|
||||
|
||||
[workspace.dependencies]
|
||||
tokio = "1.36"
|
||||
axum = "0.7"
|
||||
axum = "0.7.7"
|
||||
tracing = "0.1"
|
||||
tower-http = "0.5"
|
||||
validator = "0.17"
|
||||
|
@ -4,4 +4,8 @@
|
||||
- [*] 参考example中的jwt实现方式,移除context对extension的依赖?那么language-tag该怎么处理?
|
||||
- [ ] 参考rocket,移除参数的元组类型
|
||||
- [ ] 模拟request_util能否避免涉及到的parts.clone()?
|
||||
- [ ] 能否自定义实现宏路由
|
||||
- [ ] 能否自定义实现宏路由
|
||||
|
||||
|
||||
### note
|
||||
- 展开宏:cargo expand --manifest-path .\server\Cargo.toml controller::feedback_controller
|
@ -1,4 +1,4 @@
|
||||
use derive::Responsable;
|
||||
use macros::Responsable;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::types::JsonValue;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use derive::Responsable;
|
||||
use macros::Responsable;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::entities::feedback::Feedback;
|
||||
|
0
feeback_controller_ex.rs
Normal file
0
feeback_controller_ex.rs
Normal file
0
feedback_controller_e.rs
Normal file
0
feedback_controller_e.rs
Normal file
@ -1,5 +1,3 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use axum::{async_trait, extract::{path::ErrorKind, rejection::PathRejection, FromRequestParts}};
|
||||
use http::request::Parts;
|
||||
use i18n::{message, message_ids::MessageId};
|
||||
@ -13,7 +11,7 @@ pub struct PathVar<T>(pub T);
|
||||
#[async_trait]
|
||||
impl<S, T> FromRequestParts<S> for PathVar<T>
|
||||
where
|
||||
T: DeserializeOwned + Send + Display,
|
||||
T: DeserializeOwned + Send,
|
||||
S: Send + Sync,
|
||||
{
|
||||
type Rejection = ResErr;
|
||||
@ -25,7 +23,6 @@ where
|
||||
|
||||
match axum::extract::Path::<T>::from_request_parts(parts, state).await {
|
||||
Ok(value) => {
|
||||
tracing::info!("path params: {}", value.0);
|
||||
Ok(Self(value.0))
|
||||
},
|
||||
Err(rejection) => {
|
||||
|
@ -27,7 +27,9 @@ where
|
||||
type State = S;
|
||||
|
||||
fn typed_route(self, handler: TypedHandler<Self::State>) -> Self {
|
||||
tracing::info!("start add router");
|
||||
let (path, method_router) = handler();
|
||||
tracing::info!("adding typed route: {} - {:?}", path, method_router);
|
||||
self.route(path, method_router)
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
name = "derive"
|
||||
name = "macros"
|
||||
path = "src/lib.rs"
|
||||
proc-macro = true
|
||||
|
||||
|
140
macro/src/lib.rs
140
macro/src/lib.rs
@ -4,10 +4,11 @@ extern crate syn;
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenStream; // 用于处理宏输入
|
||||
use quote::quote; // 用于生成代码
|
||||
use syn::{parse_macro_input, Data, DeriveInput, Fields}; // 用于解析宏输入
|
||||
use proc_macro::TokenStream; // 用于生成代码
|
||||
use syn::{parse_macro_input, parse_quote, DeriveInput}; // 用于解析宏输入
|
||||
|
||||
mod responsable;
|
||||
mod route;
|
||||
|
||||
// 定义一个名为`responsable`的过程宏
|
||||
// #[proc_macro_derive(Responsable, attributes(status, headers))]
|
||||
@ -15,128 +16,23 @@ use syn::{parse_macro_input, Data, DeriveInput, Fields}; // 用于解析宏输
|
||||
pub fn responsable(input: TokenStream) -> TokenStream {
|
||||
// 解析宏输入为`DeriveInput`
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
let name = &input.ident; // 获取结构体名称
|
||||
|
||||
// 根据数据类型生成不同的代码
|
||||
let gen = match input.data {
|
||||
Data::Struct(ref data) => match data.fields {
|
||||
Fields::Named(ref _fields) => {
|
||||
// // 处理命名字段
|
||||
// let field_names = fields.named.iter().map(|f| &f.ident); // 获取所有字段名称
|
||||
// let field_types = fields.named.iter().map(|f| &f.ty); // 获取所有字段类型
|
||||
responsable::gen_responsable(input)
|
||||
}
|
||||
|
||||
// // 获取`status`属性
|
||||
// let status = match input.attrs.iter().find(|attr| attr.path().is_ident("status")) {
|
||||
// Some(attr) => {
|
||||
// let status_lit = attr.parse_args::<Ident>().unwrap(); // 解析`status`属性值
|
||||
// quote! { #status_lit } // 生成状态码
|
||||
// },
|
||||
// None => quote! { hyper::StatusCode::OK }, // 默认状态码为`OK`
|
||||
// };
|
||||
// #[proc_macro_attribute]
|
||||
// pub fn route(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
// route::gen_route(attr, item)
|
||||
// // item
|
||||
// }
|
||||
|
||||
// // 获取`headers`属性
|
||||
// let headers = match input.attrs.iter().find(|attr| attr.path().is_ident("headers")) {
|
||||
// Some(attr) => {
|
||||
// let headers_lit = attr.parse_args::<Ident>().unwrap(); // 解析`headers`属性值
|
||||
// quote! { #headers_lit } // 生成头部信息
|
||||
// },
|
||||
// None => quote! { hyper::HeaderMap::new() }, // 默认头部信息为空
|
||||
// };
|
||||
#[proc_macro_attribute]
|
||||
pub fn route(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
route::gen_route(attr, item)
|
||||
}
|
||||
|
||||
// 生成实现`IntoResponse` trait的代码
|
||||
quote! {
|
||||
impl axum::response::IntoResponse for #name {
|
||||
fn into_response(self) -> axum::http::Response<axum::body::Body> {
|
||||
let mut builder = hyper::Response::builder();
|
||||
// .status(#status) // 设置状态码
|
||||
// .headers(#headers); // 设置头部信息
|
||||
|
||||
let body = serde_json::to_string(&self).expect("Failed to serialize response"); // 序列化结构体为JSON字符串
|
||||
|
||||
axum::http::Response::new(axum::body::Body::from(body)) // 构建响应
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Fields::Unnamed(ref _fields) => {
|
||||
// // 处理未命名字段
|
||||
// let field_names = fields.unnamed.iter().enumerate().map(|(i, _)| i); // 获取所有字段索引
|
||||
// let field_types = fields.unnamed.iter().map(|f| &f.ty); // 获取所有字段类型
|
||||
|
||||
// // 获取`status`属性
|
||||
// let status = match input.attrs.iter().find(|attr| attr.path().is_ident("status")) {
|
||||
// Some(attr) => {
|
||||
// let status_lit = attr.parse_args::<Ident>().unwrap(); // 解析`status`属性值
|
||||
// quote! { #status_lit } // 生成状态码
|
||||
// },
|
||||
// None => quote! { hyper::StatusCode::OK }, // 默认状态码为`OK`
|
||||
// };
|
||||
|
||||
// // 获取`headers`属性
|
||||
// let headers = match input.attrs.iter().find(|attr| attr.path().is_ident("headers")) {
|
||||
// Some(attr) => {
|
||||
// let headers_lit = attr.parse_args::<Ident>().unwrap(); // 解析`headers`属性值
|
||||
// quote! { #headers_lit } // 生成头部信息
|
||||
// },
|
||||
// None => quote! { hyper::HeaderMap::new() }, // 默认头部信息为空
|
||||
// };
|
||||
|
||||
// 生成实现`IntoResponse` trait的代码
|
||||
quote! {
|
||||
impl axum::response::IntoResponse for #name {
|
||||
fn into_response(self) -> axum::http::Response<axum::body::Body> {
|
||||
// let mut builder = hyper::Response::builder();
|
||||
// .status(#status) // 设置状态码
|
||||
// .headers(#headers); // 设置头部信息
|
||||
|
||||
let body = serde_json::to_string(&self).expect("Failed to serialize response"); // 序列化结构体为JSON字符串
|
||||
|
||||
axum::http::Response::new(axum::body::Body::from(body)) // 构建响应
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Fields::Unit => {
|
||||
// // 处理无字段的结构体
|
||||
// // 获取`status`属性
|
||||
// let status = match input.attrs.iter().find(|attr| attr.path().is_ident("status")) {
|
||||
// Some(attr) => {
|
||||
// let status_lit = attr.parse_args::<Ident>().unwrap(); // 解析`status`属性值
|
||||
// quote! { #status_lit } // 生成状态码
|
||||
// },
|
||||
// None => quote! { hyper::StatusCode::OK }, // 默认状态码为`OK`
|
||||
// };
|
||||
|
||||
// // 获取`headers`属性
|
||||
// let headers = match input.attrs.iter().find(|attr| attr.path().is_ident("headers")) {
|
||||
// Some(attr) => {
|
||||
// let headers_lit = attr.parse_args::<Ident>().unwrap(); // 解析`headers`属性值
|
||||
// quote! { #headers_lit } // 生成头部信息
|
||||
// },
|
||||
// None => quote! { hyper::HeaderMap::new() }, // 默认头部信息为空
|
||||
// };
|
||||
|
||||
// 生成实现`IntoResponse` trait的代码
|
||||
quote! {
|
||||
impl axum::response::IntoResponse for #name {
|
||||
fn into_response(self) -> axum::http::Response<axum::body::Body> {
|
||||
// let mut builder = hyper::Response::builder();
|
||||
// .status(#status) // 设置状态码
|
||||
// .headers(#headers); // 设置头部信息
|
||||
|
||||
let body = serde_json::to_string(&self).expect("Failed to serialize response"); // 序列化结构体为JSON字符串
|
||||
|
||||
axum::http::Response::new(hyper::body::Body::from(body)) // 构建响应
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
Data::Enum(_) | Data::Union(_) => {
|
||||
// 不支持枚举或联合体
|
||||
unimplemented!("IntoResponse derive is not implemented for enums or unions.")
|
||||
},
|
||||
};
|
||||
|
||||
gen.into() // 将生成的代码转换为`TokenStream`
|
||||
#[proc_macro_attribute]
|
||||
pub fn get(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
route::gen_get_route(attr, item)
|
||||
}
|
133
macro/src/responsable.rs
Normal file
133
macro/src/responsable.rs
Normal file
@ -0,0 +1,133 @@
|
||||
extern crate proc_macro2;
|
||||
extern crate quote;
|
||||
extern crate syn;
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenStream; // 用于处理宏输入
|
||||
use quote::quote; // 用于生成代码
|
||||
use syn::{Data, DeriveInput, Fields}; // 用于解析宏输入
|
||||
|
||||
pub fn gen_responsable(input: DeriveInput) -> TokenStream {
|
||||
let name = &input.ident; // 获取结构体名称
|
||||
let gen = match input.data {
|
||||
Data::Struct(ref data) => match data.fields {
|
||||
Fields::Named(ref _fields) => {
|
||||
// // 处理命名字段
|
||||
// let field_names = fields.named.iter().map(|f| &f.ident); // 获取所有字段名称
|
||||
// let field_types = fields.named.iter().map(|f| &f.ty); // 获取所有字段类型
|
||||
|
||||
// // 获取`status`属性
|
||||
// let status = match input.attrs.iter().find(|attr| attr.path().is_ident("status")) {
|
||||
// Some(attr) => {
|
||||
// let status_lit = attr.parse_args::<Ident>().unwrap(); // 解析`status`属性值
|
||||
// quote! { #status_lit } // 生成状态码
|
||||
// },
|
||||
// None => quote! { hyper::StatusCode::OK }, // 默认状态码为`OK`
|
||||
// };
|
||||
|
||||
// // 获取`headers`属性
|
||||
// let headers = match input.attrs.iter().find(|attr| attr.path().is_ident("headers")) {
|
||||
// Some(attr) => {
|
||||
// let headers_lit = attr.parse_args::<Ident>().unwrap(); // 解析`headers`属性值
|
||||
// quote! { #headers_lit } // 生成头部信息
|
||||
// },
|
||||
// None => quote! { hyper::HeaderMap::new() }, // 默认头部信息为空
|
||||
// };
|
||||
|
||||
// 生成实现`IntoResponse` trait的代码
|
||||
quote! {
|
||||
impl axum::response::IntoResponse for #name {
|
||||
fn into_response(self) -> axum::http::Response<axum::body::Body> {
|
||||
let mut builder = hyper::Response::builder();
|
||||
// .status(#status) // 设置状态码
|
||||
// .headers(#headers); // 设置头部信息
|
||||
|
||||
let body = serde_json::to_string(&self).expect("Failed to serialize response"); // 序列化结构体为JSON字符串
|
||||
|
||||
axum::http::Response::new(axum::body::Body::from(body)) // 构建响应
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Fields::Unnamed(ref _fields) => {
|
||||
// // 处理未命名字段
|
||||
// let field_names = fields.unnamed.iter().enumerate().map(|(i, _)| i); // 获取所有字段索引
|
||||
// let field_types = fields.unnamed.iter().map(|f| &f.ty); // 获取所有字段类型
|
||||
|
||||
// // 获取`status`属性
|
||||
// let status = match input.attrs.iter().find(|attr| attr.path().is_ident("status")) {
|
||||
// Some(attr) => {
|
||||
// let status_lit = attr.parse_args::<Ident>().unwrap(); // 解析`status`属性值
|
||||
// quote! { #status_lit } // 生成状态码
|
||||
// },
|
||||
// None => quote! { hyper::StatusCode::OK }, // 默认状态码为`OK`
|
||||
// };
|
||||
|
||||
// // 获取`headers`属性
|
||||
// let headers = match input.attrs.iter().find(|attr| attr.path().is_ident("headers")) {
|
||||
// Some(attr) => {
|
||||
// let headers_lit = attr.parse_args::<Ident>().unwrap(); // 解析`headers`属性值
|
||||
// quote! { #headers_lit } // 生成头部信息
|
||||
// },
|
||||
// None => quote! { hyper::HeaderMap::new() }, // 默认头部信息为空
|
||||
// };
|
||||
|
||||
// 生成实现`IntoResponse` trait的代码
|
||||
quote! {
|
||||
impl axum::response::IntoResponse for #name {
|
||||
fn into_response(self) -> axum::http::Response<axum::body::Body> {
|
||||
// let mut builder = hyper::Response::builder();
|
||||
// .status(#status) // 设置状态码
|
||||
// .headers(#headers); // 设置头部信息
|
||||
|
||||
let body = serde_json::to_string(&self).expect("Failed to serialize response"); // 序列化结构体为JSON字符串
|
||||
|
||||
axum::http::Response::new(axum::body::Body::from(body)) // 构建响应
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Fields::Unit => {
|
||||
// // 处理无字段的结构体
|
||||
// // 获取`status`属性
|
||||
// let status = match input.attrs.iter().find(|attr| attr.path().is_ident("status")) {
|
||||
// Some(attr) => {
|
||||
// let status_lit = attr.parse_args::<Ident>().unwrap(); // 解析`status`属性值
|
||||
// quote! { #status_lit } // 生成状态码
|
||||
// },
|
||||
// None => quote! { hyper::StatusCode::OK }, // 默认状态码为`OK`
|
||||
// };
|
||||
|
||||
// // 获取`headers`属性
|
||||
// let headers = match input.attrs.iter().find(|attr| attr.path().is_ident("headers")) {
|
||||
// Some(attr) => {
|
||||
// let headers_lit = attr.parse_args::<Ident>().unwrap(); // 解析`headers`属性值
|
||||
// quote! { #headers_lit } // 生成头部信息
|
||||
// },
|
||||
// None => quote! { hyper::HeaderMap::new() }, // 默认头部信息为空
|
||||
// };
|
||||
|
||||
// 生成实现`IntoResponse` trait的代码
|
||||
quote! {
|
||||
impl axum::response::IntoResponse for #name {
|
||||
fn into_response(self) -> axum::http::Response<axum::body::Body> {
|
||||
// let mut builder = hyper::Response::builder();
|
||||
// .status(#status) // 设置状态码
|
||||
// .headers(#headers); // 设置头部信息
|
||||
|
||||
let body = serde_json::to_string(&self).expect("Failed to serialize response"); // 序列化结构体为JSON字符串
|
||||
|
||||
axum::http::Response::new(hyper::body::Body::from(body)) // 构建响应
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
Data::Enum(_) | Data::Union(_) => {
|
||||
// 不支持枚举或联合体
|
||||
unimplemented!("IntoResponse derive is not implemented for enums or unions.")
|
||||
},
|
||||
};
|
||||
gen.into()
|
||||
}
|
168
macro/src/route.rs
Normal file
168
macro/src/route.rs
Normal file
@ -0,0 +1,168 @@
|
||||
extern crate proc_macro2;
|
||||
extern crate quote;
|
||||
extern crate syn;
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
use parse::{Parse, ParseStream};
|
||||
use proc_macro::{Span, TokenStream}; use punctuated::Punctuated;
|
||||
// 用于处理宏输入
|
||||
use quote::quote; // 用于生成代码
|
||||
use syn::*;
|
||||
|
||||
struct Args {
|
||||
vars: Vec<syn::Expr>
|
||||
}
|
||||
|
||||
impl Parse for Args {
|
||||
fn parse(input: ParseStream) -> syn::parse::Result<Self> {
|
||||
let vars = Punctuated::<syn::Expr, syn::Token![,]>::parse_terminated(input)?;
|
||||
|
||||
Ok(Args {
|
||||
vars: vars.into_iter().collect(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Args {
|
||||
pub fn get_method(&self) -> syn::Result<syn::Expr> {
|
||||
match self.vars.get(0) {
|
||||
Some(var) => Ok(var.clone()),
|
||||
None => return Err(syn::Error::new(
|
||||
Span::call_site().into(),
|
||||
"No Method was provided"
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_route(&self) -> syn::Result<syn::Expr> {
|
||||
match self.vars.get(0) {
|
||||
Some(var) => Ok(var.clone()),
|
||||
None => return Err(syn::Error::new(
|
||||
Span::call_site().into(),
|
||||
"No Route was provided"
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn gen_route(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(attr as Args);
|
||||
let func = parse_macro_input!(item as ItemFn);
|
||||
|
||||
let vis = func.vis.clone();
|
||||
let ident = func.sig.ident.clone();
|
||||
|
||||
let method = args.get_method().unwrap();
|
||||
let route = args.get_route().unwrap();
|
||||
|
||||
let expanded = quote! {
|
||||
#[allow(non_camel_case_types)]
|
||||
#vis struct #ident;
|
||||
|
||||
impl #ident {
|
||||
#vis fn route() -> axum::Router {
|
||||
#func
|
||||
|
||||
axum::Router::new().route(#route, #method (#ident))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expanded.into()
|
||||
}
|
||||
|
||||
pub fn gen_get_route(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(attr as Args);
|
||||
let func = parse_macro_input!(item as ItemFn);
|
||||
|
||||
let vis = func.vis.clone();
|
||||
let ident = func.sig.ident.clone();
|
||||
|
||||
let route = args.get_route().unwrap();
|
||||
|
||||
let expanded = quote! {
|
||||
#vis fn #ident () -> (&'static str, axum::routing::method_routing::MethodRouter) {
|
||||
#func
|
||||
|
||||
(#route, axum::routing::get(#ident))
|
||||
}
|
||||
};
|
||||
expanded.into()
|
||||
}
|
||||
|
||||
pub fn gen_post_route(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(attr as Args);
|
||||
let func = parse_macro_input!(item as ItemFn);
|
||||
|
||||
let vis = func.vis.clone();
|
||||
let ident = func.sig.ident.clone();
|
||||
|
||||
let route = args.get_route().unwrap();
|
||||
|
||||
let expanded = quote! {
|
||||
#vis fn #ident () -> (&'static str, axum::routing::method_routing::MethodRouter) {
|
||||
#func
|
||||
|
||||
(#route, axum::routing::post(#ident))
|
||||
}
|
||||
};
|
||||
expanded.into()
|
||||
}
|
||||
|
||||
pub fn gen_delete_route(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(attr as Args);
|
||||
let func = parse_macro_input!(item as ItemFn);
|
||||
|
||||
let vis = func.vis.clone();
|
||||
let ident = func.sig.ident.clone();
|
||||
|
||||
let route = args.get_route().unwrap();
|
||||
|
||||
let expanded = quote! {
|
||||
#vis fn #ident () -> (&'static str, axum::routing::method_routing::MethodRouter) {
|
||||
#func
|
||||
|
||||
(#route, axum::routing::delete(#ident))
|
||||
}
|
||||
};
|
||||
expanded.into()
|
||||
}
|
||||
|
||||
pub fn gen_put_route(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(attr as Args);
|
||||
let func = parse_macro_input!(item as ItemFn);
|
||||
|
||||
let vis = func.vis.clone();
|
||||
let ident = func.sig.ident.clone();
|
||||
|
||||
let route = args.get_route().unwrap();
|
||||
|
||||
let expanded = quote! {
|
||||
#vis fn #ident () -> (&'static str, axum::routing::method_routing::MethodRouter) {
|
||||
#func
|
||||
|
||||
(#route, axum::routing::put(#ident))
|
||||
}
|
||||
};
|
||||
expanded.into()
|
||||
}
|
||||
|
||||
pub fn gen_option_route(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(attr as Args);
|
||||
let func = parse_macro_input!(item as ItemFn);
|
||||
|
||||
let vis = func.vis.clone();
|
||||
let ident = func.sig.ident.clone();
|
||||
|
||||
let route = args.get_route().unwrap();
|
||||
|
||||
let expanded = quote! {
|
||||
#vis fn #ident () -> (&'static str, axum::routing::method_routing::MethodRouter) {
|
||||
#func
|
||||
|
||||
(#route, axum::routing::option(#ident))
|
||||
}
|
||||
};
|
||||
expanded.into()
|
||||
}
|
@ -1,10 +1,14 @@
|
||||
extern crate macros;
|
||||
|
||||
use domain::dto::feedback::FeedbackAdd;
|
||||
use domain::dto::pageable::PageParams;
|
||||
use domain::vo::feedback::FeedbackPageable;
|
||||
use library::context::Context;
|
||||
use library::extractor::path_extractor::PathVar;
|
||||
use library::model::response::ResResult;
|
||||
use library::extractor::body_extractor::JsonBody;
|
||||
use library::extractor::query_extractor::QueryParams;
|
||||
use macros::get;
|
||||
|
||||
use crate::service;
|
||||
|
||||
@ -31,4 +35,18 @@ pub async fn get_feedback_list_by_page(
|
||||
page_params.page_size.unwrap(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
// #[route(get, "/feedback/:page/:pageSize")]
|
||||
#[get("/feedback/:page/:pageSize")]
|
||||
pub async fn get_feedback_list(
|
||||
context: Context,
|
||||
PathVar(page_params): PathVar<PageParams>,
|
||||
) -> ResResult<FeedbackPageable> {
|
||||
service::feedback_service::get_feedback_list_by_page(
|
||||
context,
|
||||
page_params.page.unwrap(),
|
||||
page_params.page_size.unwrap(),
|
||||
)
|
||||
.await
|
||||
}
|
@ -1,10 +1,16 @@
|
||||
use axum::{routing::post, Router};
|
||||
use axum::{routing::{get, post, MethodRouter}, Router};
|
||||
use library::typed_router::TypedRouter;
|
||||
|
||||
pub mod account_controller;
|
||||
pub mod feedback_controller;
|
||||
|
||||
pub fn init() -> Router {
|
||||
Router::new()
|
||||
// let a = feedback_controller::get_feedback_list;
|
||||
|
||||
// axum::routing::method_routing::MethodRouter::new()
|
||||
|
||||
|
||||
let router = Router::new()
|
||||
.route(
|
||||
"/account/google",
|
||||
post(account_controller::authenticate_google),
|
||||
@ -22,4 +28,17 @@ pub fn init() -> Router {
|
||||
post(feedback_controller::add_feedback)
|
||||
.get(feedback_controller::get_feedback_list_by_page)
|
||||
)
|
||||
}
|
||||
.typed_route(feedback_controller::get_feedback_list)
|
||||
// .merge(feedback_controller::get_feedback_list::route())
|
||||
// .typed_route(route)
|
||||
// .route(
|
||||
// "/feedback/:page/:pageSize",
|
||||
// get(feedback_controller::get_feedback_list)
|
||||
// )
|
||||
;
|
||||
return router;
|
||||
}
|
||||
|
||||
// fn route() -> (&'static str, MethodRouter) {
|
||||
// ("/feedback", axum::routing::get(feedback_controller::get_feedback_list_by_page))
|
||||
// }
|
Loading…
Reference in New Issue
Block a user