• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 //! HTTP [`Status Codes`].
15 //!
16 //! The status code of a response is a three-digit integer code that describes
17 //! the result of the request and the semantics of the response, including
18 //! whether the request was successful and what content is enclosed (if any).
19 //! All valid status codes are within the range of 100 to 599, inclusive.
20 //!
21 //! [`Status Codes`]: https://httpwg.org/specs/rfc9110.html#status.codes
22 
23 use core::convert::TryFrom;
24 use core::fmt::{Display, Formatter};
25 
26 use crate::error::{ErrorKind, HttpError};
27 
28 /// HTTP [`Status Codes`] implementation.
29 ///
30 /// [`Status Codes`]: https://httpwg.org/specs/rfc9110.html#status.codes
31 ///
32 /// # Examples
33 ///
34 /// ```
35 /// use ylong_http::response::status::StatusCode;
36 ///
37 /// let status = StatusCode::OK;
38 /// ```
39 #[derive(Debug, Clone, PartialEq, Eq)]
40 pub struct StatusCode(u16);
41 
42 impl StatusCode {
43     /// Converts a `u16` to a `StatusCode`.
44     ///
45     /// # Examples
46     /// ```
47     /// use ylong_http::response::status::StatusCode;
48     ///
49     /// assert_eq!(StatusCode::from_u16(200), Ok(StatusCode::OK));
50     /// ```
from_u16(code: u16) -> Result<StatusCode, HttpError>51     pub fn from_u16(code: u16) -> Result<StatusCode, HttpError> {
52         // Only three-digit status codes are valid.
53         if !(100..1000).contains(&code) {
54             return Err(ErrorKind::InvalidInput.into());
55         }
56 
57         Ok(StatusCode(code))
58     }
59 
60     /// Converts a `StatusCode` to a `u16`.
61     ///
62     /// # Examples
63     /// ```
64     /// use ylong_http::response::status::StatusCode;
65     ///
66     /// assert_eq!(StatusCode::OK.as_u16(), 200u16);
67     /// ```
as_u16(&self) -> u1668     pub fn as_u16(&self) -> u16 {
69         self.0
70     }
71 
72     /// Converts a `&[u8]` to a `StatusCode`.
73     ///
74     /// # Example
75     /// ```
76     /// use ylong_http::response::status::StatusCode;
77     ///
78     /// assert_eq!(StatusCode::from_bytes(b"200"), Ok(StatusCode::OK));
79     /// assert!(StatusCode::from_bytes(b"0").is_err());
80     /// ```
from_bytes(bytes: &[u8]) -> Result<Self, HttpError>81     pub fn from_bytes(bytes: &[u8]) -> Result<Self, HttpError> {
82         // Only three-digit status codes are valid.
83         if bytes.len() != 3 {
84             return Err(ErrorKind::InvalidInput.into());
85         }
86 
87         let a = bytes[0].wrapping_sub(b'0') as u16;
88         let b = bytes[1].wrapping_sub(b'0') as u16;
89         let c = bytes[2].wrapping_sub(b'0') as u16;
90 
91         if a == 0 || a > 9 || b > 9 || c > 9 {
92             return Err(ErrorKind::InvalidInput.into());
93         }
94 
95         // Valid status code: 1 <= a <= 9 && 0 <= b <= 9 && 0 <= c <= 9
96         Ok(StatusCode((a * 100) + (b * 10) + c))
97     }
98 
99     /// Converts a `StatusCode` to a `[u8; 3]`.
100     ///
101     /// # Example
102     /// ```
103     /// use ylong_http::response::status::StatusCode;
104     ///
105     /// assert_eq!(StatusCode::OK.as_bytes(), *b"200");
106     /// ```
as_bytes(&self) -> [u8; 3]107     pub fn as_bytes(&self) -> [u8; 3] {
108         [
109             ((self.0 / 100) as u8) + b'0',
110             (((self.0 % 100) / 10) as u8) + b'0',
111             ((self.0 % 10) as u8) + b'0',
112         ]
113     }
114 
115     /// StatusCode as str.
116     // TODO: Adapter, remove it later.
as_str(&self) -> String117     pub fn as_str(&self) -> String {
118         format!("{}", self.0)
119     }
120 
121     /// Determines whether the `StatusCode` is [`1xx (Informational)`].
122     ///
123     /// The 1xx (Informational) class of status code indicates an interim
124     /// response for communicating connection status or request progress prior
125     /// to completing the requested action and sending a final response.
126     ///
127     /// [`1xx (Informational)`]: https://httpwg.org/specs/rfc9110.html#status.1xx
128     ///
129     /// # Examples
130     /// ```
131     /// use ylong_http::response::status::StatusCode;
132     ///
133     /// assert!(StatusCode::CONTINUE.is_informational());
134     /// assert!(!StatusCode::OK.is_informational());
135     /// ```
is_informational(&self) -> bool136     pub fn is_informational(&self) -> bool {
137         self.0 >= 100 && 200 > self.0
138     }
139 
140     /// Determines whether the `StatusCode` is [`2xx (Successful)`].
141     ///
142     /// The 2xx (Successful) class of status code indicates that the client's
143     /// request was successfully received, understood, and accepted.
144     ///
145     /// [`2xx (Successful)`]: https://httpwg.org/specs/rfc9110.html#status.2xx
146     ///
147     /// # Examples
148     /// ```
149     /// use ylong_http::response::status::StatusCode;
150     ///
151     /// assert!(StatusCode::OK.is_successful());
152     /// assert!(!StatusCode::CONTINUE.is_successful());
153     /// ```
is_successful(&self) -> bool154     pub fn is_successful(&self) -> bool {
155         self.0 >= 200 && 300 > self.0
156     }
157 
158     /// Determines whether the `StatusCode` is [`3xx (Redirection)`].
159     ///
160     /// The 3xx (Redirection) class of status code indicates that further action
161     /// needs to be taken by the user agent in order to fulfill the request.
162     ///
163     /// [`3xx (Redirection)`]: https://httpwg.org/specs/rfc9110.html#status.3xx
164     ///
165     /// # Examples
166     /// ```
167     /// use ylong_http::response::status::StatusCode;
168     ///
169     /// assert!(StatusCode::MULTIPLE_CHOICES.is_redirection());
170     /// assert!(!StatusCode::OK.is_redirection());
171     /// ```
is_redirection(&self) -> bool172     pub fn is_redirection(&self) -> bool {
173         self.0 >= 300 && 400 > self.0
174     }
175 
176     /// Determines whether the `StatusCode` is [`4xx (Client Error)`].
177     ///
178     /// The 4xx (Client Error) class of status code indicates that the client
179     /// seems to have erred.
180     ///
181     /// [`4xx (Client Error)`]: https://httpwg.org/specs/rfc9110.html#status.4xx
182     ///
183     /// # Examples
184     /// ```
185     /// use ylong_http::response::status::StatusCode;
186     ///
187     /// assert!(StatusCode::BAD_REQUEST.is_client_error());
188     /// assert!(!StatusCode::OK.is_client_error());
189     /// ```
is_client_error(&self) -> bool190     pub fn is_client_error(&self) -> bool {
191         self.0 >= 400 && 500 > self.0
192     }
193 
194     /// Determines whether the `StatusCode` is [`5xx (Server Error)`].
195     ///
196     /// The 5xx (Server Error) class of status code indicates that the server is
197     /// aware that it has erred or is incapable of performing the requested
198     /// method.
199     ///
200     /// [`5xx (Server Error)`]: https://httpwg.org/specs/rfc9110.html#status.5xx
201     ///
202     /// # Examples
203     /// ```
204     /// use ylong_http::response::status::StatusCode;
205     ///
206     /// assert!(StatusCode::INTERNAL_SERVER_ERROR.is_server_error());
207     /// assert!(!StatusCode::OK.is_server_error());
208     /// ```
is_server_error(&self) -> bool209     pub fn is_server_error(&self) -> bool {
210         self.0 >= 500 && 600 > self.0
211     }
212 }
213 
214 impl TryFrom<u16> for StatusCode {
215     type Error = HttpError;
216 
try_from(value: u16) -> Result<Self, Self::Error>217     fn try_from(value: u16) -> Result<Self, Self::Error> {
218         Self::from_u16(value)
219     }
220 }
221 
222 impl<'a> TryFrom<&'a [u8]> for StatusCode {
223     type Error = HttpError;
224 
try_from(value: &'a [u8]) -> Result<Self, Self::Error>225     fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
226         Self::from_bytes(value)
227     }
228 }
229 
230 macro_rules! status_list {
231     (
232         $(
233             $(#[$docs: meta])*
234             ($num:expr, $name: ident, $phrase: expr),
235         )*
236     ) => {
237         impl StatusCode {
238             $(
239                 $(#[$docs])*
240                 pub const $name: StatusCode = StatusCode($num as u16);
241             )*
242 
243             /// Gets the reason of the `StatusCode`.
244             ///
245             /// # Examples
246             ///
247             /// ```
248             /// use ylong_http::response::status::StatusCode;
249             ///
250             /// assert_eq!(StatusCode::OK.reason(), Some("OK"));
251             /// ```
252             pub fn reason(&self) -> Option<&'static str> {
253                 match self.0 {
254                     $(
255                         $num => Some($phrase),
256                     )*
257                     _ => None,
258                 }
259             }
260         }
261 
262         /// UT test cases for `StatusCode::reason`.
263         ///
264         /// # Brief
265         /// 1. Creates all the valid `StatusCode`s.
266         /// 2. Calls `StatusCode::reason` on them.
267         /// 3. Checks if the results are correct.
268         #[test]
269         pub fn ut_status_code_reason() {
270             $(
271                 assert_eq!(StatusCode::from_u16($num as u16).unwrap().reason(), Some($phrase));
272             )*
273             assert_eq!(StatusCode::from_u16(999).unwrap().reason(), None);
274         }
275     }
276 }
277 
278 // TODO: Adapter, remove this later.
279 impl Display for StatusCode {
fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result280     fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
281         write!(
282             f,
283             "{} {}",
284             self.as_u16(),
285             self.reason().unwrap_or("Unknown status code")
286         )
287     }
288 }
289 
290 #[rustfmt::skip]
291 status_list!(
292     /// [`100 Continue`]: https://tools.ietf.org/html/rfc7231#section-6.2.1
293     (100, CONTINUE, "Continue"),
294 
295     /// [`101 Switching Protocols`]: https://tools.ietf.org/html/rfc7231#section-6.2.2
296     (101, SWITCHING_PROTOCOLS, "Switching Protocols"),
297 
298     /// [`102 Processing`]: https://tools.ietf.org/html/rfc2518
299     (102, PROCESSING, "Processing"),
300 
301     /// [`200 OK`]: https://tools.ietf.org/html/rfc7231#section-6.3.1
302     (200, OK, "OK"),
303 
304     /// [`201 Created`]: https://tools.ietf.org/html/rfc7231#section-6.3.2
305     (201, CREATED, "Created"),
306 
307     /// [`202 Accepted`]: https://tools.ietf.org/html/rfc7231#section-6.3.3
308     (202, ACCEPTED, "Accepted"),
309 
310     /// [`203 Non-Authoritative Information`]: https://tools.ietf.org/html/rfc7231#section-6.3.4
311     (203, NON_AUTHORITATIVE_INFORMATION, "Non Authoritative Information"),
312 
313     /// [`204 No Content`]: https://tools.ietf.org/html/rfc7231#section-6.3.5
314     (204, NO_CONTENT, "No Content"),
315 
316     /// [`205 Reset Content`]: https://tools.ietf.org/html/rfc7231#section-6.3.6
317     (205, RESET_CONTENT, "Reset Content"),
318 
319     /// [`206 Partial Content`]: https://tools.ietf.org/html/rfc7233#section-4.1
320     (206, PARTIAL_CONTENT, "Partial Content"),
321 
322     /// [`207 Multi-Status`]: https://tools.ietf.org/html/rfc4918
323     (207, MULTI_STATUS, "Multi-Status"),
324 
325     /// [`208 Already Reported`]: https://tools.ietf.org/html/rfc5842
326     (208, ALREADY_REPORTED, "Already Reported"),
327 
328     /// [`226 IM Used`]: https://tools.ietf.org/html/rfc3229
329     (226, IM_USED, "IM Used"),
330 
331     /// [`300 Multiple Choices`]: https://tools.ietf.org/html/rfc7231#section-6.4.1
332     (300, MULTIPLE_CHOICES, "Multiple Choices"),
333 
334     /// [`301 Moved Permanently`]: https://tools.ietf.org/html/rfc7231#section-6.4.2
335     (301, MOVED_PERMANENTLY, "Moved Permanently"),
336 
337     /// [`302 Found`]: https://tools.ietf.org/html/rfc7231#section-6.4.3
338     (302, FOUND, "Found"),
339 
340     /// [`303 See Other`]: https://tools.ietf.org/html/rfc7231#section-6.4.4
341     (303, SEE_OTHER, "See Other"),
342 
343     /// [`304 Not Modified`]: https://tools.ietf.org/html/rfc7232#section-4.1
344     (304, NOT_MODIFIED, "Not Modified"),
345 
346     /// [`305 Use Proxy`]: https://tools.ietf.org/html/rfc7231#section-6.4.5
347     (305, USE_PROXY, "Use Proxy"),
348 
349     /// [`307 Temporary Redirect`]: https://tools.ietf.org/html/rfc7231#section-6.4.7
350     (307, TEMPORARY_REDIRECT, "Temporary Redirect"),
351 
352     /// [`308 Permanent Redirect`]: https://tools.ietf.org/html/rfc7238
353     (308, PERMANENT_REDIRECT, "Permanent Redirect"),
354 
355     /// [`400 Bad Request`]: https://tools.ietf.org/html/rfc7231#section-6.5.1
356     (400, BAD_REQUEST, "Bad Request"),
357 
358     /// [`401 Unauthorized`]: https://tools.ietf.org/html/rfc7235#section-3.1
359     (401, UNAUTHORIZED, "Unauthorized"),
360 
361     /// [`402 Payment Required`]: https://tools.ietf.org/html/rfc7231#section-6.5.2
362     (402, PAYMENT_REQUIRED, "Payment Required"),
363 
364     /// [`403 Forbidden`]: https://tools.ietf.org/html/rfc7231#section-6.5.3
365     (403, FORBIDDEN, "Forbidden"),
366 
367     /// [`404 Not Found`]: https://tools.ietf.org/html/rfc7231#section-6.5.4
368     (404, NOT_FOUND, "Not Found"),
369 
370     /// [`405 Method Not Allowed`]: https://tools.ietf.org/html/rfc7231#section-6.5.5
371     (405, METHOD_NOT_ALLOWED, "Method Not Allowed"),
372 
373     /// [`406 Not Acceptable`]: https://tools.ietf.org/html/rfc7231#section-6.5.6
374     (406, NOT_ACCEPTABLE, "Not Acceptable"),
375 
376     /// [`407 Proxy Authentication Required`]: https://tools.ietf.org/html/rfc7235#section-3.2
377     (407, PROXY_AUTHENTICATION_REQUIRED, "Proxy Authentication Required"),
378 
379     /// [`408 Request Timeout`]: https://tools.ietf.org/html/rfc7231#section-6.5.7
380     (408, REQUEST_TIMEOUT, "Request Timeout"),
381 
382     /// [`409 Conflict`]: https://tools.ietf.org/html/rfc7231#section-6.5.8
383     (409, CONFLICT, "Conflict"),
384 
385     /// [`410 Gone`]: https://tools.ietf.org/html/rfc7231#section-6.5.9
386     (410, GONE, "Gone"),
387 
388     /// [`411 Length Required`]: https://tools.ietf.org/html/rfc7231#section-6.5.10
389     (411, LENGTH_REQUIRED, "Length Required"),
390 
391     /// [`412 Precondition Failed`]: https://tools.ietf.org/html/rfc7232#section-4.2
392     (412, PRECONDITION_FAILED, "Precondition Failed"),
393 
394     /// [`413 Payload Too Large`]: https://tools.ietf.org/html/rfc7231#section-6.5.11
395     (413, PAYLOAD_TOO_LARGE, "Payload Too Large"),
396 
397     /// [`414 URI Too Long`]: https://tools.ietf.org/html/rfc7231#section-6.5.12
398     (414, URI_TOO_LONG, "URI Too Long"),
399 
400     /// [`415 Unsupported Media Type`]: https://tools.ietf.org/html/rfc7231#section-6.5.13
401     (415, UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type"),
402 
403     /// [`416 Range Not Satisfiable`]: https://tools.ietf.org/html/rfc7233#section-4.4
404     (416, RANGE_NOT_SATISFIABLE, "Range Not Satisfiable"),
405 
406     /// [`417 Expectation Failed`]: https://tools.ietf.org/html/rfc7231#section-6.5.14
407     (417, EXPECTATION_FAILED, "Expectation Failed"),
408 
409     /// [`418 I'm a teapot`]: https://tools.ietf.org/html/rfc2324
410     (418, IM_A_TEAPOT, "I'm a teapot"),
411 
412     /// [`421 Misdirected Request`]: http://tools.ietf.org/html/rfc7540#section-9.1.2
413     (421, MISDIRECTED_REQUEST, "Misdirected Request"),
414 
415     /// [`422 Unprocessable Entity`]: https://tools.ietf.org/html/rfc4918
416     (422, UNPROCESSABLE_ENTITY, "Unprocessable Entity"),
417 
418     /// [`423 Locked`]: https://tools.ietf.org/html/rfc4918
419     (423, LOCKED, "Locked"),
420 
421     /// [`424 Failed Dependency`]: https://tools.ietf.org/html/rfc4918
422     (424, FAILED_DEPENDENCY, "Failed Dependency"),
423 
424     /// [`426 Upgrade Required`]: https://tools.ietf.org/html/rfc7231#section-6.5.15
425     (426, UPGRADE_REQUIRED, "Upgrade Required"),
426 
427     /// [`428 Precondition Required`]: https://tools.ietf.org/html/rfc6585
428     (428, PRECONDITION_REQUIRED, "Precondition Required"),
429 
430     /// [`429 Too Many Requests`]: https://tools.ietf.org/html/rfc6585
431     (429, TOO_MANY_REQUESTS, "Too Many Requests"),
432 
433     /// [`431 Request Header Fields Too Large`]: https://tools.ietf.org/html/rfc6585
434     (431, REQUEST_HEADER_FIELDS_TOO_LARGE, "Request Header Fields Too Large"),
435 
436     /// [`451 Unavailable For Legal Reasons`]: http://tools.ietf.org/html/rfc7725
437     (451, UNAVAILABLE_FOR_LEGAL_REASONS, "Unavailable For Legal Reasons"),
438 
439     /// [`500 Internal Server Error`]: https://tools.ietf.org/html/rfc7231#section-6.6.1
440     (500, INTERNAL_SERVER_ERROR, "Internal Server Error"),
441 
442     /// [`501 Not Implemented`]: https://tools.ietf.org/html/rfc7231#section-6.6.2
443     (501, NOT_IMPLEMENTED, "Not Implemented"),
444 
445     /// [`502 Bad Gateway`]: https://tools.ietf.org/html/rfc7231#section-6.6.3
446     (502, BAD_GATEWAY, "Bad Gateway"),
447 
448     /// [`503 Service Unavailable`]: https://tools.ietf.org/html/rfc7231#section-6.6.4
449     (503, SERVICE_UNAVAILABLE, "Service Unavailable"),
450 
451     /// [`504 Gateway Timeout`]: https://tools.ietf.org/html/rfc7231#section-6.6.5
452     (504, GATEWAY_TIMEOUT, "Gateway Timeout"),
453 
454     /// [`505 HTTP Version Not Supported`]: https://tools.ietf.org/html/rfc7231#section-6.6.6
455     (505, HTTP_VERSION_NOT_SUPPORTED, "HTTP Version Not Supported"),
456 
457     /// [`506 Variant Also Negotiates`]: https://tools.ietf.org/html/rfc2295
458     (506, VARIANT_ALSO_NEGOTIATES, "Variant Also Negotiates"),
459 
460     /// [`507 Insufficient Storage`]: https://tools.ietf.org/html/rfc4918
461     (507, INSUFFICIENT_STORAGE, "Insufficient Storage"),
462 
463     /// [`508 Loop Detected`]: https://tools.ietf.org/html/rfc5842
464     (508, LOOP_DETECTED, "Loop Detected"),
465 
466     /// [`510 Not Extended`]: https://tools.ietf.org/html/rfc2774
467     (510, NOT_EXTENDED, "Not Extended"),
468 
469     /// [`511 Network Authentication Required`]: https://tools.ietf.org/html/rfc6585
470     (511, NETWORK_AUTHENTICATION_REQUIRED, "Network Authentication Required"),
471 );
472 
473 #[cfg(test)]
474 mod ut_status_code {
475     use super::StatusCode;
476     use crate::error::{ErrorKind, HttpError};
477 
478     /// UT test cases for `StatusCode::from_bytes`.
479     ///
480     /// # Brief
481     /// 1. Calls `StatusCode::from_bytes` with various inputs.
482     /// 2. Checks if the results are correct.
483     #[test]
ut_status_code_from_u16()484     fn ut_status_code_from_u16() {
485         // Normal Test Cases:
486         assert_eq!(StatusCode::from_u16(100), Ok(StatusCode::CONTINUE));
487         assert!(StatusCode::from_u16(999).is_ok());
488 
489         // Exception Test Cases:
490         // 1. The given number is not in the range of 100 to 1000.
491         assert_eq!(
492             StatusCode::from_u16(0),
493             Err(HttpError::from(ErrorKind::InvalidInput))
494         );
495         assert_eq!(
496             StatusCode::from_u16(u16::MAX),
497             Err(HttpError::from(ErrorKind::InvalidInput))
498         );
499     }
500 
501     /// UT test cases for `StatusCode::as_u16`.
502     ///
503     /// # Brief
504     /// 1. Creates a `StatusCode`.
505     /// 2. Calls `StatusCode::as_u16` on it.
506     /// 3. Checks if the result is correct.
507     #[test]
ut_status_code_as_u16()508     fn ut_status_code_as_u16() {
509         assert_eq!(StatusCode::OK.as_u16(), 200);
510     }
511 
512     /// UT test cases for `StatusCode::from_bytes`.
513     ///
514     /// # Brief
515     /// 1. Calls `StatusCode::from_bytes` with various inputs.
516     /// 2. Checks if the results are correct.
517     #[test]
ut_status_code_from_bytes()518     fn ut_status_code_from_bytes() {
519         // Normal Test Cases:
520         assert_eq!(StatusCode::from_bytes(b"100"), Ok(StatusCode::CONTINUE));
521         assert_eq!(
522             StatusCode::from_bytes(b"500"),
523             Ok(StatusCode::INTERNAL_SERVER_ERROR)
524         );
525         assert!(StatusCode::from_bytes(b"999").is_ok());
526 
527         // Exception Test Cases:
528         // 1. Empty bytes slice.
529         assert_eq!(
530             StatusCode::from_bytes(b""),
531             Err(HttpError::from(ErrorKind::InvalidInput))
532         );
533 
534         // 2. The length of the bytes slice is not 3.
535         assert_eq!(
536             StatusCode::from_bytes(b"1"),
537             Err(HttpError::from(ErrorKind::InvalidInput))
538         );
539         assert_eq!(
540             StatusCode::from_bytes(b"1000"),
541             Err(HttpError::from(ErrorKind::InvalidInput))
542         );
543 
544         // 3. Other error branch coverage test cases.
545         assert_eq!(
546             StatusCode::from_bytes(b"099"),
547             Err(HttpError::from(ErrorKind::InvalidInput))
548         );
549         assert_eq!(
550             StatusCode::from_bytes(b"a99"),
551             Err(HttpError::from(ErrorKind::InvalidInput))
552         );
553         assert_eq!(
554             StatusCode::from_bytes(b"1a9"),
555             Err(HttpError::from(ErrorKind::InvalidInput))
556         );
557         assert_eq!(
558             StatusCode::from_bytes(b"19a"),
559             Err(HttpError::from(ErrorKind::InvalidInput))
560         );
561         assert_eq!(
562             StatusCode::from_bytes(b"\n\n\n"),
563             Err(HttpError::from(ErrorKind::InvalidInput))
564         );
565     }
566 
567     /// UT test cases for `StatusCode::is_informational`.
568     ///
569     /// # Brief
570     /// 1. Creates some `StatusCode`s that have different type with each other.
571     /// 2. Calls `StatusCode::is_informational` on them.
572     /// 3. Checks if the results are correct.
573     #[test]
ut_status_code_is_informational()574     fn ut_status_code_is_informational() {
575         assert!(StatusCode::CONTINUE.is_informational());
576         assert!(!StatusCode::OK.is_informational());
577         assert!(!StatusCode::MULTIPLE_CHOICES.is_informational());
578         assert!(!StatusCode::BAD_REQUEST.is_informational());
579         assert!(!StatusCode::INTERNAL_SERVER_ERROR.is_informational());
580         assert!(!StatusCode::from_u16(999).unwrap().is_informational());
581     }
582 
583     /// UT test cases for `StatusCode::is_successful`.
584     ///
585     /// # Brief
586     /// 1. Creates some `StatusCode`s that have different type with each other.
587     /// 2. Calls `StatusCode::is_successful` on them.
588     /// 3. Checks if the results are correct.
589     #[test]
ut_status_code_is_successful()590     fn ut_status_code_is_successful() {
591         assert!(!StatusCode::CONTINUE.is_successful());
592         assert!(StatusCode::OK.is_successful());
593         assert!(!StatusCode::MULTIPLE_CHOICES.is_successful());
594         assert!(!StatusCode::BAD_REQUEST.is_successful());
595         assert!(!StatusCode::INTERNAL_SERVER_ERROR.is_successful());
596         assert!(!StatusCode::from_u16(999).unwrap().is_successful());
597     }
598 
599     /// UT test cases for `StatusCode::is_redirection`.
600     ///
601     /// # Brief
602     /// 1. Creates some `StatusCode`s that have different type with each other.
603     /// 2. Calls `StatusCode::is_redirection` on them.
604     /// 3. Checks if the results are correct.
605     #[test]
ut_status_code_is_redirection()606     fn ut_status_code_is_redirection() {
607         assert!(!StatusCode::CONTINUE.is_redirection());
608         assert!(!StatusCode::OK.is_redirection());
609         assert!(StatusCode::MULTIPLE_CHOICES.is_redirection());
610         assert!(!StatusCode::BAD_REQUEST.is_redirection());
611         assert!(!StatusCode::INTERNAL_SERVER_ERROR.is_redirection());
612         assert!(!StatusCode::from_u16(999).unwrap().is_redirection());
613     }
614 
615     /// UT test cases for `StatusCode::is_client_error`.
616     ///
617     /// # Brief
618     /// 1. Creates some `StatusCode`s that have different type with each other.
619     /// 2. Calls `StatusCode::is_client_error` on them.
620     /// 3. Checks if the results are correct.
621     #[test]
ut_status_code_is_client_error()622     fn ut_status_code_is_client_error() {
623         assert!(!StatusCode::CONTINUE.is_client_error());
624         assert!(!StatusCode::OK.is_client_error());
625         assert!(!StatusCode::MULTIPLE_CHOICES.is_client_error());
626         assert!(StatusCode::BAD_REQUEST.is_client_error());
627         assert!(!StatusCode::INTERNAL_SERVER_ERROR.is_client_error());
628         assert!(!StatusCode::from_u16(999).unwrap().is_client_error());
629     }
630 
631     /// UT test cases for `StatusCode::is_server_error`.
632     ///
633     /// # Brief
634     /// 1. Creates some `StatusCode`s that have different type with each other.
635     /// 2. Calls `StatusCode::is_server_error` on them.
636     /// 3. Checks if the results are correct.
637     #[test]
ut_status_code_is_server_error()638     fn ut_status_code_is_server_error() {
639         assert!(!StatusCode::CONTINUE.is_server_error());
640         assert!(!StatusCode::OK.is_server_error());
641         assert!(!StatusCode::MULTIPLE_CHOICES.is_server_error());
642         assert!(!StatusCode::BAD_REQUEST.is_server_error());
643         assert!(StatusCode::INTERNAL_SERVER_ERROR.is_server_error());
644         assert!(!StatusCode::from_u16(999).unwrap().is_server_error());
645     }
646 
647     /// UT test cases for `StatusCode::as_bytes`.
648     ///
649     /// # Brief
650     /// 1. Creates some `StatusCode`s that have different type with each other.
651     /// 2. Calls `StatusCode::as_bytes` on them.
652     /// 3. Checks if the results are correct.
653     #[test]
ut_status_code_as_bytes()654     fn ut_status_code_as_bytes() {
655         assert_eq!(StatusCode::OK.as_bytes(), *b"200");
656         assert_eq!(StatusCode::FOUND.as_bytes(), *b"302");
657         assert_eq!(StatusCode::NOT_FOUND.as_bytes(), *b"404");
658         assert_eq!(StatusCode::GATEWAY_TIMEOUT.as_bytes(), *b"504");
659     }
660 }
661