1use std::fmt::Display;
3
4#[non_exhaustive]
5#[derive(Hash, Eq, PartialEq, PartialOrd, Ord, Clone, Debug)]
6pub enum HttpStatus {
10 Informational(InformationalResponse),
12 Success(SuccessResponse),
14 Redirection(RedirectionResponse),
16 ClientError(ClientErrorResponse),
18 ServerError(ServerErrorResponse),
20}
21
22#[allow(unused)]
23impl HttpStatus {
24 pub const INTERNAL_SERVER_ERROR: Self =
25 Self::ServerError(ServerErrorResponse::InternalServerError);
26 pub const UNAUTHORIZED: Self = Self::ClientError(ClientErrorResponse::Unauthorized);
27 pub const NOT_FOUND: Self = Self::ClientError(ClientErrorResponse::NotFound);
28 pub const FORBIDDEN: Self = Self::ClientError(ClientErrorResponse::Forbidden);
29 pub const BAD_REQUEST: Self = Self::ClientError(ClientErrorResponse::BadRequest);
30 pub const TOO_MANY_REQUESTS: Self = Self::ClientError(ClientErrorResponse::TooManyRequests);
31 pub const OK: Self = Self::Success(SuccessResponse::OK);
32 pub const MOVED_PERMANENTLY: Self = Self::Redirection(RedirectionResponse::MovedPermanently);
33}
34
35impl Default for HttpStatus {
36 fn default() -> Self {
37 Self::Success(SuccessResponse::OK)
38 }
39}
40
41#[non_exhaustive]
42#[derive(Hash, Eq, PartialEq, PartialOrd, Ord, Clone, Debug)]
43pub enum InformationalResponse {
47 SwitchingProtocols = 101,
49 Processing = 102,
50 EarlyHints = 103,
51}
52#[non_exhaustive]
53#[derive(Hash, Eq, PartialEq, PartialOrd, Ord, Clone, Debug, Default)]
54pub enum SuccessResponse {
58 #[default]
59 OK = 200,
60 Created = 201,
61 Accepted = 202,
62 NonAuthoritativeInformation = 203,
63 NoContent = 204,
64 ResetContent = 205,
65 PartialContent = 206,
66 MultiStatus = 207,
67 AlreadyReported = 208,
68 IMUsed = 226,
69}
70#[non_exhaustive]
71#[derive(Hash, Eq, PartialEq, PartialOrd, Ord, Clone, Debug)]
72pub enum RedirectionResponse {
76 MultipleChoices = 300,
77 MovedPermanently = 301,
78 Found = 302,
79 SeeOther = 303,
80 NotModified = 304,
81 UseProxy = 305,
82 SwitchProxy = 306,
83 TemporaryRedirect = 307,
84 PermanentRedirect = 308,
85}
86#[non_exhaustive]
87#[derive(Hash, Eq, PartialEq, PartialOrd, Ord, Clone, Debug)]
88pub enum ClientErrorResponse {
92 BadRequest = 400,
93 Unauthorized = 401,
94 PaymentRequired = 402,
95 Forbidden = 403,
96 NotFound = 404,
97 MethodNotAllowed = 405,
98 NotAcceptable = 406,
99 ProxyAuthenticationRequired = 407,
100 RequestTimeout = 408,
101 Conflict = 409,
102 Gone = 410,
103 LengthRequired = 411,
104 PreconditionFailed = 412,
105 PayloadTooLarge = 413,
106 URITooLong = 414,
107 UnsupportedMediaType = 415,
108 RangeNotSatisfiable = 416,
109 ExpectationFailed = 417,
110 ImATeapot = 418,
111 MisdirectedRequest = 421,
112 UnprocessableContent = 422,
113 Locked = 423,
114 FailedDependency = 424,
115 TooEarly = 425,
116 UpgradeRequired = 426,
117 PreconditionRequired = 428,
118 TooManyRequests = 429,
119 RequestHeaderFieldsTooLarge = 431,
120 UnavailableForLegalReasons = 451,
121}
122#[non_exhaustive]
123#[derive(Hash, Eq, PartialEq, PartialOrd, Ord, Clone, Debug)]
124pub enum ServerErrorResponse {
128 InternalServerError = 500,
129 NotImplemented = 501,
130 BadGateway = 502,
131 ServiceUnavailable = 503,
132 GatewayTimeout = 504,
133 HTTPVersionNotSupported = 505,
134 VariantAlsoNegotiates = 506,
135 InsufficientStorage = 507,
136 LoopDetected = 508,
137 NotExtended = 510,
138 NetworkAuthenticationRequired = 511,
139}
140
141impl Display for HttpStatus {
142 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
143 match self {
144 HttpStatus::Informational(informational_response) => {
145 write!(f, "{informational_response}")
146 }
147 HttpStatus::Success(success_response) => write!(f, "{success_response}"),
148 HttpStatus::Redirection(redirection_response) => write!(f, "{redirection_response}"),
149 HttpStatus::ClientError(client_error_response) => write!(f, "{client_error_response}"),
150 HttpStatus::ServerError(server_error_response) => write!(f, "{server_error_response}"),
151 }
152 }
153}
154
155impl Display for ServerErrorResponse {
156 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
157 let (name, num) = match self {
158 ServerErrorResponse::InternalServerError => (
159 "InternalServerError",
160 ServerErrorResponse::InternalServerError as u16,
161 ),
162 ServerErrorResponse::NotImplemented => {
163 ("NotImplemented", ServerErrorResponse::NotImplemented as u16)
164 }
165 ServerErrorResponse::BadGateway => {
166 ("BadGateway", ServerErrorResponse::BadGateway as u16)
167 }
168 ServerErrorResponse::ServiceUnavailable => (
169 "ServiceUnavailable",
170 ServerErrorResponse::ServiceUnavailable as u16,
171 ),
172 ServerErrorResponse::GatewayTimeout => {
173 ("GatewayTimeout", ServerErrorResponse::GatewayTimeout as u16)
174 }
175 ServerErrorResponse::HTTPVersionNotSupported => (
176 "HTTPVersionNotSupported",
177 ServerErrorResponse::HTTPVersionNotSupported as u16,
178 ),
179 ServerErrorResponse::VariantAlsoNegotiates => (
180 "VariantAlsoNegotiates",
181 ServerErrorResponse::VariantAlsoNegotiates as u16,
182 ),
183 ServerErrorResponse::InsufficientStorage => (
184 "InsufficientStorage",
185 ServerErrorResponse::InsufficientStorage as u16,
186 ),
187 ServerErrorResponse::LoopDetected => {
188 ("LoopDetected", ServerErrorResponse::LoopDetected as u16)
189 }
190 ServerErrorResponse::NotExtended => {
191 ("NotExtended", ServerErrorResponse::NotExtended as u16)
192 }
193 ServerErrorResponse::NetworkAuthenticationRequired => (
194 "NetworkAuthenticationRequired",
195 ServerErrorResponse::NetworkAuthenticationRequired as u16,
196 ),
197 };
198 write!(f, "{num} {name}")
199 }
200}
201
202impl Display for ClientErrorResponse {
203 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
204 let (name, num) = match self {
205 ClientErrorResponse::BadRequest => {
206 ("BadRequest", ClientErrorResponse::BadRequest as u16)
207 }
208 ClientErrorResponse::Unauthorized => {
209 ("Unauthorized", ClientErrorResponse::Unauthorized as u16)
210 }
211 ClientErrorResponse::PaymentRequired => (
212 "PaymentRequired",
213 ClientErrorResponse::PaymentRequired as u16,
214 ),
215 ClientErrorResponse::Forbidden => ("Forbidden", ClientErrorResponse::Forbidden as u16),
216 ClientErrorResponse::NotFound => ("NotFound", ClientErrorResponse::NotFound as u16),
217 ClientErrorResponse::MethodNotAllowed => (
218 "MethodNotAllowed",
219 ClientErrorResponse::MethodNotAllowed as u16,
220 ),
221 ClientErrorResponse::NotAcceptable => {
222 ("NotAcceptable", ClientErrorResponse::NotAcceptable as u16)
223 }
224 ClientErrorResponse::ProxyAuthenticationRequired => (
225 "ProxyAuthenticationRequired",
226 ClientErrorResponse::ProxyAuthenticationRequired as u16,
227 ),
228 ClientErrorResponse::RequestTimeout => {
229 ("RequestTimeout", ClientErrorResponse::RequestTimeout as u16)
230 }
231 ClientErrorResponse::Conflict => ("Conflict", ClientErrorResponse::Conflict as u16),
232 ClientErrorResponse::Gone => ("Gone", ClientErrorResponse::Gone as u16),
233 ClientErrorResponse::LengthRequired => {
234 ("LengthRequired", ClientErrorResponse::LengthRequired as u16)
235 }
236 ClientErrorResponse::PreconditionFailed => (
237 "PreconditionFailed",
238 ClientErrorResponse::PreconditionFailed as u16,
239 ),
240 ClientErrorResponse::PayloadTooLarge => (
241 "PayloadTooLarge",
242 ClientErrorResponse::PayloadTooLarge as u16,
243 ),
244 ClientErrorResponse::URITooLong => {
245 ("URITooLong", ClientErrorResponse::URITooLong as u16)
246 }
247 ClientErrorResponse::UnsupportedMediaType => (
248 "UnsupportedMediaType",
249 ClientErrorResponse::UnsupportedMediaType as u16,
250 ),
251 ClientErrorResponse::RangeNotSatisfiable => (
252 "RangeNotSatisfiable",
253 ClientErrorResponse::RangeNotSatisfiable as u16,
254 ),
255 ClientErrorResponse::ExpectationFailed => (
256 "ExpectationFailed",
257 ClientErrorResponse::ExpectationFailed as u16,
258 ),
259 ClientErrorResponse::ImATeapot => ("ImATeapot", ClientErrorResponse::ImATeapot as u16),
260 ClientErrorResponse::MisdirectedRequest => (
261 "MisdirectedRequest",
262 ClientErrorResponse::MisdirectedRequest as u16,
263 ),
264 ClientErrorResponse::UnprocessableContent => (
265 "UnprocessableContent",
266 ClientErrorResponse::UnprocessableContent as u16,
267 ),
268 ClientErrorResponse::Locked => ("Locked", ClientErrorResponse::Locked as u16),
269 ClientErrorResponse::FailedDependency => (
270 "FailedDependency",
271 ClientErrorResponse::FailedDependency as u16,
272 ),
273 ClientErrorResponse::TooEarly => ("TooEarly", ClientErrorResponse::TooEarly as u16),
274 ClientErrorResponse::UpgradeRequired => (
275 "UpgradeRequired",
276 ClientErrorResponse::UpgradeRequired as u16,
277 ),
278 ClientErrorResponse::PreconditionRequired => (
279 "PreconditionRequired",
280 ClientErrorResponse::PreconditionRequired as u16,
281 ),
282 ClientErrorResponse::TooManyRequests => (
283 "TooManyRequests",
284 ClientErrorResponse::TooManyRequests as u16,
285 ),
286 ClientErrorResponse::RequestHeaderFieldsTooLarge => (
287 "RequestHeaderFieldsTooLarge",
288 ClientErrorResponse::RequestHeaderFieldsTooLarge as u16,
289 ),
290 ClientErrorResponse::UnavailableForLegalReasons => (
291 "UnavailableForLegalReasons",
292 ClientErrorResponse::UnavailableForLegalReasons as u16,
293 ),
294 };
295 write!(f, "{num} {name}")
296 }
297}
298
299impl Display for RedirectionResponse {
300 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
301 let (name, num) = match self {
302 RedirectionResponse::MultipleChoices => (
303 "MultipleChoices",
304 RedirectionResponse::MultipleChoices as u16,
305 ),
306 RedirectionResponse::MovedPermanently => (
307 "MovedPermanently",
308 RedirectionResponse::MovedPermanently as u16,
309 ),
310 RedirectionResponse::Found => ("Found", RedirectionResponse::Found as u16),
311 RedirectionResponse::SeeOther => ("SeeOther", RedirectionResponse::SeeOther as u16),
312 RedirectionResponse::NotModified => {
313 ("NotModified", RedirectionResponse::NotModified as u16)
314 }
315 RedirectionResponse::UseProxy => ("UseProxy", RedirectionResponse::UseProxy as u16),
316 RedirectionResponse::SwitchProxy => {
317 ("SwitchProxy", RedirectionResponse::SwitchProxy as u16)
318 }
319 RedirectionResponse::TemporaryRedirect => (
320 "TemporaryRedirect",
321 RedirectionResponse::TemporaryRedirect as u16,
322 ),
323 RedirectionResponse::PermanentRedirect => (
324 "PermanentRedirect",
325 RedirectionResponse::PermanentRedirect as u16,
326 ),
327 };
328 write!(f, "{num} {name}")
329 }
330}
331
332impl Display for SuccessResponse {
333 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
334 let (name, num) = match self {
335 SuccessResponse::OK => ("OK", SuccessResponse::OK as u16),
336 SuccessResponse::Created => ("Created", SuccessResponse::Created as u16),
337 SuccessResponse::Accepted => ("Accepted", SuccessResponse::Accepted as u16),
338 SuccessResponse::NonAuthoritativeInformation => (
339 "NonAuthoritativeInformation",
340 SuccessResponse::NonAuthoritativeInformation as u16,
341 ),
342 SuccessResponse::NoContent => ("NoContent", SuccessResponse::NoContent as u16),
343 SuccessResponse::ResetContent => ("ResetContent", SuccessResponse::ResetContent as u16),
344 SuccessResponse::PartialContent => {
345 ("PartialContent", SuccessResponse::PartialContent as u16)
346 }
347 SuccessResponse::MultiStatus => ("MultiStatus", SuccessResponse::MultiStatus as u16),
348 SuccessResponse::AlreadyReported => {
349 ("AlreadyReported", SuccessResponse::AlreadyReported as u16)
350 }
351 SuccessResponse::IMUsed => ("IMUsed", SuccessResponse::IMUsed as u16),
352 };
353 write!(f, "{num} {name}")
354 }
355}
356
357impl Display for InformationalResponse {
358 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
359 match self {
360 InformationalResponse::SwitchingProtocols => write!(
361 f,
362 "{} SwitchingProtocols",
363 InformationalResponse::SwitchingProtocols
364 ),
365 InformationalResponse::Processing => {
366 write!(f, "{} Processing", InformationalResponse::Processing)
367 }
368 InformationalResponse::EarlyHints => {
369 write!(f, "{} EarlyHints", InformationalResponse::EarlyHints)
370 }
371 }
372 }
373}
374
375impl From<ClientErrorResponse> for HttpStatus {
376 fn from(val: ClientErrorResponse) -> Self {
377 HttpStatus::ClientError(val)
378 }
379}
380impl From<ServerErrorResponse> for HttpStatus {
381 fn from(val: ServerErrorResponse) -> Self {
382 HttpStatus::ServerError(val)
383 }
384}
385impl From<InformationalResponse> for HttpStatus {
386 fn from(val: InformationalResponse) -> Self {
387 HttpStatus::Informational(val)
388 }
389}
390impl From<RedirectionResponse> for HttpStatus {
391 fn from(val: RedirectionResponse) -> Self {
392 HttpStatus::Redirection(val)
393 }
394}
395impl From<SuccessResponse> for HttpStatus {
396 fn from(val: SuccessResponse) -> Self {
397 HttpStatus::Success(val)
398 }
399}