simbld_http/responses/
redirection.rs

1/// The above Rust code defines an enum representing HTTP responses redirection codes with associated descriptions and provides functions to retrieve specific code descriptions.
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 ResponsesRedirectionCodes {
13  #[strum(props(
14    Description = "The request has more than one possible response. The user-agent or user should choose one of them. There is no standardized way of choosing one of the responses, but HTML links to the possibilities are recommended so the user can pick manually"
15  ))]
16  MultipleChoices = 300,
17  #[strum(props(
18    Description = "The resource has been permanently moved to a new URI. Future requests should use the new URI. This status code is typically used for URL redirection"
19  ))]
20  MovedPermanently = 301,
21  #[strum(props(
22    Description = "The resource is temporarily available at a different URI. The client should continue using the original URI for future requests. This status code is often used for URL redirection"
23  ))]
24  Found = 302,
25  #[strum(props(
26    Description = "The response to the request can be found under another URI, and the client should use GET to retrieve it. This status code is used to direct the client to retrieve the resource from a different URI"
27  ))]
28  SeeOther = 303,
29  #[strum(props(
30    Description = "The resource has not been modified since the version specified in the request headers. This status code is used for caching purposes to reduce unnecessary network traffic"
31  ))]
32  NotModified = 304,
33  #[strum(props(
34    Description = "The requested resource must be accessed through a specified proxy. This status code is used to inform the client that it should use a proxy server to access the resource"
35  ))]
36  UseProxy = 305,
37  #[strum(props(
38    Description = "Switch to the specified proxy. This is no longer used, and it is now considered deprecated"
39  ))]
40  SwitchProxy = 306,
41  #[strum(props(
42    Description = "The resource is temporarily located at a different URI. The client should use the same method to access it. This status code is used for temporary URL redirection"
43  ))]
44  TemporaryRedirect = 307,
45  #[strum(props(
46    Description = "The resource has been permanently moved to a new URI. The client should update its references. This status code is used for permanent URL redirection"
47  ))]
48  PermanentRedirect = 308,
49  #[strum(props(
50    Description = "The client has been redirected too many times, possibly causing a redirection loop. This status code is used to prevent infinite redirection loops"
51  ))]
52  TooManyRedirects = 310,
53  #[strum(props(
54    Description = "The client should use a different method to access the resource. This status code is used to inform the client that it should use a different HTTP method, such as GET or POST"
55  ))]
56  RedirectMethod = 311,
57  #[strum(props(
58    Description = "This code is currently unassigned and reserved for future use. It may be used for a new feature or status code in the future"
59  ))]
60  Unassigned = 312,
61  #[strum(props(
62    Description = "The requested resource has been permanently moved to a new URI, but the client should continue to use the original URI. This status code is used for special cases of permanent redirection"
63  ))]
64  MovedPermanentlyRedirected = 321,
65  #[strum(props(
66    Description = "The requested resource is temporarily available at a new URI but the client should not update its original URI. This status code is used for special cases of temporary redirection"
67  ))]
68  MovedTemporarilyRedirected = 322,
69  #[strum(props(
70    Description = "The requested resource can be accessed at a different URI using the GET method. This status code is used to direct the client to retrieve the resource from a different URI using GET"
71  ))]
72  SeeOtherRedirected = 323,
73  #[strum(props(
74    Description = "The requested resource has not been modified and can be retrieved from the cache. This status code is used for caching purposes to reduce unnecessary network traffic"
75  ))]
76  NotModifiedRedirected = 324,
77  #[strum(props(
78    Description = "The resource must be accessed through a proxy, and the proxy details are provided. This status code is used to inform the client that it should use a proxy server to access the resource"
79  ))]
80  UseProxyRedirected = 325,
81  #[strum(props(
82    Description = "This status code is reserved and not used anymore. It was previously used for a proposed feature that was never implemented"
83  ))]
84  UnusedRedirected = 326,
85  #[strum(props(
86    Description = "The requested resource is temporarily located at a new URI. The client should not update its reference. This status code is used for special cases of temporary redirection"
87  ))]
88  TemporaryRedirectRedirected = 327,
89  #[strum(props(
90    Description = "The resource has been permanently moved to a new URI, and future requests should use the new URI. This status code is used for special cases of permanent redirection"
91  ))]
92  PermanentRedirected = 328,
93  #[strum(props(
94    Description = "The client has been redirected too many times during a redirection loop. This status code is used to prevent infinite redirection loops"
95  ))]
96  TooManyRedirectsRedirected = 329,
97  #[strum(props(
98    Description = "The redirection requires the client to use a different request method. This status code is used to inform the client that it should use a different HTTP method, such as GET or POST"
99  ))]
100  RedirectMethodRedirected = 330,
101  #[strum(props(
102    Description = "The username is valid, but the client must provide a password to proceed. This status code is used for authentication purposes"
103  ))]
104  UserNameOkPasswordNeeded = 331,
105  #[strum(props(
106    Description = "The requested resource does not require a user account for access. This status code is used to inform the client that no login is necessary"
107  ))]
108  NoNeedAccountForLogin = 332,
109  #[strum(props(
110    Description = "The request is missing a session key in the header. This status code is used for session management purposes"
111  ))]
112  SessionKeyNotPresentInHeader = 333,
113  #[strum(props(
114    Description = "The session key provided in the request cannot be decrypted or parsed. This status code is used for session management purposes"
115  ))]
116  SessionKeyPresentAndNotDecryptableParsable = 334,
117  #[strum(props(
118    Description = "The server refuses to process the request, often due to policy restrictions. This status code is used to inform the client that the server is unwilling to process the request"
119  ))]
120  ServerIsUnwillingToProcessTheRequest = 335,
121  #[strum(props(
122    Description = "Challenge-response authentication was successfully completed. This status code is used to inform the client that authentication was successful"
123  ))]
124  ChallengeResponseAuthenticationOk = 336,
125  #[strum(props(
126    Description = "Challenge-response authentication failed due to invalid credentials or other issues. This status code is used to inform the client that authentication failed"
127  ))]
128  ChallengeResponseAuthenticationFailed = 337,
129  #[strum(props(
130    Description = "The request did not specify the length of its content, which is required by the server. This status code is used to inform the client that the length is required"
131  ))]
132  LengthRequired = 342,
133  #[strum(props(
134    Description = "The server does not meet the preconditions set by the client in its request. This status code is used to inform the client that the preconditions failed"
135  ))]
136  PreconditionFailed = 343,
137  #[strum(props(
138    Description = "The request is larger than the server is willing or able to process. This status code is used to inform the client that the request entity is too large"
139  ))]
140  RequestEntityTooLarge = 344,
141  #[strum(props(
142    Description = "The media type of the request is not supported by the server. This status code is used to inform the client that the media type is unsupported"
143  ))]
144  UnsupportedMediaType = 346,
145  #[strum(props(
146    Description = "The server cannot supply the portion of the file requested by the client. This status code is used to inform the client that the requested range is not satisfiable"
147  ))]
148  RequestedRangeNotSatisfiable = 347,
149  #[strum(props(
150    Description = "The server cannot meet the requirements specified in the Expect header of the request. This status code is used to inform the client that the expectation failed"
151  ))]
152  ExpectationFailed = 348,
153  #[strum(props(
154    Description = "A humorous response indicating the server is a teapot and refuses to brew coffee. This status code is used as an April Fools' joke"
155  ))]
156  ImATeapot = 349,
157  #[strum(props(
158    Description = "The server encountered an error while attempting to access the specified URL. This status code is used to inform the client that there was an error accessing the URL"
159  ))]
160  ErrorAccessingURL = 350,
161  #[strum(props(
162    Description = "The requested redirection trigger could not be found on the server. This status code is used to inform the client that the trigger was not found"
163  ))]
164  TriggerNotFound = 351,
165  #[strum(props(
166    Description = "The server refuses to fulfill the request due to access restrictions. This status code is used to inform the client that access is denied"
167  ))]
168  AccessDenied = 352,
169  #[strum(props(
170    Description = "A condition required to complete the redirection was not satisfied. This status code is used to inform the client that the condition failed"
171  ))]
172  ConditionFailed = 353,
173  #[strum(props(
174    Description = "A required parameter for the request is missing or null. This status code is used to inform the client that a mandatory parameter is null"
175  ))]
176  MandatoryParameterIsNull = 354,
177  #[strum(props(
178    Description = "A parameter specified in the request does not exist. This status code is used to inform the client that the parameter does not exist"
179  ))]
180  TheParameterDoesNotExist = 355,
181  #[strum(props(
182    Description = "The data payload for a POST request must not be null. This status code is used to inform the client that the data BLOB should not be null for POST method"
183  ))]
184  DataBLOBShouldNotBeNullForPostMethod = 356,
185}
186
187impl ToU16 for ResponsesRedirectionCodes {
188  fn to_u16(self) -> u16 {
189    self.into() // Conversion`Into<u16>`
190  }
191}
192
193impl FromU16 for ResponsesRedirectionCodes {
194  fn from_u16(code: u16) -> Option<Self> {
195    Self::try_from(code).ok() // Conversion`TryFrom<u16>`
196  }
197}
198
199impl Into<(u16, &'static str)> for ResponsesRedirectionCodes {
200  fn into(self) -> (u16, &'static str) {
201    let code: u16 = self.to_u16();
202    let description = self.get_str("Description").unwrap_or("No description");
203    (code, description) // Tuple
204  }
205}
206
207pub fn multiple_choices() -> (u16, &'static str) {
208  (300, "The request has more than one possible response. The user-agent or user should choose one of them. There is no standardized way of choosing one of the responses, but HTML links to the possibilities are recommended so the user can pick manually")
209}
210
211pub fn moved_permanently() -> (u16, &'static str) {
212  (301, "The resource has been permanently moved to a new URI. Future requests should use the new URI. This status code is typically used for URL redirection")
213}
214
215pub fn found() -> (u16, &'static str) {
216  (302, "The resource is temporarily available at a different URI. The client should continue using the original URI for future requests. This status code is often used for URL redirection")
217}
218
219pub fn see_other() -> (u16, &'static str) {
220  (303, "The response to the request can be found under another URI, and the client should use GET to retrieve it. This status code is used to direct the client to retrieve the resource from a different URI")
221}
222
223pub fn not_modified() -> (u16, &'static str) {
224  (304, "The resource has not been modified since the version specified in the request headers. This status code is used for caching purposes to reduce unnecessary network traffic")
225}
226
227pub fn use_proxy() -> (u16, &'static str) {
228  (305, "The requested resource must be accessed through a specified proxy. This status code is used to inform the client that it should use a proxy server to access the resource")
229}
230
231pub fn switch_proxy() -> (u16, &'static str) {
232  (
233    306,
234    "Switch to the specified proxy. This is no longer used, and it is now considered deprecated",
235  )
236}
237
238pub fn temporary_redirect() -> (u16, &'static str) {
239  (307, "The resource is temporarily available at a different URI. The client should use the same method to access it. This status code is used for temporary URL redirection")
240}
241
242pub fn permanent_redirect() -> (u16, &'static str) {
243  (308, "The resource has been permanently moved to a new URI. The client should update its references. This status code is used for permanent URL redirection")
244}
245
246pub fn too_many_redirects() -> (u16, &'static str) {
247  (310, "The client has been redirected too many times, possibly causing a redirection loop. This status code is used to prevent infinite redirection loops")
248}
249
250pub fn redirect_method() -> (u16, &'static str) {
251  (311, "The client should use a different method to access the resource. This status code is used to inform the client that it should use a different HTTP method, such as GET or POST")
252}
253
254pub fn unassigned() -> (u16, &'static str) {
255  (312, "This code is currently unassigned and reserved for future use. It may be used for a new feature or status code in the future")
256}
257
258pub fn moved_permanently_redirected() -> (u16, &'static str) {
259  (321, "The requested resource has been permanently moved to a new URI, but the client should continue to use the original URI. This status code is used for special cases of permanent redirection")
260}
261
262pub fn moved_temporarily_redirected() -> (u16, &'static str) {
263  (322, "The requested resource is temporarily available at a new URI but the client should not update its original URI. This status code is used for special cases of temporary redirection")
264}
265
266pub fn see_other_redirected() -> (u16, &'static str) {
267  (323, "The requested resource can be accessed at a different URI using the GET method. This status code is used to direct the client to retrieve the resource from a different URI using GET")
268}
269
270pub fn not_modified_redirected() -> (u16, &'static str) {
271  (324, "The requested resource has not been modified and can be retrieved from the cache. This status code is used for caching purposes to reduce unnecessary network traffic")
272}
273
274pub fn use_proxy_redirected() -> (u16, &'static str) {
275  (325, "The resource must be accessed through a proxy, and the proxy details are provided. This status code is used to inform the client that it should use a proxy server to access the resource")
276}
277
278pub fn unused_redirected() -> (u16, &'static str) {
279  (326, "This status code is reserved and not used anymore. It was previously used for a proposed feature that was never implemented")
280}
281
282pub fn temporary_redirect_redirected() -> (u16, &'static str) {
283  (327, "The requested resource is temporarily located at a new URI. The client should not update its reference. This status code is used for special cases of temporary redirection")
284}
285
286pub fn permanent_redirected() -> (u16, &'static str) {
287  (328, "The resource has been permanently moved to a new URI, and future requests should use the new URI. This status code is used for special cases of permanent redirection")
288}
289
290pub fn too_many_redirects_redirected() -> (u16, &'static str) {
291  (329, "The client has been redirected too many times during a redirection loop. This status code is used to prevent infinite redirection loops")
292}
293
294pub fn redirect_method_redirected() -> (u16, &'static str) {
295  (330, "The redirection requires the client to use a different request method. This status code is used to inform the client that it should use a different HTTP method, such as GET or POST")
296}
297
298pub fn user_name_ok_password_needed() -> (u16, &'static str) {
299  (331, "The username is valid, but the client must provide a password to proceed. This status code is used for authentication purposes")
300}
301
302pub fn no_need_account_for_login() -> (u16, &'static str) {
303  (332, "The requested resource does not require a user account for access. This status code is used to inform the client that no login is necessary")
304}
305
306pub fn session_key_not_present_in_header() -> (u16, &'static str) {
307  (333, "The request is missing a session key in the header. This status code is used for session management purposes")
308}
309
310pub fn session_key_present_and_not_decryptable_parsable() -> (u16, &'static str) {
311  (334, "The session key provided in the request cannot be decrypted or parsed. This status code is used for session management purposes")
312}
313
314pub fn server_is_unwilling_to_process_the_request() -> (u16, &'static str) {
315  (335, "The server refuses to process the request, often due to policy restrictions. This status code is used to inform the client that the server is unwilling to process the request")
316}
317
318pub fn challenge_response_authentication_ok() -> (u16, &'static str) {
319  (336, "Challenge-response authentication was successfully completed. This status code is used to inform the client that authentication was successful")
320}
321
322pub fn challenge_response_authentication_failed() -> (u16, &'static str) {
323  (337, "Challenge-response authentication failed due to invalid credentials or other issues. This status code is used to inform the client that authentication failed")
324}
325
326pub fn length_required() -> (u16, &'static str) {
327  (342, "The request did not specify the length of its content, which is required by the server. This status code is used to inform the client that the length is required")
328}
329
330pub fn precondition_failed() -> (u16, &'static str) {
331  (343, "The server does not meet the preconditions set by the client in its request. This status code is used to inform the client that the preconditions failed")
332}
333
334pub fn request_entity_too_large() -> (u16, &'static str) {
335  (344, "The request is larger than the server is willing or able to process. This status code is used to inform the client that the request entity is too large")
336}
337
338pub fn unsupported_media_type() -> (u16, &'static str) {
339  (346, "The media type of the request is not supported by the server. This status code is used to inform the client that the media type is unsupported")
340}
341
342pub fn requested_range_not_satisfiable() -> (u16, &'static str) {
343  (347, "The server cannot supply the portion of the file requested by the client. This status code is used to inform the client that the requested range is not satisfiable")
344}
345
346pub fn expectation_failed() -> (u16, &'static str) {
347  (348, "The server cannot meet the requirements specified in the Expect header of the request. This status code is used to inform the client that the expectation failed")
348}
349
350pub fn im_a_teapot() -> (u16, &'static str) {
351  (349, "A humorous response indicating the server is a teapot and refuses to brew coffee. This status code is used as an April Fools' joke")
352}
353
354pub fn error_accessing_url() -> (u16, &'static str) {
355  (350, "The server encountered an error while attempting to access the specified URL. This status code is used to inform the client that there was an error accessing the URL")
356}
357
358pub fn trigger_not_found() -> (u16, &'static str) {
359  (351, "The requested redirection trigger could not be found on the server. This status code is used to inform the client that the trigger was not found")
360}
361
362pub fn access_denied() -> (u16, &'static str) {
363  (352, "The server refuses to fulfill the request due to access restrictions. This status code is used to inform the client that access is denied")
364}
365
366pub fn condition_failed() -> (u16, &'static str) {
367  (353, "A condition required to complete the redirection was not satisfied. This status code is used to inform the client that the condition failed")
368}
369
370pub fn mandatory_parameter_is_null() -> (u16, &'static str) {
371  (354, "A required parameter for the request is missing or null. This status code is used to inform the client that a mandatory parameter is null")
372}
373
374pub fn the_parameter_does_not_exist() -> (u16, &'static str) {
375  (355, "A parameter specified in the request does not exist. This status code is used to inform the client that the parameter does not exist")
376}
377
378pub fn data_blob_should_not_be_null_for_post_method() -> (u16, &'static str) {
379  (356, "The data payload for a POST request must not be null. This status code is used to inform the client that the data BLOB should not be null for POST method")
380}
381
382#[cfg(test)]
383mod tests {
384  use super::*;
385
386  #[test]
387  fn test_generated_function_redirection() {
388    let response = ResponsesRedirectionCodes::MultipleChoices;
389    let (code, description): (u16, &str) = response.into();
390    assert_eq!(code, 300);
391    assert_eq!(
392      description,
393      "The request has more than one possible response. The user-agent or user should choose one of them. There is no standardized way of choosing one of the responses, but HTML links to the possibilities are recommended so the user can pick manually"
394    );
395  }
396
397  #[test]
398  fn test_to_u16_success() {
399    let response = ResponsesRedirectionCodes::Found;
400    let code = response.to_u16();
401    assert_eq!(code, 302);
402  }
403
404  #[test]
405  fn test_moved_permanently() {
406    assert_eq!(moved_permanently(), (301, "The resource has been permanently moved to a new URI. Future requests should use the new URI. This status code is typically used for URL redirection"));
407  }
408
409  #[test]
410  fn test_from_u16_too_many_redirects() {
411    let code = 310;
412    let response = ResponsesRedirectionCodes::from_u16(code);
413    assert_eq!(response, Some(ResponsesRedirectionCodes::TooManyRedirects));
414  }
415}