Skip to content

Commit

Permalink
refactor(header): make some headers more allocator friendly
Browse files Browse the repository at this point in the history
Change the internal implementation of some simple headers to make them
more allocator friendly. Also add a constructor method to allow changing
the implementation in the future again.

The headers are:

- Location
- Referrer
- Server
- UserAgent

This change was suggested in [hyperium#1104].

BREAKING CHANGES:
- Old code that creates the header structs directly will stop working.
- It's not possible to implement DerefMut for a Cow<'static,str>. Code
that needs to modify header after creation will stop working.
  • Loading branch information
hag committed Apr 8, 2017
1 parent 5c1cfa2 commit f25db1c
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 12 deletions.
6 changes: 3 additions & 3 deletions src/header/common/location.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ header! {
/// use hyper::header::{Headers, Location};
///
/// let mut headers = Headers::new();
/// headers.set(Location("/People.html#tim".to_owned()));
/// headers.set(Location::new("/People.html#tim"));
/// ```
/// ```
/// use hyper::header::{Headers, Location};
///
/// let mut headers = Headers::new();
/// headers.set(Location("http://www.example.com/index.html".to_owned()));
/// headers.set(Location::new("http://www.example.com/index.html"));
/// ```
// TODO: Use URL
(Location, "Location") => [String]
(Location, "Location") => Cow[str]

test_location {
// Testcase from RFC
Expand Down
43 changes: 43 additions & 0 deletions src/header/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,41 @@ macro_rules! header {
}
}
};
// Single value cow header
($(#[$a:meta])*($id:ident, $n:expr) => Cow[$value:ty]) => {
$(#[$a])*
#[derive(Clone, Debug, PartialEq)]
pub struct $id(::std::borrow::Cow<'static,$value>);
impl $id {
/// Creates a new $id
pub fn new<I: Into<::std::borrow::Cow<'static,$value>>>(value: I) -> Self {
$id(value.into())
}
}
impl ::std::ops::Deref for $id {
type Target = ::std::borrow::Cow<'static,$value>;
fn deref(&self) -> &Self::Target {
&(self.0)
}
}
impl $crate::header::Header for $id {
fn header_name() -> &'static str {
static NAME: &'static str = $n;
NAME
}
fn parse_header(raw: &$crate::header::Raw) -> $crate::Result<Self> {
$crate::header::parsing::from_one_raw_str::<<$value as ::std::borrow::ToOwned>::Owned>(raw).map($id::new)
}
fn fmt_header(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
::std::fmt::Display::fmt(&**self, f)
}
}
impl ::std::fmt::Display for $id {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
::std::fmt::Display::fmt(&**self, f)
}
}
};
// List header, one or more items with "*" option
($(#[$a:meta])*($id:ident, $n:expr) => {Any / ($item:ty)+}) => {
$(#[$a])*
Expand Down Expand Up @@ -329,6 +364,14 @@ macro_rules! header {

__hyper__tm! { $id, $tm { $($tf)* }}
};
($(#[$a:meta])*($id:ident, $n:expr) => Cow[$item:ty] $tm:ident{$($tf:item)*}) => {
header! {
$(#[$a])*
($id, $n) => Cow[$item]
}

__hyper__tm! { $id, $tm { $($tf)* }}
};
($(#[$a:meta])*($id:ident, $n:expr) => {Any / ($item:ty)+} $tm:ident{$($tf:item)*}) => {
header! {
$(#[$a])*
Expand Down
6 changes: 3 additions & 3 deletions src/header/common/referer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ header! {
/// use hyper::header::{Headers, Referer};
///
/// let mut headers = Headers::new();
/// headers.set(Referer("/People.html#tim".to_owned()));
/// headers.set(Referer::new("/People.html#tim"));
/// ```
/// ```
/// use hyper::header::{Headers, Referer};
///
/// let mut headers = Headers::new();
/// headers.set(Referer("http://www.example.com/index.html".to_owned()));
/// headers.set(Referer::new("http://www.example.com/index.html"));
/// ```
// TODO Use URL
(Referer, "Referer") => [String]
(Referer, "Referer") => Cow[str]

test_referer {
// Testcase from the RFC
Expand Down
4 changes: 2 additions & 2 deletions src/header/common/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ header! {
/// use hyper::header::{Headers, Server};
///
/// let mut headers = Headers::new();
/// headers.set(Server("hyper/0.5.2".to_owned()));
/// headers.set(Server::new("hyper/0.5.2"));
/// ```
// TODO: Maybe parse as defined in the spec?
(Server, "Server") => [String]
(Server, "Server") => Cow[str]

test_server {
// Testcase from RFC
Expand Down
6 changes: 3 additions & 3 deletions src/header/common/user_agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ header! {
/// use hyper::header::{Headers, UserAgent};
///
/// let mut headers = Headers::new();
/// headers.set(UserAgent("hyper/0.5.2".to_owned()));
/// headers.set(UserAgent::new("hyper/0.5.2"));
/// ```
(UserAgent, "User-Agent") => [String]
(UserAgent, "User-Agent") => Cow[str]

test_user_agent {
// Testcase from RFC
test_header!(test1, vec![b"CERN-LineMode/2.15 libwww/2.17b3"]);
// Own testcase
test_header!(test2, vec![b"Bunnies"], Some(UserAgent("Bunnies".to_owned())));
test_header!(test2, vec![b"Bunnies"], Some(UserAgent::new("Bunnies")));
}
}
2 changes: 1 addition & 1 deletion src/header/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ fn test_get_type() {
use ::header::{ContentLength, UserAgent};

let len = ContentLength(5);
let agent = UserAgent("hyper".to_owned());
let agent = UserAgent::new("hyper");

assert_eq!(TypeId::of::<ContentLength>(), len.get_type());
assert_eq!(TypeId::of::<UserAgent>(), agent.get_type());
Expand Down

0 comments on commit f25db1c

Please sign in to comment.