sark_http/payload/response/
status.rs1use std::num::NonZero;
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
5#[repr(transparent)]
6pub struct Code(NonZero<u16>);
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq)]
9pub struct Error {
10 actual: u16,
11}
12
13impl Code {
14 pub const CONTINUE: Self = Self::exact::<100>();
15 pub const SWITCHING_PROTOCOLS: Self = Self::exact::<101>();
16 pub const PROCESSING: Self = Self::exact::<102>();
17 pub const EARLY_HINTS: Self = Self::exact::<103>();
18 pub const OK: Self = Self::exact::<200>();
19 pub const CREATED: Self = Self::exact::<201>();
20 pub const ACCEPTED: Self = Self::exact::<202>();
21 pub const NON_AUTHORITATIVE_INFORMATION: Self = Self::exact::<203>();
22 pub const NO_CONTENT: Self = Self::exact::<204>();
23 pub const RESET_CONTENT: Self = Self::exact::<205>();
24 pub const PARTIAL_CONTENT: Self = Self::exact::<206>();
25 pub const MULTI_STATUS: Self = Self::exact::<207>();
26 pub const ALREADY_REPORTED: Self = Self::exact::<208>();
27 pub const IM_USED: Self = Self::exact::<226>();
28 pub const MULTIPLE_CHOICES: Self = Self::exact::<300>();
29 pub const MOVED_PERMANENTLY: Self = Self::exact::<301>();
30 pub const FOUND: Self = Self::exact::<302>();
31 pub const SEE_OTHER: Self = Self::exact::<303>();
32 pub const NOT_MODIFIED: Self = Self::exact::<304>();
33 pub const USE_PROXY: Self = Self::exact::<305>();
34 pub const TEMPORARY_REDIRECT: Self = Self::exact::<307>();
35 pub const PERMANENT_REDIRECT: Self = Self::exact::<308>();
36 pub const BAD_REQUEST: Self = Self::exact::<400>();
37 pub const UNAUTHORIZED: Self = Self::exact::<401>();
38 pub const PAYMENT_REQUIRED: Self = Self::exact::<402>();
39 pub const FORBIDDEN: Self = Self::exact::<403>();
40 pub const NOT_FOUND: Self = Self::exact::<404>();
41 pub const METHOD_NOT_ALLOWED: Self = Self::exact::<405>();
42 pub const NOT_ACCEPTABLE: Self = Self::exact::<406>();
43 pub const PROXY_AUTHENTICATION_REQUIRED: Self = Self::exact::<407>();
44 pub const REQUEST_TIMEOUT: Self = Self::exact::<408>();
45 pub const CONFLICT: Self = Self::exact::<409>();
46 pub const GONE: Self = Self::exact::<410>();
47 pub const LENGTH_REQUIRED: Self = Self::exact::<411>();
48 pub const PRECONDITION_FAILED: Self = Self::exact::<412>();
49 pub const PAYLOAD_TOO_LARGE: Self = Self::exact::<413>();
50 pub const URI_TOO_LONG: Self = Self::exact::<414>();
51 pub const UNSUPPORTED_MEDIA_TYPE: Self = Self::exact::<415>();
52 pub const RANGE_NOT_SATISFIABLE: Self = Self::exact::<416>();
53 pub const EXPECTATION_FAILED: Self = Self::exact::<417>();
54 pub const IM_A_TEAPOT: Self = Self::exact::<418>();
55 pub const MISDIRECTED_REQUEST: Self = Self::exact::<421>();
56 pub const UNPROCESSABLE_ENTITY: Self = Self::exact::<422>();
57 pub const LOCKED: Self = Self::exact::<423>();
58 pub const FAILED_DEPENDENCY: Self = Self::exact::<424>();
59 pub const TOO_EARLY: Self = Self::exact::<425>();
60 pub const UPGRADE_REQUIRED: Self = Self::exact::<426>();
61 pub const PRECONDITION_REQUIRED: Self = Self::exact::<428>();
62 pub const TOO_MANY_REQUESTS: Self = Self::exact::<429>();
63 pub const REQUEST_HEADER_FIELDS_TOO_LARGE: Self = Self::exact::<431>();
64 pub const UNAVAILABLE_FOR_LEGAL_REASONS: Self = Self::exact::<451>();
65 pub const INTERNAL_SERVER_ERROR: Self = Self::exact::<500>();
66 pub const NOT_IMPLEMENTED: Self = Self::exact::<501>();
67 pub const BAD_GATEWAY: Self = Self::exact::<502>();
68 pub const SERVICE_UNAVAILABLE: Self = Self::exact::<503>();
69 pub const GATEWAY_TIMEOUT: Self = Self::exact::<504>();
70 pub const HTTP_VERSION_NOT_SUPPORTED: Self = Self::exact::<505>();
71 pub const VARIANT_ALSO_NEGOTIATES: Self = Self::exact::<506>();
72 pub const INSUFFICIENT_STORAGE: Self = Self::exact::<507>();
73 pub const LOOP_DETECTED: Self = Self::exact::<508>();
74 pub const NOT_EXTENDED: Self = Self::exact::<510>();
75 pub const NETWORK_AUTHENTICATION_REQUIRED: Self = Self::exact::<511>();
76
77 pub const fn from_u16(actual: u16) -> Result<Self, Error> {
79 if actual < 100 || actual > 599 {
80 return Err(Error { actual });
81 }
82 Ok(Self(NonZero::<u16>::MIN.saturating_add(actual - 1)))
83 }
84
85 pub const fn as_u16(&self) -> u16 {
86 self.0.get()
87 }
88
89 pub const fn as_bytes(&self) -> [u8; 3] {
90 let value = self.as_u16();
91 [
92 b'0' + (value / 100) as u8,
93 b'0' + ((value / 10) % 10) as u8,
94 b'0' + (value % 10) as u8,
95 ]
96 }
97
98 pub const fn is_info(&self) -> bool {
99 self.as_u16() / 100 == 1
100 }
101
102 pub const fn is_success(&self) -> bool {
103 self.as_u16() / 100 == 2
104 }
105
106 pub const fn reason(&self) -> Option<&str> {
107 match self.as_u16() {
108 100 => Some("Continue"),
109 101 => Some("Switching Protocols"),
110 102 => Some("Processing"),
111 103 => Some("Early Hints"),
112 200 => Some("OK"),
113 201 => Some("Created"),
114 202 => Some("Accepted"),
115 203 => Some("Non Authoritative Information"),
116 204 => Some("No Content"),
117 205 => Some("Reset Content"),
118 206 => Some("Partial Content"),
119 207 => Some("Multi-Status"),
120 208 => Some("Already Reported"),
121 226 => Some("IM Used"),
122 300 => Some("Multiple Choices"),
123 301 => Some("Moved Permanently"),
124 302 => Some("Found"),
125 303 => Some("See Other"),
126 304 => Some("Not Modified"),
127 305 => Some("Use Proxy"),
128 307 => Some("Temporary Redirect"),
129 308 => Some("Permanent Redirect"),
130 400 => Some("Bad Request"),
131 401 => Some("Unauthorized"),
132 402 => Some("Payment Required"),
133 403 => Some("Forbidden"),
134 404 => Some("Not Found"),
135 405 => Some("Method Not Allowed"),
136 406 => Some("Not Acceptable"),
137 407 => Some("Proxy Authentication Required"),
138 408 => Some("Request Timeout"),
139 409 => Some("Conflict"),
140 410 => Some("Gone"),
141 411 => Some("Length Required"),
142 412 => Some("Precondition Failed"),
143 413 => Some("Payload Too Large"),
144 414 => Some("URI Too Long"),
145 415 => Some("Unsupported Media Type"),
146 416 => Some("Range Not Satisfiable"),
147 417 => Some("Expectation Failed"),
148 418 => Some("I'm a teapot"),
149 421 => Some("Misdirected Request"),
150 422 => Some("Unprocessable Entity"),
151 423 => Some("Locked"),
152 424 => Some("Failed Dependency"),
153 425 => Some("Too Early"),
154 426 => Some("Upgrade Required"),
155 428 => Some("Precondition Required"),
156 429 => Some("Too Many Requests"),
157 431 => Some("Request Header Fields Too Large"),
158 451 => Some("Unavailable For Legal Reasons"),
159 500 => Some("Internal Server Error"),
160 501 => Some("Not Implemented"),
161 502 => Some("Bad Gateway"),
162 503 => Some("Service Unavailable"),
163 504 => Some("Gateway Timeout"),
164 505 => Some("HTTP Version Not Supported"),
165 506 => Some("Variant Also Negotiates"),
166 507 => Some("Insufficient Storage"),
167 508 => Some("Loop Detected"),
168 510 => Some("Not Extended"),
169 511 => Some("Network Authentication Required"),
170 _ => None,
171 }
172 }
173
174 const fn exact<const VALUE: u16>() -> Self {
175 const { assert!(VALUE >= 100 && VALUE <= 599) };
176 Self(NonZero::<u16>::MIN.saturating_add(VALUE - 1))
177 }
178}
179
180impl Default for Code {
181 fn default() -> Self {
182 Self::OK
183 }
184}
185
186impl From<Code> for u16 {
187 fn from(code: Code) -> Self {
188 code.as_u16()
189 }
190}
191
192impl Error {
193 pub const fn actual(self) -> u16 {
194 self.actual
195 }
196}
197
198const _: () = {
199 assert!(size_of::<Code>() == size_of::<u16>());
200 assert!(size_of::<Option<Code>>() == size_of::<Code>());
201 assert!(size_of::<Error>() == size_of::<u16>());
202 assert!(!std::mem::needs_drop::<Code>());
203 assert!(!std::mem::needs_drop::<Error>());
204};