Skip to main content

use_status/
lib.rs

1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4/// A common HTTP status code and its standard reason phrase.
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6pub struct HttpStatus {
7    pub code: u16,
8    pub reason: &'static str,
9}
10
11/// A broad HTTP status code class.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
13pub enum StatusClass {
14    Informational,
15    Success,
16    Redirection,
17    ClientError,
18    ServerError,
19}
20
21/// Returns the standard reason phrase for a common status code.
22#[must_use]
23pub const fn reason_phrase(code: u16) -> Option<&'static str> {
24    match code {
25        100 => Some("Continue"),
26        101 => Some("Switching Protocols"),
27        102 => Some("Processing"),
28        103 => Some("Early Hints"),
29        200 => Some("OK"),
30        201 => Some("Created"),
31        202 => Some("Accepted"),
32        204 => Some("No Content"),
33        206 => Some("Partial Content"),
34        300 => Some("Multiple Choices"),
35        301 => Some("Moved Permanently"),
36        302 => Some("Found"),
37        303 => Some("See Other"),
38        304 => Some("Not Modified"),
39        307 => Some("Temporary Redirect"),
40        308 => Some("Permanent Redirect"),
41        400 => Some("Bad Request"),
42        401 => Some("Unauthorized"),
43        403 => Some("Forbidden"),
44        404 => Some("Not Found"),
45        405 => Some("Method Not Allowed"),
46        409 => Some("Conflict"),
47        410 => Some("Gone"),
48        415 => Some("Unsupported Media Type"),
49        422 => Some("Unprocessable Content"),
50        429 => Some("Too Many Requests"),
51        500 => Some("Internal Server Error"),
52        501 => Some("Not Implemented"),
53        502 => Some("Bad Gateway"),
54        503 => Some("Service Unavailable"),
55        504 => Some("Gateway Timeout"),
56        _ => None,
57    }
58}
59
60/// Returns the broad HTTP status class for a code in the standard range.
61#[must_use]
62pub const fn status_class(code: u16) -> Option<StatusClass> {
63    match code {
64        100..=199 => Some(StatusClass::Informational),
65        200..=299 => Some(StatusClass::Success),
66        300..=399 => Some(StatusClass::Redirection),
67        400..=499 => Some(StatusClass::ClientError),
68        500..=599 => Some(StatusClass::ServerError),
69        _ => None,
70    }
71}
72
73/// Returns `true` when the code is informational.
74#[must_use]
75pub const fn is_informational(code: u16) -> bool {
76    matches!(status_class(code), Some(StatusClass::Informational))
77}
78
79/// Returns `true` when the code is successful.
80#[must_use]
81pub const fn is_success(code: u16) -> bool {
82    matches!(status_class(code), Some(StatusClass::Success))
83}
84
85/// Returns `true` when the code is a redirect.
86#[must_use]
87pub const fn is_redirect(code: u16) -> bool {
88    matches!(status_class(code), Some(StatusClass::Redirection))
89}
90
91/// Returns `true` when the code is a client error.
92#[must_use]
93pub const fn is_client_error(code: u16) -> bool {
94    matches!(status_class(code), Some(StatusClass::ClientError))
95}
96
97/// Returns `true` when the code is a server error.
98#[must_use]
99pub const fn is_server_error(code: u16) -> bool {
100    matches!(status_class(code), Some(StatusClass::ServerError))
101}
102
103/// Returns `true` when the code is a client or server error.
104#[must_use]
105pub const fn is_error(code: u16) -> bool {
106    is_client_error(code) || is_server_error(code)
107}
108
109/// Returns `true` for codes that are cacheable by default in common HTTP semantics.
110#[must_use]
111pub const fn is_cacheable_by_default(code: u16) -> bool {
112    matches!(
113        code,
114        200 | 203 | 204 | 206 | 300 | 301 | 404 | 405 | 410 | 414 | 501
115    )
116}