http_type/http_status/
impl.rs

1use crate::*;
2
3/// The `HttpStatus` enum represents the HTTP status codes.
4///
5/// It maps common HTTP status codes to their respective meanings. It provides methods to retrieve
6/// the corresponding numeric code as well as the associated status text. Additionally, it implements
7/// conversion from a string representation of the status code.
8impl HttpStatus {
9    /// Returns the numeric HTTP status code associated with this status code variant.
10    ///
11    /// This method returns the corresponding HTTP numeric status code based on the `HttpStatus` variant.
12    /// For example:
13    /// - `Self::Ok` returns 200.
14    /// - `Self::BadRequest` returns 400.
15    /// - `Self::Unknown` returns 0 (the default for unrecognized status codes).
16    ///
17    /// # Parameters
18    /// - `&self`: A reference to the `HttpStatus` enum instance. This represents the specific variant of the `HttpStatus` enum that the method is called on.
19    ///
20    /// # Return Value
21    /// - `ResponseStatusCode`: The numeric HTTP status code associated with the `HttpStatus` variant. For example:
22    pub fn code(&self) -> ResponseStatusCode {
23        match self {
24            Self::Continue => 100,
25            Self::SwitchingProtocols => 101,
26            Self::Processing => 102,
27            Self::EarlyHints => 103,
28            Self::Ok => 200,
29            Self::Created => 201,
30            Self::Accepted => 202,
31            Self::NonAuthoritativeInformation => 203,
32            Self::NoContent => 204,
33            Self::ResetContent => 205,
34            Self::PartialContent => 206,
35            Self::MultiStatus => 207,
36            Self::AlreadyReported => 208,
37            Self::IMUsed => 226,
38            Self::MultipleChoices => 300,
39            Self::MovedPermanently => 301,
40            Self::Found => 302,
41            Self::SeeOther => 303,
42            Self::NotModified => 304,
43            Self::UseProxy => 305,
44            Self::TemporaryRedirect => 307,
45            Self::PermanentRedirect => 308,
46            Self::BadRequest => 400,
47            Self::Unauthorized => 401,
48            Self::PaymentRequired => 402,
49            Self::Forbidden => 403,
50            Self::NotFound => 404,
51            Self::MethodNotAllowed => 405,
52            Self::NotAcceptable => 406,
53            Self::ProxyAuthenticationRequired => 407,
54            Self::RequestTimeout => 408,
55            Self::Conflict => 409,
56            Self::Gone => 410,
57            Self::LengthRequired => 411,
58            Self::PreconditionFailed => 412,
59            Self::PayloadTooLarge => 413,
60            Self::URITooLong => 414,
61            Self::UnsupportedMediaType => 415,
62            Self::RangeNotSatisfiable => 416,
63            Self::ExpectationFailed => 417,
64            Self::ImATeapot => 418,
65            Self::MisdirectedRequest => 421,
66            Self::UnprocessableEntity => 422,
67            Self::Locked => 423,
68            Self::FailedDependency => 424,
69            Self::TooEarly => 425,
70            Self::UpgradeRequired => 426,
71            Self::PreconditionRequired => 428,
72            Self::TooManyRequests => 429,
73            Self::RequestHeaderFieldsTooLarge => 431,
74            Self::UnavailableForLegalReasons => 451,
75            Self::InternalServerError => 500,
76            Self::NotImplemented => 501,
77            Self::BadGateway => 502,
78            Self::ServiceUnavailable => 503,
79            Self::GatewayTimeout => 504,
80            Self::HTTPVersionNotSupported => 505,
81            Self::VariantAlsoNegotiates => 506,
82            Self::InsufficientStorage => 507,
83            Self::LoopDetected => 508,
84            Self::NotExtended => 510,
85            Self::NetworkAuthenticationRequired => 511,
86            Self::Unknown => 0,
87        }
88    }
89
90    /// Converts an HTTP status code to its corresponding textual description.
91    ///
92    /// This method matches a given numeric HTTP status code and returns the corresponding
93    /// textual representation defined in the `HttpStatus` enum.
94    ///
95    /// # Parameters
96    /// - `code`: A `ResponseStatusCode` representing the HTTP status code to convert.
97    ///
98    /// # Return Value
99    /// - `String`: A string representing the textual description of the HTTP status code.
100    pub fn phrase(code: ResponseStatusCode) -> String {
101        match code {
102            100 => Self::Continue.to_string(),
103            101 => Self::SwitchingProtocols.to_string(),
104            102 => Self::Processing.to_string(),
105            103 => Self::EarlyHints.to_string(),
106            200 => Self::Ok.to_string(),
107            201 => Self::Created.to_string(),
108            202 => Self::Accepted.to_string(),
109            203 => Self::NonAuthoritativeInformation.to_string(),
110            204 => Self::NoContent.to_string(),
111            205 => Self::ResetContent.to_string(),
112            206 => Self::PartialContent.to_string(),
113            207 => Self::MultiStatus.to_string(),
114            208 => Self::AlreadyReported.to_string(),
115            226 => Self::IMUsed.to_string(),
116            300 => Self::MultipleChoices.to_string(),
117            301 => Self::MovedPermanently.to_string(),
118            302 => Self::Found.to_string(),
119            303 => Self::SeeOther.to_string(),
120            304 => Self::NotModified.to_string(),
121            305 => Self::UseProxy.to_string(),
122            307 => Self::TemporaryRedirect.to_string(),
123            308 => Self::PermanentRedirect.to_string(),
124            400 => Self::BadRequest.to_string(),
125            401 => Self::Unauthorized.to_string(),
126            402 => Self::PaymentRequired.to_string(),
127            403 => Self::Forbidden.to_string(),
128            404 => Self::NotFound.to_string(),
129            405 => Self::MethodNotAllowed.to_string(),
130            406 => Self::NotAcceptable.to_string(),
131            407 => Self::ProxyAuthenticationRequired.to_string(),
132            408 => Self::RequestTimeout.to_string(),
133            409 => Self::Conflict.to_string(),
134            410 => Self::Gone.to_string(),
135            411 => Self::LengthRequired.to_string(),
136            412 => Self::PreconditionFailed.to_string(),
137            413 => Self::PayloadTooLarge.to_string(),
138            414 => Self::URITooLong.to_string(),
139            415 => Self::UnsupportedMediaType.to_string(),
140            416 => Self::RangeNotSatisfiable.to_string(),
141            417 => Self::ExpectationFailed.to_string(),
142            418 => Self::ImATeapot.to_string(),
143            421 => Self::MisdirectedRequest.to_string(),
144            422 => Self::UnprocessableEntity.to_string(),
145            423 => Self::Locked.to_string(),
146            424 => Self::FailedDependency.to_string(),
147            425 => Self::TooEarly.to_string(),
148            426 => Self::UpgradeRequired.to_string(),
149            428 => Self::PreconditionRequired.to_string(),
150            429 => Self::TooManyRequests.to_string(),
151            431 => Self::RequestHeaderFieldsTooLarge.to_string(),
152            451 => Self::UnavailableForLegalReasons.to_string(),
153            500 => Self::InternalServerError.to_string(),
154            501 => Self::NotImplemented.to_string(),
155            502 => Self::BadGateway.to_string(),
156            503 => Self::ServiceUnavailable.to_string(),
157            504 => Self::GatewayTimeout.to_string(),
158            505 => Self::HTTPVersionNotSupported.to_string(),
159            506 => Self::VariantAlsoNegotiates.to_string(),
160            507 => Self::InsufficientStorage.to_string(),
161            508 => Self::LoopDetected.to_string(),
162            510 => Self::NotExtended.to_string(),
163            511 => Self::NetworkAuthenticationRequired.to_string(),
164            _ => Self::Unknown.to_string(),
165        }
166    }
167
168    /// Compares the current status code with a given string representation.
169    ///
170    /// This method checks if the given `code_str` matches either the numeric HTTP status code
171    /// returned by `code()` or the string representation of the status code variant.
172    /// The comparison is case-insensitive.
173    ///
174    /// # Parameters
175    /// - `&self`: A reference to the `HttpStatus` enum instance.
176    /// - `code_str`: A string slice containing the status code to compare against.
177    ///
178    /// # Return Value
179    /// - `bool`: Returns `true` if `code_str` matches the numeric code or the string representation of `self`, otherwise `false`.
180    pub fn same(&self, code_str: &str) -> bool {
181        self.to_string().eq_ignore_ascii_case(code_str)
182    }
183}
184
185impl Display for HttpStatus {
186    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
187        let res: &str = match self {
188            Self::Continue => CONTINUE,
189            Self::SwitchingProtocols => SWITCHING_PROTOCOLS,
190            Self::Processing => PROCESSING,
191            Self::EarlyHints => EARLY_HINTS,
192            Self::Ok => OK,
193            Self::Created => CREATED,
194            Self::Accepted => ACCEPTED,
195            Self::NonAuthoritativeInformation => NON_AUTHORITATIVE_INFORMATION,
196            Self::NoContent => NO_CONTENT,
197            Self::ResetContent => RESET_CONTENT,
198            Self::PartialContent => PARTIAL_CONTENT,
199            Self::MultiStatus => MULTI_STATUS,
200            Self::AlreadyReported => ALREADY_REPORTED,
201            Self::IMUsed => IM_USED,
202            Self::MultipleChoices => MULTIPLE_CHOICES,
203            Self::MovedPermanently => MOVED_PERMANENTLY,
204            Self::Found => FOUND,
205            Self::SeeOther => SEE_OTHER,
206            Self::NotModified => NOT_MODIFIED,
207            Self::UseProxy => USE_PROXY,
208            Self::TemporaryRedirect => TEMPORARY_REDIRECT,
209            Self::PermanentRedirect => PERMANENT_REDIRECT,
210            Self::BadRequest => BAD_REQUEST,
211            Self::Unauthorized => UNAUTHORIZED,
212            Self::PaymentRequired => PAYMENT_REQUIRED,
213            Self::Forbidden => FORBIDDEN,
214            Self::NotFound => NOT_FOUND,
215            Self::MethodNotAllowed => METHOD_NOT_ALLOWED,
216            Self::NotAcceptable => NOT_ACCEPTABLE,
217            Self::ProxyAuthenticationRequired => PROXY_AUTHENTICATION_REQUIRED,
218            Self::RequestTimeout => REQUEST_TIMEOUT,
219            Self::Conflict => CONFLICT,
220            Self::Gone => GONE,
221            Self::LengthRequired => LENGTH_REQUIRED,
222            Self::PreconditionFailed => PRECONDITION_FAILED,
223            Self::PayloadTooLarge => PAYLOAD_TOO_LARGE,
224            Self::URITooLong => URI_TOO_LONG,
225            Self::UnsupportedMediaType => UNSUPPORTED_MEDIA_TYPE,
226            Self::RangeNotSatisfiable => RANGE_NOT_SATISFIABLE,
227            Self::ExpectationFailed => EXPECTATION_FAILED,
228            Self::ImATeapot => IM_A_TEAPOT,
229            Self::MisdirectedRequest => MISDIRECTED_REQUEST,
230            Self::UnprocessableEntity => UNPROCESSABLE_ENTITY,
231            Self::Locked => LOCKED,
232            Self::FailedDependency => FAILED_DEPENDENCY,
233            Self::TooEarly => TOO_EARLY,
234            Self::UpgradeRequired => UPGRADE_REQUIRED,
235            Self::PreconditionRequired => PRECONDITION_REQUIRED,
236            Self::TooManyRequests => TOO_MANY_REQUESTS,
237            Self::RequestHeaderFieldsTooLarge => REQUEST_HEADER_FIELDS_TOO_LARGE,
238            Self::UnavailableForLegalReasons => UNAVAILABLE_FOR_LEGAL_REASONS,
239            Self::InternalServerError => INTERNAL_SERVER_ERROR,
240            Self::NotImplemented => NOT_IMPLEMENTED,
241            Self::BadGateway => BAD_GATEWAY,
242            Self::ServiceUnavailable => SERVICE_UNAVAILABLE,
243            Self::GatewayTimeout => GATEWAY_TIMEOUT,
244            Self::HTTPVersionNotSupported => HTTP_VERSION_NOT_SUPPORTED,
245            Self::VariantAlsoNegotiates => VARIANT_ALSO_NEGOTIATES,
246            Self::InsufficientStorage => INSUFFICIENT_STORAGE,
247            Self::LoopDetected => LOOP_DETECTED,
248            Self::NotExtended => NOT_EXTENDED,
249            Self::NetworkAuthenticationRequired => NETWORK_AUTHENTICATION_REQUIRED,
250            Self::Unknown => UNKNOWN,
251        };
252        write!(f, "{}", res)
253    }
254}
255
256impl FromStr for HttpStatus {
257    type Err = ();
258
259    fn from_str(code_str: &str) -> Result<Self, Self::Err> {
260        if let Ok(code) = code_str.parse::<ResponseStatusCode>() {
261            match code {
262                100 => Ok(Self::Continue),
263                101 => Ok(Self::SwitchingProtocols),
264                102 => Ok(Self::Processing),
265                103 => Ok(Self::EarlyHints),
266                200 => Ok(Self::Ok),
267                201 => Ok(Self::Created),
268                202 => Ok(Self::Accepted),
269                203 => Ok(Self::NonAuthoritativeInformation),
270                204 => Ok(Self::NoContent),
271                205 => Ok(Self::ResetContent),
272                206 => Ok(Self::PartialContent),
273                207 => Ok(Self::MultiStatus),
274                208 => Ok(Self::AlreadyReported),
275                226 => Ok(Self::IMUsed),
276                300 => Ok(Self::MultipleChoices),
277                301 => Ok(Self::MovedPermanently),
278                302 => Ok(Self::Found),
279                303 => Ok(Self::SeeOther),
280                304 => Ok(Self::NotModified),
281                305 => Ok(Self::UseProxy),
282                307 => Ok(Self::TemporaryRedirect),
283                308 => Ok(Self::PermanentRedirect),
284                400 => Ok(Self::BadRequest),
285                401 => Ok(Self::Unauthorized),
286                402 => Ok(Self::PaymentRequired),
287                403 => Ok(Self::Forbidden),
288                404 => Ok(Self::NotFound),
289                405 => Ok(Self::MethodNotAllowed),
290                406 => Ok(Self::NotAcceptable),
291                407 => Ok(Self::ProxyAuthenticationRequired),
292                408 => Ok(Self::RequestTimeout),
293                409 => Ok(Self::Conflict),
294                410 => Ok(Self::Gone),
295                411 => Ok(Self::LengthRequired),
296                412 => Ok(Self::PreconditionFailed),
297                413 => Ok(Self::PayloadTooLarge),
298                414 => Ok(Self::URITooLong),
299                415 => Ok(Self::UnsupportedMediaType),
300                416 => Ok(Self::RangeNotSatisfiable),
301                417 => Ok(Self::ExpectationFailed),
302                418 => Ok(Self::ImATeapot),
303                421 => Ok(Self::MisdirectedRequest),
304                422 => Ok(Self::UnprocessableEntity),
305                423 => Ok(Self::Locked),
306                424 => Ok(Self::FailedDependency),
307                425 => Ok(Self::TooEarly),
308                426 => Ok(Self::UpgradeRequired),
309                428 => Ok(Self::PreconditionRequired),
310                429 => Ok(Self::TooManyRequests),
311                431 => Ok(Self::RequestHeaderFieldsTooLarge),
312                451 => Ok(Self::UnavailableForLegalReasons),
313                500 => Ok(Self::InternalServerError),
314                501 => Ok(Self::NotImplemented),
315                502 => Ok(Self::BadGateway),
316                503 => Ok(Self::ServiceUnavailable),
317                504 => Ok(Self::GatewayTimeout),
318                505 => Ok(Self::HTTPVersionNotSupported),
319                506 => Ok(Self::VariantAlsoNegotiates),
320                507 => Ok(Self::InsufficientStorage),
321                508 => Ok(Self::LoopDetected),
322                510 => Ok(Self::NotExtended),
323                511 => Ok(Self::NetworkAuthenticationRequired),
324                _ => Ok(Self::Unknown),
325            }
326        } else {
327            Ok(Self::Unknown)
328        }
329    }
330}
331
332impl Default for HttpStatus {
333    fn default() -> Self {
334        Self::Ok
335    }
336}