tosic_http/extractors/
query.rs

1//! Query extractor
2
3use 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)]
11/// The `Query` extractor
12pub struct Query<V>(pub V);
13
14impl<T> Query<T> {
15    #[inline]
16    /// Get the inner value
17    pub fn into_inner(self) -> T {
18        self.0
19    }
20}
21
22impl<T: DeserializeOwned> Query<T> {
23    #[inline]
24    /// Create a new `Query` extractor from the query
25    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}