Skip to content

Commit 47e103f

Browse files
lovasoaseanmonstar
authored andcommitted
Implement HttpTryFrom<HashMap<String,String>> for HeaderMap (#326)
1 parent 192b172 commit 47e103f

File tree

4 files changed

+65
-6
lines changed

4 files changed

+65
-6
lines changed

src/convert.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use Error;
2-
use header::{HeaderName, HeaderValue};
2+
use header::{HeaderName, HeaderValue, HeaderMap};
33
use method::Method;
44
use sealed::Sealed;
55
use status::StatusCode;
@@ -56,6 +56,7 @@ reflexive! {
5656
Uri,
5757
Method,
5858
StatusCode,
59+
HeaderMap,
5960
HeaderName,
6061
HeaderValue,
6162
Scheme,

src/header/map.rs

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
use super::HeaderValue;
2-
use super::name::{HeaderName, HdrName, InvalidHeaderName};
3-
41
use std::{fmt, mem, ops, ptr, vec};
52
use std::collections::hash_map::RandomState;
6-
use std::hash::{BuildHasher, Hasher, Hash};
3+
use std::collections::HashMap;
4+
use std::hash::{BuildHasher, Hash, Hasher};
75
use std::iter::FromIterator;
86
use std::marker::PhantomData;
97

8+
use convert::{HttpTryFrom, HttpTryInto};
9+
use Error;
10+
11+
use super::HeaderValue;
12+
use super::name::{HdrName, HeaderName, InvalidHeaderName};
13+
1014
pub use self::as_header_name::AsHeaderName;
1115
pub use self::into_header_name::IntoHeaderName;
1216

@@ -23,6 +27,7 @@ pub use self::into_header_name::IntoHeaderName;
2327
/// ```
2428
/// # use http::HeaderMap;
2529
/// # use http::header::{CONTENT_LENGTH, HOST, LOCATION};
30+
/// # use http::HttpTryFrom;
2631
/// let mut headers = HeaderMap::new();
2732
///
2833
/// headers.insert(HOST, "example.com".parse().unwrap());
@@ -1720,6 +1725,43 @@ impl<T> FromIterator<(HeaderName, T)> for HeaderMap<T>
17201725
}
17211726
}
17221727

1728+
/// Convert a collection of tuples into a HeaderMap
1729+
///
1730+
/// # Examples
1731+
///
1732+
/// ```
1733+
/// # use http::{HttpTryFrom, Result, header::HeaderMap};
1734+
/// # use std::collections::HashMap;
1735+
/// let mut headers_hashmap: HashMap<String, String> = vec![
1736+
/// ("X-Custom-Header".to_string(), "my value".to_string()),
1737+
/// ].iter().cloned().collect();
1738+
///
1739+
/// let good_headers: Result<HeaderMap> = HeaderMap::try_from(&headers_hashmap);
1740+
/// assert!(good_headers.is_ok());
1741+
///
1742+
/// headers_hashmap.insert("\r".into(), "\0".into());
1743+
/// let bad_headers: Result<HeaderMap> = HeaderMap::try_from(&headers_hashmap);
1744+
/// assert!(bad_headers.is_err());
1745+
/// ```
1746+
impl<'a, K, V> HttpTryFrom<&'a HashMap<K, V>> for HeaderMap<HeaderValue>
1747+
where
1748+
K: Eq + Hash,
1749+
HeaderName: HttpTryFrom<&'a K>,
1750+
HeaderValue: HttpTryFrom<&'a V>
1751+
{
1752+
type Error = Error;
1753+
1754+
fn try_from(c: &'a HashMap<K, V>) -> Result<Self, Self::Error> {
1755+
c.into_iter()
1756+
.map(|(k, v)| -> ::Result<(HeaderName, HeaderValue)> {
1757+
let name : HeaderName = k.http_try_into()?;
1758+
let value : HeaderValue = v.http_try_into()?;
1759+
Ok((name, value))
1760+
})
1761+
.collect()
1762+
}
1763+
}
1764+
17231765
impl<T> Extend<(Option<HeaderName>, T)> for HeaderMap<T> {
17241766
/// Extend a `HeaderMap` with the contents of another `HeaderMap`.
17251767
///
@@ -3161,7 +3203,7 @@ mod as_header_name {
31613203
use super::{Entry, HdrName, HeaderMap, HeaderName, InvalidHeaderName};
31623204

31633205
/// A marker trait used to identify values that can be used as search keys
3164-
/// to a `HeaderMap`.
3206+
/// to a `HeaderMap`.
31653207
pub trait AsHeaderName: Sealed {}
31663208

31673209
// All methods are on this pub(super) trait, instead of `AsHeaderName`,

src/header/name.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,6 +1775,14 @@ impl<'a> HttpTryFrom<&'a str> for HeaderName {
17751775
}
17761776
}
17771777

1778+
impl<'a> HttpTryFrom<&'a String> for HeaderName {
1779+
type Error = InvalidHeaderName;
1780+
#[inline]
1781+
fn try_from(s: &'a String) -> Result<Self, Self::Error> {
1782+
Self::from_bytes(s.as_bytes())
1783+
}
1784+
}
1785+
17781786
impl<'a> HttpTryFrom<&'a [u8]> for HeaderName {
17791787
type Error = InvalidHeaderName;
17801788
#[inline]

src/header/value.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,14 @@ impl<'a> HttpTryFrom<&'a str> for HeaderValue {
521521
}
522522
}
523523

524+
impl<'a> HttpTryFrom<&'a String> for HeaderValue {
525+
type Error = InvalidHeaderValue;
526+
#[inline]
527+
fn try_from(s: &'a String) -> Result<Self, Self::Error> {
528+
Self::from_bytes(s.as_bytes())
529+
}
530+
}
531+
524532
impl<'a> HttpTryFrom<&'a [u8]> for HeaderValue {
525533
type Error = InvalidHeaderValue;
526534

0 commit comments

Comments
 (0)