1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
//! Provides functionality for handling HTTP status codes.
use std::convert::TryFrom;
/// Represents an HTTP status code.
/// Can be converted to and from both `u16` and `&str`.
///
/// ## Example
/// ```
/// let status = StatusCode::NotFound;
/// let status2 = StatusCode::try_from(404)?;
/// assert_eq!(status, status2);
///
/// let status_code: u16 = status.into();
/// let status_name: &str = status.into();
/// assert_eq!(status_code, 404);
/// assert_eq!(status_name, "Not Found");
/// ```
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum StatusCode {
/// `100 Continue`: Continue with request.
Continue,
/// `101 Switching Protocols`: Protocol upgrade.
SwitchingProtocols,
/// `200 OK`: Request succeeded.
OK,
/// `201 Created`: Resource created.
Created,
/// `202 Accepted`: Request received, but not yet acted upon.
Accepted,
/// `203 Non-Authoritative Information`: Request processed, but response is from another source.
NonAuthoritative,
/// `204 No Content`: There is no content to send for this request.
NoContent,
/// `205 Reset Content`: Indicates that the document which sent this request should be reset.
ResetContent,
/// `206 Partial Content`: This response only contains part of a resource.
PartialContent,
/// `300 Multiple Choice`: The request has multiple possible responses.
MultipleChoices,
/// `301 Moved Permanently`: The resource has moved permanently to a new location.
MovedPermanently,
/// `302 Found`: The resource has moved temporarily to a new location.
Found,
/// `303 See Other`: The resource can be found under a different URI.
SeeOther,
/// `304 Not Modified`: The resource has not been modified since the last request.
NotModified,
/// `305 Use Proxy`: The requested resource must be accessed through a proxy.
UseProxy,
/// `307 Temporary Redirect`: The resource has moved temporarily to a new location.
TemporaryRedirect,
/// `400 Bad Request`: The request could not be understood by the server.
BadRequest,
/// `401 Unauthorized`: The request requires user authentication.
Unauthorized,
/// `403 Forbidden`: The client is not allowed to access this content.
Forbidden,
/// `404 Not Found`: The server can not find the requested resource.
NotFound,
/// `405 Method Not Allowed`: The method specified in the request is not allowed for the resource.
MethodNotAllowed,
/// `406 Not Acceptable`: No content that meets the criteria is available.
NotAcceptable,
/// `407 Proxy Authentication Required`: The client must first authenticate itself with a proxy.
ProxyAuthenticationRequired,
/// `408 Request Timeout`: The server timed out waiting for the request.
RequestTimeout,
/// `409 Conflict`: The request could not be completed because of a conflict with the server's current state.
Conflict,
/// `410 Gone`: The requested resource is no longer available.
Gone,
/// `411 Length Required`: The request did not specify the length of its content.
LengthRequired,
/// `412 Precondition Failed`: The server does not meet one of the client's preconditions.
PreconditionFailed,
/// `413 Payload Too Large`: The request is larger than the server is willing or able to process.
RequestEntityTooLarge,
/// `414 URI Too Long`: The URI provided was too long for the server to process.
RequestURITooLong,
/// `415 Unsupported Media Type`: The request entity has a media type which the server or resource does not support.
UnsupportedMediaType,
/// `416 Requested Range Not Satisfiable`: The range specified in the `Range` header cannot be fulfilled.
RequestedRangeNotSatisfiable,
/// `417 Expectation Failed`: The expectation given in the `Expect` header could not be met by the server.
ExpectationFailed,
/// `500 Internal Server Error`: The server encountered an unexpected error which prevented it from fulfilling the request.
InternalError,
/// `501 Not Implemented`: The server does not support the functionality required to fulfill the request.
NotImplemented,
/// `502 Bad Gateway`: The server, while acting as a gateway or proxy, received an invalid response from the upstream server.
BadGateway,
/// `503 Service Unavailable`: The server is temporarily unable to handle the request.
ServiceUnavailable,
/// `504 Gateway Timeout`: The server, while acting as a gateway or proxy, did not receive a timely response from the upstream server.
GatewayTimeout,
/// `505 HTTP Version Not Supported`: The server does not support the HTTP protocol version used in the request.
VersionNotSupported,
}
/// Represents an error with the status code.
#[derive(PartialEq, Eq)]
pub struct StatusCodeError;
impl TryFrom<u16> for StatusCode {
fn try_from(code: u16) -> Result<Self, StatusCodeError> {
match code {
100 => Ok(StatusCode::Continue),
101 => Ok(StatusCode::SwitchingProtocols),
200 => Ok(StatusCode::OK),
201 => Ok(StatusCode::Created),
202 => Ok(StatusCode::Accepted),
203 => Ok(StatusCode::NonAuthoritative),
204 => Ok(StatusCode::NoContent),
205 => Ok(StatusCode::ResetContent),
206 => Ok(StatusCode::PartialContent),
300 => Ok(StatusCode::MultipleChoices),
301 => Ok(StatusCode::MovedPermanently),
302 => Ok(StatusCode::Found),
303 => Ok(StatusCode::SeeOther),
304 => Ok(StatusCode::NotModified),
305 => Ok(StatusCode::UseProxy),
307 => Ok(StatusCode::TemporaryRedirect),
400 => Ok(StatusCode::BadRequest),
401 => Ok(StatusCode::Unauthorized),
403 => Ok(StatusCode::Forbidden),
404 => Ok(StatusCode::NotFound),
405 => Ok(StatusCode::MethodNotAllowed),
406 => Ok(StatusCode::NotAcceptable),
407 => Ok(StatusCode::ProxyAuthenticationRequired),
408 => Ok(StatusCode::RequestTimeout),
409 => Ok(StatusCode::Conflict),
410 => Ok(StatusCode::Gone),
411 => Ok(StatusCode::LengthRequired),
412 => Ok(StatusCode::PreconditionFailed),
413 => Ok(StatusCode::RequestEntityTooLarge),
414 => Ok(StatusCode::RequestURITooLong),
415 => Ok(StatusCode::UnsupportedMediaType),
416 => Ok(StatusCode::RequestedRangeNotSatisfiable),
417 => Ok(StatusCode::ExpectationFailed),
500 => Ok(StatusCode::InternalError),
501 => Ok(StatusCode::NotImplemented),
502 => Ok(StatusCode::BadGateway),
503 => Ok(StatusCode::ServiceUnavailable),
504 => Ok(StatusCode::GatewayTimeout),
505 => Ok(StatusCode::VersionNotSupported),
_ => Err(StatusCodeError),
}
}
type Error = StatusCodeError;
}
impl From<StatusCode> for u16 {
fn from(val: StatusCode) -> Self {
match val {
StatusCode::Continue => 100,
StatusCode::SwitchingProtocols => 101,
StatusCode::OK => 200,
StatusCode::Created => 201,
StatusCode::Accepted => 202,
StatusCode::NonAuthoritative => 203,
StatusCode::NoContent => 204,
StatusCode::ResetContent => 205,
StatusCode::PartialContent => 206,
StatusCode::MultipleChoices => 300,
StatusCode::MovedPermanently => 301,
StatusCode::Found => 302,
StatusCode::SeeOther => 303,
StatusCode::NotModified => 304,
StatusCode::UseProxy => 305,
StatusCode::TemporaryRedirect => 307,
StatusCode::BadRequest => 400,
StatusCode::Unauthorized => 401,
StatusCode::Forbidden => 403,
StatusCode::NotFound => 404,
StatusCode::MethodNotAllowed => 405,
StatusCode::NotAcceptable => 406,
StatusCode::ProxyAuthenticationRequired => 407,
StatusCode::RequestTimeout => 408,
StatusCode::Conflict => 409,
StatusCode::Gone => 410,
StatusCode::LengthRequired => 411,
StatusCode::PreconditionFailed => 412,
StatusCode::RequestEntityTooLarge => 413,
StatusCode::RequestURITooLong => 414,
StatusCode::UnsupportedMediaType => 415,
StatusCode::RequestedRangeNotSatisfiable => 416,
StatusCode::ExpectationFailed => 417,
StatusCode::InternalError => 500,
StatusCode::NotImplemented => 501,
StatusCode::BadGateway => 502,
StatusCode::ServiceUnavailable => 503,
StatusCode::GatewayTimeout => 504,
StatusCode::VersionNotSupported => 505,
}
}
}
impl From<StatusCode> for &str {
fn from(val: StatusCode) -> Self {
match val {
StatusCode::Continue => "Continue",
StatusCode::SwitchingProtocols => "Switching Protocols",
StatusCode::OK => "OK",
StatusCode::Created => "Created",
StatusCode::Accepted => "Accepted",
StatusCode::NonAuthoritative => "Non-Authoritative Information",
StatusCode::NoContent => "No Content",
StatusCode::ResetContent => "Reset Content",
StatusCode::PartialContent => "Partial Content",
StatusCode::MultipleChoices => "Multiple Choices",
StatusCode::MovedPermanently => "Moved Permanently",
StatusCode::Found => "Found",
StatusCode::SeeOther => "See Other",
StatusCode::NotModified => "Not Modified",
StatusCode::UseProxy => "Use Proxy",
StatusCode::TemporaryRedirect => "Temporary Redirect",
StatusCode::BadRequest => "Bad Request",
StatusCode::Unauthorized => "Unauthorized",
StatusCode::Forbidden => "Forbidden",
StatusCode::NotFound => "Not Found",
StatusCode::MethodNotAllowed => "Method Not Allowed",
StatusCode::NotAcceptable => "Not Acceptable",
StatusCode::ProxyAuthenticationRequired => "Proxy Authentication Required",
StatusCode::RequestTimeout => "Request Timeout",
StatusCode::Conflict => "Conflict",
StatusCode::Gone => "Gone",
StatusCode::LengthRequired => "Length Required",
StatusCode::PreconditionFailed => "Precondition Failed",
StatusCode::RequestEntityTooLarge => "Request Entity Too Large",
StatusCode::RequestURITooLong => "Request-URI Too Long",
StatusCode::UnsupportedMediaType => "Unsupported Media Type",
StatusCode::RequestedRangeNotSatisfiable => "Requested Range Not Satisfiable",
StatusCode::ExpectationFailed => "Expectation Failed",
StatusCode::InternalError => "Internal Server Error",
StatusCode::NotImplemented => "Not Implemented",
StatusCode::BadGateway => "Bad Gateway",
StatusCode::ServiceUnavailable => "Service Unavailable",
StatusCode::GatewayTimeout => "Gateway Timeout",
StatusCode::VersionNotSupported => "HTTP Version Not Supported",
}
}
}