ftth_rsip/message/
headers_ext.rs

1use crate::{
2    headers::{self, Header},
3    param::Branch,
4    Error,
5};
6
7/// Helpful trait to access most common headers from a [Request](crate::Request),
8/// [Response](crate::Response) and [SipMessage](crate::SipMessage) structs.
9///
10/// Some headers that are expected to be there return a `Result<T, ftth_rsip::Error>` while others
11/// return just an `Option<T>`, where `T` is the actual [untyped](crate::headers::untyped) header.
12pub trait HeadersExt: super::HasHeaders {
13    fn to_header(&self) -> Result<&headers::To, Error> {
14        header!(
15            self.headers().iter(),
16            Header::To,
17            Error::missing_header("To")
18        )
19    }
20
21    fn to_header_mut(&mut self) -> Result<&mut headers::To, Error> {
22        header!(
23            self.headers_mut().iter_mut(),
24            Header::To,
25            Error::missing_header("To")
26        )
27    }
28
29    #[allow(clippy::wrong_self_convention)]
30    fn from_header(&self) -> Result<&headers::From, Error> {
31        header!(
32            self.headers().iter(),
33            Header::From,
34            Error::missing_header("From")
35        )
36    }
37
38    #[allow(clippy::wrong_self_convention)]
39    fn from_header_mut(&mut self) -> Result<&mut headers::From, Error> {
40        header!(
41            self.headers_mut().iter_mut(),
42            Header::From,
43            Error::missing_header("From")
44        )
45    }
46
47    fn via_header(&self) -> Result<&headers::Via, Error> {
48        header!(
49            self.headers().iter(),
50            Header::Via,
51            Error::missing_header("Via")
52        )
53    }
54    fn via_header_mut(&mut self) -> Result<&mut headers::Via, Error> {
55        header!(
56            self.headers_mut().iter_mut(),
57            Header::Via,
58            Error::missing_header("Via")
59        )
60    }
61
62    fn call_id_header(&self) -> Result<&headers::CallId, Error> {
63        header!(
64            self.headers().iter(),
65            Header::CallId,
66            Error::missing_header("CallID")
67        )
68    }
69    fn call_id_header_mut(&mut self) -> Result<&mut headers::CallId, Error> {
70        header!(
71            self.headers_mut().iter_mut(),
72            Header::CallId,
73            Error::missing_header("CallID")
74        )
75    }
76
77    fn cseq_header(&self) -> Result<&headers::CSeq, Error> {
78        header!(
79            self.headers().iter(),
80            Header::CSeq,
81            Error::missing_header("CSeq")
82        )
83    }
84    fn cseq_header_mut(&mut self) -> Result<&mut headers::CSeq, Error> {
85        header!(
86            self.headers_mut().iter_mut(),
87            Header::CSeq,
88            Error::missing_header("CSeq")
89        )
90    }
91
92    fn max_forwards_header(&self) -> Result<&headers::MaxForwards, Error> {
93        header!(
94            self.headers().iter(),
95            Header::MaxForwards,
96            Error::missing_header("Max-Forwards")
97        )
98    }
99    fn max_forwards_header_mut(&mut self) -> Result<&mut headers::MaxForwards, Error> {
100        header!(
101            self.headers_mut().iter_mut(),
102            Header::MaxForwards,
103            Error::missing_header("Max-Forwards")
104        )
105    }
106
107    fn contact_header(&self) -> Result<&headers::Contact, Error> {
108        header!(
109            self.headers().iter(),
110            Header::Contact,
111            Error::missing_header("Contact")
112        )
113    }
114
115    fn contact_header_mut(&mut self) -> Result<&mut headers::Contact, Error> {
116        header!(
117            self.headers_mut().iter_mut(),
118            Header::Contact,
119            Error::missing_header("Contact")
120        )
121    }
122
123    fn contact_headers(&self) -> Vec<&headers::Contact> {
124        all_headers!(self.headers().iter(), Header::Contact)
125    }
126
127    fn record_route_header(&self) -> Option<&headers::RecordRoute> {
128        header_opt!(self.headers().iter(), Header::RecordRoute)
129    }
130
131    fn route_header(&self) -> Option<&headers::Route> {
132        header_opt!(self.headers().iter(), Header::Route)
133    }
134
135    fn user_agent_header(&self) -> Option<&headers::UserAgent> {
136        header_opt!(self.headers().iter(), Header::UserAgent)
137    }
138
139    fn authorization_header(&self) -> Option<&headers::Authorization> {
140        header_opt!(self.headers().iter(), Header::Authorization)
141    }
142
143    fn www_authenticate_header(&self) -> Option<&headers::WwwAuthenticate> {
144        header_opt!(self.headers().iter(), Header::WwwAuthenticate)
145    }
146
147    fn expires_header(&self) -> Option<&headers::Expires> {
148        header_opt!(self.headers().iter(), Header::Expires)
149    }
150
151    fn min_expires_header(&self) -> Option<&headers::MinExpires> {
152        header_opt!(self.headers().iter(), Header::MinExpires)
153    }
154
155    //TODO: this is not correct? this is just the branch id
156    //however RFC3261 states clear ways on how transactions should be matched
157    fn transaction_id(&self) -> Result<Branch, Error> {
158        self.via_header()?.branch()
159    }
160}
161
162impl HeadersExt for crate::Request {}
163impl HeadersExt for crate::Response {}
164impl HeadersExt for crate::SipMessage {}