1#![crate_name = "httpstatus"]
6
7use serde::{Deserialize, Serialize};
8use std::convert::From;
9use std::fmt::{Display, Error, Formatter};
10
11#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Hash, Serialize, Deserialize)]
13pub enum StatusCode {
14 Continue,
16
17 SwitchingProtocols,
19
20 Processing,
22
23 EarlyHints,
25
26 Ok,
28
29 Created,
31
32 Accepted,
34
35 NonAuthoritativeInformation,
37
38 NoContent,
40
41 ResetContent,
43
44 PartialContent,
46
47 MultiStatus,
49
50 AlreadyReported,
52
53 IMUsed,
55
56 MultipleChoices,
58
59 MovedPermanently,
61
62 Found,
64
65 SeeOther,
67
68 NotModified,
70
71 UseProxy,
73
74 SwitchProxy,
76
77 TemporaryRedirect,
79
80 PermanentRedirect,
82
83 BadRequest,
85
86 Unauthorized,
88
89 PaymentRequired,
91
92 Forbidden,
94
95 NotFound,
97
98 MethodNotAllowed,
100
101 NotAcceptable,
103
104 ProxyAuthenticationRequired,
106
107 RequestTimeout,
109
110 Conflict,
112
113 Gone,
115
116 LengthRequired,
118
119 PreconditionFailed,
121
122 PayloadTooLarge,
124
125 UriTooLong,
127
128 UnsupportedMediaType,
130
131 RangeNotSatisfiable,
133
134 ExpectationFailed,
136
137 ImATeapot,
139
140 MisdirectedRequest,
142
143 UnprocessableEntity,
145
146 Locked,
148
149 FailedDependency,
151
152 UpgradeRequired,
154
155 PreconditionRequired,
157
158 TooManyRequests,
160
161 RequestHeaderFieldsTooLarge,
163
164 UnavailableForLegalReasons,
166
167 InternalServerError,
169
170 NotImplemented,
172
173 BadGateway,
175
176 ServiceUnavailable,
178
179 GatewayTimeout,
181
182 HttpVersionNotSupported,
184
185 VariantAlsoNegotiates,
187
188 InsufficientStorage,
190
191 LoopDetected,
193
194 NotExtended,
196
197 NetworkAuthenticationRequired,
199
200 Unknown(u16),
202}
203
204#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Hash, Serialize, Deserialize)]
206pub enum StatusClass {
207 Informational,
209
210 Success,
212
213 Redirection,
215
216 ClientError,
218
219 ServerError,
221
222 Unknown,
224}
225
226impl StatusCode {
227 #[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 #[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 #[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}