1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-30 18:44:35 +01:00
actix-web/src/types/header.rs

113 lines
2.6 KiB
Rust
Raw Normal View History

//! For header extractor helper documentation, see [`Header`](crate::types::Header).
use std::{fmt, ops};
use actix_utils::future::{err, ok, Ready};
use crate::{
dev::Payload, error::ParseError, extract::FromRequest, http::header::Header as ParseHeader,
HttpRequest,
};
/// Extract typed headers from the request.
///
/// To extract a header, the inner type `T` must implement the
/// [`Header`](crate::http::header::Header) trait.
///
/// # Examples
/// ```
/// use actix_web::{get, web, http::header};
///
/// #[get("/")]
/// async fn index(date: web::Header<header::Date>) -> String {
/// format!("Request was sent at {}", date.to_string())
/// }
/// ```
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Header<T>(pub T);
impl<T> Header<T> {
/// Unwrap into the inner `T` value.
pub fn into_inner(self) -> T {
self.0
}
}
impl<T> ops::Deref for Header<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}
impl<T> ops::DerefMut for Header<T> {
fn deref_mut(&mut self) -> &mut T {
&mut self.0
}
}
impl<T> fmt::Debug for Header<T>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Header: {:?}", self.0)
}
}
impl<T> fmt::Display for Header<T>
where
T: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
impl<T> FromRequest for Header<T>
where
T: ParseHeader,
{
type Error = ParseError;
type Future = Ready<Result<Self, Self::Error>>;
type Config = ();
#[inline]
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
match ParseHeader::parse(req) {
Ok(header) => ok(Header(header)),
Err(e) => err(e),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::http::{header, Method};
use crate::test::TestRequest;
#[actix_rt::test]
async fn test_header_extract() {
let (req, mut pl) = TestRequest::default()
.insert_header((header::CONTENT_TYPE, mime::APPLICATION_JSON))
.insert_header((header::ALLOW, header::Allow(vec![Method::GET])))
.to_http_parts();
let s = Header::<header::ContentType>::from_request(&req, &mut pl)
.await
.unwrap();
assert_eq!(s.into_inner().0, mime::APPLICATION_JSON);
let s = Header::<header::Allow>::from_request(&req, &mut pl)
.await
.unwrap();
assert_eq!(s.into_inner().0, vec![Method::GET]);
assert!(Header::<header::Date>::from_request(&req, &mut pl)
.await
.is_err());
}
}