pub mod names;
pub mod standards;
#[cfg(test)]
mod tests;
use std::{
cmp::{Eq, PartialEq},
convert::{TryFrom, TryInto},
ops::{Deref, DerefMut},
};
use indexmap::IndexMap;
pub use names::{HeaderName, InvalidHeaderName};
pub use standards::{Protocol, Standard, StandardHeader, Status};
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub struct HeaderMap(indexmap::IndexMap<HeaderName, String>);
impl std::ops::Index<usize> for HeaderMap {
type Output = str;
#[inline]
fn index(&self, k: usize) -> &Self::Output {
(self.0)[k].as_str()
}
}
impl std::ops::Index<&[u8]> for HeaderMap {
type Output = str;
#[inline]
fn index(&self, k: &[u8]) -> &Self::Output {
(self.0)[&HeaderName::try_from(k).expect("Invalid bytes in header name.")].as_str()
}
}
impl std::ops::Index<&str> for HeaderMap {
type Output = str;
#[inline]
fn index(&self, k: &str) -> &Self::Output {
(self.0)[&HeaderName::try_from(k).expect("Invalid bytes in header name.")].as_str()
}
}
impl std::ops::Index<&HeaderName> for HeaderMap {
type Output = str;
#[inline]
fn index(&self, k: &HeaderName) -> &Self::Output {
(self.0)[k].as_str()
}
}
impl std::ops::Index<HeaderName> for HeaderMap {
type Output = str;
#[inline]
fn index(&self, k: HeaderName) -> &Self::Output {
(self.0)[&k].as_str()
}
}
impl HeaderMap {
#[inline]
pub fn empty() -> Self {
Self::default()
}
#[inline]
pub fn new() -> Self {
Self::default()
}
#[inline]
fn get_mut_inner(&mut self, key: &HeaderName) -> Option<&mut String> {
(self.0).get_mut(key)
}
#[inline]
pub fn get_mut<T: TryInto<HeaderName> + std::fmt::Debug>(
&mut self,
key: T,
) -> Option<&mut String>
where
<T as TryInto<HeaderName>>::Error: std::fmt::Debug,
{
let k = key.try_into().ok()?;
self.get_mut_inner(&k)
}
#[inline]
fn get_inner(&self, key: &HeaderName) -> Option<&str> {
(self.0).get(key).map(|x| x.as_str())
}
#[inline]
pub fn get<T: TryInto<HeaderName> + std::fmt::Debug>(&self, key: T) -> Option<&str>
where
<T as TryInto<HeaderName>>::Error: std::fmt::Debug,
{
let k = key.try_into().ok()?;
self.get_inner(&k)
}
#[inline]
fn contains_key_inner(&self, key: &HeaderName) -> bool {
(self.0).contains_key(key)
}
#[inline]
pub fn contains_key<T: TryInto<HeaderName> + std::fmt::Debug>(&self, key: T) -> bool
where
<T as TryInto<HeaderName>>::Error: std::fmt::Debug,
{
key.try_into()
.ok()
.map(|k| self.contains_key_inner(&k))
.unwrap_or(false)
}
#[inline]
fn remove_inner(&mut self, key: &HeaderName) -> Option<String> {
(self.0).shift_remove(key)
}
#[inline]
pub fn remove<T: TryInto<HeaderName> + std::fmt::Debug>(&mut self, key: T) -> Option<String>
where
<T as TryInto<HeaderName>>::Error: std::fmt::Debug,
{
key.try_into().ok().and_then(|k| self.remove_inner(&k))
}
#[inline]
pub fn into_inner(self) -> indexmap::IndexMap<HeaderName, String> {
self.0
}
}
impl Deref for HeaderMap {
type Target = IndexMap<HeaderName, String>;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for HeaderMap {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}