poem_queryext/
query_ext.rs1use poem::{http::StatusCode, Error, FromRequest, Result};
2use serde::Deserialize;
3use std::marker::PhantomData;
4use urlencoding::decode;
5
6#[deprecated(
8 since = "0.1.2",
9 note = "Use `QueryExtN` instead,because `QueryExt` may cause a memory leak"
10)]
11#[derive(Debug)]
12pub struct QueryExt<'a, T>(pub T, PhantomData<&'a T>)
13where
14 T: Deserialize<'a>;
15
16impl<'a, T> FromRequest<'a> for QueryExt<'a, T>
17where
18 T: Deserialize<'a>,
19{
20 async fn from_request(req: &'a poem::Request, _: &mut poem::RequestBody) -> Result<Self> {
21 let query = req.uri().query().unwrap_or_default();
22 let decode_query = match decode(query) {
23 Ok(query) => query.into_owned(),
24 Err(err) => {
25 return Err(Error::from_string(
26 format!("decode query string error:{}", err),
27 StatusCode::INTERNAL_SERVER_ERROR,
28 ));
29 }
30 };
31 let decode_query = Box::leak(decode_query.into_boxed_str());
33 let object = serde_qs::from_str::<T>(decode_query);
35 match object {
36 Ok(object) => {
37 return Ok(QueryExt(object, PhantomData));
38 }
39 Err(err) => {
40 return Err(Error::from_string(
41 format!("parse query string to object error:{}", err),
42 StatusCode::INTERNAL_SERVER_ERROR,
43 ));
44 }
45 }
46 }
47}
48
49#[derive(Debug)]
51pub struct QueryExtN<T>(pub T)
52where
53 T: for<'a> Deserialize<'a>;
54
55impl<'a, T> FromRequest<'a> for QueryExtN<T>
56where
57 T: for<'b> Deserialize<'b>,
58{
59 async fn from_request(req: &'a poem::Request, _: &mut poem::RequestBody) -> Result<Self> {
60 let query = req.uri().query().unwrap_or_default();
61 let decode_query = match decode(query) {
62 Ok(query) => query.into_owned(),
63 Err(err) => {
64 return Err(Error::from_string(
65 format!("decode query string error:{}", err),
66 StatusCode::INTERNAL_SERVER_ERROR,
67 ));
68 }
69 };
70 let object = serde_qs::from_str::<T>(&decode_query);
72 match object {
73 Ok(object) => {
74 return Ok(Self(object));
75 }
76 Err(err) => {
77 return Err(Error::from_string(
78 format!("parse query string to object error:{}", err),
79 StatusCode::INTERNAL_SERVER_ERROR,
80 ));
81 }
82 }
83 }
84}