1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
//! Query extractor use std::{fmt, ops}; use actix_http::error::Error; use serde::de; use serde_urlencoded; use crate::extract::FromRequest; use crate::service::ServiceFromRequest; #[derive(PartialEq, Eq, PartialOrd, Ord)] /// Extract typed information from from the request's query. /// /// ## Example /// /// ```rust /// #[macro_use] extern crate serde_derive; /// use actix_web::{web, App}; /// /// #[derive(Debug, Deserialize)] /// pub enum ResponseType { /// Token, /// Code /// } /// /// #[derive(Deserialize)] /// pub struct AuthRequest { /// id: u64, /// response_type: ResponseType, /// } /// /// // Use `Query` extractor for query information. /// // This handler get called only if request's query contains `username` field /// // The correct request for this handler would be `/index.html?id=64&response_type=Code"` /// fn index(info: web::Query<AuthRequest>) -> String { /// format!("Authorization request for client with id={} and type={:?}!", info.id, info.response_type) /// } /// /// fn main() { /// let app = App::new().service( /// web::resource("/index.html").route(web::get().to(index))); // <- use `Query` extractor /// } /// ``` pub struct Query<T>(T); impl<T> Query<T> { /// Deconstruct to a inner value pub fn into_inner(self) -> T { self.0 } } impl<T> ops::Deref for Query<T> { type Target = T; fn deref(&self) -> &T { &self.0 } } impl<T> ops::DerefMut for Query<T> { fn deref_mut(&mut self) -> &mut T { &mut self.0 } } impl<T: fmt::Debug> fmt::Debug for Query<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.fmt(f) } } impl<T: fmt::Display> fmt::Display for Query<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.fmt(f) } } /// Extract typed information from from the request's query. /// /// ## Example /// /// ```rust /// #[macro_use] extern crate serde_derive; /// use actix_web::{web, App}; /// /// #[derive(Debug, Deserialize)] /// pub enum ResponseType { /// Token, /// Code /// } /// /// #[derive(Deserialize)] /// pub struct AuthRequest { /// id: u64, /// response_type: ResponseType, /// } /// /// // Use `Query` extractor for query information. /// // This handler get called only if request's query contains `username` field /// // The correct request for this handler would be `/index.html?id=64&response_type=Code"` /// fn index(info: web::Query<AuthRequest>) -> String { /// format!("Authorization request for client with id={} and type={:?}!", info.id, info.response_type) /// } /// /// fn main() { /// let app = App::new().service( /// web::resource("/index.html") /// .route(web::get().to(index))); // <- use `Query` extractor /// } /// ``` impl<T, P> FromRequest<P> for Query<T> where T: de::DeserializeOwned, { type Error = Error; type Future = Result<Self, Error>; #[inline] fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future { serde_urlencoded::from_str::<T>(req.query_string()) .map(|val| Ok(Query(val))) .unwrap_or_else(|e| Err(e.into())) } }