Skip to content

Commit f085897

Browse files
committed
refactor(extractor): 重构萃取器模块结构
将 extractor 模块拆分为多个文件以提高代码组织性: - 新增 from_request.rs 包含 FromRequest trait 实现 - 新增 types.rs 包含萃取器类型定义 - 重构 mod.rs 为模块入口文件 - 更新 lib.rs 中的导出 - 优化 session middleware 中的代码逻辑
1 parent 005f33f commit f085897

File tree

5 files changed

+356
-352
lines changed

5 files changed

+356
-352
lines changed
Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
use async_trait::async_trait;
2+
3+
use crate::{Request, Response, SilentError, core::path_param::PathParam, headers::HeaderMapExt};
4+
5+
use super::types::{
6+
Configs, Extension, Form, Json, Method, Path, Query, RemoteAddr, TypedHeader, Uri, Version,
7+
};
8+
9+
#[async_trait]
10+
pub trait FromRequest: Sized {
11+
type Rejection: Into<crate::Response> + Send + 'static;
12+
async fn from_request(req: &mut Request) -> Result<Self, Self::Rejection>;
13+
}
14+
15+
#[async_trait]
16+
impl<T> FromRequest for Path<T>
17+
where
18+
for<'de> T: serde::Deserialize<'de> + Send + 'static,
19+
{
20+
type Rejection = SilentError;
21+
22+
async fn from_request(req: &mut Request) -> Result<Self, Self::Rejection> {
23+
use crate::core::serde::{from_str_map, from_str_val};
24+
let params = req.path_params();
25+
if params.is_empty() {
26+
return Err(SilentError::ParamsEmpty);
27+
}
28+
29+
if params.len() == 1 {
30+
let value = params.values().next().unwrap();
31+
let single = path_param_to_string(value);
32+
let parsed: T = from_str_val(single.as_str())?;
33+
return Ok(Path(parsed));
34+
}
35+
36+
let map_iter = params
37+
.iter()
38+
.map(|(k, v)| (k.as_str(), path_param_to_string(v)));
39+
let parsed: T = from_str_map(map_iter)?;
40+
Ok(Path(parsed))
41+
}
42+
}
43+
44+
#[async_trait]
45+
impl<T> FromRequest for Query<T>
46+
where
47+
for<'de> T: serde::Deserialize<'de> + Send + 'static,
48+
{
49+
type Rejection = SilentError;
50+
51+
async fn from_request(req: &mut Request) -> Result<Self, Self::Rejection> {
52+
let value = req.params_parse::<T>()?;
53+
Ok(Query(value))
54+
}
55+
}
56+
57+
#[async_trait]
58+
impl<T> FromRequest for Json<T>
59+
where
60+
for<'de> T: serde::Deserialize<'de> + Send + 'static,
61+
{
62+
type Rejection = SilentError;
63+
64+
async fn from_request(req: &mut Request) -> Result<Self, Self::Rejection> {
65+
let value = req.json_parse::<T>().await?;
66+
Ok(Json(value))
67+
}
68+
}
69+
70+
#[async_trait]
71+
impl<T> FromRequest for Form<T>
72+
where
73+
for<'de> T: serde::Deserialize<'de> + serde::Serialize + Send + 'static,
74+
{
75+
type Rejection = SilentError;
76+
77+
async fn from_request(req: &mut Request) -> Result<Self, Self::Rejection> {
78+
let value = req.form_parse::<T>().await?;
79+
Ok(Form(value))
80+
}
81+
}
82+
83+
#[async_trait]
84+
impl<T> FromRequest for Configs<T>
85+
where
86+
T: Send + Sync + Clone + 'static,
87+
{
88+
type Rejection = SilentError;
89+
90+
async fn from_request(req: &mut Request) -> Result<Self, Self::Rejection> {
91+
let cfg = req.get_config::<T>()?.clone();
92+
Ok(Configs(cfg))
93+
}
94+
}
95+
96+
#[async_trait]
97+
impl<T> FromRequest for Extension<T>
98+
where
99+
T: Clone + Send + Sync + 'static,
100+
{
101+
type Rejection = SilentError;
102+
103+
async fn from_request(req: &mut Request) -> Result<Self, Self::Rejection> {
104+
let ext = req
105+
.extensions()
106+
.get::<T>()
107+
.cloned()
108+
.ok_or(SilentError::ParamsNotFound)?;
109+
Ok(Extension(ext))
110+
}
111+
}
112+
113+
#[async_trait]
114+
impl<H> FromRequest for TypedHeader<H>
115+
where
116+
H: headers::Header + Send + 'static,
117+
{
118+
type Rejection = SilentError;
119+
120+
async fn from_request(req: &mut Request) -> Result<Self, Self::Rejection> {
121+
let h = req
122+
.headers()
123+
.typed_get::<H>()
124+
.ok_or(SilentError::ParamsNotFound)?;
125+
Ok(TypedHeader(h))
126+
}
127+
}
128+
129+
#[async_trait]
130+
impl FromRequest for Method {
131+
type Rejection = SilentError;
132+
async fn from_request(req: &mut Request) -> Result<Self, Self::Rejection> {
133+
Ok(Method(req.method().clone()))
134+
}
135+
}
136+
137+
#[async_trait]
138+
impl FromRequest for Uri {
139+
type Rejection = SilentError;
140+
async fn from_request(req: &mut Request) -> Result<Self, Self::Rejection> {
141+
Ok(Uri(req.uri().clone()))
142+
}
143+
}
144+
145+
#[async_trait]
146+
impl FromRequest for Version {
147+
type Rejection = SilentError;
148+
async fn from_request(req: &mut Request) -> Result<Self, Self::Rejection> {
149+
Ok(Version(req.version()))
150+
}
151+
}
152+
153+
#[async_trait]
154+
impl FromRequest for RemoteAddr {
155+
type Rejection = SilentError;
156+
async fn from_request(req: &mut Request) -> Result<Self, Self::Rejection> {
157+
Ok(RemoteAddr(req.remote()))
158+
}
159+
}
160+
161+
#[async_trait]
162+
impl<A> FromRequest for (A,)
163+
where
164+
A: FromRequest + Send + 'static,
165+
{
166+
type Rejection = Response;
167+
168+
async fn from_request(req: &mut Request) -> Result<Self, Self::Rejection> {
169+
let a = match <A as FromRequest>::from_request(req).await {
170+
Ok(v) => v,
171+
Err(e) => return Err(e.into()),
172+
};
173+
Ok((a,))
174+
}
175+
}
176+
177+
#[async_trait]
178+
impl<A, B> FromRequest for (A, B)
179+
where
180+
A: FromRequest + Send + 'static,
181+
B: FromRequest + Send + 'static,
182+
{
183+
type Rejection = Response;
184+
185+
async fn from_request(req: &mut Request) -> Result<Self, Self::Rejection> {
186+
let a = match <A as FromRequest>::from_request(req).await {
187+
Ok(v) => v,
188+
Err(e) => return Err(e.into()),
189+
};
190+
let b = match <B as FromRequest>::from_request(req).await {
191+
Ok(v) => v,
192+
Err(e) => return Err(e.into()),
193+
};
194+
Ok((a, b))
195+
}
196+
}
197+
198+
#[async_trait]
199+
impl<A, B, C> FromRequest for (A, B, C)
200+
where
201+
A: FromRequest + Send + 'static,
202+
B: FromRequest + Send + 'static,
203+
C: FromRequest + Send + 'static,
204+
{
205+
type Rejection = Response;
206+
207+
async fn from_request(req: &mut Request) -> Result<Self, Self::Rejection> {
208+
let a = match <A as FromRequest>::from_request(req).await {
209+
Ok(v) => v,
210+
Err(e) => return Err(e.into()),
211+
};
212+
let b = match <B as FromRequest>::from_request(req).await {
213+
Ok(v) => v,
214+
Err(e) => return Err(e.into()),
215+
};
216+
let c = match <C as FromRequest>::from_request(req).await {
217+
Ok(v) => v,
218+
Err(e) => return Err(e.into()),
219+
};
220+
Ok((a, b, c))
221+
}
222+
}
223+
224+
#[async_trait]
225+
impl<A, B, C, D> FromRequest for (A, B, C, D)
226+
where
227+
A: FromRequest + Send + 'static,
228+
B: FromRequest + Send + 'static,
229+
C: FromRequest + Send + 'static,
230+
D: FromRequest + Send + 'static,
231+
{
232+
type Rejection = Response;
233+
234+
async fn from_request(req: &mut Request) -> Result<Self, Self::Rejection> {
235+
let a = match <A as FromRequest>::from_request(req).await {
236+
Ok(v) => v,
237+
Err(e) => return Err(e.into()),
238+
};
239+
let b = match <B as FromRequest>::from_request(req).await {
240+
Ok(v) => v,
241+
Err(e) => return Err(e.into()),
242+
};
243+
let c = match <C as FromRequest>::from_request(req).await {
244+
Ok(v) => v,
245+
Err(e) => return Err(e.into()),
246+
};
247+
let d = match <D as FromRequest>::from_request(req).await {
248+
Ok(v) => v,
249+
Err(e) => return Err(e.into()),
250+
};
251+
Ok((a, b, c, d))
252+
}
253+
}
254+
255+
#[async_trait]
256+
impl<T> FromRequest for Option<T>
257+
where
258+
T: FromRequest + Send + 'static,
259+
{
260+
type Rejection = Response;
261+
262+
async fn from_request(req: &mut Request) -> Result<Self, Self::Rejection> {
263+
match T::from_request(req).await {
264+
Ok(v) => Ok(Some(v)),
265+
Err(_e) => Ok(None),
266+
}
267+
}
268+
}
269+
270+
#[async_trait]
271+
impl<T> FromRequest for Result<T, Response>
272+
where
273+
T: FromRequest + Send + 'static,
274+
{
275+
type Rejection = Response;
276+
277+
async fn from_request(req: &mut Request) -> Result<Self, Self::Rejection> {
278+
match T::from_request(req).await {
279+
Ok(v) => Ok(Ok(v)),
280+
Err(e) => Ok(Err(e.into())),
281+
}
282+
}
283+
}
284+
285+
#[inline]
286+
fn path_param_to_string(param: &PathParam) -> String {
287+
match param {
288+
PathParam::String(s) => s.clone(),
289+
PathParam::Path(s) => s.clone(),
290+
PathParam::Int(v) => v.to_string(),
291+
PathParam::Int32(v) => v.to_string(),
292+
PathParam::Int64(v) => v.to_string(),
293+
PathParam::UInt32(v) => v.to_string(),
294+
PathParam::UInt64(v) => v.to_string(),
295+
PathParam::Uuid(u) => u.to_string(),
296+
}
297+
}

0 commit comments

Comments
 (0)