diff options
Diffstat (limited to 'sip/src/encoding/request.rs')
-rw-r--r-- | sip/src/encoding/request.rs | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/sip/src/encoding/request.rs b/sip/src/encoding/request.rs new file mode 100644 index 0000000..ab41b7c --- /dev/null +++ b/sip/src/encoding/request.rs @@ -0,0 +1,57 @@ +use super::{headermap::HeaderMap, method::Method, uri::Uri}; +use anyhow::{anyhow, bail}; +use std::{fmt::Display, str::FromStr}; + +#[derive(Debug, Clone)] +pub struct Request { + pub method: Method, + pub uri: Uri, + pub headers: HeaderMap, + pub body: String, +} + +impl Display for Request { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let Self { + headers, + method, + uri, + .. + } = self; + write!(f, "{method} {uri} SIP/2.0\r\n")?; + write!(f, "{headers}\r\n")?; + Ok(()) + } +} +impl FromStr for Request { + type Err = anyhow::Error; + fn from_str(s: &str) -> Result<Self, Self::Err> { + let mut lines = s.lines(); + let statusline = lines.next().ok_or(anyhow!("status line missing"))?; + let (method, rest) = statusline + .split_once(" ") + .ok_or(anyhow!("status line malformed"))?; + let (uri, sipver) = rest + .split_once(" ") + .ok_or(anyhow!("status line malformed"))?; + + let Some(ver) = sipver.strip_prefix("SIP/") else { + bail!("sip version malformed"); + }; + if ver != "2.0" { + bail!("sip version {ver:?} is not supported"); + } + + let uri = Uri::from_str(uri)?; + + let headers = HeaderMap::parse(&mut lines)?; + let method = Method::from_str(method)?; + + Ok(Self { + body: String::new(), + headers, + method, + uri, + }) + } +} |