#[derive(Debug, Clone, Default)]
pub struct Headers {
fields: Vec<(String, String)>,
}
impl Headers {
pub fn new() -> Headers {
Headers { fields: Vec::new() }
}
pub fn len(&self) -> usize {
self.fields.len()
}
pub fn is_empty(&self) -> bool {
self.fields.is_empty()
}
pub fn append(&mut self, name: impl Into<String>, value: impl Into<String>) {
self.fields.push((name.into(), value.into()));
}
pub fn set(&mut self, name: impl Into<String>, value: impl Into<String>) {
let name = name.into();
self.remove(&name);
self.fields.push((name, value.into()));
}
pub fn set_if_absent(&mut self, name: &str, value: impl Into<String>) {
if self.get(name).is_none() {
self.fields.push((name.to_owned(), value.into()));
}
}
pub fn remove(&mut self, name: &str) {
self.fields.retain(|(k, _)| !k.eq_ignore_ascii_case(name));
}
pub fn get(&self, name: &str) -> Option<&str> {
self.fields
.iter()
.find(|(k, _)| k.eq_ignore_ascii_case(name))
.map(|(_, v)| v.as_str())
}
pub fn get_all<'a>(&'a self, name: &'a str) -> impl Iterator<Item = &'a str> + 'a {
self.fields
.iter()
.filter(move |(k, _)| k.eq_ignore_ascii_case(name))
.map(|(_, v)| v.as_str())
}
pub fn contains(&self, name: &str) -> bool {
self.get(name).is_some()
}
pub fn iter(&self) -> impl Iterator<Item = (&str, &str)> {
self.fields.iter().map(|(k, v)| (k.as_str(), v.as_str()))
}
pub fn contains_token(&self, name: &str, token: &str) -> bool {
self.get_all(name)
.any(|v| v.split(',').any(|t| t.trim().eq_ignore_ascii_case(token)))
}
}