feat(header): introduce header::Raw (#869)

The Raw type repesents the raw bytes of a header-value.

Having a special type allows a couple of benefits:

- The exact representation has become private, allowing "uglier"
internals. Specifically, since the common case is for a header to only
have 1 line of bytes, an enum is used to skip allocating a Vec for only
1 line. Additionally, a Cow<'static, [u8]> is used, so static bytes
don't require a copy. Finally, since we can use static bytes, when
parsing, we can compare the incoming bytes against a couple of the most
common header-values, and possibly remove another copy.

- As its own type, the `Headers.set_raw` method can be generic over
`Into<Raw>`, which allows for more ergnomic method calls.

BREAKING CHANGE: `Header::parse_header` now receives `&Raw`, instead of
  a `&[Vec<u8>]`. `Raw` provides several methods to ease using it, but
  may require some changes to existing code.
This commit is contained in:
Sean McArthur
2016-07-23 12:54:16 -07:00
committed by GitHub
parent d67dbc6028
commit 50ccdaa7e7
27 changed files with 489 additions and 245 deletions

View File

@@ -1,4 +1,4 @@
use header::{Header, Host};
use header::{Header, Raw, Host};
use std::fmt;
use std::str::FromStr;
use header::parsing::from_one_raw_str;
@@ -57,7 +57,7 @@ impl Header for Origin {
NAME
}
fn parse_header(raw: &[Vec<u8>]) -> ::Result<Origin> {
fn parse_header(raw: &Raw) -> ::Result<Origin> {
from_one_raw_str(raw)
}
@@ -100,10 +100,10 @@ mod tests {
#[test]
fn test_origin() {
let origin = Header::parse_header([b"http://foo.com".to_vec()].as_ref());
let origin = Header::parse_header(&vec![b"http://foo.com".to_vec()].into());
assert_eq!(origin.ok(), Some(Origin::new("http", "foo.com", None)));
let origin = Header::parse_header([b"https://foo.com:443".to_vec()].as_ref());
let origin = Header::parse_header(&vec![b"https://foo.com:443".to_vec()].into());
assert_eq!(origin.ok(), Some(Origin::new("https", "foo.com", Some(443))));
}
}