diff options
Diffstat (limited to 'sip/src/encoding/headermap.rs')
-rw-r--r-- | sip/src/encoding/headermap.rs | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/sip/src/encoding/headermap.rs b/sip/src/encoding/headermap.rs new file mode 100644 index 0000000..01e1962 --- /dev/null +++ b/sip/src/encoding/headermap.rs @@ -0,0 +1,60 @@ +use super::headers::Header; +use anyhow::{anyhow, Result}; +use std::fmt::Display; + +#[derive(Debug, Clone)] +pub struct HeaderMap(pub Vec<(String, String)>); + +impl HeaderMap { + pub fn new() -> Self { + Self(vec![]) + } + pub fn add<H: Header>(mut self, h: H) -> Self { + self.0.push((H::NAME.to_string(), format!("{h}"))); + self + } + pub fn insert<H: Header>(&mut self, h: H) { + self.0.push((H::NAME.to_string(), format!("{h}"))); + } + pub fn get_raw(&self, name: &str) -> Option<&str> { + self.0 + .iter() + .find(|(k, _)| k.eq_ignore_ascii_case(name)) + .map(|(_, v)| v.as_str()) + } + pub fn get<H: Header>(&self) -> Option<Result<H>> { + self.get_raw(H::NAME).map(H::from_str) + } + pub fn get_res<H: Header>(&self) -> Result<H> { + self.get().ok_or(anyhow!("{} header missing", H::NAME))? + } + pub fn insert_raw(&mut self, key: String, value: String) { + self.0.push((key, value)) + } +} + +impl Display for HeaderMap { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for (k, v) in &self.0 { + write!(f, "{k}: {v}\r\n")?; + } + Ok(()) + } +} +impl HeaderMap { + pub fn parse<'a>(lines: &mut impl Iterator<Item = &'a str>) -> Result<Self> { + let mut headers = HeaderMap::new(); + for line in lines { + // TODO multiline values + let (key, value) = line.split_once(":").ok_or(anyhow!("header malformed"))?; + headers.insert_raw(key.trim().to_string(), value.trim().to_string()) + } + Ok(headers) + } +} + +impl FromIterator<(String, String)> for HeaderMap { + fn from_iter<T: IntoIterator<Item = (String, String)>>(iter: T) -> Self { + Self(Vec::from_iter(iter)) + } +} |