initial commit
This commit is contained in:
+119
@@ -0,0 +1,119 @@
|
||||
use crate::header::{Header, parse_header};
|
||||
|
||||
pub trait HeaderMap<'a, H: Header<'a>> {
|
||||
fn get_all_headers(&self, key: &str) -> Vec<&H>;
|
||||
fn get_all_headers_mut(&mut self, key: &str) -> Vec<&mut H>;
|
||||
fn get_first_header(&self, key: &str) -> Option<&H>;
|
||||
fn get_first_header_mut(&mut self, key: &str) -> Option<&mut H>;
|
||||
fn get_all_values(&self, key: &str) -> Vec<String>;
|
||||
fn get_first_value(&self, key: &str) -> Option<String>;
|
||||
fn add_header<K: ToString, V: ToString>(&mut self, key: K, value: V);
|
||||
fn insert_header<K: ToString, V: ToString>(&mut self, key: K, value: V, index: usize);
|
||||
fn replace_header<K: ToString, V: ToString>(&mut self, key: K, value: V, index: usize);
|
||||
fn replace_all_headers<K: ToString, V: ToString>(&mut self, key: K, value: V);
|
||||
fn remove_header(&mut self, key: &str, index: usize);
|
||||
fn remove_all_headers(&mut self, key: &str);
|
||||
}
|
||||
|
||||
impl<'a, H: Header<'a>> HeaderMap<'a, H> for Vec<H> {
|
||||
fn get_all_headers(&self, key: &str) -> Vec<&H> {
|
||||
self.iter().filter(|h| h.get_key().eq_ignore_ascii_case(key)).collect()
|
||||
}
|
||||
|
||||
fn get_all_headers_mut(&mut self, key: &str) -> Vec<&mut H> {
|
||||
self.iter_mut()
|
||||
.filter(|h| h.get_key().eq_ignore_ascii_case(key))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn get_first_header(&self, key: &str) -> Option<&H> {
|
||||
self.iter().find(|h| h.get_key().eq_ignore_ascii_case(key))
|
||||
}
|
||||
|
||||
fn get_first_header_mut(&mut self, key: &str) -> Option<&mut H> {
|
||||
self.iter_mut().find(|h| h.get_key().eq_ignore_ascii_case(key))
|
||||
}
|
||||
|
||||
fn get_all_values(&self, key: &str) -> Vec<String> {
|
||||
self.get_all_headers(key).into_iter().map(|h| h.get_value()).collect()
|
||||
}
|
||||
|
||||
fn get_first_value(&self, key: &str) -> Option<String> {
|
||||
self.get_first_header(key).map(|h| h.get_value())
|
||||
}
|
||||
|
||||
fn add_header<K: ToString, V: ToString>(&mut self, key: K, value: V) {
|
||||
self.push(H::new(key, value))
|
||||
}
|
||||
|
||||
fn insert_header<K: ToString, V: ToString>(&mut self, key: K, value: V, index: usize) {
|
||||
let index = std::cmp::min(index, self.len());
|
||||
let header = H::new(key, value);
|
||||
self.insert(index, header);
|
||||
}
|
||||
|
||||
fn replace_all_headers<K: ToString, V: ToString>(&mut self, key: K, value: V) {
|
||||
let key = key.to_string();
|
||||
for header in self {
|
||||
if !header.get_key().eq_ignore_ascii_case(&key) {
|
||||
continue;
|
||||
}
|
||||
header.set_value(value.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
fn replace_header<K: ToString, V: ToString>(&mut self, key: K, value: V, index: usize) {
|
||||
let key = key.to_string();
|
||||
let mut count: usize = 0;
|
||||
for header in self {
|
||||
if !header.get_key().eq_ignore_ascii_case(&key) {
|
||||
continue;
|
||||
}
|
||||
if count == index {
|
||||
header.set_value(value);
|
||||
break;
|
||||
}
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_all_headers(&mut self, key: &str) {
|
||||
self.retain(|h| !h.get_key().eq_ignore_ascii_case(key));
|
||||
}
|
||||
|
||||
fn remove_header(&mut self, key: &str, index: usize) {
|
||||
if let Some((index, _)) = self
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(move |h| h.1.get_key().eq_ignore_ascii_case(key))
|
||||
.nth(index)
|
||||
{
|
||||
self.remove(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn parse_headers<'a, H: Header<'a>>(raw_data: &'a [u8]) -> Result<(Vec<H>, usize), &'static str> {
|
||||
let mut headers: Vec<H> = Vec::new();
|
||||
let mut ix = 0;
|
||||
loop {
|
||||
if ix >= raw_data.len() {
|
||||
break;
|
||||
} else if raw_data[ix] == b'\n' {
|
||||
ix += 1;
|
||||
break;
|
||||
} else if raw_data[ix] == b'\r' {
|
||||
if ix + 1 < raw_data.len() && raw_data[ix + 1] == b'\n' {
|
||||
ix += 2;
|
||||
break;
|
||||
} else {
|
||||
return Err("Headers were followed by an unexpected lone CR character!");
|
||||
}
|
||||
}
|
||||
let (header, ix_next) = parse_header(&raw_data[ix..]).unwrap();
|
||||
headers.push(header);
|
||||
ix += ix_next;
|
||||
}
|
||||
Ok((headers, ix))
|
||||
}
|
||||
Reference in New Issue
Block a user