httpstatus/
lib.rs

1// In the name of Allah
2
3//! List of HTTP response status codes
4
5#![crate_name = "httpstatus"]
6
7use serde::{Deserialize, Serialize};
8use std::convert::From;
9use std::fmt::{Display, Error, Formatter};
10
11/// Represents an HTTP status code
12#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Hash, Serialize, Deserialize)]
13pub enum StatusCode {
14    /// 100 Continue (RFC 7231)
15    Continue,
16
17    /// 101 Switching Protocols (RFC 7231)
18    SwitchingProtocols,
19
20    /// 102 Processing (RFC 2518)
21    Processing,
22
23    /// 103 Early Hints (RFC 8297)
24    EarlyHints,
25
26    /// 200 OK (RFC 7231)
27    Ok,
28
29    /// 201 Created (RFC 7231)
30    Created,
31
32    /// 202 Accepted (RFC 7231)
33    Accepted,
34
35    /// 203 Non-Authoritative Information (RFC 7231)
36    NonAuthoritativeInformation,
37
38    /// 204 No Content (RFC 7231)
39    NoContent,
40
41    /// 205 Reset Content (RFC 7231)
42    ResetContent,
43
44    /// 206 Partial Content (RFC 7233)
45    PartialContent,
46
47    /// 207 Multi-Status (RFC 4918)
48    MultiStatus,
49
50    /// 208 Already Reported (RFC 5842)
51    AlreadyReported,
52
53    /// 226 IM Used (RFC 3229)
54    IMUsed,
55
56    /// 300 Multiple Choices (RFC 7231)
57    MultipleChoices,
58
59    /// 301 Moved Permanently (RFC 7231)
60    MovedPermanently,
61
62    /// 302 Found (RFC 7231)
63    Found,
64
65    /// 303 See Other (RFC 7231)
66    SeeOther,
67
68    /// 304 Not Modified (RFC 7232)
69    NotModified,
70
71    /// 305 Use Proxy (RFC 7231)
72    UseProxy,
73
74    /// 306 Switch Proxy (RFC 7231)
75    SwitchProxy,
76
77    /// 307 Temporary Redirect (RFC 7231)
78    TemporaryRedirect,
79
80    /// 308 Permanent Redirect (RFC 7538)
81    PermanentRedirect,
82
83    /// 400 Bad Request (RFC 7231)
84    BadRequest,
85
86    /// 401 Unauthorized (RFC 7235)
87    Unauthorized,
88
89    /// 402 Payment Required (RFC 7231)
90    PaymentRequired,
91
92    /// 403 Forbidden (RFC 7231)
93    Forbidden,
94
95    /// 404 Not Found (RFC 7231)
96    NotFound,
97
98    /// 405 Method Not Allowed (RFC 7231)
99    MethodNotAllowed,
100
101    /// 406 Not Acceptable (RFC 7231)
102    NotAcceptable,
103
104    /// 407 Proxy Authentication Required (RFC 7235)
105    ProxyAuthenticationRequired,
106
107    /// 408 Request Timeout (RFC 7231)
108    RequestTimeout,
109
110    /// 409 Conflict (RFC 7231)
111    Conflict,
112
113    /// 410 Gone (RFC 7231)
114    Gone,
115
116    /// 411 Length Required (RFC 7231)
117    LengthRequired,
118
119    /// 412 Precondition Failed (RFC 7232)
120    PreconditionFailed,
121
122    /// 413 Payload Too Large (RFC 7231)
123    PayloadTooLarge,
124
125    /// 414 URI Too Long (RFC 7231)
126    UriTooLong,
127
128    /// 415 Unsupported Media Type (RFC 7231)
129    UnsupportedMediaType,
130
131    /// 416 Range Not Satisfiable (RFC 7233)
132    RangeNotSatisfiable,
133
134    /// 417 Expectation Failed (RFC 7231)
135    ExpectationFailed,
136
137    /// 418 I'm a teapot (RFC 2324)
138    ImATeapot,
139
140    /// 421 Misdirected Request (RFC 7540)
141    MisdirectedRequest,
142
143    /// 422 Unprocessable Entity (RFC 4918)
144    UnprocessableEntity,
145
146    /// 423 Locked (RFC 4918)
147    Locked,
148
149    /// 424 Failed Dependency (RFC 4918)
150    FailedDependency,
151
152    /// 426 Upgrade Required (RFC 7231)
153    UpgradeRequired,
154
155    /// 428 Precondition Required (RFC 6585)
156    PreconditionRequired,
157
158    /// 429 Too Many Requests (RFC 6585)
159    TooManyRequests,
160
161    /// 431 Request Header Fields Too Large (RFC 6585)
162    RequestHeaderFieldsTooLarge,
163
164    /// 451 Unavailable For Legal Reasons (RFC 7725)
165    UnavailableForLegalReasons,
166
167    /// 500 Internal Server Error (RFC 7231)
168    InternalServerError,
169
170    /// 501 Not Implemented (RFC 7231)
171    NotImplemented,
172
173    /// 502 Bad Gateway (RFC 7231)
174    BadGateway,
175
176    /// 503 Service Unavailable (RFC 7231)
177    ServiceUnavailable,
178
179    /// 504 Gateway Timeout (RFC 7231)
180    GatewayTimeout,
181
182    /// 505 HTTP Version Not Supported (RFC 7231)
183    HttpVersionNotSupported,
184
185    /// 506 Variant Also Negotiates (RFC 2295)
186    VariantAlsoNegotiates,
187
188    /// 507 Insufficient Storage (RFC 4918)
189    InsufficientStorage,
190
191    /// 508 Loop Detected (RFC 5842)
192    LoopDetected,
193
194    /// 510 Not Extended (RFC 2774)
195    NotExtended,
196
197    /// 511 Network Authentication Required (RFC 6585)
198    NetworkAuthenticationRequired,
199
200    /// Unknown status code
201    Unknown(u16),
202}
203
204/// Represents an HTTP status class
205#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Hash, Serialize, Deserialize)]
206pub enum StatusClass {
207    /// 1xx Informational
208    Informational,
209
210    /// 2xx Success
211    Success,
212
213    /// 3xx Redirection
214    Redirection,
215
216    /// 4xx Client errors
217    ClientError,
218
219    /// 5xx Server errors
220    ServerError,
221
222    /// Unknown status class
223    Unknown,
224}
225
226impl StatusCode {
227    /// Returns the numeric status code
228    #[inline]
229    pub fn as_u16(&self) -> u16 {
230        match *self {
231            StatusCode::Continue => 100,
232            StatusCode::SwitchingProtocols => 101,
233            StatusCode::Processing => 102,
234            StatusCode::EarlyHints => 103,
235            StatusCode::Ok => 200,
236            StatusCode::Created => 201,
237            StatusCode::Accepted => 202,
238            StatusCode::NonAuthoritativeInformation => 203,
239            StatusCode::NoContent => 204,
240            StatusCode::ResetContent => 205,
241            StatusCode::PartialContent => 206,
242            StatusCode::MultiStatus => 207,
243            StatusCode::AlreadyReported => 208,
244            StatusCode::IMUsed => 226,
245            StatusCode::MultipleChoices => 300,
246            StatusCode::MovedPermanently => 301,
247            StatusCode::Found => 302,
248            StatusCode::SeeOther => 303,
249            StatusCode::NotModified => 304,
250            StatusCode::UseProxy => 305,
251            StatusCode::SwitchProxy => 306,
252            StatusCode::TemporaryRedirect => 307,
253            StatusCode::PermanentRedirect => 308,
254            StatusCode::BadRequest => 400,
255            StatusCode::Unauthorized => 401,
256            StatusCode::PaymentRequired => 402,
257            StatusCode::Forbidden => 403,
258            StatusCode::NotFound => 404,
259            StatusCode::MethodNotAllowed => 405,
260            StatusCode::NotAcceptable => 406,
261            StatusCode::ProxyAuthenticationRequired => 407,
262            StatusCode::RequestTimeout => 408,
263            StatusCode::Conflict => 409,
264            StatusCode::Gone => 410,
265            StatusCode::LengthRequired => 411,
266            StatusCode::PreconditionFailed => 412,
267            StatusCode::PayloadTooLarge => 413,
268            StatusCode::UriTooLong => 414,
269            StatusCode::UnsupportedMediaType => 415,
270            StatusCode::RangeNotSatisfiable => 416,
271            StatusCode::ExpectationFailed => 417,
272            StatusCode::ImATeapot => 418,
273            StatusCode::MisdirectedRequest => 421,
274            StatusCode::UnprocessableEntity => 422,
275            StatusCode::Locked => 423,
276            StatusCode::FailedDependency => 424,
277            StatusCode::UpgradeRequired => 426,
278            StatusCode::PreconditionRequired => 428,
279            StatusCode::TooManyRequests => 429,
280            StatusCode::RequestHeaderFieldsTooLarge => 431,
281            StatusCode::UnavailableForLegalReasons => 451,
282            StatusCode::InternalServerError => 500,
283            StatusCode::NotImplemented => 501,
284            StatusCode::BadGateway => 502,
285            StatusCode::ServiceUnavailable => 503,
286            StatusCode::GatewayTimeout => 504,
287            StatusCode::HttpVersionNotSupported => 505,
288            StatusCode::VariantAlsoNegotiates => 506,
289            StatusCode::InsufficientStorage => 507,
290            StatusCode::LoopDetected => 508,
291            StatusCode::NotExtended => 510,
292            StatusCode::NetworkAuthenticationRequired => 511,
293            StatusCode::Unknown(code) => code,
294        }
295    }
296
297    /// Returns the reason phrase of HTTP status code
298    #[inline]
299    pub fn reason_phrase(&self) -> &'static str {
300        match *self {
301            StatusCode::Continue => "Continue",
302            StatusCode::SwitchingProtocols => "Switching Protocols",
303            StatusCode::Processing => "Processing",
304            StatusCode::EarlyHints => "Early Hints",
305            StatusCode::Ok => "OK",
306            StatusCode::Created => "Created",
307            StatusCode::Accepted => "Accepted",
308            StatusCode::NonAuthoritativeInformation => "Non-Authoritative Information",
309            StatusCode::NoContent => "No Content",
310            StatusCode::ResetContent => "Reset Content",
311            StatusCode::PartialContent => "Partial Content",
312            StatusCode::MultiStatus => "Multi-Status",
313            StatusCode::AlreadyReported => "Already Reported",
314            StatusCode::IMUsed => "IM Used",
315            StatusCode::MultipleChoices => "Multiple Choices",
316            StatusCode::MovedPermanently => "Moved Permanently",
317            StatusCode::Found => "Found",
318            StatusCode::SeeOther => "See Other",
319            StatusCode::NotModified => "Not Modified",
320            StatusCode::UseProxy => "Use Proxy",
321            StatusCode::SwitchProxy => "Switch Proxy",
322            StatusCode::TemporaryRedirect => "Temporary Redirect",
323            StatusCode::PermanentRedirect => "Permanent Redirect",
324            StatusCode::BadRequest => "Bad Request",
325            StatusCode::Unauthorized => "Unauthorized",
326            StatusCode::PaymentRequired => "Payment Required",
327            StatusCode::Forbidden => "Forbidden",
328            StatusCode::NotFound => "Not Found",
329            StatusCode::MethodNotAllowed => "Method Not Allowed",
330            StatusCode::NotAcceptable => "Not Acceptable",
331            StatusCode::ProxyAuthenticationRequired => "Proxy Authentication Required",
332            StatusCode::RequestTimeout => "Request Timeout",
333            StatusCode::Conflict => "Conflict",
334            StatusCode::Gone => "Gone",
335            StatusCode::LengthRequired => "Length Required",
336            StatusCode::PreconditionFailed => "Precondition Failed",
337            StatusCode::PayloadTooLarge => "Payload Too Large",
338            StatusCode::UriTooLong => "URI Too Long",
339            StatusCode::UnsupportedMediaType => "Unsupported Media Type",
340            StatusCode::RangeNotSatisfiable => "Range Not Satisfiable",
341            StatusCode::ExpectationFailed => "Expectation Failed",
342            StatusCode::ImATeapot => "I'm a teapot",
343            StatusCode::MisdirectedRequest => "Misdirected Request",
344            StatusCode::UnprocessableEntity => "Unprocessable Entity",
345            StatusCode::Locked => "Locked",
346            StatusCode::FailedDependency => "Failed Dependency",
347            StatusCode::UpgradeRequired => "Upgrade Required",
348            StatusCode::PreconditionRequired => "Precondition Required",
349            StatusCode::TooManyRequests => "Too Many Requests",
350            StatusCode::RequestHeaderFieldsTooLarge => "Request Header Fields Too Large",
351            StatusCode::UnavailableForLegalReasons => "Unavailable For Legal Reasons",
352            StatusCode::InternalServerError => "Internal Server Error",
353            StatusCode::NotImplemented => "Not Implemented",
354            StatusCode::BadGateway => "Bad Gateway",
355            StatusCode::ServiceUnavailable => "Service Unavailable",
356            StatusCode::GatewayTimeout => "Gateway Timeout",
357            StatusCode::HttpVersionNotSupported => "Http Version Not Supported",
358            StatusCode::VariantAlsoNegotiates => "Variant Also Negotiates",
359            StatusCode::InsufficientStorage => "Insufficient Storage",
360            StatusCode::LoopDetected => "Loop Detected",
361            StatusCode::NotExtended => "Not Extended",
362            StatusCode::NetworkAuthenticationRequired => "Network Authentication Required",
363            StatusCode::Unknown(_) => "",
364        }
365    }
366
367    /// Returns the status class of status code
368    #[inline]
369    pub fn class(&self) -> StatusClass {
370        match self.as_u16() {
371            100..=199 => StatusClass::Informational,
372            200..=299 => StatusClass::Success,
373            300..=399 => StatusClass::Redirection,
374            400..=499 => StatusClass::ClientError,
375            500..=599 => StatusClass::ServerError,
376            _ => StatusClass::Unknown,
377        }
378    }
379}
380
381impl From<u16> for StatusCode {
382    fn from(code: u16) -> Self {
383        match code {
384            100 => StatusCode::Continue,
385            101 => StatusCode::SwitchingProtocols,
386            102 => StatusCode::Processing,
387            103 => StatusCode::EarlyHints,
388            200 => StatusCode::Ok,
389            201 => StatusCode::Created,
390            202 => StatusCode::Accepted,
391            203 => StatusCode::NonAuthoritativeInformation,
392            204 => StatusCode::NoContent,
393            205 => StatusCode::ResetContent,
394            206 => StatusCode::PartialContent,
395            207 => StatusCode::MultiStatus,
396            208 => StatusCode::AlreadyReported,
397            226 => StatusCode::IMUsed,
398            300 => StatusCode::MultipleChoices,
399            301 => StatusCode::MovedPermanently,
400            302 => StatusCode::Found,
401            303 => StatusCode::SeeOther,
402            304 => StatusCode::NotModified,
403            305 => StatusCode::UseProxy,
404            306 => StatusCode::SwitchProxy,
405            307 => StatusCode::TemporaryRedirect,
406            308 => StatusCode::PermanentRedirect,
407            400 => StatusCode::BadRequest,
408            401 => StatusCode::Unauthorized,
409            402 => StatusCode::PaymentRequired,
410            403 => StatusCode::Forbidden,
411            404 => StatusCode::NotFound,
412            405 => StatusCode::MethodNotAllowed,
413            406 => StatusCode::NotAcceptable,
414            407 => StatusCode::ProxyAuthenticationRequired,
415            408 => StatusCode::RequestTimeout,
416            409 => StatusCode::Conflict,
417            410 => StatusCode::Gone,
418            411 => StatusCode::LengthRequired,
419            412 => StatusCode::PreconditionFailed,
420            413 => StatusCode::PayloadTooLarge,
421            414 => StatusCode::UriTooLong,
422            415 => StatusCode::UnsupportedMediaType,
423            416 => StatusCode::RangeNotSatisfiable,
424            417 => StatusCode::ExpectationFailed,
425            418 => StatusCode::ImATeapot,
426            421 => StatusCode::MisdirectedRequest,
427            422 => StatusCode::UnprocessableEntity,
428            423 => StatusCode::Locked,
429            424 => StatusCode::FailedDependency,
430            426 => StatusCode::UpgradeRequired,
431            428 => StatusCode::PreconditionRequired,
432            429 => StatusCode::TooManyRequests,
433            431 => StatusCode::RequestHeaderFieldsTooLarge,
434            451 => StatusCode::UnavailableForLegalReasons,
435            500 => StatusCode::InternalServerError,
436            501 => StatusCode::NotImplemented,
437            502 => StatusCode::BadGateway,
438            503 => StatusCode::ServiceUnavailable,
439            504 => StatusCode::GatewayTimeout,
440            505 => StatusCode::HttpVersionNotSupported,
441            506 => StatusCode::VariantAlsoNegotiates,
442            507 => StatusCode::InsufficientStorage,
443            508 => StatusCode::LoopDetected,
444            510 => StatusCode::NotExtended,
445            511 => StatusCode::NetworkAuthenticationRequired,
446            _ => StatusCode::Unknown(code),
447        }
448    }
449}
450
451impl Display for StatusCode {
452    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
453        write!(
454            f,
455            "{}{}{}",
456            self.as_u16(),
457            if let StatusCode::Unknown(_) = *self {
458                ""
459            } else {
460                " "
461            },
462            self.reason_phrase()
463        )
464    }
465}