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:
@@ -6,13 +6,17 @@ use std::str::FromStr;
|
||||
use std::fmt::{self, Display};
|
||||
use url::percent_encoding;
|
||||
|
||||
use header::Raw;
|
||||
use header::shared::Charset;
|
||||
|
||||
/// Reads a single raw string when parsing a header.
|
||||
pub fn from_one_raw_str<T: str::FromStr>(raw: &[Vec<u8>]) -> ::Result<T> {
|
||||
if raw.len() != 1 || unsafe { raw.get_unchecked(0) } == b"" { return Err(::Error::Header) }
|
||||
// we JUST checked that raw.len() == 1, so raw[0] WILL exist.
|
||||
from_raw_str( unsafe { raw.get_unchecked(0) })
|
||||
pub fn from_one_raw_str<T: str::FromStr>(raw: &Raw) -> ::Result<T> {
|
||||
if let Some(line) = raw.one() {
|
||||
if !line.is_empty() {
|
||||
return from_raw_str(line)
|
||||
}
|
||||
}
|
||||
Err(::Error::Header)
|
||||
}
|
||||
|
||||
/// Reads a raw string into a value.
|
||||
@@ -23,7 +27,7 @@ pub fn from_raw_str<T: str::FromStr>(raw: &[u8]) -> ::Result<T> {
|
||||
|
||||
/// Reads a comma-delimited raw header into a Vec.
|
||||
#[inline]
|
||||
pub fn from_comma_delimited<T: str::FromStr, S: AsRef<[u8]>>(raw: &[S]) -> ::Result<Vec<T>> {
|
||||
pub fn from_comma_delimited<T: str::FromStr>(raw: &Raw) -> ::Result<Vec<T>> {
|
||||
let mut result = Vec::new();
|
||||
for s in raw {
|
||||
let s = try!(str::from_utf8(s.as_ref()));
|
||||
|
||||
Reference in New Issue
Block a user