diff --git a/src/extract.rs b/src/extract.rs index facd8f54d..921d9fc36 100644 --- a/src/extract.rs +++ b/src/extract.rs @@ -231,45 +231,6 @@ impl FromRequest for () { } } -macro_rules! header_from_req { - ( $( $header:ident ),* ) => { - $( - impl FromRequest for crate::http::header::$header { - type Error = actix_http::error::ParseError; - type Future = Ready>; - type Config = (); - - #[inline] - fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future { - let header = crate::http::header::Header::parse(req); - ready(header) - } - } - )* - }; -} - -header_from_req! { - IfMatch, - IfNoneMatch, - IfRange, - Accept, - AcceptCharset, - AcceptLanguage, - Allow, - CacheControl, - ContentDisposition, - ContentLanguage, - ContentRange, - ContentType, - Date, - ETag, - Expires, - IfModifiedSince, - IfUnmodifiedSince, - LastModified -} - macro_rules! tuple_from_req ({$fut_type:ident, $(($n:tt, $T:ident)),+} => { // This module is a trick to get around the inability of diff --git a/src/types/header.rs b/src/types/header.rs new file mode 100644 index 000000000..61852e9e0 --- /dev/null +++ b/src/types/header.rs @@ -0,0 +1,69 @@ +use std::{fmt, ops}; + +use futures_util::future::{err, ok, Ready}; + +use crate::dev::Payload; +use crate::error::ParseError; +use crate::extract::FromRequest; +use crate::http::header; +use crate::HttpRequest; + +/// Header extractor and responder. +pub struct Header(pub T); + +impl Header { + /// Unwrap into inner `T` value. + pub fn into_inner(self) -> T { + self.0 + } +} + +impl ops::Deref for Header { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +impl ops::DerefMut for Header { + fn deref_mut(&mut self) -> &mut T { + &mut self.0 + } +} + +impl fmt::Debug for Header +where + T: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Header: {:?}", self.0) + } +} + +impl fmt::Display for Header +where + T: fmt::Display, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.0, f) + } +} + +/// See [here](#extractor) for example of usage as an extractor. +impl FromRequest for Header +where + T: header::Header, +{ + type Error = ParseError; + type Future = Ready>; + type Config = (); + + #[inline] + fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future { + match header::Header::parse(req) { + Ok(header) => ok(Header(header)), + Err(e) => err(e), + } + } +} diff --git a/src/types/mod.rs b/src/types/mod.rs index a062c351e..461d771eb 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -3,6 +3,7 @@ // TODO: review visibility mod either; pub(crate) mod form; +mod header; pub(crate) mod json; mod path; pub(crate) mod payload; @@ -11,6 +12,7 @@ pub(crate) mod readlines; pub use self::either::{Either, EitherExtractError}; pub use self::form::{Form, FormConfig}; +pub use self::header::Header; pub use self::json::{Json, JsonConfig}; pub use self::path::{Path, PathConfig}; pub use self::payload::{Payload, PayloadConfig};