Implement HttpTryFrom<HashMap<String,String>> for HeaderMap (#326)

This commit is contained in:
Ophir LOJKINE
2019-07-25 19:22:13 +02:00
committed by Sean McArthur
parent 291a28912c
commit 7ecbeb03f2
4 changed files with 65 additions and 6 deletions
+2 -1
View File
@@ -1,5 +1,5 @@
use Error;
use header::{HeaderName, HeaderValue};
use header::{HeaderName, HeaderValue, HeaderMap};
use method::Method;
use sealed::Sealed;
use status::StatusCode;
@@ -56,6 +56,7 @@ reflexive! {
Uri,
Method,
StatusCode,
HeaderMap,
HeaderName,
HeaderValue,
Scheme,
+47 -5
View File
@@ -1,12 +1,16 @@
use super::HeaderValue;
use super::name::{HeaderName, HdrName, InvalidHeaderName};
use std::{fmt, mem, ops, ptr, vec};
use std::collections::hash_map::RandomState;
use std::hash::{BuildHasher, Hasher, Hash};
use std::collections::HashMap;
use std::hash::{BuildHasher, Hash, Hasher};
use std::iter::FromIterator;
use std::marker::PhantomData;
use convert::{HttpTryFrom, HttpTryInto};
use Error;
use super::HeaderValue;
use super::name::{HdrName, HeaderName, InvalidHeaderName};
pub use self::as_header_name::AsHeaderName;
pub use self::into_header_name::IntoHeaderName;
@@ -23,6 +27,7 @@ pub use self::into_header_name::IntoHeaderName;
/// ```
/// # use http::HeaderMap;
/// # use http::header::{CONTENT_LENGTH, HOST, LOCATION};
/// # use http::HttpTryFrom;
/// let mut headers = HeaderMap::new();
///
/// headers.insert(HOST, "example.com".parse().unwrap());
@@ -1720,6 +1725,43 @@ impl<T> FromIterator<(HeaderName, T)> for HeaderMap<T>
}
}
/// Convert a collection of tuples into a HeaderMap
///
/// # Examples
///
/// ```
/// # use http::{HttpTryFrom, Result, header::HeaderMap};
/// # use std::collections::HashMap;
/// let mut headers_hashmap: HashMap<String, String> = vec![
/// ("X-Custom-Header".to_string(), "my value".to_string()),
/// ].iter().cloned().collect();
///
/// let good_headers: Result<HeaderMap> = HeaderMap::try_from(&headers_hashmap);
/// assert!(good_headers.is_ok());
///
/// headers_hashmap.insert("\r".into(), "\0".into());
/// let bad_headers: Result<HeaderMap> = HeaderMap::try_from(&headers_hashmap);
/// assert!(bad_headers.is_err());
/// ```
impl<'a, K, V> HttpTryFrom<&'a HashMap<K, V>> for HeaderMap<HeaderValue>
where
K: Eq + Hash,
HeaderName: HttpTryFrom<&'a K>,
HeaderValue: HttpTryFrom<&'a V>
{
type Error = Error;
fn try_from(c: &'a HashMap<K, V>) -> Result<Self, Self::Error> {
c.into_iter()
.map(|(k, v)| -> ::Result<(HeaderName, HeaderValue)> {
let name : HeaderName = k.http_try_into()?;
let value : HeaderValue = v.http_try_into()?;
Ok((name, value))
})
.collect()
}
}
impl<T> Extend<(Option<HeaderName>, T)> for HeaderMap<T> {
/// Extend a `HeaderMap` with the contents of another `HeaderMap`.
///
@@ -3161,7 +3203,7 @@ mod as_header_name {
use super::{Entry, HdrName, HeaderMap, HeaderName, InvalidHeaderName};
/// A marker trait used to identify values that can be used as search keys
/// to a `HeaderMap`.
/// to a `HeaderMap`.
pub trait AsHeaderName: Sealed {}
// All methods are on this pub(super) trait, instead of `AsHeaderName`,
+8
View File
@@ -1775,6 +1775,14 @@ impl<'a> HttpTryFrom<&'a str> for HeaderName {
}
}
impl<'a> HttpTryFrom<&'a String> for HeaderName {
type Error = InvalidHeaderName;
#[inline]
fn try_from(s: &'a String) -> Result<Self, Self::Error> {
Self::from_bytes(s.as_bytes())
}
}
impl<'a> HttpTryFrom<&'a [u8]> for HeaderName {
type Error = InvalidHeaderName;
#[inline]
+8
View File
@@ -521,6 +521,14 @@ impl<'a> HttpTryFrom<&'a str> for HeaderValue {
}
}
impl<'a> HttpTryFrom<&'a String> for HeaderValue {
type Error = InvalidHeaderValue;
#[inline]
fn try_from(s: &'a String) -> Result<Self, Self::Error> {
Self::from_bytes(s.as_bytes())
}
}
impl<'a> HttpTryFrom<&'a [u8]> for HeaderValue {
type Error = InvalidHeaderValue;