ezk_sip_types/code.rs
1use std::fmt;
2use std::str::FromStr;
3
4type Repr = u16;
5
6/// Code is a representation of an SIP-Code encoded in an u16
7#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
8pub struct StatusCode(Repr);
9
10impl fmt::Debug for StatusCode {
11 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12 let mut tuple = f.debug_tuple("Code");
13 tuple.field(&self.0);
14 if let Some(text) = self.text() {
15 tuple.field(&text);
16 }
17 tuple.finish()
18 }
19}
20
21/// CodeKind represents the kind of SIP-Code for broader Code handling
22#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
23pub enum CodeKind {
24 /// Represents code 100..=199
25 Provisional,
26
27 /// Represents code 200..=299
28 Success,
29
30 /// Represents code 300..=399
31 Redirection,
32
33 /// Represents code 400..=499
34 RequestFailure,
35
36 /// Represents code 500..=599
37 ServerFailure,
38
39 /// Represents code 600..=699
40 GlobalFailure,
41
42 /// Represents all other codes
43 Custom,
44}
45
46impl StatusCode {
47 /// Returns the [CodeKind] of the code
48 ///
49 /// # Example
50 ///
51 /// ```
52 /// use ezk_sip_types::StatusCode;
53 /// use ezk_sip_types::CodeKind;
54 ///
55 /// let code = StatusCode::from(200);
56 ///
57 /// assert_eq!(code.kind(), CodeKind::Success);
58 /// ```
59 #[inline]
60 pub fn kind(self) -> CodeKind {
61 match self.0 {
62 100..=199 => CodeKind::Provisional,
63 200..=299 => CodeKind::Success,
64 300..=399 => CodeKind::Redirection,
65 400..=499 => CodeKind::RequestFailure,
66 500..=599 => CodeKind::ServerFailure,
67 600..=699 => CodeKind::GlobalFailure,
68 _ => CodeKind::Custom,
69 }
70 }
71
72 /// Returns the number that the code represents
73 pub fn into_u16(self) -> Repr {
74 self.0
75 }
76}
77
78impl FromStr for StatusCode {
79 type Err = <Repr as FromStr>::Err;
80
81 fn from_str(s: &str) -> Result<Self, Self::Err> {
82 Ok(StatusCode(Repr::from_str(s)?))
83 }
84}
85
86impl From<Repr> for StatusCode {
87 fn from(r: Repr) -> StatusCode {
88 StatusCode(r)
89 }
90}
91
92macro_rules! codes {
93 ($($(#[$comments:meta])* [$code:expr => $name:ident, $text:literal];)*) => {
94 impl StatusCode {
95 /// Returns the default response-text for a known Code
96 pub fn text(self) -> Option<&'static str> {
97 match self.0 {
98 $($code => Some($text),)*
99 _ => None
100 }
101 }
102
103 $(
104 $(#[$comments])*
105 pub const $name: StatusCode = StatusCode($code);
106 )*
107 }
108 };
109}
110
111codes! {
112 // ==== PROVISIONAL 1XX ====
113
114 /// [[RFC3621, Section 21.1.1](https://tools.ietf.org/html/rfc3261#section-21.1.1)]
115 /// 100 Trying
116 [100 => TRYING, "Trying"];
117
118 /// [[RFC3621, Section 21.1.2](https://tools.ietf.org/html/rfc3261#section-21.1.2)]
119 /// 180 Ringing
120 [180 => RINGING, "Ringing"];
121
122 /// [[RFC3621, Section 21.1.3](https://tools.ietf.org/html/rfc3261#section-21.1.3)]
123 /// 181 Call Is Being Forwarded
124 [181 => CALL_IS_BEING_FORWARDED, "Call Is Being Forwarded"];
125
126 /// [[RFC3621, Section 21.1.4](https://tools.ietf.org/html/rfc3261#section-21.1.4)]
127 /// 182 Queued
128 [182 => QUEUED, "Queued"];
129
130 /// [[RFC3621, Section 21.1.5](https://tools.ietf.org/html/rfc3261#section-21.1.5)]
131 /// 183 Session Progress
132 [183 => SESSION_PROGRESS, "Session Progress"];
133
134 /// [[RFC6228](https://tools.ietf.org/html/rfc6228)]
135 /// 199 Early Dialog Terminated
136 [199 => EARLY_DIALOG_TERMINATED, "Early Dialog Terminated"];
137
138 // ==== SUCCESS 2XX ====
139
140 /// [[RFC3621, Section 21.2.1](https://tools.ietf.org/html/rfc3261#section-21.2.1)]
141 /// 200 OK
142 [200 => OK, "OK"];
143
144 // ==== REDIRECTION 3XX ====
145
146 /// [[RFC3621, Section 21.3.1](https://tools.ietf.org/html/rfc3261#section-21.3.1)]
147 /// 300 Multiple Choices
148 [300 => MULTIPLE_CHOICES, "Multiple Choices"];
149
150 /// [[RFC3621, Section 21.3.2](https://tools.ietf.org/html/rfc3261#section-21.3.2)]
151 /// 301 Moved Permanently
152 [301 => MOVED_PERMANENTLY, "Moved Permanently"];
153
154 /// [[RFC3621, Section 21.3.3](https://tools.ietf.org/html/rfc3261#section-21.3.3)]
155 /// 302 Moved Temporarily
156 [302 => MOVED_TEMPORARILY, "Moved Temporarily"];
157
158 /// [[RFC3621, Section 21.3.4](https://tools.ietf.org/html/rfc3261#section-21.3.4)]
159 /// 302 Use Proxy
160 [305 => USE_PROXY, "Use Proxy"];
161
162 /// [[RFC3621, Section 21.3.5](https://tools.ietf.org/html/rfc3261#section-21.3.5)]
163 /// 380 Alternative Service
164 [380 => ALTERNATIVE_SERVICE, "Alternative Service"];
165
166 // ==== REQUEST FAILURE 4XX ====
167
168 /// [[RFC3621, Section 21.4.1](https://tools.ietf.org/html/rfc3261#section-21.4.1)]
169 /// 400 Bad Request
170 [400 => BAD_REQUEST, "Bad Request"];
171
172 /// [[RFC3621, Section 21.4.2](https://tools.ietf.org/html/rfc3261#section-21.4.2)]
173 /// 401 Unauthorized
174 [401 => UNAUTHORIZED, "Unauthorized"];
175
176 /// [[RFC3621, Section 21.4.3](https://tools.ietf.org/html/rfc3261#section-21.4.3)]
177 /// 402 Payment Required
178 [402 => PAYMENT_REQUIRED, "Payment Required"];
179
180 /// [[RFC3621, Section 21.4.4](https://tools.ietf.org/html/rfc3261#section-21.4.4)]
181 /// 403 Forbidden
182 [403 => FORBIDDEN, "Forbidden"];
183
184 /// [[RFC3621, Section 21.4.5](https://tools.ietf.org/html/rfc3261#section-21.4.5)]
185 /// 404 Not Found
186 [404 => NOT_FOUND, "Not Found"];
187
188 /// [[RFC3621, Section 21.4.6](https://tools.ietf.org/html/rfc3261#section-21.4.6)]
189 /// 405 Method Not Allowed
190 [405 => METHOD_NOT_ALLOWED, "Method Not Allowed"];
191
192 /// [[RFC3621, Section 21.4.7](https://tools.ietf.org/html/rfc3261#section-21.4.7)]
193 /// 406 Not Acceptable
194 [406 => NOT_ACCEPTABLE, "Not Acceptable"];
195
196 /// [[RFC3621, Section 21.4.8](https://tools.ietf.org/html/rfc3261#section-21.4.8)]
197 /// 407 Proxy Authentication Required
198 [407 => PROXY_AUTHENTICATION_REQUIRED, "Proxy Authentication Required"];
199
200 /// [[RFC3621, Section 21.4.9](https://tools.ietf.org/html/rfc3261#section-21.4.9)]
201 /// 408 Request Timeout
202 [408 => REQUEST_TIMEOUT, "Request Timeout"];
203
204 /// [[RFC3621, Section 21.4.10](https://tools.ietf.org/html/rfc3261#section-21.4.10)]
205 /// 410 Gone
206 [410 => GONE, "Gone"];
207
208 /// [[RFC3621, Section 21.4.11](https://tools.ietf.org/html/rfc3261#section-21.4.11)]
209 /// 413 Request Entity Too Large
210 [413 => REQUEST_ENTITY_TOO_LARGE, "Request Entity Too Large"];
211
212 /// [[RFC3621, Section 21.4.12](https://tools.ietf.org/html/rfc3261#section-21.4.12)]
213 /// 414 Request-URI Too Long
214 [414 => REQUEST_URI_TOO_LONG, "Request-URI Too Long"];
215
216 /// [[RFC3621, Section 21.4.13](https://tools.ietf.org/html/rfc3261#section-21.4.13)]
217 /// 415 Unsupported Media Type
218 [415 => UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type"];
219
220 /// [[RFC3621, Section 21.4.14](https://tools.ietf.org/html/rfc3261#section-21.4.14)]
221 /// 416 Unsupported URI Scheme
222 [416 => UNSUPPORTED_URI_SCHEME, "Unsupported URI Scheme"];
223
224 /// [[RFC3621, Section 21.4.15](https://tools.ietf.org/html/rfc3261#section-21.4.15)]
225 /// 420 Bad Extension
226 [420 => BAD_EXTENSION, "Bad Extension"];
227
228 /// [[RFC3621, Section 21.4.16](https://tools.ietf.org/html/rfc3261#section-21.4.16)]
229 /// 421 Extension Required
230 [421 => EXTENSION_REQUIRED, "Extension Required"];
231
232 /// [[RFC4028, Section 6](https://datatracker.ietf.org/doc/html/rfc4028#section-6)]
233 /// 422 Session Interval Too Small
234 [422 => SESSION_INTERVAL_TOO_SMALL, "Session Interval Too Small"];
235
236 /// [[RFC3621, Section 21.4.17](https://tools.ietf.org/html/rfc3261#section-21.4.17)]
237 /// 423 Interval Too Brief
238 [423 => INTERVAL_TOO_BRIEF, "Interval Too Brief"];
239
240 /// [[RFC3621, Section 21.4.18](https://tools.ietf.org/html/rfc3261#section-21.4.18)]
241 /// 480 Temporarily Unavailable
242 [480 => TEMPORARILY_UNAVAILABLE, "Temporarily Unavailable"];
243
244 /// [[RFC3621, Section 21.4.19](https://tools.ietf.org/html/rfc3261#section-21.4.19)]
245 /// 481 Call/Transaction Does Not Exist
246 [481 => CALL_OR_TRANSACTION_DOES_NOT_EXIST, "Call/Transaction Does Not Exist"];
247
248 /// [[RFC3621, Section 21.4.20](https://tools.ietf.org/html/rfc3261#section-21.4.20)]
249 /// 482 Loop Detected
250 [482 => LOOP_DETECTED, "Loop Detected"];
251
252 /// [[RFC3621, Section 21.4.21](https://tools.ietf.org/html/rfc3261#section-21.4.21)]
253 /// 483 Too Many Hops
254 [483 => TOO_MANY_HOPS, "Too Many Hops"];
255
256 /// [[RFC3621, Section 21.4.22](https://tools.ietf.org/html/rfc3261#section-21.4.22)]
257 /// 484 Address Incomplete
258 [484 => ADDRESS_INCOMPLETE, "Address Incomplete"];
259
260 /// [[RFC3621, Section 21.4.23](https://tools.ietf.org/html/rfc3261#section-21.4.23)]
261 /// 485 Ambiguous
262 [485 => AMBIGUOUS, "Ambiguous"];
263
264 /// [[RFC3621, Section 21.4.24](https://tools.ietf.org/html/rfc3261#section-21.4.24)]
265 /// 486 Busy Here
266 [486 => BUSY_HERE, "Busy Here"];
267
268 /// [[RFC3621, Section 21.4.25](https://tools.ietf.org/html/rfc3261#section-21.4.25)]
269 /// 487 Request Terminated
270 [487 => REQUEST_TERMINATED, "Request Terminated"];
271
272 /// [[RFC3621, Section 21.4.26](https://tools.ietf.org/html/rfc3261#section-21.4.26)]
273 /// 488 Not Acceptable Here
274 [488 => NOT_ACCEPTABLE_HERE, "Not Acceptable Here"];
275
276 /// [[RFC6665, Section 8.3.2](https://datatracker.ietf.org/doc/html/rfc6665#section-8.3.2)]
277 /// 489 Bad Event
278 [489 => BAD_EVENT, "Bad Event"];
279
280 /// [[RFC3621, Section 21.4.27](https://tools.ietf.org/html/rfc3261#section-21.4.27)]
281 /// 491 Request Pending
282 [491 => REQUEST_PENDING, "Request Pending"];
283
284 /// [[RFC3621, Section 21.4.28](https://tools.ietf.org/html/rfc3261#section-21.4.28)]
285 /// 493 Undecipherable
286 [493 => UNDECIPHERABLE, "Undecipherable"];
287
288 // ==== SERVER FAILURE 5XX ====
289
290 /// [[RFC3621, Section 21.5.1](https://tools.ietf.org/html/rfc3261#section-21.5.1)]
291 /// 500 Server Internal Error
292 [500 => SERVER_INTERNAL_ERROR, "Server Internal Error"];
293
294 /// [[RFC3621, Section 21.5.2](https://tools.ietf.org/html/rfc3261#section-21.5.2)]
295 /// 501 Not Implemented
296 [501 => NOT_IMPLMENTED, "Not Implemented"];
297
298 /// [[RFC3621, Section 21.5.3](https://tools.ietf.org/html/rfc3261#section-21.5.3)]
299 /// 502 Bad Gateway
300 [502 => BAD_GATEWAY, "Bad Gateway"];
301
302 /// [[RFC3621, Section 21.5.4](https://tools.ietf.org/html/rfc3261#section-21.5.4)]
303 /// 503 Service Unavailable
304 [503 => SERVICE_UNAVAILABLE, "Service Unavailable"];
305
306 /// [[RFC3621, Section 21.5.5](https://tools.ietf.org/html/rfc3261#section-21.5.5)]
307 /// 504 Server Time-out
308 [504 => SERVER_TIMEOUT, "Server Time-out"];
309
310 /// [[RFC3621, Section 21.5.6](https://tools.ietf.org/html/rfc3261#section-21.5.6)]
311 /// 505 Version Not Supported
312 [505 => VERSION_NOT_SUPPORTED, "Version Not Supported"];
313
314 /// [[RFC3621, Section 21.5.7](https://tools.ietf.org/html/rfc3261#section-21.5.7)]
315 /// 513 Message Too Large
316 [513 => MESSAGE_TOO_LARGE, "Message Too Large"];
317
318 // ==== GLOBAL FAILURE 6XX ====
319
320 /// [[RFC3621, Section 21.6.1](https://tools.ietf.org/html/rfc3261#section-21.6.1)]
321 /// 600 Busy Everywhere
322 [600 => BUSY_EVERYWHERE, "Busy Everywhere"];
323
324 /// [[RFC3621, Section 21.6.2](https://tools.ietf.org/html/rfc3261#section-21.6.2)]
325 /// 603 Decline
326 [603 => DECLINE, "Decline"];
327
328 /// [[RFC3621, Section 21.6.3](https://tools.ietf.org/html/rfc3261#section-21.6.3)]
329 /// 604 Does Not Exist Anywhere
330 [604 => DOES_NOT_EXIST_ANYWHERE, "Does Not Exist Anywhere"];
331
332 /// [[RFC3621, Section 21.6.4](https://tools.ietf.org/html/rfc3261#section-21.6.4)]
333 /// 606 Not Acceptable
334 [606 => NOT_ACCEPTABLE6, "Not Acceptable"];
335}