tosic_http/extractors/
query.rs1use crate::extractors::ExtractionError;
4use crate::futures::{err, ok, Ready};
5use crate::request::{HttpPayload, HttpRequest};
6use crate::traits::from_request::FromRequest;
7use serde::de::DeserializeOwned;
8use std::fmt::Debug;
9
10#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
11pub struct Query<V>(pub V);
13
14impl<T> Query<T> {
15 #[inline]
16 pub fn into_inner(self) -> T {
18 self.0
19 }
20}
21
22impl<T: DeserializeOwned> Query<T> {
23 #[inline]
24 pub fn from_query(query: &str) -> Result<Self, ExtractionError> {
26 serde_urlencoded::from_str::<T>(query)
27 .map(Self)
28 .map_err(ExtractionError::Query)
29 }
30}
31
32impl<T> std::ops::Deref for Query<T> {
33 type Target = T;
34 #[inline]
35 fn deref(&self) -> &Self::Target {
36 &self.0
37 }
38}
39
40impl<T> std::ops::DerefMut for Query<T> {
41 #[inline]
42 fn deref_mut(&mut self) -> &mut Self::Target {
43 &mut self.0
44 }
45}
46
47impl<V: DeserializeOwned> FromRequest for Query<V> {
48 type Error = ExtractionError;
49 type Future = Ready<Result<Query<V>, Self::Error>>;
50
51 #[inline]
52 fn from_request(req: &HttpRequest, _: &mut HttpPayload) -> Self::Future {
53 let query = req.uri().query().unwrap_or("");
54
55 match Self::from_query(query) {
56 Ok(query) => ok(query),
57 Err(error) => err(error),
58 }
59 }
60}