Merge pull request #321 from pyfisch/refactorheaders
refactor(headers): Use macros for headers where possible
This commit is contained in:
		| @@ -1,9 +1,6 @@ | ||||
| use std::fmt; | ||||
| use mime::Mime; | ||||
|  | ||||
| use header; | ||||
| use header::parsing; | ||||
|  | ||||
| use mime; | ||||
| use header::QualityItem; | ||||
|  | ||||
| /// The `Accept` header. | ||||
| /// | ||||
| @@ -26,43 +23,36 @@ use mime; | ||||
| ///     qitem(Mime(Text, Xml, vec![])) ])); | ||||
| /// ``` | ||||
| #[derive(Clone, PartialEq, Debug)] | ||||
| pub struct Accept(pub Vec<header::QualityItem<mime::Mime>>); | ||||
| pub struct Accept(pub Vec<QualityItem<Mime>>); | ||||
|  | ||||
| deref!(Accept => Vec<header::QualityItem<mime::Mime>>); | ||||
| impl_list_header!(Accept, | ||||
|                   "Accept", | ||||
|                   Vec<QualityItem<Mime>>); | ||||
|  | ||||
| impl header::Header for Accept { | ||||
|     fn header_name() -> &'static str { | ||||
|         "Accept" | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use mime::*; | ||||
|  | ||||
|     use header::{Header, QualityItem, qitem}; | ||||
|     use super::Accept; | ||||
|  | ||||
|     #[test] | ||||
|     fn test_parse_header_no_quality() { | ||||
|         let a: Accept = Header::parse_header([b"text/plain; charset=utf-8".to_vec()].as_slice()).unwrap(); | ||||
|         let b = Accept(vec![ | ||||
|             qitem(Mime(TopLevel::Text, SubLevel::Plain, vec![(Attr::Charset, Value::Utf8)])), | ||||
|         ]); | ||||
|         assert_eq!(a, b); | ||||
|     } | ||||
|  | ||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<Accept> { | ||||
|         // TODO: Return */* if no value is given. | ||||
|         parsing::from_comma_delimited(raw).map(Accept) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl header::HeaderFormat for Accept { | ||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||
|         parsing::fmt_comma_delimited(fmt, &self[]) | ||||
|     #[test] | ||||
|     fn test_parse_header_with_quality() { | ||||
|         let a: Accept = Header::parse_header([b"text/plain; charset=utf-8; q=0.5".to_vec()].as_slice()).unwrap(); | ||||
|         let b = Accept(vec![ | ||||
|             QualityItem::new(Mime(TopLevel::Text, SubLevel::Plain, vec![(Attr::Charset, Value::Utf8)]), 0.5f32), | ||||
|         ]); | ||||
|         assert_eq!(a, b); | ||||
|     } | ||||
| } | ||||
|  | ||||
| bench_header!(bench, Accept, { vec![b"text/plain; q=0.5, text/html".to_vec()] }); | ||||
|  | ||||
| #[test] | ||||
| fn test_parse_header_no_quality() { | ||||
|     let a: Accept = header::Header::parse_header([b"text/plain; charset=utf-8".to_vec()].as_slice()).unwrap(); | ||||
|     let b = Accept(vec![ | ||||
|         header::QualityItem{item: mime::Mime(mime::TopLevel::Text, mime::SubLevel::Plain, vec![(mime::Attr::Charset, mime::Value::Utf8)]), quality: 1f32}, | ||||
|     ]); | ||||
|     assert_eq!(a, b); | ||||
| } | ||||
|  | ||||
| #[test] | ||||
| fn test_parse_header_with_quality() { | ||||
|     let a: Accept = header::Header::parse_header([b"text/plain; charset=utf-8; q=0.5".to_vec()].as_slice()).unwrap(); | ||||
|     let b = Accept(vec![ | ||||
|         header::QualityItem{item: mime::Mime(mime::TopLevel::Text, mime::SubLevel::Plain, vec![(mime::Attr::Charset, mime::Value::Utf8)]), quality: 0.5f32}, | ||||
|     ]); | ||||
|     assert_eq!(a, b); | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| use header::{self, Encoding, QualityItem}; | ||||
| use header::{Encoding, QualityItem}; | ||||
|  | ||||
| /// The `Accept-Encoding` header | ||||
| /// | ||||
| @@ -11,12 +11,19 @@ impl_list_header!(AcceptEncoding, | ||||
|                   "Accept-Encoding", | ||||
|                   Vec<QualityItem<Encoding>>); | ||||
|  | ||||
| #[test] | ||||
| fn test_parse_header() { | ||||
|     let a: AcceptEncoding = header::Header::parse_header([b"gzip;q=1.0, identity; q=0.5".to_vec()].as_slice()).unwrap(); | ||||
|     let b = AcceptEncoding(vec![ | ||||
|         QualityItem{item: Encoding::Gzip, quality: 1f32}, | ||||
|         QualityItem{item: Encoding::Identity, quality: 0.5f32}, | ||||
|     ]); | ||||
|     assert_eq!(a, b); | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use header::{Encoding, Header, QualityItem}; | ||||
|  | ||||
|     use super::*; | ||||
|  | ||||
|     #[test] | ||||
|     fn test_parse_header() { | ||||
|         let a: AcceptEncoding = Header::parse_header([b"gzip;q=1.0, identity; q=0.5".to_vec()].as_slice()).unwrap(); | ||||
|         let b = AcceptEncoding(vec![ | ||||
|             QualityItem{item: Encoding::Gzip, quality: 1f32}, | ||||
|             QualityItem{item: Encoding::Identity, quality: 0.5f32}, | ||||
|         ]); | ||||
|         assert_eq!(a, b); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,4 @@ | ||||
| use header::{Header, HeaderFormat}; | ||||
| use method::Method; | ||||
| use std::fmt::{self}; | ||||
| use header::parsing::{from_comma_delimited, fmt_comma_delimited}; | ||||
|  | ||||
| /// The `Allow` header. | ||||
| /// See also https://tools.ietf.org/html/rfc7231#section-7.4.1 | ||||
| @@ -9,23 +6,9 @@ use header::parsing::{from_comma_delimited, fmt_comma_delimited}; | ||||
| #[derive(Clone, PartialEq, Debug)] | ||||
| pub struct Allow(pub Vec<Method>); | ||||
|  | ||||
| deref!(Allow => Vec<Method>); | ||||
|  | ||||
| impl Header for Allow { | ||||
|     fn header_name() -> &'static str { | ||||
|         "Allow" | ||||
|     } | ||||
|  | ||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<Allow> { | ||||
|         from_comma_delimited(raw).map(|vec| Allow(vec)) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl HeaderFormat for Allow { | ||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||
|         fmt_comma_delimited(fmt, &self[]) | ||||
|     } | ||||
| } | ||||
| impl_list_header!(Allow, | ||||
|                   "Allow", | ||||
|                   Vec<Method>); | ||||
|  | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|   | ||||
| @@ -1,31 +1,11 @@ | ||||
| use std::fmt; | ||||
|  | ||||
| use header::{Header, HeaderFormat}; | ||||
| use header::parsing::from_one_raw_str; | ||||
|  | ||||
| /// The `Content-Length` header. | ||||
| /// | ||||
| /// Simply a wrapper around a `usize`. | ||||
| /// Simply a wrapper around a `u64`. | ||||
| #[derive(Copy, Clone, PartialEq, Debug)] | ||||
| pub struct ContentLength(pub u64); | ||||
|  | ||||
| deref!(ContentLength => u64); | ||||
|  | ||||
| impl Header for ContentLength { | ||||
|     fn header_name() -> &'static str { | ||||
|         "Content-Length" | ||||
|     } | ||||
|  | ||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<ContentLength> { | ||||
|         from_one_raw_str(raw).map(|u| ContentLength(u)) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl HeaderFormat for ContentLength { | ||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||
|        fmt::Display::fmt(&self.0, fmt) | ||||
|     } | ||||
| } | ||||
| impl_header!(ContentLength, | ||||
|              "Content-Length", | ||||
|              u64); | ||||
|  | ||||
| bench_header!(bench, ContentLength, { vec![b"42349984".to_vec()] }); | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,3 @@ | ||||
| use header::{Header, HeaderFormat}; | ||||
| use std::fmt; | ||||
| use header::parsing::from_one_raw_str; | ||||
| use mime::Mime; | ||||
|  | ||||
| /// The `Content-Type` header. | ||||
| @@ -10,23 +7,8 @@ use mime::Mime; | ||||
| #[derive(Clone, PartialEq, Debug)] | ||||
| pub struct ContentType(pub Mime); | ||||
|  | ||||
| deref!(ContentType => Mime); | ||||
|  | ||||
| impl Header for ContentType { | ||||
|     fn header_name() -> &'static str { | ||||
|         "Content-Type" | ||||
|     } | ||||
|  | ||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<ContentType> { | ||||
|         from_one_raw_str(raw).map(|mime| ContentType(mime)) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl HeaderFormat for ContentType { | ||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||
|         fmt::Display::fmt(&self.0, fmt) | ||||
|     } | ||||
| } | ||||
| impl_header!(ContentType, | ||||
|              "Content-Type", | ||||
|              Mime); | ||||
|  | ||||
| bench_header!(bench, ContentType, { vec![b"application/json; charset=utf-8".to_vec()] }); | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,3 @@ | ||||
| use header::{Header, HeaderFormat}; | ||||
| use std::fmt; | ||||
| use header::parsing::from_one_raw_str; | ||||
|  | ||||
| /// The `Location` header. | ||||
| /// | ||||
| /// The Location response-header field is used to redirect the recipient to | ||||
| @@ -16,23 +12,8 @@ use header::parsing::from_one_raw_str; | ||||
| #[derive(Clone, PartialEq, Debug)] | ||||
| pub struct Location(pub String); | ||||
|  | ||||
| deref!(Location => String); | ||||
|  | ||||
| impl Header for Location { | ||||
|     fn header_name() -> &'static str { | ||||
|         "Location" | ||||
|     } | ||||
|  | ||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<Location> { | ||||
|         from_one_raw_str(raw).map(|s| Location(s)) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl HeaderFormat for Location { | ||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||
|         fmt.write_str(&*self.0) | ||||
|     } | ||||
| } | ||||
| impl_header!(Location, | ||||
|              "Location", | ||||
|              String); | ||||
|  | ||||
| bench_header!(bench, Location, { vec![b"http://foo.com/hello:3000".to_vec()] }); | ||||
|  | ||||
|   | ||||
| @@ -90,7 +90,7 @@ macro_rules! impl_list_header( | ||||
|     ($from:ident, $name:expr, $item:ty) => { | ||||
|         deref!($from => $item); | ||||
|  | ||||
|         impl header::Header for $from { | ||||
|         impl $crate::header::Header for $from { | ||||
|             fn header_name() -> &'static str { | ||||
|                 $name | ||||
|             } | ||||
| @@ -100,7 +100,7 @@ macro_rules! impl_list_header( | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         impl header::HeaderFormat for $from { | ||||
|         impl $crate::header::HeaderFormat for $from { | ||||
|             fn fmt_header(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { | ||||
|                 $crate::header::parsing::fmt_comma_delimited(fmt, &self[]) | ||||
|             } | ||||
| @@ -120,7 +120,7 @@ macro_rules! impl_header( | ||||
|     ($from:ident, $name:expr, $item:ty) => { | ||||
|         deref!($from => $item); | ||||
|  | ||||
|         impl header::Header for $from { | ||||
|         impl $crate::header::Header for $from { | ||||
|             fn header_name() -> &'static str { | ||||
|                 $name | ||||
|             } | ||||
| @@ -130,7 +130,7 @@ macro_rules! impl_header( | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         impl header::HeaderFormat for $from { | ||||
|         impl $crate::header::HeaderFormat for $from { | ||||
|             fn fmt_header(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { | ||||
|                 ::std::fmt::Display::fmt(&**self, f) | ||||
|             } | ||||
|   | ||||
| @@ -1,7 +1,3 @@ | ||||
| use header::{Header, HeaderFormat}; | ||||
| use std::fmt; | ||||
| use header::parsing::from_one_raw_str; | ||||
|  | ||||
| /// The `Referer` header. | ||||
| /// | ||||
| /// The Referer header is used by user agents to inform server about | ||||
| @@ -13,22 +9,8 @@ use header::parsing::from_one_raw_str; | ||||
| #[derive(Clone, PartialEq, Debug)] | ||||
| pub struct Referer(pub String); | ||||
|  | ||||
| deref!(Referer => String); | ||||
|  | ||||
| impl Header for Referer { | ||||
|     fn header_name() -> &'static str { | ||||
|         "Referer" | ||||
|     } | ||||
|  | ||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<Referer> { | ||||
|         from_one_raw_str(raw).map(|s| Referer(s)) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl HeaderFormat for Referer { | ||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||
|         fmt::Display::fmt(&self.0, fmt) | ||||
|     } | ||||
| } | ||||
| impl_header!(Referer, | ||||
|              "Referer", | ||||
|              String); | ||||
|  | ||||
| bench_header!(bench, Referer, { vec![b"http://foo.com/hello:3000".to_vec()] }); | ||||
|   | ||||
| @@ -1,5 +1,3 @@ | ||||
| use header; | ||||
|  | ||||
| /// The `Server` header field. | ||||
| /// | ||||
| /// They can contain any value, so it just wraps a `String`. | ||||
|   | ||||
| @@ -1,7 +1,4 @@ | ||||
| use header::{Header, HeaderFormat}; | ||||
| use std::fmt; | ||||
| use header::Encoding; | ||||
| use header::parsing::{from_comma_delimited, fmt_comma_delimited}; | ||||
| use header::{self, Encoding}; | ||||
|  | ||||
| /// The `Transfer-Encoding` header. | ||||
| /// | ||||
| @@ -19,23 +16,9 @@ use header::parsing::{from_comma_delimited, fmt_comma_delimited}; | ||||
| #[derive(Clone, PartialEq, Debug)] | ||||
| pub struct TransferEncoding(pub Vec<Encoding>); | ||||
|  | ||||
| deref!(TransferEncoding => Vec<Encoding>); | ||||
|  | ||||
| impl Header for TransferEncoding { | ||||
|     fn header_name() -> &'static str { | ||||
|         "Transfer-Encoding" | ||||
|     } | ||||
|  | ||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<TransferEncoding> { | ||||
|         from_comma_delimited(raw).map(TransferEncoding) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl HeaderFormat for TransferEncoding { | ||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||
|         fmt_comma_delimited(fmt, &self[]) | ||||
|     } | ||||
| } | ||||
| impl_list_header!(TransferEncoding, | ||||
|                   "Transfer-Encoding", | ||||
|                   Vec<Encoding>); | ||||
|  | ||||
| bench_header!(normal, TransferEncoding, { vec![b"chunked, gzip".to_vec()] }); | ||||
| bench_header!(ext, TransferEncoding, { vec![b"ext".to_vec()] }); | ||||
|   | ||||
| @@ -1,30 +1,12 @@ | ||||
| use header::{Header, HeaderFormat}; | ||||
| use std::fmt; | ||||
| use header::parsing::from_one_raw_str; | ||||
|  | ||||
| /// The `User-Agent` header field. | ||||
| /// | ||||
| /// They can contain any value, so it just wraps a `String`. | ||||
| #[derive(Clone, PartialEq, Debug)] | ||||
| pub struct UserAgent(pub String); | ||||
|  | ||||
| deref!(UserAgent => String); | ||||
|  | ||||
| impl Header for UserAgent { | ||||
|     fn header_name() -> &'static str { | ||||
|         "User-Agent" | ||||
|     } | ||||
|  | ||||
|     fn parse_header(raw: &[Vec<u8>]) -> Option<UserAgent> { | ||||
|         from_one_raw_str(raw).map(|s| UserAgent(s)) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl HeaderFormat for UserAgent { | ||||
|     fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||||
|         fmt.write_str(&*self.0) | ||||
|     } | ||||
| } | ||||
| impl_header!(UserAgent, | ||||
|              "User-Agent", | ||||
|              String); | ||||
|  | ||||
| bench_header!(bench, UserAgent, { vec![b"cargo bench".to_vec()] }); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user