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