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    #[inline]
23    pub fn code(&self) -> ResponseStatusCode {
24        match self {
25            Self::Continue => 100,
26            Self::SwitchingProtocols => 101,
27            Self::Processing => 102,
28            Self::EarlyHints => 103,
29            Self::Ok => 200,
30            Self::Created => 201,
31            Self::Accepted => 202,
32            Self::NonAuthoritativeInformation => 203,
33            Self::NoContent => 204,
34            Self::ResetContent => 205,
35            Self::PartialContent => 206,
36            Self::MultiStatus => 207,
37            Self::AlreadyReported => 208,
38            Self::IMUsed => 226,
39            Self::MultipleChoices => 300,
40            Self::MovedPermanently => 301,
41            Self::Found => 302,
42            Self::SeeOther => 303,
43            Self::NotModified => 304,
44            Self::UseProxy => 305,
45            Self::TemporaryRedirect => 307,
46            Self::PermanentRedirect => 308,
47            Self::BadRequest => 400,
48            Self::Unauthorized => 401,
49            Self::PaymentRequired => 402,
50            Self::Forbidden => 403,
51            Self::NotFound => 404,
52            Self::MethodNotAllowed => 405,
53            Self::NotAcceptable => 406,
54            Self::ProxyAuthenticationRequired => 407,
55            Self::RequestTimeout => 408,
56            Self::Conflict => 409,
57            Self::Gone => 410,
58            Self::LengthRequired => 411,
59            Self::PreconditionFailed => 412,
60            Self::PayloadTooLarge => 413,
61            Self::URITooLong => 414,
62            Self::UnsupportedMediaType => 415,
63            Self::RangeNotSatisfiable => 416,
64            Self::ExpectationFailed => 417,
65            Self::ImATeapot => 418,
66            Self::MisdirectedRequest => 421,
67            Self::UnprocessableEntity => 422,
68            Self::Locked => 423,
69            Self::FailedDependency => 424,
70            Self::TooEarly => 425,
71            Self::UpgradeRequired => 426,
72            Self::PreconditionRequired => 428,
73            Self::TooManyRequests => 429,
74            Self::RequestHeaderFieldsTooLarge => 431,
75            Self::UnavailableForLegalReasons => 451,
76            Self::InternalServerError => 500,
77            Self::NotImplemented => 501,
78            Self::BadGateway => 502,
79            Self::ServiceUnavailable => 503,
80            Self::GatewayTimeout => 504,
81            Self::HTTPVersionNotSupported => 505,
82            Self::VariantAlsoNegotiates => 506,
83            Self::InsufficientStorage => 507,
84            Self::LoopDetected => 508,
85            Self::NotExtended => 510,
86            Self::NetworkAuthenticationRequired => 511,
87            Self::Unknown => 0,
88        }
89    }
90
91    /// Converts an HTTP status code to its corresponding textual description.
92    ///
93    /// This method matches a given numeric HTTP status code and returns the corresponding
94    /// textual representation defined in the `HttpStatus` enum.
95    ///
96    /// # Parameters
97    /// - `code`: A `ResponseStatusCode` representing the HTTP status code to convert.
98    ///
99    /// # Return Value
100    /// - `String`: A string representing the textual description of the HTTP status code.
101    #[inline]
102    pub fn phrase(code: ResponseStatusCode) -> String {
103        match code {
104            100 => Self::Continue.to_string(),
105            101 => Self::SwitchingProtocols.to_string(),
106            102 => Self::Processing.to_string(),
107            103 => Self::EarlyHints.to_string(),
108            200 => Self::Ok.to_string(),
109            201 => Self::Created.to_string(),
110            202 => Self::Accepted.to_string(),
111            203 => Self::NonAuthoritativeInformation.to_string(),
112            204 => Self::NoContent.to_string(),
113            205 => Self::ResetContent.to_string(),
114            206 => Self::PartialContent.to_string(),
115            207 => Self::MultiStatus.to_string(),
116            208 => Self::AlreadyReported.to_string(),
117            226 => Self::IMUsed.to_string(),
118            300 => Self::MultipleChoices.to_string(),
119            301 => Self::MovedPermanently.to_string(),
120            302 => Self::Found.to_string(),
121            303 => Self::SeeOther.to_string(),
122            304 => Self::NotModified.to_string(),
123            305 => Self::UseProxy.to_string(),
124            307 => Self::TemporaryRedirect.to_string(),
125            308 => Self::PermanentRedirect.to_string(),
126            400 => Self::BadRequest.to_string(),
127            401 => Self::Unauthorized.to_string(),
128            402 => Self::PaymentRequired.to_string(),
129            403 => Self::Forbidden.to_string(),
130            404 => Self::NotFound.to_string(),
131            405 => Self::MethodNotAllowed.to_string(),
132            406 => Self::NotAcceptable.to_string(),
133            407 => Self::ProxyAuthenticationRequired.to_string(),
134            408 => Self::RequestTimeout.to_string(),
135            409 => Self::Conflict.to_string(),
136            410 => Self::Gone.to_string(),
137            411 => Self::LengthRequired.to_string(),
138            412 => Self::PreconditionFailed.to_string(),
139            413 => Self::PayloadTooLarge.to_string(),
140            414 => Self::URITooLong.to_string(),
141            415 => Self::UnsupportedMediaType.to_string(),
142            416 => Self::RangeNotSatisfiable.to_string(),
143            417 => Self::ExpectationFailed.to_string(),
144            418 => Self::ImATeapot.to_string(),
145            421 => Self::MisdirectedRequest.to_string(),
146            422 => Self::UnprocessableEntity.to_string(),
147            423 => Self::Locked.to_string(),
148            424 => Self::FailedDependency.to_string(),
149            425 => Self::TooEarly.to_string(),
150            426 => Self::UpgradeRequired.to_string(),
151            428 => Self::PreconditionRequired.to_string(),
152            429 => Self::TooManyRequests.to_string(),
153            431 => Self::RequestHeaderFieldsTooLarge.to_string(),
154            451 => Self::UnavailableForLegalReasons.to_string(),
155            500 => Self::InternalServerError.to_string(),
156            501 => Self::NotImplemented.to_string(),
157            502 => Self::BadGateway.to_string(),
158            503 => Self::ServiceUnavailable.to_string(),
159            504 => Self::GatewayTimeout.to_string(),
160            505 => Self::HTTPVersionNotSupported.to_string(),
161            506 => Self::VariantAlsoNegotiates.to_string(),
162            507 => Self::InsufficientStorage.to_string(),
163            508 => Self::LoopDetected.to_string(),
164            510 => Self::NotExtended.to_string(),
165            511 => Self::NetworkAuthenticationRequired.to_string(),
166            _ => Self::Unknown.to_string(),
167        }
168    }
169
170    /// Compares the current status code with a given string representation.
171    ///
172    /// This method checks if the given `code_str` matches either the numeric HTTP status code
173    /// returned by `code()` or the string representation of the status code variant.
174    /// The comparison is case-insensitive.
175    ///
176    /// # Parameters
177    /// - `&self`: A reference to the `HttpStatus` enum instance.
178    /// - `code_str`: A string slice containing the status code to compare against.
179    ///
180    /// # Return Value
181    /// - `bool`: Returns `true` if `code_str` matches the numeric code or the string representation of `self`, otherwise `false`.
182    #[inline]
183    pub fn same(&self, code_str: &str) -> bool {
184        self.to_string().eq_ignore_ascii_case(code_str)
185    }
186}
187
188impl Display for HttpStatus {
189    #[inline]
190    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
191        let res: &str = match self {
192            Self::Continue => "Continue",
193            Self::SwitchingProtocols => "Switching Protocols",
194            Self::Processing => "Processing",
195            Self::EarlyHints => "Early Hints",
196            Self::Ok => "OK",
197            Self::Created => "Created",
198            Self::Accepted => "Accepted",
199            Self::NonAuthoritativeInformation => "Non-Authoritative Information",
200            Self::NoContent => "No Content",
201            Self::ResetContent => "Reset Content",
202            Self::PartialContent => "Partial Content",
203            Self::MultiStatus => "Multi-Status",
204            Self::AlreadyReported => "Already Reported",
205            Self::IMUsed => "IM Used",
206            Self::MultipleChoices => "Multiple Choices",
207            Self::MovedPermanently => "Moved Permanently",
208            Self::Found => "Found",
209            Self::SeeOther => "See Other",
210            Self::NotModified => "Not Modified",
211            Self::UseProxy => "Use Proxy",
212            Self::TemporaryRedirect => "Temporary Redirect",
213            Self::PermanentRedirect => "Permanent Redirect",
214            Self::BadRequest => "Bad Request",
215            Self::Unauthorized => "Unauthorized",
216            Self::PaymentRequired => "Payment Required",
217            Self::Forbidden => "Forbidden",
218            Self::NotFound => "Not Found",
219            Self::MethodNotAllowed => "Method Not Allowed",
220            Self::NotAcceptable => "Not Acceptable",
221            Self::ProxyAuthenticationRequired => "Proxy Authentication Required",
222            Self::RequestTimeout => "Request Timeout",
223            Self::Conflict => "Conflict",
224            Self::Gone => "Gone",
225            Self::LengthRequired => "Length Required",
226            Self::PreconditionFailed => "Precondition Failed",
227            Self::PayloadTooLarge => "Payload Too Large",
228            Self::URITooLong => "URI Too Long",
229            Self::UnsupportedMediaType => "Unsupported Media Type",
230            Self::RangeNotSatisfiable => "Range Not Satisfiable",
231            Self::ExpectationFailed => "Expectation Failed",
232            Self::ImATeapot => "I'm a teapot",
233            Self::MisdirectedRequest => "Misdirected Request",
234            Self::UnprocessableEntity => "Unprocessable Entity",
235            Self::Locked => "Locked",
236            Self::FailedDependency => "Failed Dependency",
237            Self::TooEarly => "Too Early",
238            Self::UpgradeRequired => "Upgrade Required",
239            Self::PreconditionRequired => "Precondition Required",
240            Self::TooManyRequests => "Too Many Requests",
241            Self::RequestHeaderFieldsTooLarge => "Request Header Fields Too Large",
242            Self::UnavailableForLegalReasons => "Unavailable For Legal Reasons",
243            Self::InternalServerError => "Internal Server Error",
244            Self::NotImplemented => "Not Implemented",
245            Self::BadGateway => "Bad Gateway",
246            Self::ServiceUnavailable => "Service Unavailable",
247            Self::GatewayTimeout => "Gateway Timeout",
248            Self::HTTPVersionNotSupported => "HTTP Version Not Supported",
249            Self::VariantAlsoNegotiates => "Variant Also Negotiates",
250            Self::InsufficientStorage => "Insufficient Storage",
251            Self::LoopDetected => "Loop Detected",
252            Self::NotExtended => "Not Extended",
253            Self::NetworkAuthenticationRequired => "Network Authentication Required",
254            Self::Unknown => "Unknown",
255        };
256        write!(f, "{}", res)
257    }
258}
259
260impl FromStr for HttpStatus {
261    type Err = ();
262
263    #[inline]
264    fn from_str(code_str: &str) -> Result<Self, Self::Err> {
265        match code_str {
266            _code_str if Self::Continue.same(_code_str) => Ok(Self::Continue),
267            _code_str if Self::SwitchingProtocols.same(_code_str) => Ok(Self::SwitchingProtocols),
268            _code_str if Self::Processing.same(_code_str) => Ok(Self::Processing),
269            _code_str if Self::EarlyHints.same(_code_str) => Ok(Self::EarlyHints),
270            _code_str if Self::Ok.same(_code_str) => Ok(Self::Ok),
271            _code_str if Self::Created.same(_code_str) => Ok(Self::Created),
272            _code_str if Self::Accepted.same(_code_str) => Ok(Self::Accepted),
273            _code_str if Self::NonAuthoritativeInformation.same(_code_str) => {
274                Ok(Self::NonAuthoritativeInformation)
275            }
276            _code_str if Self::NoContent.same(_code_str) => Ok(Self::NoContent),
277            _code_str if Self::ResetContent.same(_code_str) => Ok(Self::ResetContent),
278            _code_str if Self::PartialContent.same(_code_str) => Ok(Self::PartialContent),
279            _code_str if Self::MultiStatus.same(_code_str) => Ok(Self::MultiStatus),
280            _code_str if Self::AlreadyReported.same(_code_str) => Ok(Self::AlreadyReported),
281            _code_str if Self::IMUsed.same(_code_str) => Ok(Self::IMUsed),
282            _code_str if Self::MultipleChoices.same(_code_str) => Ok(Self::MultipleChoices),
283            _code_str if Self::MovedPermanently.same(_code_str) => Ok(Self::MovedPermanently),
284            _code_str if Self::Found.same(_code_str) => Ok(Self::Found),
285            _code_str if Self::SeeOther.same(_code_str) => Ok(Self::SeeOther),
286            _code_str if Self::NotModified.same(_code_str) => Ok(Self::NotModified),
287            _code_str if Self::UseProxy.same(_code_str) => Ok(Self::UseProxy),
288            _code_str if Self::TemporaryRedirect.same(_code_str) => Ok(Self::TemporaryRedirect),
289            _code_str if Self::PermanentRedirect.same(_code_str) => Ok(Self::PermanentRedirect),
290            _code_str if Self::BadRequest.same(_code_str) => Ok(Self::BadRequest),
291            _code_str if Self::Unauthorized.same(_code_str) => Ok(Self::Unauthorized),
292            _code_str if Self::PaymentRequired.same(_code_str) => Ok(Self::PaymentRequired),
293            _code_str if Self::Forbidden.same(_code_str) => Ok(Self::Forbidden),
294            _code_str if Self::NotFound.same(_code_str) => Ok(Self::NotFound),
295            _code_str if Self::MethodNotAllowed.same(_code_str) => Ok(Self::MethodNotAllowed),
296            _code_str if Self::NotAcceptable.same(_code_str) => Ok(Self::NotAcceptable),
297            _code_str if Self::ProxyAuthenticationRequired.same(_code_str) => {
298                Ok(Self::ProxyAuthenticationRequired)
299            }
300            _code_str if Self::RequestTimeout.same(_code_str) => Ok(Self::RequestTimeout),
301            _code_str if Self::Conflict.same(_code_str) => Ok(Self::Conflict),
302            _code_str if Self::Gone.same(_code_str) => Ok(Self::Gone),
303            _code_str if Self::LengthRequired.same(_code_str) => Ok(Self::LengthRequired),
304            _code_str if Self::PreconditionFailed.same(_code_str) => Ok(Self::PreconditionFailed),
305            _code_str if Self::PayloadTooLarge.same(_code_str) => Ok(Self::PayloadTooLarge),
306            _code_str if Self::URITooLong.same(_code_str) => Ok(Self::URITooLong),
307            _code_str if Self::UnsupportedMediaType.same(_code_str) => {
308                Ok(Self::UnsupportedMediaType)
309            }
310            _code_str if Self::RangeNotSatisfiable.same(_code_str) => Ok(Self::RangeNotSatisfiable),
311            _code_str if Self::ExpectationFailed.same(_code_str) => Ok(Self::ExpectationFailed),
312            _code_str if Self::ImATeapot.same(_code_str) => Ok(Self::ImATeapot),
313            _code_str if Self::MisdirectedRequest.same(_code_str) => Ok(Self::MisdirectedRequest),
314            _code_str if Self::UnprocessableEntity.same(_code_str) => Ok(Self::UnprocessableEntity),
315            _code_str if Self::Locked.same(_code_str) => Ok(Self::Locked),
316            _code_str if Self::FailedDependency.same(_code_str) => Ok(Self::FailedDependency),
317            _code_str if Self::TooEarly.same(_code_str) => Ok(Self::TooEarly),
318            _code_str if Self::UpgradeRequired.same(_code_str) => Ok(Self::UpgradeRequired),
319            _code_str if Self::PreconditionRequired.same(_code_str) => {
320                Ok(Self::PreconditionRequired)
321            }
322            _code_str if Self::TooManyRequests.same(_code_str) => Ok(Self::TooManyRequests),
323            _code_str if Self::RequestHeaderFieldsTooLarge.same(_code_str) => {
324                Ok(Self::RequestHeaderFieldsTooLarge)
325            }
326            _code_str if Self::UnavailableForLegalReasons.same(_code_str) => {
327                Ok(Self::UnavailableForLegalReasons)
328            }
329            _code_str if Self::InternalServerError.same(_code_str) => Ok(Self::InternalServerError),
330            _code_str if Self::NotImplemented.same(_code_str) => Ok(Self::NotImplemented),
331            _code_str if Self::BadGateway.same(_code_str) => Ok(Self::BadGateway),
332            _code_str if Self::ServiceUnavailable.same(_code_str) => Ok(Self::ServiceUnavailable),
333            _code_str if Self::GatewayTimeout.same(_code_str) => Ok(Self::GatewayTimeout),
334            _code_str if Self::HTTPVersionNotSupported.same(_code_str) => {
335                Ok(Self::HTTPVersionNotSupported)
336            }
337            _code_str if Self::VariantAlsoNegotiates.same(_code_str) => {
338                Ok(Self::VariantAlsoNegotiates)
339            }
340            _code_str if Self::InsufficientStorage.same(_code_str) => Ok(Self::InsufficientStorage),
341            _code_str if Self::LoopDetected.same(_code_str) => Ok(Self::LoopDetected),
342            _code_str if Self::NotExtended.same(_code_str) => Ok(Self::NotExtended),
343            _code_str if Self::NetworkAuthenticationRequired.same(_code_str) => {
344                Ok(Self::NetworkAuthenticationRequired)
345            }
346            _ => Ok(Self::Unknown),
347        }
348    }
349}
350
351impl Default for HttpStatus {
352    #[inline]
353    fn default() -> Self {
354        Self::Ok
355    }
356}