use core::iter::{FromIterator, FusedIterator};
use core::str;
pub use crate::abi::proxy_wasm::types::ByteString;
#[derive(Debug, Default, Clone, Eq, PartialEq)]
pub struct HeaderMap {
entries: Vec<(ByteString, ByteString)>,
}
impl HeaderMap {
fn from_entries(entries: Vec<(ByteString, ByteString)>) -> Self {
HeaderMap { entries }
}
pub fn builder() -> HeaderMapBuilder {
HeaderMapBuilder::new()
}
pub fn new() -> Self {
Self::default()
}
pub fn with_capacity(capacity: usize) -> Self {
HeaderMap {
entries: Vec::with_capacity(capacity),
}
}
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
pub fn len(&self) -> usize {
self.entries.len()
}
pub fn as_slice(&self) -> &[(ByteString, ByteString)] {
self.entries.as_slice()
}
pub fn into_vec(self) -> Vec<(ByteString, ByteString)> {
self.entries
}
pub fn iter(&self) -> Iter<'_> {
Iter {
inner: self.entries.iter(),
}
}
pub fn get<Q>(&self, key: Q) -> Option<&ByteString>
where
Q: AsRef<[u8]>,
{
for i in 0..self.entries.len() {
if self.entries[i].0 == key.as_ref() {
return Some(&self.entries[i].1);
}
}
None
}
pub fn insert<K, V>(&mut self, key: K, value: V) -> Option<ByteString>
where
K: Into<ByteString>,
V: Into<ByteString>,
{
self.entries.push((key.into(), value.into()));
for i in 0..self.entries.len() - 1 {
if self.entries[i].0 == self.entries[self.entries.len() - 1].0 {
return Some(self.entries.swap_remove(i).1);
}
}
None
}
pub fn remove<Q>(&mut self, key: Q) -> Option<ByteString>
where
Q: AsRef<[u8]>,
{
for i in 0..self.entries.len() {
if self.entries[i].0 == key.as_ref() {
return Some(self.entries.remove(i).1);
}
}
None
}
}
#[derive(Debug, Default)]
pub struct HeaderMapBuilder {
map: HeaderMap,
}
impl HeaderMapBuilder {
pub fn new() -> Self {
HeaderMapBuilder::default()
}
pub fn header<K, V>(mut self, name: K, value: V) -> Self
where
K: Into<ByteString>,
V: Into<ByteString>,
{
self.map.insert(name, value);
self
}
pub fn build(self) -> HeaderMap {
self.map
}
}
impl<'a> IntoIterator for &'a HeaderMap {
type Item = (&'a ByteString, &'a ByteString);
type IntoIter = Iter<'a>;
fn into_iter(self) -> Iter<'a> {
self.iter()
}
}
#[derive(Debug)]
pub struct Iter<'a> {
inner: std::slice::Iter<'a, (ByteString, ByteString)>,
}
impl<'a> Iterator for Iter<'a> {
type Item = (&'a ByteString, &'a ByteString);
fn next(&mut self) -> Option<Self::Item> {
self.inner
.next()
.map(|&(ref name, ref value)| (name, value))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<'a> FusedIterator for Iter<'a> {}
impl IntoIterator for HeaderMap {
type Item = (ByteString, ByteString);
type IntoIter = IntoIter;
fn into_iter(self) -> IntoIter {
IntoIter {
inner: self.entries.into_iter(),
}
}
}
pub struct IntoIter {
inner: std::vec::IntoIter<(ByteString, ByteString)>,
}
impl Iterator for IntoIter {
type Item = (ByteString, ByteString);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl FusedIterator for IntoIter {}
impl FromIterator<(ByteString, ByteString)> for HeaderMap {
fn from_iter<T: IntoIterator<Item = (ByteString, ByteString)>>(iter: T) -> Self {
let iterator = iter.into_iter();
let (lower, _) = iterator.size_hint();
let mut headers = Self::with_capacity(lower);
for (name, value) in iterator {
headers.insert(name, value);
}
headers
}
}
impl<'a> FromIterator<&'a (&'a str, &'a str)> for HeaderMap {
fn from_iter<T: IntoIterator<Item = &'a (&'a str, &'a str)>>(iter: T) -> Self {
let iterator = iter.into_iter();
let (lower, _) = iterator.size_hint();
let mut headers = Self::with_capacity(lower);
for (name, value) in iterator {
headers.insert(*name, *value);
}
headers
}
}
impl From<&HeaderMap> for HeaderMap {
fn from(other: &HeaderMap) -> Self {
other.clone()
}
}
impl From<Vec<(ByteString, ByteString)>> for HeaderMap {
fn from(entries: Vec<(ByteString, ByteString)>) -> Self {
Self::from_entries(entries)
}
}
impl From<&[(&str, &str)]> for HeaderMap {
fn from(entries: &[(&str, &str)]) -> Self {
Self::from_entries(
entries
.iter()
.map(|(name, value)| ((*name).into(), (*value).to_owned().into()))
.collect(),
)
}
}