use crate::{
header::{HeaderKey, HeaderValue},
Header,
};
#[derive(Debug, PartialEq, Clone)]
pub struct Headers<'a> {
headers: Vec<Header<'a>>,
max_value_length: usize,
}
impl<'a> Headers<'a> {
pub fn new() -> Self {
Self {
headers: Vec::new(),
max_value_length: 0,
}
}
pub fn with_capacity(cap: usize) -> Self {
Self {
headers: Vec::with_capacity(cap),
max_value_length: 0,
}
}
pub fn set<'b, K, V>(&mut self, key: K, value: V)
where
'b: 'a,
K: Into<HeaderKey<'a>>,
V: Into<HeaderValue<'a>>,
{
let final_key = key.into();
if let Some(index) = self.find(&final_key) {
self.headers.remove(index);
}
let n_value: HeaderValue = value.into();
let n_value_length = n_value.length();
if n_value_length > self.max_value_length {
self.max_value_length = n_value_length;
}
self.headers.push(Header {
key: final_key,
value: n_value,
});
}
pub fn append<K, V>(&mut self, key: K, value: V)
where
K: Into<HeaderKey<'a>>,
V: Into<HeaderValue<'a>>,
{
let n_value: HeaderValue = value.into();
let n_value_length = n_value.length();
if n_value_length > self.max_value_length {
self.max_value_length = n_value_length;
}
self.headers.push(Header {
key: key.into(),
value: n_value,
})
}
fn find(&self, key: &HeaderKey<'a>) -> Option<usize> {
for (index, pair) in self.headers.iter().enumerate() {
if &pair.key == key {
return Some(index);
}
}
None
}
pub fn remove<K>(&mut self, key: K)
where
K: Into<HeaderKey<'a>>,
{
if let Some(index) = self.find(&key.into()) {
self.headers.remove(index);
}
}
pub fn get<K>(&self, key: K) -> Option<&HeaderValue<'a>>
where
K: Into<HeaderKey<'a>>,
{
self.find(&key.into())
.map(|index| &self.headers.get(index).unwrap().value)
}
pub fn serialize(&self, buf: &mut Vec<u8>) {
for pair in self.headers.iter() {
pair.serialize(buf);
}
}
pub fn get_max_value_size(&self) -> usize {
self.max_value_length
}
pub fn get_header_count(&self) -> usize {
self.headers.len()
}
pub fn to_owned<'refed, 'owned>(&'refed self) -> Headers<'owned> {
let mut n_headers = Vec::with_capacity(self.headers.len());
for tmp in self.headers.iter() {
n_headers.push(tmp.to_owned());
}
Headers {
headers: n_headers,
max_value_length: self.max_value_length,
}
}
}
impl<'a> Default for Headers<'a> {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn headers_add_new() {
let mut headers = Headers::new();
headers.set("test-key", "test-value");
assert_eq!(
vec![Header {
key: HeaderKey::StrRef("test-key"),
value: HeaderValue::StrRef("test-value")
}],
headers.headers
);
}
#[test]
fn headers_add_already_exists() {
let mut headers = Headers::new();
headers.set("test-key", "test-value");
assert_eq!(
vec![Header {
key: HeaderKey::StrRef("test-key"),
value: HeaderValue::StrRef("test-value")
}],
headers.headers
);
headers.set("test-key", "other value");
assert_eq!(
vec![Header {
key: HeaderKey::StrRef("test-key"),
value: HeaderValue::StrRef("other value")
}],
headers.headers
);
}
#[test]
fn headers_remove_existing() {
let mut headers = Headers::new();
headers.set("test-key", "test-value");
assert_eq!(
vec![Header {
key: HeaderKey::StrRef("test-key"),
value: HeaderValue::StrRef("test-value")
}],
headers.headers
);
headers.remove("test-key");
assert_eq!(Vec::<Header>::new(), headers.headers);
}
#[test]
fn headers_remove_non_existing() {
let mut headers = Headers::new();
headers.set("test-key", "test-value");
assert_eq!(
vec![Header {
key: HeaderKey::StrRef("test-key"),
value: HeaderValue::StrRef("test-value")
}],
headers.headers
);
headers.remove("other-key");
assert_eq!(
vec![Header {
key: HeaderKey::StrRef("test-key"),
value: HeaderValue::StrRef("test-value")
}],
headers.headers
);
}
#[test]
fn headers_get_existing() {
let mut headers = Headers::new();
headers.set("test-key", "test-value");
assert_eq!(
vec![Header {
key: HeaderKey::StrRef("test-key"),
value: HeaderValue::StrRef("test-value")
}],
headers.headers
);
assert_eq!(
Some(&HeaderValue::StrRef("test-value")),
headers.get("test-key")
);
}
#[test]
fn headers_get_not_existing() {
let mut headers = Headers::new();
headers.set("test-key", "test-value");
assert_eq!(
vec![Header {
key: HeaderKey::StrRef("test-key"),
value: HeaderValue::StrRef("test-value")
}],
headers.headers
);
assert_eq!(None, headers.get("other-key"));
}
#[test]
fn headers_serialize() {
let mut headers = Headers::new();
headers.set("test-key", "test-value");
assert_eq!(
vec![Header {
key: HeaderKey::StrRef("test-key"),
value: HeaderValue::StrRef("test-value")
}],
headers.headers
);
let result = "test-key: test-value\r\n".as_bytes();
let mut tmp: Vec<u8> = Vec::new();
headers.serialize(&mut tmp);
assert_eq!(result, &tmp);
}
}