freeswitch_types/variables/
sip_invite.rs1use serde::{Deserialize, Serialize};
12
13#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct ParseSipInviteHeaderError(pub String);
16
17impl std::fmt::Display for ParseSipInviteHeaderError {
18 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19 write!(f, "unknown SIP invite header variable: {}", self.0)
20 }
21}
22
23impl std::error::Error for ParseSipInviteHeaderError {}
24
25define_header_enum! {
26 error_type: ParseSipInviteHeaderError,
27 pub enum SipInviteHeader {
42 From => "sip_i_from",
46 To => "sip_i_to",
48 CallId => "sip_i_call_id",
50 Cseq => "sip_i_cseq",
52 Identity => "sip_i_identity",
54 Route => "sip_i_route",
56 MaxForwards => "sip_i_max_forwards",
58 ProxyRequire => "sip_i_proxy_require",
60 Contact => "sip_i_contact",
62 UserAgent => "sip_i_user_agent",
64 Subject => "sip_i_subject",
66 Priority => "sip_i_priority",
68 Organization => "sip_i_organization",
70 InReplyTo => "sip_i_in_reply_to",
72 AcceptEncoding => "sip_i_accept_encoding",
74 AcceptLanguage => "sip_i_accept_language",
76 Allow => "sip_i_allow",
78 Require => "sip_i_require",
80 Supported => "sip_i_supported",
82 Date => "sip_i_date",
84 Timestamp => "sip_i_timestamp",
86 Expires => "sip_i_expires",
88 MinExpires => "sip_i_min_expires",
90 SessionExpires => "sip_i_session_expires",
92 MinSe => "sip_i_min_se",
94 Privacy => "sip_i_privacy",
96 MimeVersion => "sip_i_mime_version",
98 ContentType => "sip_i_content_type",
100 ContentEncoding => "sip_i_content_encoding",
102 ContentLanguage => "sip_i_content_language",
104 ContentDisposition => "sip_i_content_disposition",
106 ContentLength => "sip_i_content_length",
108
109 Via => "sip_i_via",
113 RecordRoute => "sip_i_record_route",
115 ProxyAuthorization => "sip_i_proxy_authorization",
117 CallInfo => "sip_i_call_info",
119 Accept => "sip_i_accept",
121 Authorization => "sip_i_authorization",
123 AlertInfo => "sip_i_alert_info",
125 PAssertedIdentity => "sip_i_p_asserted_identity",
127 PPreferredIdentity => "sip_i_p_preferred_identity",
129 RemotePartyId => "sip_i_remote_party_id",
131 ReplyTo => "sip_i_reply_to",
133 }
134}
135
136impl SipInviteHeader {
137 pub const ARRAY_HEADERS: &[SipInviteHeader] = &[
139 SipInviteHeader::Via,
140 SipInviteHeader::RecordRoute,
141 SipInviteHeader::ProxyAuthorization,
142 SipInviteHeader::CallInfo,
143 SipInviteHeader::Accept,
144 SipInviteHeader::Authorization,
145 SipInviteHeader::AlertInfo,
146 SipInviteHeader::PAssertedIdentity,
147 SipInviteHeader::PPreferredIdentity,
148 SipInviteHeader::RemotePartyId,
149 SipInviteHeader::ReplyTo,
150 ];
151
152 pub fn is_array_header(&self) -> bool {
154 Self::ARRAY_HEADERS.contains(self)
155 }
156}
157
158#[cfg(test)]
159mod tests {
160 use super::*;
161
162 #[test]
163 fn display_round_trip() {
164 assert_eq!(
165 SipInviteHeader::PAssertedIdentity.to_string(),
166 "sip_i_p_asserted_identity"
167 );
168 assert_eq!(SipInviteHeader::From.to_string(), "sip_i_from");
169 assert_eq!(SipInviteHeader::Via.to_string(), "sip_i_via");
170 }
171
172 #[test]
173 fn as_ref_str() {
174 let v: &str = SipInviteHeader::CallId.as_ref();
175 assert_eq!(v, "sip_i_call_id");
176 }
177
178 #[test]
179 fn from_str_case_insensitive() {
180 assert_eq!(
181 "sip_i_p_asserted_identity".parse::<SipInviteHeader>(),
182 Ok(SipInviteHeader::PAssertedIdentity)
183 );
184 assert_eq!(
185 "SIP_I_P_ASSERTED_IDENTITY".parse::<SipInviteHeader>(),
186 Ok(SipInviteHeader::PAssertedIdentity)
187 );
188 }
189
190 #[test]
191 fn from_str_unknown() {
192 assert!("sip_i_nonexistent"
193 .parse::<SipInviteHeader>()
194 .is_err());
195 }
196
197 #[test]
198 fn from_str_round_trip_all() {
199 let variants = [
200 SipInviteHeader::From,
201 SipInviteHeader::To,
202 SipInviteHeader::CallId,
203 SipInviteHeader::Via,
204 SipInviteHeader::RecordRoute,
205 SipInviteHeader::PAssertedIdentity,
206 SipInviteHeader::PPreferredIdentity,
207 SipInviteHeader::RemotePartyId,
208 SipInviteHeader::AlertInfo,
209 SipInviteHeader::Privacy,
210 SipInviteHeader::ContentType,
211 ];
212 for v in variants {
213 let wire = v.to_string();
214 let parsed: SipInviteHeader = wire
215 .parse()
216 .unwrap();
217 assert_eq!(parsed, v, "round-trip failed for {wire}");
218 }
219 }
220
221 #[test]
222 fn array_headers_classification() {
223 assert!(SipInviteHeader::Via.is_array_header());
224 assert!(SipInviteHeader::PAssertedIdentity.is_array_header());
225 assert!(SipInviteHeader::RecordRoute.is_array_header());
226 assert!(!SipInviteHeader::From.is_array_header());
227 assert!(!SipInviteHeader::CallId.is_array_header());
228 assert!(!SipInviteHeader::ContentType.is_array_header());
229 }
230}