use actix_web::dev::Payload; use actix_web::{FromRequest, HttpRequest}; use futures_util::future::LocalBoxFuture; use std::future::{Ready, ready}; use std::ops; /// # Async extractor. /// Asynchronous object extractor from a query. pub struct AsyncExtractor(T); impl AsyncExtractor { #[allow(dead_code)] /// Retrieve the object extracted with the extractor. pub fn into_inner(self) -> T { self.0 } } impl ops::Deref for AsyncExtractor { type Target = T; fn deref(&self) -> &Self::Target { &self.0 } } impl ops::DerefMut for AsyncExtractor { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } pub trait FromRequestAsync: Sized { type Error: Into; /// Asynchronous function for extracting data from a query. /// /// returns: Result /// /// # Examples /// /// ``` /// struct User { /// pub id: String, /// pub username: String, /// } /// /// // TODO: Я вообще этот экстрактор не использую, нахуя мне тогда писать пример, если я не ебу как его использовать. Я забыл. /// /// #[get("/")] /// fn get_user_async( /// user: web::AsyncExtractor, /// ) -> web::Json { /// let user = user.into_inner(); /// /// web::Json(user) /// } /// ``` async fn from_request_async( req: &HttpRequest, payload: &mut Payload, ) -> Result; } impl FromRequest for AsyncExtractor { type Error = T::Error; type Future = LocalBoxFuture<'static, Result>; fn from_request(req: &HttpRequest, _payload: &mut Payload) -> Self::Future { let req = req.clone(); let mut payload = Payload::None; Box::pin(async move { T::from_request_async(&req, &mut payload) .await .map(|res| Self(res)) }) } } /// # Sync extractor. /// Synchronous object extractor from a query. pub struct SyncExtractor(T); impl SyncExtractor { /// Retrieving an object extracted with the extractor. #[allow(unused)] pub fn into_inner(self) -> T { self.0 } } impl ops::Deref for SyncExtractor { type Target = T; fn deref(&self) -> &Self::Target { &self.0 } } impl ops::DerefMut for SyncExtractor { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } pub trait FromRequestSync: Sized { type Error: Into; /// Synchronous function for extracting data from a query. /// /// returns: Result /// /// # Examples /// /// ``` /// struct User { /// pub id: String, /// pub username: String, /// } /// /// impl FromRequestSync for User { /// type Error = actix_web::Error; /// /// fn from_request_sync(req: &HttpRequest, _: &mut Payload) -> Result { /// // do magic here. /// /// Ok(User { /// id: "qwerty".to_string(), /// username: "n08i40k".to_string() /// }) /// } /// } /// /// #[get("/")] /// fn get_user_sync( /// user: web::SyncExtractor, /// ) -> web::Json { /// let user = user.into_inner(); /// /// web::Json(user) /// } /// ``` fn from_request_sync(req: &HttpRequest, payload: &mut Payload) -> Result; } impl FromRequest for SyncExtractor { type Error = T::Error; type Future = Ready>; fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future { ready(T::from_request_sync(req, payload).map(|res| Self(res))) } }