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