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:
@@ -1,6 +1,6 @@
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use header::Header;
|
||||
use header::{Header, Raw};
|
||||
use header::parsing::{from_comma_delimited, fmt_comma_delimited};
|
||||
|
||||
/// `Cache-Control` header, defined in [RFC7234](https://tools.ietf.org/html/rfc7234#section-5.2)
|
||||
@@ -55,7 +55,7 @@ impl Header for CacheControl {
|
||||
NAME
|
||||
}
|
||||
|
||||
fn parse_header(raw: &[Vec<u8>]) -> ::Result<CacheControl> {
|
||||
fn parse_header(raw: &Raw) -> ::Result<CacheControl> {
|
||||
let directives = try!(from_comma_delimited(raw));
|
||||
if !directives.is_empty() {
|
||||
Ok(CacheControl(directives))
|
||||
@@ -167,27 +167,27 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_parse_multiple_headers() {
|
||||
let cache = Header::parse_header(&[b"no-cache".to_vec(), b"private".to_vec()]);
|
||||
let cache = Header::parse_header(&vec![b"no-cache".to_vec(), b"private".to_vec()].into());
|
||||
assert_eq!(cache.ok(), Some(CacheControl(vec![CacheDirective::NoCache,
|
||||
CacheDirective::Private])))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_argument() {
|
||||
let cache = Header::parse_header(&[b"max-age=100, private".to_vec()]);
|
||||
let cache = Header::parse_header(&vec![b"max-age=100, private".to_vec()].into());
|
||||
assert_eq!(cache.ok(), Some(CacheControl(vec![CacheDirective::MaxAge(100),
|
||||
CacheDirective::Private])))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_quote_form() {
|
||||
let cache = Header::parse_header(&[b"max-age=\"200\"".to_vec()]);
|
||||
let cache = Header::parse_header(&vec![b"max-age=\"200\"".to_vec()].into());
|
||||
assert_eq!(cache.ok(), Some(CacheControl(vec![CacheDirective::MaxAge(200)])))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_extension() {
|
||||
let cache = Header::parse_header(&[b"foo, bar=baz".to_vec()]);
|
||||
let cache = Header::parse_header(&vec![b"foo, bar=baz".to_vec()].into());
|
||||
assert_eq!(cache.ok(), Some(CacheControl(vec![
|
||||
CacheDirective::Extension("foo".to_owned(), None),
|
||||
CacheDirective::Extension("bar".to_owned(), Some("baz".to_owned()))])))
|
||||
@@ -195,7 +195,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_parse_bad_syntax() {
|
||||
let cache: ::Result<CacheControl> = Header::parse_header(&[b"foo=".to_vec()]);
|
||||
let cache: ::Result<CacheControl> = Header::parse_header(&vec![b"foo=".to_vec()].into());
|
||||
assert_eq!(cache.ok(), None)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user