simbld_http/responses/
client.rs

1/// The code defines an enum representing HTTP response status codes with corresponding descriptions and provides helper functions to retrieve code-description pairs.
2use crate::helpers::{from_u16_helper::FromU16, to_u16_helper::ToU16};
3use num_enum::{IntoPrimitive, TryFromPrimitive};
4use strum::EnumProperty;
5use strum_macros::{Display, EnumIter, EnumProperty};
6
7#[derive(
8  Display, IntoPrimitive, TryFromPrimitive, EnumProperty, EnumIter, Debug, Copy, Clone, PartialEq,
9)]
10#[repr(u16)]
11
12pub enum ResponsesClientCodes {
13  #[strum(props(
14    Description = "The server cannot process the request due to malformed syntax or invalid parameters in the client request"
15  ))]
16  BadRequest = 400,
17  #[strum(props(
18    Description = "The client must authenticate itself to get the requested resource, typically a 401 Unauthorized response"
19  ))]
20  Unauthorized = 401,
21  #[strum(props(
22    Description = "Payment is required to access the requested resource, though this is not widely used in practice"
23  ))]
24  PaymentRequired = 402,
25  #[strum(props(
26    Description = "The server understands the request but refuses to authorize it, indicating insufficient permissions"
27  ))]
28  Forbidden = 403,
29  #[strum(props(
30    Description = "The server cannot find the requested resource, indicating a non-existent or inaccessible URI"
31  ))]
32  NotFound = 404,
33  #[strum(props(
34    Description = "The HTTP method used in the request is not supported for the target resource"
35  ))]
36  MethodNotAllowed = 405,
37  #[strum(props(
38    Description = "The requested resource cannot be provided in a format acceptable according to the request's Accept headers"
39  ))]
40  NotAcceptable = 406,
41  #[strum(props(
42    Description = "The client must authenticate with a proxy server before accessing the resource"
43  ))]
44  ProxyAuthenticationRequired = 407,
45  #[strum(props(
46    Description = "The server timed out while waiting for the request from the client. This status code is used to inform the client that the server timed out."
47  ))]
48  RequestTimeout = 408,
49  #[strum(props(
50    Description = "The request could not be completed due to a conflict with the current state of the target resource"
51  ))]
52  Conflict = 409,
53  #[strum(props(
54    Description = "The requested resource is no longer available and has been permanently removed from the server and will not be available again"
55  ))]
56  Gone = 410,
57  #[strum(props(Description = "The request does not include the required Content-Length header"))]
58  LengthRequired = 411,
59  #[strum(props(
60    Description = "One or more conditions in the request headers are not met by the server"
61  ))]
62  PreconditionFailed = 412,
63  #[strum(props(
64    Description = "The size of the request payload exceeds the server's capacity or configuration limits"
65  ))]
66  PayloadTooLarge = 413,
67  #[strum(props(
68    Description = "The URI of the request is too long for the server to process. This status code is used to inform the client that the request URI is too long"
69  ))]
70  RequestUriTooLong = 414,
71  #[strum(props(
72    Description = "The media type of the request payload is not supported by the server or target resource"
73  ))]
74  UnsupportedMediaType = 415,
75  #[strum(props(
76    Description = "The client requested a range that is not satisfiable for the target resource"
77  ))]
78  RequestedRangeUnsatisfiable = 416,
79  #[strum(props(
80    Description = "The server cannot meet the requirements specified in the Expect header field of the request"
81  ))]
82  ExpectationFailed = 417,
83  #[strum(props(
84    Description = "A playful response indicating the server is a teapot and cannot brew coffee (RFC 2324)"
85  ))]
86  ImATeapot = 418,
87  #[strum(props(
88    Description = "Issued by Laravel when a CSRF token is missing or expired, unofficial"
89  ))]
90  PageExpired = 419,
91  #[strum(props(
92    Description = "The method specified in the request is known by the server but cannot be processed due to a failure in the server's implementation, Issued by Spring when a method has failed. Now deprecated and reserved for backward compatibility, unofficial"
93  ))]
94  MethodFailure = 420,
95  #[strum(props(
96    Description = "Used by Twitter to indicate that the client has sent too many requests in a given amount of time, unofficial"
97  ))]
98  MisdirectedRequest = 421,
99  #[strum(props(
100    Description = "The request is well-formed but cannot be processed due to semantic errors, commonly used in APIs, use in WebDav RFC 4918"
101  ))]
102  UnprocessableEntity = 422,
103  #[strum(props(
104    Description = "The resource is locked and cannot be accessed or modified, typically used in WebDav RFC 4918"
105  ))]
106  LockedTemporarilyUnavailable = 423,
107  #[strum(props(
108    Description = "The request failed because it depended on another operation that failed, often used in WebDav RFC 4918"
109  ))]
110  FailedDependency = 424,
111  #[strum(props(
112    Description = "The server is unwilling to process the request because it might be replayed"
113  ))]
114  TooEarly = 425, // Only for Firefox
115  #[strum(props(
116    Description = "The client must upgrade to a different protocol to continue with the request"
117  ))]
118  UpgradeRequired = 426,
119  #[strum(props(
120    Description = "The server requires the request to include specific preconditions to proceed"
121  ))]
122  PreconditionRequired = 428,
123  #[strum(props(
124    Description = "The resource is rate-limited and the client has sent too many requests in the allotted time"
125  ))]
126  TooManyRequests = 429,
127  #[strum(props(
128    Description = "Issued by Shopify to indicate a rate-limit effect. This is used instead of 429, unofficial"
129  ))]
130  RequestHeaderFieldsTooLarge = 430,
131  #[strum(props(
132    Description = "Authentication is required to access the requested resource, typically in web applications"
133  ))]
134  LoginRequired = 432,
135  #[strum(props(
136    Description = "The request was rejected due to an issue with the origin server or client IP"
137  ))]
138  OriginError = 433,
139  #[strum(props(
140    Description = "The request was rejected due to an issue with the destination server or target configuration"
141  ))]
142  DestinationError = 434,
143  #[strum(props(
144    Description = "The size of the requested resource or payload exceeds the allowable limit for the server"
145  ))]
146  TooLarge = 435,
147  #[strum(props(
148    Description = "An error occurred due to an invalid or untrusted SSL certificate"
149  ))]
150  SSLCertificateError = 436,
151  #[strum(props(
152    Description = "The server requires a valid SSL certificate for the connection to proceed securely"
153  ))]
154  SSLCertificateRequired = 437,
155  #[strum(props(
156    Description = "The client did not provide an SSL certificate required for secure communication"
157  ))]
158  NoCertificate = 438,
159  #[strum(props(
160    Description = "The client session timed out and must log in again, iis, unofficial"
161  ))]
162  LoginTimeout = 440,
163  #[strum(props(
164    Description = "The client has exceeded the allocated data quota for the requested operation"
165  ))]
166  OverDataQuota = 441,
167  #[strum(props(
168    Description = "The server closed the connection without sending any response, often used in scenarios where the server chooses to silently drop the request, nginx, unofficial"
169  ))]
170  NoResponse = 444,
171  #[strum(props(
172    Description = "The user has not provided the required information, iis, unofficial"
173  ))]
174  RetryWith = 449,
175  #[strum(props(
176    Description = "Issued by Microsoft when Windows Parental Controls are turned on and a resource is blocked, unofficial"
177  ))]
178  BlockedByWindowsParentalControls = 450,
179  #[strum(props(
180    Description = "The server is denying access to the resource due to legal reasons, such as censorship or compliance with local laws"
181  ))]
182  UnavailableForLegalReasons = 451,
183  #[strum(props(
184    Description = "The server is unable to process the request because it contains too many recipients"
185  ))]
186  TooManyRecipients = 452,
187  #[strum(props(
188    Description = "The method specified in the request is not valid for the current state of the resource or server"
189  ))]
190  MethodNotValidInThisState = 455,
191  #[strum(props(
192    Description = "The server encountered a critical error that prevents it from continuing to process the request"
193  ))]
194  UnrecoverableError = 456,
195  #[strum(props(
196    Description = "The client closed the connection before the server was able to send a response, often due to a timeout or network interruption"
197  ))]
198  ClientClosedConnexionPrematurely = 460,
199  #[strum(props(
200    Description = "The server rejected the request due to an excessive number of forwarded IP addresses in the request headers, potentially indicating a misconfiguration or a security concern"
201  ))]
202  TooManyForwardedIPAddresses = 463,
203  #[strum(props(
204    Description = "An internet security policy violation or configuration issue occurred, often related to SSL/TLS settings, certificates, or protocol mismatches"
205  ))]
206  InternetSecurityError = 467,
207  #[strum(props(
208    Description = "The server is temporarily unavailable, usually due to maintenance or overload"
209  ))]
210  TemporaryUnavailable = 480,
211  #[strum(props(
212    Description = "The server is unable to process the request because the headers are too large, often due to a misconfiguration or an attack, nginx, unofficial"
213  ))]
214  RequestHeaderTooLarge = 494,
215  #[strum(props(
216    Description = "The SSL certificate presented by the client is invalid or cannot be verified by the server, preventing a secure connection from being established, nginx, unofficial"
217  ))]
218  CertError = 495,
219  #[strum(props(
220    Description = "A required client certificate wasn't provided, preventing the server from establishing a secure connection, nginx, unofficial"
221  ))]
222  NoCert = 496,
223  #[strum(props(
224    Description = "The client sent an unencrypted HTTP request to a server that requires HTTPS, and the server is redirecting the client to the HTTPS version of the resource, nginx, unofficial"
225  ))]
226  HTTPToHTTPS = 497,
227  #[strum(props(
228    Description = "The provided token is invalid, expired, or malformed, and cannot be used for authentication or authorization, Issued by ArcGIS for Server, unofficial"
229  ))]
230  InvalidToken = 498,
231  #[strum(props(
232    Description = "The client closed the connection before the server could provide a response, often due to client timeout or network interruption, nginx, unofficial"
233  ))]
234  ClientClosedRequest = 499,
235}
236
237impl ToU16 for ResponsesClientCodes {
238  fn to_u16(self) -> u16 {
239    self.into() // Conversion`Into<u16>`
240  }
241}
242
243impl FromU16 for ResponsesClientCodes {
244  fn from_u16(code: u16) -> Option<Self> {
245    Self::try_from(code).ok() // Conversion`TryFrom<u16>`
246  }
247}
248
249impl Into<(u16, &'static str)> for ResponsesClientCodes {
250  fn into(self) -> (u16, &'static str) {
251    let code: u16 = self.to_u16();
252    let description = self.get_str("Description").unwrap_or("No description");
253    (code, description) // Tuple
254  }
255}
256
257pub fn bad_request() -> (u16, &'static str) {
258  (400, "The server cannot process the request due to malformed syntax or invalid parameters in the client request")
259}
260
261pub fn unauthorized() -> (u16, &'static str) {
262  (401, "The client must authenticate itself to get the requested resource, typically a 401 Unauthorized response")
263}
264
265pub fn payment_required() -> (u16, &'static str) {
266  (402, "Payment is required to access the requested resource, though this is not widely used in practice")
267}
268
269pub fn forbidden() -> (u16, &'static str) {
270  (403, "The server understands the request but refuses to authorize it, indicating insufficient permissions")
271}
272
273pub fn not_found() -> (u16, &'static str) {
274  (
275    404,
276    "The server cannot find the requested resource, indicating a non-existent or inaccessible URI",
277  )
278}
279
280pub fn method_not_allowed() -> (u16, &'static str) {
281  (405, "The HTTP method used in the request is not supported for the target resource")
282}
283
284pub fn not_acceptable() -> (u16, &'static str) {
285  (406, "The requested resource cannot be provided in a format acceptable according to the request's Accept headers")
286}
287
288pub fn proxy_authentication_required() -> (u16, &'static str) {
289  (407, "The client must authenticate with a proxy server before accessing the resource")
290}
291
292pub fn request_timeout() -> (u16, &'static str) {
293  (408, "The server timed out while waiting for the request from the client. This status code is used to inform the client that the server timed out.")
294}
295
296pub fn conflict() -> (u16, &'static str) {
297  (409, "The request could not be completed due to a conflict with the current state of the target resource")
298}
299
300pub fn gone() -> (u16, &'static str) {
301  (410, "The requested resource is no longer available and has been permanently removed from the server and will not be available again")
302}
303
304pub fn length_required() -> (u16, &'static str) {
305  (411, "The request does not include the required Content-Length header")
306}
307
308pub fn precondition_failed() -> (u16, &'static str) {
309  (412, "One or more conditions in the request headers are not met by the server")
310}
311
312pub fn payload_too_large() -> (u16, &'static str) {
313  (413, "The size of the request payload exceeds the server's capacity or configuration limits")
314}
315
316pub fn request_uri_too_long() -> (u16, &'static str) {
317  (414, "The URI of the request is too long for the server to process. This status code is used to inform the client that the request URI is too long")
318}
319
320pub fn unsupported_media_type() -> (u16, &'static str) {
321  (415, "The media type of the request payload is not supported by the server or target resource")
322}
323
324pub fn requested_range_unsatisfiable() -> (u16, &'static str) {
325  (416, "The client requested a range that is not satisfiable for the target resource")
326}
327
328pub fn expectation_failed() -> (u16, &'static str) {
329  (
330    417,
331    "The server cannot meet the requirements specified in the Expect header field of the request",
332  )
333}
334
335pub fn im_a_teapot() -> (u16, &'static str) {
336  (418, "A playful response indicating the server is a teapot and cannot brew coffee (RFC 2324)")
337}
338
339pub fn page_expired() -> (u16, &'static str) {
340  (419, "Issued by Laravel when a CSRF token is missing or expired, unofficial")
341}
342
343pub fn method_failure() -> (u16, &'static str) {
344  (420, "The method specified in the request is known by the server but cannot be processed due to a failure in the server's implementation, Issued by Spring when a method has failed. Now deprecated and reserved for backward compatibility, unofficial")
345}
346
347pub fn misdirected_request() -> (u16, &'static str) {
348  (421, "Used by Twitter to indicate that the client has sent too many requests in a given amount of time, unofficial")
349}
350
351pub fn unprocessable_entity() -> (u16, &'static str) {
352  (422, "The request is well-formed but cannot be processed due to semantic errors, commonly used in APIs, use in WebDav RFC 4918")
353}
354
355pub fn locked_temporarily_unavailable() -> (u16, &'static str) {
356  (
357    423,
358    "The resource is locked and cannot be accessed or modified, typically used in WebDav RFC 4918",
359  )
360}
361
362pub fn failed_dependency() -> (u16, &'static str) {
363  (424, "The request failed because it depended on another operation that failed, often used in WebDav RFC 4918")
364}
365
366pub fn too_early() -> (u16, &'static str) {
367  (425, "The server is unwilling to process the request because it might be replayed")
368}
369
370pub fn upgrade_required() -> (u16, &'static str) {
371  (426, "The client must upgrade to a different protocol to continue with the request")
372}
373
374pub fn precondition_required() -> (u16, &'static str) {
375  (428, "The server requires the request to include specific preconditions to proceed")
376}
377
378pub fn too_many_requests() -> (u16, &'static str) {
379  (
380    429,
381    "The resource is rate-limited and the client has sent too many requests in the allotted time",
382  )
383}
384
385pub fn request_header_fields_too_large() -> (u16, &'static str) {
386  (
387    430,
388    "Issued by Shopify to indicate a rate-limit effect. This is used instead of 429, unofficial",
389  )
390}
391
392pub fn login_required() -> (u16, &'static str) {
393  (
394    432,
395    "Authentication is required to access the requested resource, typically in web applications",
396  )
397}
398
399pub fn origin_error() -> (u16, &'static str) {
400  (433, "The request was rejected due to an issue with the origin server or client IP")
401}
402
403pub fn destination_error() -> (u16, &'static str) {
404  (
405    434,
406    "The request was rejected due to an issue with the destination server or target configuration",
407  )
408}
409
410pub fn too_large() -> (u16, &'static str) {
411  (435, "The size of the requested resource or payload exceeds the allowable limit for the server")
412}
413
414pub fn ssl_certificate_error() -> (u16, &'static str) {
415  (436, "An error occurred due to an invalid or untrusted SSL certificate")
416}
417
418pub fn ssl_certificate_required() -> (u16, &'static str) {
419  (437, "The server requires a valid SSL certificate for the connection to proceed securely")
420}
421
422pub fn no_certificate() -> (u16, &'static str) {
423  (438, "The client did not provide an SSL certificate required for secure communication")
424}
425
426pub fn login_timeout() -> (u16, &'static str) {
427  (440, "The client session timed out and must log in again, iis, unofficial")
428}
429
430pub fn over_data_quota() -> (u16, &'static str) {
431  (441, "The client has exceeded the allocated data quota for the requested operation")
432}
433
434pub fn no_response() -> (u16, &'static str) {
435  (444, "The server closed the connection without sending any response, often used in scenarios where the server chooses to silently drop the request, nginx, unofficial")
436}
437
438pub fn retry_with() -> (u16, &'static str) {
439  (449, "The user has not provided the required information, iis, unofficial")
440}
441
442pub fn blocked_by_windows_parental_controls() -> (u16, &'static str) {
443  (450, "Issued by Microsoft when Windows Parental Controls are turned on and a resource is blocked, unofficial")
444}
445
446pub fn unavailable_for_legal_reasons() -> (u16, &'static str) {
447  (451, "The server is denying access to the resource due to legal reasons, such as censorship or compliance with local laws")
448}
449
450pub fn too_many_recipients() -> (u16, &'static str) {
451  (452, "The server is unable to process the request because it contains too many recipients")
452}
453
454pub fn method_not_valid_in_this_state() -> (u16, &'static str) {
455  (455, "The method specified in the request is not valid for the current state of the resource or server")
456}
457
458pub fn unrecoverable_error() -> (u16, &'static str) {
459  (456, "The server encountered a critical error that prevents it from continuing to process the request")
460}
461
462pub fn client_closed_connexion_prematurely() -> (u16, &'static str) {
463  (460, "The client closed the connection before the server was able to send a response, often due to a timeout or network interruption")
464}
465
466pub fn too_many_forwarded_ip_addresses() -> (u16, &'static str) {
467  (463, "The server rejected the request due to an excessive number of forwarded IP addresses in the request headers, potentially indicating a misconfiguration or a security concern")
468}
469
470pub fn internet_security_error() -> (u16, &'static str) {
471  (467, "An internet security policy violation or configuration issue occurred, often related to SSL/TLS settings, certificates, or protocol mismatches")
472}
473
474pub fn temporary_unavailable() -> (u16, &'static str) {
475  (480, "The server is temporarily unavailable, usually due to maintenance or overload")
476}
477
478pub fn request_header_too_large() -> (u16, &'static str) {
479  (494, "The server is unable to process the request because the headers are too large, often due to a misconfiguration or an attack, nginx, unofficial")
480}
481
482pub fn cert_error() -> (u16, &'static str) {
483  (495, "The SSL certificate presented by the client is invalid or cannot be verified by the server, preventing a secure connection from being established, nginx, unofficial")
484}
485
486pub fn no_cert() -> (u16, &'static str) {
487  (496, "A required client certificate wasn't provided, preventing the server from establishing a secure connection, nginx, unofficial")
488}
489
490pub fn http_to_https() -> (u16, &'static str) {
491  (497, "The client sent an unencrypted HTTP request to a server that requires HTTPS, and the server is redirecting the client to the HTTPS version of the resource, nginx, unofficial")
492}
493
494pub fn invalid_token() -> (u16, &'static str) {
495  (498, "The provided token is invalid, expired, or malformed, and cannot be used for authentication or authorization, Issued by ArcGIS for Server, unofficial")
496}
497
498pub fn client_closed_request() -> (u16, &'static str) {
499  (499, "The client closed the connection before the server could provide a response, often due to client timeout or network interruption, nginx, unofficial")
500}
501
502#[cfg(test)]
503mod tests {
504  use super::*;
505
506  #[test]
507  fn test_generated_function_bad_request() {
508    let response = ResponsesClientCodes::BadRequest;
509    let (code, description) = response.into();
510    assert_eq!(code, 400);
511    assert_eq!(description, "The server cannot process the request due to malformed syntax or invalid parameters in the client request");
512  }
513
514  #[test]
515  fn test_to_u16_unauthorized() {
516    let response = ResponsesClientCodes::Unauthorized;
517    let code = response.to_u16();
518    assert_eq!(code, 401);
519  }
520
521  #[test]
522  fn test_payment_required() {
523    assert_eq!(payment_required(), (402, "Payment is required to access the requested resource, though this is not widely used in practice"));
524  }
525
526  #[test]
527  fn tes_from_u16_not_found() {
528    let response = ResponsesClientCodes::from_u16(404);
529    assert_eq!(response, Some(ResponsesClientCodes::NotFound));
530  }
531}