twilight_http/response/
status_code.rs1use std::fmt::{Display, Formatter, Result as FmtResult};
2
3#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
15pub struct StatusCode(u16);
16
17impl StatusCode {
18 pub(crate) const fn new(code: u16) -> Self {
20 Self(code)
23 }
24
25 #[must_use = "status code must be used to be useful"]
27 pub const fn get(self) -> u16 {
28 self.0
29 }
30
31 #[must_use = "whether a status code is informational must be used"]
35 pub const fn is_informational(self) -> bool {
36 self.in_range(100, 200)
37 }
38
39 #[must_use = "whether a status code is a success must be used"]
43 pub const fn is_success(self) -> bool {
44 self.in_range(200, 300)
45 }
46
47 #[must_use = "whether a status code is redirectional must be used"]
51 pub const fn is_redirection(self) -> bool {
52 self.in_range(300, 400)
53 }
54
55 #[must_use = "whether a status code is a client error must be used"]
59 pub const fn is_client_error(self) -> bool {
60 self.in_range(400, 500)
61 }
62
63 #[must_use = "whether a status code is a server error must be used"]
67 pub const fn is_server_error(self) -> bool {
68 self.in_range(500, 600)
69 }
70
71 const fn in_range(self, min: u16, max: u16) -> bool {
75 self.0 >= min && self.0 < max
76 }
77
78 pub const OK: StatusCode = StatusCode::new(200);
80
81 pub const CREATED: StatusCode = StatusCode::new(201);
83
84 pub const NO_CONTENT: StatusCode = StatusCode::new(204);
86
87 pub const NOT_MODIFIED: StatusCode = StatusCode::new(304);
89
90 pub const BAD_REQUEST: StatusCode = StatusCode::new(400);
92
93 pub const UNAUTHORIZED: StatusCode = StatusCode::new(401);
95
96 pub const FORBIDDEN: StatusCode = StatusCode::new(403);
98
99 pub const NOT_FOUND: StatusCode = StatusCode::new(404);
101
102 pub const METHOD_NOT_ALLOWED: StatusCode = StatusCode::new(405);
104
105 pub const TOO_MANY_REQUESTS: StatusCode = StatusCode::new(429);
107
108 pub const GATEWAY_UNAVAILABLE: StatusCode = StatusCode::new(502);
110}
111
112impl Display for StatusCode {
113 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
114 self.0.fmt(f)
115 }
116}
117
118impl PartialEq<u16> for StatusCode {
119 fn eq(&self, other: &u16) -> bool {
120 self.get() == *other
121 }
122}
123
124impl PartialEq<StatusCode> for u16 {
125 fn eq(&self, other: &StatusCode) -> bool {
126 *self == other.get()
127 }
128}
129
130#[cfg(test)]
131mod tests {
132 use super::StatusCode;
133 use static_assertions::assert_impl_all;
134 use std::{
135 fmt::{Debug, Display},
136 hash::Hash,
137 };
138
139 assert_impl_all!(
140 StatusCode: Clone,
141 Copy,
142 Debug,
143 Display,
144 Eq,
145 Hash,
146 PartialEq,
147 PartialOrd,
148 Ord,
149 Send,
150 Sync
151 );
152
153 #[test]
154 fn eq_with_integer() {
155 assert_eq!(200_u16, StatusCode::new(200));
156 assert_eq!(StatusCode::new(404), 404_u16);
157 }
158
159 #[test]
165 fn get() {
166 assert_eq!(200, StatusCode::new(200).get());
167 assert_eq!(403, StatusCode::new(403).get());
168 assert_eq!(404, StatusCode::new(404).get());
169 }
170
171 #[test]
172 fn ranges() {
173 assert!(StatusCode::new(100).is_informational());
174 assert!(StatusCode::new(199).is_informational());
175 assert!(StatusCode::new(200).is_success());
176 assert!(StatusCode::new(299).is_success());
177 assert!(StatusCode::new(300).is_redirection());
178 assert!(StatusCode::new(399).is_redirection());
179 assert!(StatusCode::new(400).is_client_error());
180 assert!(StatusCode::new(499).is_client_error());
181 assert!(StatusCode::new(500).is_server_error());
182 assert!(StatusCode::new(599).is_server_error());
183 }
184}