poem_queryext/
query_ext.rs1use poem::{http::StatusCode, Error, FromRequest, Result};
2use serde::Deserialize;
3use std::marker::PhantomData;
4use urlencoding::decode;
5
6#[derive(Debug)]
8pub struct QueryExt<'a, T>(pub T, PhantomData<&'a T>)
9where
10 T: Deserialize<'a>;
11
12impl<'a, T> FromRequest<'a> for QueryExt<'a, T>
13where
14 T: Deserialize<'a>,
15{
16 async fn from_request(req: &'a poem::Request, _: &mut poem::RequestBody) -> Result<Self> {
17 let path_and_query = req.uri().path_and_query();
18 if let Some(path_and_query) = path_and_query {
19 let path_and_query = path_and_query.as_str().split_once("?");
20 let query = match path_and_query {
21 Some((_, query)) => query,
22 None => "",
23 };
24 let decode_query = match decode(query) {
25 Ok(query) => query.into_owned(),
26 Err(err) => {
27 return Err(Error::from_string(
28 format!("decode query string error:{}", err.to_string()),
29 StatusCode::INTERNAL_SERVER_ERROR,
30 ));
31 }
32 };
33 let decode_query = Box::leak(decode_query.into_boxed_str());
35 let object = serde_qs::from_str::<T>(decode_query);
37 match object {
38 Ok(object) => {
39 return Ok(QueryExt(object, PhantomData));
40 }
41 Err(err) => {
42 return Err(Error::from_string(
43 format!("parse query string to object error:{}", err.to_string()),
44 StatusCode::INTERNAL_SERVER_ERROR,
45 ));
46 }
47 }
48 } else {
49 return Err(Error::from_status(StatusCode::INTERNAL_SERVER_ERROR));
50 }
51 }
52}