1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
use buildstructor::buildstructor;
use derive_more::From;
use http::header::{HeaderName, CONTENT_TYPE};
use http::{HeaderMap, HeaderValue};
use multimap::MultiMap;
use std::error::Error;
pub struct Collections {
headers: HeaderMap,
}
#[buildstructor]
impl Collections {
#[builder]
fn new(
headers: MultiMap<IntoHeaderName, IntoHeaderValue>,
) -> Result<Collections, Box<dyn Error>> {
let mut valid_headers = HeaderMap::new();
for (key, values) in headers {
let header_name: HeaderName = key.try_into()?;
for value in values {
let header_value: HeaderValue = value.try_into()?;
valid_headers.insert(header_name.clone(), header_value);
}
}
Ok(Self {
headers: valid_headers,
})
}
}
#[derive(From, Eq, Hash, PartialEq)]
pub enum IntoHeaderName {
String(String),
HeaderName(HeaderName),
}
#[derive(From, Eq, Hash, PartialEq)]
pub enum IntoHeaderValue {
String(String),
HeaderValue(HeaderValue),
}
impl From<&str> for IntoHeaderName {
fn from(name: &str) -> Self {
IntoHeaderName::String(name.to_string())
}
}
impl From<&str> for IntoHeaderValue {
fn from(value: &str) -> Self {
IntoHeaderValue::String(value.to_string())
}
}
impl TryFrom<IntoHeaderName> for HeaderName {
type Error = Box<dyn Error>;
fn try_from(value: IntoHeaderName) -> Result<Self, Self::Error> {
Ok(match value {
IntoHeaderName::String(name) => HeaderName::try_from(name)?,
IntoHeaderName::HeaderName(name) => name,
})
}
}
impl TryFrom<IntoHeaderValue> for HeaderValue {
type Error = Box<dyn Error>;
fn try_from(value: IntoHeaderValue) -> Result<Self, Self::Error> {
Ok(match value {
IntoHeaderValue::String(value) => HeaderValue::try_from(value)?,
IntoHeaderValue::HeaderValue(value) => value,
})
}
}
fn main() {
let collections = Collections::builder()
.header("foo", "bar")
.header(CONTENT_TYPE, "html")
.header("bif".to_string(), "baz".to_string())
.build()
.unwrap();
assert_eq!(
collections.headers.get("foo").unwrap(),
HeaderValue::from_static("bar")
);
assert_eq!(
collections.headers.get(CONTENT_TYPE).unwrap(),
HeaderValue::from_static("html")
);
assert_eq!(
collections.headers.get("bif").unwrap(),
HeaderValue::from_static("baz")
);
}
|