actix_web/types/
header.rs1use std::{fmt, ops};
4
5use actix_utils::future::{ready, Ready};
6
7use crate::{
8 dev::Payload, error::ParseError, extract::FromRequest, http::header::Header as ParseHeader,
9 HttpRequest,
10};
11
12#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
27pub struct Header<T>(pub T);
28
29impl<T> Header<T> {
30 pub fn into_inner(self) -> T {
32 self.0
33 }
34}
35
36impl<T> ops::Deref for Header<T> {
37 type Target = T;
38
39 fn deref(&self) -> &T {
40 &self.0
41 }
42}
43
44impl<T> ops::DerefMut for Header<T> {
45 fn deref_mut(&mut self) -> &mut T {
46 &mut self.0
47 }
48}
49
50impl<T> fmt::Display for Header<T>
51where
52 T: fmt::Display,
53{
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 fmt::Display::fmt(&self.0, f)
56 }
57}
58
59impl<T> FromRequest for Header<T>
60where
61 T: ParseHeader,
62{
63 type Error = ParseError;
64 type Future = Ready<Result<Self, Self::Error>>;
65
66 #[inline]
67 fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
68 match ParseHeader::parse(req) {
69 Ok(header) => ready(Ok(Header(header))),
70 Err(err) => ready(Err(err)),
71 }
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78 use crate::{
79 http::{header, Method},
80 test::TestRequest,
81 };
82
83 #[actix_rt::test]
84 async fn test_header_extract() {
85 let (req, mut pl) = TestRequest::default()
86 .insert_header((header::CONTENT_TYPE, mime::APPLICATION_JSON))
87 .insert_header((header::ALLOW, header::Allow(vec![Method::GET])))
88 .to_http_parts();
89
90 let s = Header::<header::ContentType>::from_request(&req, &mut pl)
91 .await
92 .unwrap();
93 assert_eq!(s.into_inner().0, mime::APPLICATION_JSON);
94
95 let s = Header::<header::Allow>::from_request(&req, &mut pl)
96 .await
97 .unwrap();
98 assert_eq!(s.into_inner().0, vec![Method::GET]);
99
100 assert!(Header::<header::Date>::from_request(&req, &mut pl)
101 .await
102 .is_err());
103 }
104}