1pub fn ensure_sip_scheme(uri: String) -> String {
6 if uri.starts_with("sip:") || uri.starts_with("sips:") {
7 uri
8 } else {
9 format!("sip:{}", uri)
10 }
11}
12
13pub fn sip_headers_from_map(
15 headers: &std::collections::HashMap<String, String>,
16) -> Vec<rsipstack::rsip::Header> {
17 headers
18 .iter()
19 .map(|(k, v)| rsipstack::rsip::Header::Other(k.clone(), v.clone()))
20 .collect()
21}
22
23pub fn hangup_headers_from_extras(
26 extras: &std::collections::HashMap<String, serde_json::Value>,
27) -> Option<Vec<rsipstack::rsip::Header>> {
28 let value = extras.get("_hangup_headers")?;
29 let map =
30 serde_json::from_value::<std::collections::HashMap<String, String>>(value.clone()).ok()?;
31 let headers = sip_headers_from_map(&map);
32 (!headers.is_empty()).then_some(headers)
33}
34
35#[cfg(test)]
36mod tests {
37 use super::*;
38
39 #[test]
40 fn adds_scheme_when_missing() {
41 assert_eq!(
42 ensure_sip_scheme("bob@example.com".into()),
43 "sip:bob@example.com"
44 );
45 assert_eq!(
46 ensure_sip_scheme("sip:bob@example.com".into()),
47 "sip:bob@example.com"
48 );
49 assert_eq!(
50 ensure_sip_scheme("sips:bob@example.com".into()),
51 "sips:bob@example.com"
52 );
53 }
54
55 #[test]
56 fn converts_header_maps() {
57 let mut map = std::collections::HashMap::new();
58 map.insert("X-Job-Id".to_string(), "42".to_string());
59 let headers = sip_headers_from_map(&map);
60 assert_eq!(headers.len(), 1);
61 assert!(matches!(&headers[0], rsipstack::rsip::Header::Other(k, v)
62 if k == "X-Job-Id" && v == "42"));
63 }
64
65 #[test]
66 fn extracts_hangup_headers_from_extras() {
67 let mut extras = std::collections::HashMap::new();
68 assert!(hangup_headers_from_extras(&extras).is_none());
69
70 let mut map = std::collections::HashMap::new();
71 map.insert("X-Reason".to_string(), "done".to_string());
72 extras.insert(
73 "_hangup_headers".to_string(),
74 serde_json::to_value(&map).unwrap(),
75 );
76 assert!(hangup_headers_from_extras(&extras).is_some());
77 }
78}