1use std::{borrow::Cow, fmt};
2
3#[derive(Clone, Debug, PartialEq, Eq)]
4pub struct Status<'a> {
5 pub code: u16,
6 pub reason: Cow<'a, str>,
7}
8
9impl<'a> Status<'a> {
10 pub const fn borrowed(code: u16, reason: &'a str) -> Self {
11 Self {
12 code,
13 reason: Cow::Borrowed(reason),
14 }
15 }
16 pub fn owned(code: u16, reason: String) -> Self {
17 Self {
18 code,
19 reason: Cow::Owned(reason),
20 }
21 }
22}
23
24impl fmt::Display for Status<'_> {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 write!(f, "{} {}", self.code, self.reason)
27 }
28}
29
30impl From<u16> for Status<'_> {
31 fn from(code: u16) -> Self {
32 Self::of(code)
33 }
34}
35
36impl PartialEq<u16> for Status<'_> {
37 fn eq(&self, other: &u16) -> bool {
38 self.code == *other
39 }
40}
41
42macro_rules! define_statuses {
43 (
44 common {
45 $( $pcode:literal => $pident:ident, $preason:expr );* $(;)?
46 }
47 other {
48 $( $ocode:literal => $oident:ident, $oreason:expr );* $(;)?
49 }
50 ) => {
51 impl<'a> Status<'a> {
52 $(
53 pub const $pident: Status<'a> = Status::borrowed($pcode, $preason);
54 )*
55 $(
56 const $oident: Status<'a> = Status::borrowed($ocode, $oreason);
57 )*
58
59 pub const fn of(code: u16) -> Self {
60 match code {
61 $(
62 $pcode => Status::$pident,
63 )*
64 $(
65 $ocode => Status::$oident,
66 )*
67 _ => Status::borrowed(code, ""),
68 }
69 }
70 }
71 };
72}
73
74define_statuses! {
75 common {
76 200 => OK, "OK";
77 201 => CREATED, "CREATED";
78 204 => NO_CONTENT, "NO CONTENT";
79 301 => MOVED_PERMANENTLY, "MOVED PERMANENTLY";
80 302 => FOUND, "FOUND";
81 304 => NOT_MODIFIED, "NOT MODIFIED";
82 400 => BAD_REQUEST, "BAD REQUEST";
83 401 => UNAUTHORIZED, "UNAUTHORIZED";
84 403 => FORBIDDEN, "FORBIDDEN";
85 404 => NOT_FOUND, "NOT FOUND";
86 429 => TOO_MANY_REQUESTS, "TOO MANY REQUESTS";
87 500 => INTERNAL_SERVER_ERROR, "INTERNAL SERVER ERROR";
88 503 => SERVICE_UNAVAILABLE, "SERVICE UNAVAILABLE";
89 }
90 other {
91 100 => CONTINUE, "CONTINUE";
92 101 => SWITCHING_PROTOCOLS, "SWITCHING PROTOCOLS";
93 102 => PROCESSING, "PROCESSING";
94 103 => EARLY_HINTS, "EARLY HINTS";
95 202 => ACCEPTED, "ACCEPTED";
96 203 => NON_AUTHORITATIVE_INFORMATION, "NON-AUTHORITATIVE INFORMATION";
97 205 => RESET_CONTENT, "RESET CONTENT";
98 206 => PARTIAL_CONTENT, "PARTIAL CONTENT";
99 207 => MULTI_STATUS, "MULTI-STATUS";
100 208 => ALREADY_REPORTED, "ALREADY REPORTED";
101 226 => IM_USED, "IM USED";
102 300 => MULTIPLE_CHOICES, "MULTIPLE CHOICES";
103 303 => SEE_OTHER, "SEE OTHER";
104 305 => USE_PROXY, "USE PROXY";
105 307 => TEMPORARY_REDIRECT, "TEMPORARY REDIRECT";
106 308 => PERMANENT_REDIRECT, "PERMANENT REDIRECT";
107 402 => PAYMENT_REQUIRED, "PAYMENT REQUIRED";
108 405 => METHOD_NOT_ALLOWED, "METHOD NOT ALLOWED";
109 406 => NOT_ACCEPTABLE, "NOT ACCEPTABLE";
110 407 => PROXY_AUTHENTICATION_REQUIRED, "PROXY AUTHENTICATION REQUIRED";
111 408 => REQUEST_TIMEOUT, "REQUEST TIMEOUT";
112 409 => CONFLICT, "CONFLICT";
113 410 => GONE, "GONE";
114 411 => LENGTH_REQUIRED, "LENGTH REQUIRED";
115 412 => PRECONDITION_FAILED, "PRECONDITION FAILED";
116 413 => PAYLOAD_TOO_LARGE, "PAYLOAD TOO LARGE";
117 414 => URI_TOO_LONG, "URI TOO LONG";
118 415 => UNSUPPORTED_MEDIA_TYPE, "UNSUPPORTED MEDIA TYPE";
119 416 => RANGE_NOT_SATISFIABLE, "RANGE NOT SATISFIABLE";
120 417 => EXPECTATION_FAILED, "EXPECTATION FAILED";
121 418 => IM_A_TEAPOT, "I'M A TEAPOT";
122 421 => MISDIRECTED_REQUEST, "MISDIRECTED REQUEST";
123 422 => UNPROCESSABLE_ENTITY, "UNPROCESSABLE ENTITY";
124 423 => LOCKED, "LOCKED";
125 424 => FAILED_DEPENDENCY, "FAILED DEPENDENCY";
126 425 => TOO_EARLY, "TOO EARLY";
127 426 => UPGRADE_REQUIRED, "UPGRADE REQUIRED";
128 428 => PRECONDITION_REQUIRED, "PRECONDITION REQUIRED";
129 431 => REQUEST_HEADER_FIELDS_TOO_LARGE, "REQUEST HEADER FIELDS TOO LARGE";
130 451 => UNAVAILABLE_FOR_LEGAL_REASONS, "UNAVAILABLE FOR LEGAL REASONS";
131 501 => NOT_IMPLEMENTED, "NOT IMPLEMENTED";
132 502 => BAD_GATEWAY, "BAD GATEWAY";
133 504 => GATEWAY_TIMEOUT, "GATEWAY TIMEOUT";
134 505 => HTTP_VERSION_NOT_SUPPORTED, "HTTP VERSION NOT SUPPORTED";
135 506 => VARIANT_ALSO_NEGOTIATES, "VARIANT ALSO NEGOTIATES";
136 507 => INSUFFICIENT_STORAGE, "INSUFFICIENT STORAGE";
137 508 => LOOP_DETECTED, "LOOP DETECTED";
138 510 => NOT_EXTENDED, "NOT EXTENDED";
139 511 => NETWORK_AUTHENTICATION_REQUIRED, "NETWORK AUTHENTICATION REQUIRED";
140 }
141}