diff options
Diffstat (limited to 'src/encoding')
-rw-r--r-- | src/encoding/headers.rs | 14 | ||||
-rw-r--r-- | src/encoding/uri.rs | 41 |
2 files changed, 50 insertions, 5 deletions
diff --git a/src/encoding/headers.rs b/src/encoding/headers.rs index afcfef1..e880739 100644 --- a/src/encoding/headers.rs +++ b/src/encoding/headers.rs @@ -166,7 +166,17 @@ impl Display for Contact { } impl FromStr for Contact { type Err = anyhow::Error; - fn from_str(_s: &str) -> Result<Self, Self::Err> { - todo!() + fn from_str(s: &str) -> Result<Self, Self::Err> { + let (display_name, rest) = s.split_once("<").ok_or(anyhow!("malformed contact"))?; + let (uri, params) = rest.split_once(">;").ok_or(anyhow!("malformed contact"))?; + Ok(Self { + display_name: if display_name.is_empty() { + None + } else { + Some(display_name.to_string()) + }, + params: params.to_string(), + uri: Uri::from_str(uri)?, + }) } } diff --git a/src/encoding/uri.rs b/src/encoding/uri.rs index a56cad4..db20700 100644 --- a/src/encoding/uri.rs +++ b/src/encoding/uri.rs @@ -1,21 +1,56 @@ +use anyhow::anyhow; use std::{fmt::Display, str::FromStr}; #[derive(Debug, Clone)] pub struct Uri { - pub content: String, + pub protocol: String, + pub localpart: Option<String>, + pub addr: String, + pub params: String, } impl Display for Uri { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.content)?; + let Self { + protocol, + localpart, + addr, + params, + } = self; + write!( + f, + "{protocol}:{}{addr}{}", + if let Some(localpart) = localpart { + format!("{localpart}@") + } else { + "".to_string() + }, + if params.is_empty() { + "".to_string() + } else { + format!(";{params}") + } + )?; Ok(()) } } impl FromStr for Uri { type Err = anyhow::Error; fn from_str(s: &str) -> Result<Self, Self::Err> { + eprintln!("{s:?}"); + let (pr, s) = s.split_once(":").ok_or(anyhow!("protocol sep"))?; + let (lp, s) = s.split_once("@").unwrap_or(("", s)); + let (addr, params) = s.split_once(";").unwrap_or((s, "")); + Ok(Self { - content: s.to_string(), + addr: addr.to_owned(), + localpart: if lp.is_empty() { + None + } else { + Some(lp.to_string()) + }, + params: params.to_string(), + protocol: pr.to_string(), }) } } |