diff options
Diffstat (limited to 'sip/src/encoding/uri.rs')
-rw-r--r-- | sip/src/encoding/uri.rs | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/sip/src/encoding/uri.rs b/sip/src/encoding/uri.rs new file mode 100644 index 0000000..b1a1282 --- /dev/null +++ b/sip/src/encoding/uri.rs @@ -0,0 +1,55 @@ +use anyhow::anyhow; +use std::{fmt::Display, str::FromStr}; + +#[derive(Debug, Clone)] +pub struct Uri { + 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 { + 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> { + 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 { + addr: addr.to_owned(), + localpart: if lp.is_empty() { + None + } else { + Some(lp.to_string()) + }, + params: params.to_string(), + protocol: pr.to_string(), + }) + } +} |