aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/response.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/encoding/response.rs')
-rw-r--r--src/encoding/response.rs40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/encoding/response.rs b/src/encoding/response.rs
new file mode 100644
index 0000000..3564b34
--- /dev/null
+++ b/src/encoding/response.rs
@@ -0,0 +1,40 @@
+use super::headermap::HeaderMap;
+use anyhow::{anyhow, bail, Context};
+use std::str::FromStr;
+
+#[derive(Debug)]
+pub struct Response {
+ pub code: u16,
+ pub headers: HeaderMap,
+}
+
+impl FromStr for Response {
+ 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 (sipver, rest) = statusline
+ .split_once(" ")
+ .ok_or(anyhow!("status line malformed"))?;
+ let (code, _status_str) = rest
+ .split_once(" ")
+ .ok_or(anyhow!("status line malformed"))?;
+ let code = u16::from_str(code).context("status code")?;
+
+ let Some(ver) = sipver.strip_prefix("SIP/") else {
+ bail!("sip version malformed");
+ };
+ if ver != "2.0" {
+ bail!("sip version {ver:?} is not supported");
+ }
+
+ 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(Self { code, headers })
+ }
+}