poem_queryext/
query_ext.rs

1use poem::{http::StatusCode, Error, FromRequest, Result};
2use serde::Deserialize;
3use std::marker::PhantomData;
4use urlencoding::decode;
5
6/// Deserialize struct wrapper.
7#[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        //leak the decode_query
32        let decode_query = Box::leak(decode_query.into_boxed_str());
33        //parse query string to object
34        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///Deserialize struct new wrapper.
50#[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        //parse query string to object
71        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}