Skip to main content

core_rs/
http_status_code.rs

1/**
2 * Copyright 2025-present Coinbase Global, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *  http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
17#[repr(u16)]
18pub enum HttpStatusCode {
19    Continue = 100,
20    SwitchingProtocols = 101,
21    Processing = 102,
22    EarlyHints = 103,
23
24    Ok = 200,
25    Created = 201,
26    Accepted = 202,
27    NonAuthoritativeInformation = 203,
28    NoContent = 204,
29    ResetContent = 205,
30    PartialContent = 206,
31    MultiStatus = 207,
32    AlreadyReported = 208,
33    ImUsed = 226,
34
35    MultipleChoices = 300,
36    MovedPermanently = 301,
37    Found = 302,
38    SeeOther = 303,
39    NotModified = 304,
40    UseProxy = 305,
41    TemporaryRedirect = 307,
42    PermanentRedirect = 308,
43
44    BadRequest = 400,
45    Unauthorized = 401,
46    PaymentRequired = 402,
47    Forbidden = 403,
48    NotFound = 404,
49    MethodNotAllowed = 405,
50    NotAcceptable = 406,
51    ProxyAuthenticationRequired = 407,
52    RequestTimeout = 408,
53    Conflict = 409,
54    Gone = 410,
55    LengthRequired = 411,
56    PreconditionFailed = 412,
57    PayloadTooLarge = 413,
58    UriTooLong = 414,
59    UnsupportedMediaType = 415,
60    RangeNotSatisfiable = 416,
61    ExpectationFailed = 417,
62    ImATeapot = 418,
63    MisdirectedRequest = 421,
64    UnprocessableEntity = 422,
65    Locked = 423,
66    FailedDependency = 424,
67    TooEarly = 425,
68    UpgradeRequired = 426,
69    PreconditionRequired = 428,
70    TooManyRequests = 429,
71    RequestHeaderFieldsTooLarge = 431,
72    UnavailableForLegalReasons = 451,
73
74    InternalServerError = 500,
75    NotImplemented = 501,
76    BadGateway = 502,
77    ServiceUnavailable = 503,
78    GatewayTimeout = 504,
79    HttpVersionNotSupported = 505,
80    VariantAlsoNegotiates = 506,
81    InsufficientStorage = 507,
82    LoopDetected = 508,
83    NotExtended = 510,
84    NetworkAuthenticationRequired = 511,
85
86    Custom(u16),
87}
88
89impl HttpStatusCode {
90    /// Get the numeric status code
91    pub fn as_u16(&self) -> u16 {
92        match self {
93            HttpStatusCode::Continue => 100,
94            HttpStatusCode::SwitchingProtocols => 101,
95            HttpStatusCode::Processing => 102,
96            HttpStatusCode::EarlyHints => 103,
97            HttpStatusCode::Ok => 200,
98            HttpStatusCode::Created => 201,
99            HttpStatusCode::Accepted => 202,
100            HttpStatusCode::NonAuthoritativeInformation => 203,
101            HttpStatusCode::NoContent => 204,
102            HttpStatusCode::ResetContent => 205,
103            HttpStatusCode::PartialContent => 206,
104            HttpStatusCode::MultiStatus => 207,
105            HttpStatusCode::AlreadyReported => 208,
106            HttpStatusCode::ImUsed => 226,
107            HttpStatusCode::MultipleChoices => 300,
108            HttpStatusCode::MovedPermanently => 301,
109            HttpStatusCode::Found => 302,
110            HttpStatusCode::SeeOther => 303,
111            HttpStatusCode::NotModified => 304,
112            HttpStatusCode::UseProxy => 305,
113            HttpStatusCode::TemporaryRedirect => 307,
114            HttpStatusCode::PermanentRedirect => 308,
115            HttpStatusCode::BadRequest => 400,
116            HttpStatusCode::Unauthorized => 401,
117            HttpStatusCode::PaymentRequired => 402,
118            HttpStatusCode::Forbidden => 403,
119            HttpStatusCode::NotFound => 404,
120            HttpStatusCode::MethodNotAllowed => 405,
121            HttpStatusCode::NotAcceptable => 406,
122            HttpStatusCode::ProxyAuthenticationRequired => 407,
123            HttpStatusCode::RequestTimeout => 408,
124            HttpStatusCode::Conflict => 409,
125            HttpStatusCode::Gone => 410,
126            HttpStatusCode::LengthRequired => 411,
127            HttpStatusCode::PreconditionFailed => 412,
128            HttpStatusCode::PayloadTooLarge => 413,
129            HttpStatusCode::UriTooLong => 414,
130            HttpStatusCode::UnsupportedMediaType => 415,
131            HttpStatusCode::RangeNotSatisfiable => 416,
132            HttpStatusCode::ExpectationFailed => 417,
133            HttpStatusCode::ImATeapot => 418,
134            HttpStatusCode::MisdirectedRequest => 421,
135            HttpStatusCode::UnprocessableEntity => 422,
136            HttpStatusCode::Locked => 423,
137            HttpStatusCode::FailedDependency => 424,
138            HttpStatusCode::TooEarly => 425,
139            HttpStatusCode::UpgradeRequired => 426,
140            HttpStatusCode::PreconditionRequired => 428,
141            HttpStatusCode::TooManyRequests => 429,
142            HttpStatusCode::RequestHeaderFieldsTooLarge => 431,
143            HttpStatusCode::UnavailableForLegalReasons => 451,
144            HttpStatusCode::InternalServerError => 500,
145            HttpStatusCode::NotImplemented => 501,
146            HttpStatusCode::BadGateway => 502,
147            HttpStatusCode::ServiceUnavailable => 503,
148            HttpStatusCode::GatewayTimeout => 504,
149            HttpStatusCode::HttpVersionNotSupported => 505,
150            HttpStatusCode::VariantAlsoNegotiates => 506,
151            HttpStatusCode::InsufficientStorage => 507,
152            HttpStatusCode::LoopDetected => 508,
153            HttpStatusCode::NotExtended => 510,
154            HttpStatusCode::NetworkAuthenticationRequired => 511,
155            HttpStatusCode::Custom(code) => *code,
156        }
157    }
158
159    /// Check if the status code indicates success (2xx)
160    pub fn is_success(&self) -> bool {
161        let code = self.as_u16();
162        code >= 200 && code < 300
163    }
164
165    /// Check if the status code indicates a client error (4xx)
166    pub fn is_client_error(&self) -> bool {
167        let code = self.as_u16();
168        code >= 400 && code < 500
169    }
170
171    /// Check if the status code indicates a server error (5xx)
172    pub fn is_server_error(&self) -> bool {
173        let code = self.as_u16();
174        code >= 500 && code < 600
175    }
176
177    /// Check if the status code indicates an error (4xx or 5xx)
178    pub fn is_error(&self) -> bool {
179        self.is_client_error() || self.is_server_error()
180    }
181
182    /// Check if the status code indicates a redirection (3xx)
183    pub fn is_redirection(&self) -> bool {
184        let code = self.as_u16();
185        code >= 300 && code < 400
186    }
187
188    /// Check if the status code indicates an informational response (1xx)
189    pub fn is_informational(&self) -> bool {
190        let code = self.as_u16();
191        code >= 100 && code < 200
192    }
193}
194
195impl From<reqwest::StatusCode> for HttpStatusCode {
196    fn from(status: reqwest::StatusCode) -> Self {
197        let code = status.as_u16();
198        match code {
199            100 => HttpStatusCode::Continue,
200            101 => HttpStatusCode::SwitchingProtocols,
201            102 => HttpStatusCode::Processing,
202            103 => HttpStatusCode::EarlyHints,
203            200 => HttpStatusCode::Ok,
204            201 => HttpStatusCode::Created,
205            202 => HttpStatusCode::Accepted,
206            203 => HttpStatusCode::NonAuthoritativeInformation,
207            204 => HttpStatusCode::NoContent,
208            205 => HttpStatusCode::ResetContent,
209            206 => HttpStatusCode::PartialContent,
210            207 => HttpStatusCode::MultiStatus,
211            208 => HttpStatusCode::AlreadyReported,
212            226 => HttpStatusCode::ImUsed,
213            300 => HttpStatusCode::MultipleChoices,
214            301 => HttpStatusCode::MovedPermanently,
215            302 => HttpStatusCode::Found,
216            303 => HttpStatusCode::SeeOther,
217            304 => HttpStatusCode::NotModified,
218            305 => HttpStatusCode::UseProxy,
219            307 => HttpStatusCode::TemporaryRedirect,
220            308 => HttpStatusCode::PermanentRedirect,
221            400 => HttpStatusCode::BadRequest,
222            401 => HttpStatusCode::Unauthorized,
223            402 => HttpStatusCode::PaymentRequired,
224            403 => HttpStatusCode::Forbidden,
225            404 => HttpStatusCode::NotFound,
226            405 => HttpStatusCode::MethodNotAllowed,
227            406 => HttpStatusCode::NotAcceptable,
228            407 => HttpStatusCode::ProxyAuthenticationRequired,
229            408 => HttpStatusCode::RequestTimeout,
230            409 => HttpStatusCode::Conflict,
231            410 => HttpStatusCode::Gone,
232            411 => HttpStatusCode::LengthRequired,
233            412 => HttpStatusCode::PreconditionFailed,
234            413 => HttpStatusCode::PayloadTooLarge,
235            414 => HttpStatusCode::UriTooLong,
236            415 => HttpStatusCode::UnsupportedMediaType,
237            416 => HttpStatusCode::RangeNotSatisfiable,
238            417 => HttpStatusCode::ExpectationFailed,
239            418 => HttpStatusCode::ImATeapot,
240            421 => HttpStatusCode::MisdirectedRequest,
241            422 => HttpStatusCode::UnprocessableEntity,
242            423 => HttpStatusCode::Locked,
243            424 => HttpStatusCode::FailedDependency,
244            425 => HttpStatusCode::TooEarly,
245            426 => HttpStatusCode::UpgradeRequired,
246            428 => HttpStatusCode::PreconditionRequired,
247            429 => HttpStatusCode::TooManyRequests,
248            431 => HttpStatusCode::RequestHeaderFieldsTooLarge,
249            451 => HttpStatusCode::UnavailableForLegalReasons,
250            500 => HttpStatusCode::InternalServerError,
251            501 => HttpStatusCode::NotImplemented,
252            502 => HttpStatusCode::BadGateway,
253            503 => HttpStatusCode::ServiceUnavailable,
254            504 => HttpStatusCode::GatewayTimeout,
255            505 => HttpStatusCode::HttpVersionNotSupported,
256            506 => HttpStatusCode::VariantAlsoNegotiates,
257            507 => HttpStatusCode::InsufficientStorage,
258            508 => HttpStatusCode::LoopDetected,
259            510 => HttpStatusCode::NotExtended,
260            511 => HttpStatusCode::NetworkAuthenticationRequired,
261            _ => HttpStatusCode::Custom(code),
262        }
263    }
264}
265
266impl std::fmt::Display for HttpStatusCode {
267    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
268        write!(f, "{}", self.as_u16())
269    }
270}