diff --git a/src/headers/header_values.rs b/src/headers/header_values.rs index d34cec9..27fc004 100644 --- a/src/headers/header_values.rs +++ b/src/headers/header_values.rs @@ -146,6 +146,7 @@ impl AsMut for HeaderValues { &mut self.inner[0] } } + impl Deref for HeaderValues { type Target = HeaderValue; @@ -170,6 +171,22 @@ impl<'a> IntoIterator for &'a HeaderValues { } } +impl From> for HeaderValues { + fn from(headers: Vec) -> Self { + Self { inner: headers } + } +} + +impl IntoIterator for HeaderValues { + type Item = HeaderValue; + type IntoIter = std::vec::IntoIter; + + #[inline] + fn into_iter(self) -> Self::IntoIter { + self.inner.into_iter() + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/hyperium_http.rs b/src/hyperium_http.rs index b423c99..cfea56b 100644 --- a/src/hyperium_http.rs +++ b/src/hyperium_http.rs @@ -1,8 +1,8 @@ // This is the compat file for the "hyperium/http" crate. use crate::headers::{HeaderName, HeaderValue, Headers}; -use crate::{Body, Method, Request, Response, StatusCode, Url, Version}; -use std::convert::TryFrom; +use crate::{Body, Error, Method, Request, Response, StatusCode, Url, Version}; +use std::convert::{TryFrom, TryInto}; use std::str::FromStr; impl From for Method { @@ -54,6 +54,92 @@ impl From for http::Version { } } +impl TryFrom for HeaderName { + type Error = Error; + + fn try_from(name: http::header::HeaderName) -> Result { + let name = name.as_str().as_bytes().to_owned(); + HeaderName::from_bytes(name) + } +} + +impl TryFrom for http::header::HeaderName { + type Error = Error; + + fn try_from(name: HeaderName) -> Result { + let name = name.as_str().as_bytes(); + http::header::HeaderName::from_bytes(name).map_err(|e| Error::new_adhoc(e)) + } +} + +impl TryFrom for HeaderValue { + type Error = Error; + + fn try_from(value: http::header::HeaderValue) -> Result { + let value = value.as_bytes().to_owned(); + HeaderValue::from_bytes(value) + } +} + +impl TryFrom for http::header::HeaderValue { + type Error = Error; + + fn try_from(value: HeaderValue) -> Result { + let value = value.as_str().as_bytes(); + http::header::HeaderValue::from_bytes(value).map_err(|e| Error::new_adhoc(e)) + } +} + +impl TryFrom for Headers { + type Error = Error; + + fn try_from(hyperium_headers: http::HeaderMap) -> Result { + let mut headers = Headers::new(); + + hyperium_headers + .into_iter() + .map(|(name, value)| { + if let Some(name) = name { + let value: HeaderValue = value.try_into()?; + let name: HeaderName = name.try_into()?; + headers.append(name, value); + } + Ok(()) + }) + .collect::, Error>>()?; + + Ok(headers) + } +} + +impl TryFrom for http::HeaderMap { + type Error = Error; + + fn try_from(headers: Headers) -> Result { + let mut hyperium_headers = http::HeaderMap::new(); + + headers + .into_iter() + .map(|(name, values)| { + let name: http::header::HeaderName = name.try_into()?; + + values + .into_iter() + .map(|value| { + let value: http::header::HeaderValue = value.try_into()?; + hyperium_headers.append(&name, value); + Ok(()) + }) + .collect::, Error>>()?; + + Ok(()) + }) + .collect::, Error>>()?; + + Ok(hyperium_headers) + } +} + fn hyperium_headers_to_headers(hyperium_headers: http::HeaderMap, headers: &mut Headers) { for (name, value) in hyperium_headers { let value = value.as_bytes().to_owned();