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; fn get_first_value(&self, key: &str) -> Option; fn add_header(&mut self, key: K, value: V); fn insert_header(&mut self, key: K, value: V, index: usize); fn replace_header(&mut self, key: K, value: V, index: usize); fn replace_all_headers(&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 { 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 { self.get_all_headers(key).into_iter().map(|h| h.get_value()).collect() } fn get_first_value(&self, key: &str) -> Option { self.get_first_header(key).map(|h| h.get_value()) } fn add_header(&mut self, key: K, value: V) { self.push(H::new(key, value)) } fn insert_header(&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(&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(&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, usize), &'static str> { let mut headers: Vec = 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)) }