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}