From de1be672625071a386afe09cfafe4dfc38b5de62 Mon Sep 17 00:00:00 2001 From: Pyfisch Date: Mon, 16 Feb 2015 19:26:40 +0100 Subject: [PATCH] refactor(headers): Use macros for headers where possible --- src/header/common/accept.rs | 68 +++++++++++--------------- src/header/common/accept_encoding.rs | 25 ++++++---- src/header/common/allow.rs | 23 ++------- src/header/common/content_length.rs | 28 ++--------- src/header/common/content_type.rs | 24 ++------- src/header/common/location.rs | 25 ++-------- src/header/common/mod.rs | 8 +-- src/header/common/referer.rs | 24 ++------- src/header/common/server.rs | 2 - src/header/common/transfer_encoding.rs | 25 ++-------- src/header/common/user_agent.rs | 24 ++------- 11 files changed, 72 insertions(+), 204 deletions(-) diff --git a/src/header/common/accept.rs b/src/header/common/accept.rs index 1e6f0f002a..d07d40adde 100644 --- a/src/header/common/accept.rs +++ b/src/header/common/accept.rs @@ -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>); - -deref!(Accept => Vec>); - -impl header::Header for Accept { - fn header_name() -> &'static str { - "Accept" - } - - fn parse_header(raw: &[Vec]) -> Option { - // TODO: Return */* if no value is given. - parsing::from_comma_delimited(raw).map(Accept) +pub struct Accept(pub Vec>); + +impl_list_header!(Accept, + "Accept", + Vec>); + +#[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); } -} -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); -} diff --git a/src/header/common/accept_encoding.rs b/src/header/common/accept_encoding.rs index 7399d25c1f..4e330058bc 100644 --- a/src/header/common/accept_encoding.rs +++ b/src/header/common/accept_encoding.rs @@ -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>); -#[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); + } } diff --git a/src/header/common/allow.rs b/src/header/common/allow.rs index 57c1234fd9..471a56f37e 100644 --- a/src/header/common/allow.rs +++ b/src/header/common/allow.rs @@ -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); -deref!(Allow => Vec); - -impl Header for Allow { - fn header_name() -> &'static str { - "Allow" - } - - fn parse_header(raw: &[Vec]) -> Option { - 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); #[cfg(test)] mod tests { diff --git a/src/header/common/content_length.rs b/src/header/common/content_length.rs index 4038d49728..f65744ab89 100644 --- a/src/header/common/content_length.rs +++ b/src/header/common/content_length.rs @@ -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]) -> Option { - 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()] }); - diff --git a/src/header/common/content_type.rs b/src/header/common/content_type.rs index 27d1e3dcf9..264ed257b9 100644 --- a/src/header/common/content_type.rs +++ b/src/header/common/content_type.rs @@ -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]) -> Option { - 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()] }); - diff --git a/src/header/common/location.rs b/src/header/common/location.rs index 3397fb74ae..a1232482a2 100644 --- a/src/header/common/location.rs +++ b/src/header/common/location.rs @@ -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]) -> Option { - 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()] }); - diff --git a/src/header/common/mod.rs b/src/header/common/mod.rs index f9bbd0fb7c..9f282db1c8 100644 --- a/src/header/common/mod.rs +++ b/src/header/common/mod.rs @@ -88,7 +88,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 } @@ -98,7 +98,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[]) } @@ -118,7 +118,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 } @@ -128,7 +128,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) } diff --git a/src/header/common/referer.rs b/src/header/common/referer.rs index 873deebe91..4839401538 100644 --- a/src/header/common/referer.rs +++ b/src/header/common/referer.rs @@ -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]) -> Option { - 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()] }); diff --git a/src/header/common/server.rs b/src/header/common/server.rs index 1a649296c0..2b95033e5e 100644 --- a/src/header/common/server.rs +++ b/src/header/common/server.rs @@ -1,5 +1,3 @@ -use header; - /// The `Server` header field. /// /// They can contain any value, so it just wraps a `String`. diff --git a/src/header/common/transfer_encoding.rs b/src/header/common/transfer_encoding.rs index ccad76d2b7..de169d71ae 100644 --- a/src/header/common/transfer_encoding.rs +++ b/src/header/common/transfer_encoding.rs @@ -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); -deref!(TransferEncoding => Vec); - -impl Header for TransferEncoding { - fn header_name() -> &'static str { - "Transfer-Encoding" - } - - fn parse_header(raw: &[Vec]) -> Option { - 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); bench_header!(normal, TransferEncoding, { vec![b"chunked, gzip".to_vec()] }); bench_header!(ext, TransferEncoding, { vec![b"ext".to_vec()] }); diff --git a/src/header/common/user_agent.rs b/src/header/common/user_agent.rs index 38ed8186b8..51112d1fba 100644 --- a/src/header/common/user_agent.rs +++ b/src/header/common/user_agent.rs @@ -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]) -> Option { - 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()] });