diff options
author | metamuffin <metamuffin@disroot.org> | 2024-11-19 02:08:52 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-11-19 02:08:52 +0100 |
commit | cbc111f90b5facc1f2a9dd79ced216279d6260af (patch) | |
tree | fa5a1d2d67874413d8e66673825c6789e8cc0945 /sip/src/encoding/response.rs | |
parent | 2d9a31244eab6d3a9871369d3148de253e902d36 (diff) | |
download | sip-rs-cbc111f90b5facc1f2a9dd79ced216279d6260af.tar sip-rs-cbc111f90b5facc1f2a9dd79ced216279d6260af.tar.bz2 sip-rs-cbc111f90b5facc1f2a9dd79ced216279d6260af.tar.zst |
move files + rtp parser
Diffstat (limited to 'sip/src/encoding/response.rs')
-rw-r--r-- | sip/src/encoding/response.rs | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/sip/src/encoding/response.rs b/sip/src/encoding/response.rs new file mode 100644 index 0000000..0b7996c --- /dev/null +++ b/sip/src/encoding/response.rs @@ -0,0 +1,53 @@ +use super::{headermap::HeaderMap, status::Status}; +use anyhow::{anyhow, bail, Context}; +use std::{fmt::Display, str::FromStr}; + +#[derive(Debug, Clone)] +pub struct Response { + pub status: Status, + pub headers: HeaderMap, + pub body: String, +} + +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 headers = HeaderMap::parse(&mut lines)?; + + let status = Status::from_code(code); + Ok(Self { + status, + headers, + body: String::new(), + }) + } +} +impl Display for Response { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let Self { + status, + headers, + body, + } = self; + write!(f, "SIP/2.0 {} {status:?}\r\n", status.to_code())?; + write!(f, "{headers}\r\n{body}")?; + Ok(()) + } +} |