tin_actix_api_resp/macros.rs
1use actix_web::http::StatusCode;
2use serde::{Deserialize, Serialize};
3
4macro_rules! status_codes {
5 (
6 $(
7 $(#[$docs:meta])*
8 ($konst:ident, $code:expr, $status:ident, $message:expr);
9 )+
10 ) => {
11 #[derive(Debug, Clone, Serialize, Deserialize)]
12 pub enum ApiRes<T: Serialize> {
13 /// Custom response with status code, error code, message, and optional data
14 Custom(u16, u32, String, Option<T>),
15 /// 200 OK with data
16 /// [[RFC7231, Section 6.3.1](https://tools.ietf.org/html/rfc7231#section-6.3.1)]
17 Ok(T),
18 /// 200 OK with additional status code and message
19 /// [[RFC7231, Section 6.3.1](https://tools.ietf.org/html/rfc7231#section-6.3.1)]
20 OkWith(u32, String, T),
21 /// 200 OK empty data
22 Empty,
23 $(
24 $(#[$docs])*
25 $konst(String),
26 )+
27 }
28
29
30 impl<T: Serialize> ApiRes<T> {
31 pub fn status(&self) -> StatusCode {
32 match self {
33 ApiRes::Custom(status,_, _, _) => StatusCode::from_u16(*status).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR),
34 ApiRes::Ok(_) => StatusCode::OK,
35 ApiRes::OkWith(_, _, _) => StatusCode::OK,
36 ApiRes::Empty => StatusCode::OK,
37 $(
38 ApiRes::$konst(_) => StatusCode::$status,
39 )+
40 }
41 }
42
43 pub fn code(&self) -> u32 {
44 match self {
45 ApiRes::Custom(_,code, _, _) => *code,
46 ApiRes::Ok(_) => 200,
47 ApiRes::OkWith(code, _, _) => *code,
48 ApiRes::Empty => 200,
49 $(
50 ApiRes::$konst(_) => $code,
51 )+
52 }
53 }
54
55 pub fn message(&self) -> &str {
56 match self {
57 ApiRes::Custom(_,_, msg, _) => msg,
58 ApiRes::Ok(_) => "Success",
59 ApiRes::OkWith(_, msg, _) => msg,
60 ApiRes::Empty => "Success",
61 $(
62 ApiRes::$konst(msg) => msg,
63 )+
64 }
65 }
66
67 pub fn data(&self) -> Option<&T> {
68 match self {
69 ApiRes::Custom(_,_, _, data) => data.as_ref(),
70 ApiRes::Ok(data) => Some(data),
71 ApiRes::OkWith(_, _, data) => Some(data),
72 ApiRes::Empty => None,
73 _ => None,
74 }
75 }
76 }
77 };
78}
79
80status_codes! {
81 /// 100 Continue
82 /// [[RFC7231, Section 6.2.1](https://tools.ietf.org/html/rfc7231#section-6.2.1)]
83 (Continue,100, CONTINUE, "Continue");
84 /// 101 Switching Protocols
85 /// [[RFC7231, Section 6.2.2](https://tools.ietf.org/html/rfc7231#section-6.2.2)]
86 (SwitchingProtocols,101, SWITCHING_PROTOCOLS, "Switching Protocols");
87 /// 102 Processing
88 /// [[RFC2518](https://tools.ietf.org/html/rfc2518)]
89 (Processing,102, PROCESSING, "Processing");
90
91 /// 201 Created
92 /// [[RFC7231, Section 6.3.2](https://tools.ietf.org/html/rfc7231#section-6.3.2)]
93 (Created,201, CREATED, "Created");
94 /// 202 Accepted
95 /// [[RFC7231, Section 6.3.3](https://tools.ietf.org/html/rfc7231#section-6.3.3)]
96 (Accepted,202, ACCEPTED, "Accepted");
97 /// 203 Non-Authoritative Information
98 /// [[RFC7231, Section 6.3.4](https://tools.ietf.org/html/rfc7231#section-6.3.4)]
99 (NonAuthoritativeInformation,203, NON_AUTHORITATIVE_INFORMATION, "Non Authoritative Information");
100 /// 204 No Content
101 /// [[RFC7231, Section 6.3.5](https://tools.ietf.org/html/rfc7231#section-6.3.5)]
102 (NoContent,204, NO_CONTENT, "No Content");
103 /// 205 Reset Content
104 /// [[RFC7231, Section 6.3.6](https://tools.ietf.org/html/rfc7231#section-6.3.6)]
105 (ResetContent,205, RESET_CONTENT, "Reset Content");
106 /// 206 Partial Content
107 /// [[RFC7233, Section 4.1](https://tools.ietf.org/html/rfc7233#section-4.1)]
108 (PartialContent,206, PARTIAL_CONTENT, "Partial Content");
109 /// 207 Multi-Status
110 /// [[RFC4918](https://tools.ietf.org/html/rfc4918)]
111 (MultiStatus,207, MULTI_STATUS, "Multi-Status");
112 /// 208 Already Reported
113 /// [[RFC5842](https://tools.ietf.org/html/rfc5842)]
114 (AlreadyReported,208, ALREADY_REPORTED, "Already Reported");
115
116 /// 226 IM Used
117 /// [[RFC3229](https://tools.ietf.org/html/rfc3229)]
118 (IMUsed,226, IM_USED, "IM Used");
119
120 /// 300 Multiple Choices
121 /// [[RFC7231, Section 6.4.1](https://tools.ietf.org/html/rfc7231#section-6.4.1)]
122 (MultipleChoices,300, MULTIPLE_CHOICES, "Multiple Choices");
123 /// 301 Moved Permanently
124 /// [[RFC7231, Section 6.4.2](https://tools.ietf.org/html/rfc7231#section-6.4.2)]
125 (MovedPermanently,301, MOVED_PERMANENTLY, "Moved Permanently");
126 /// 302 Found
127 /// [[RFC7231, Section 6.4.3](https://tools.ietf.org/html/rfc7231#section-6.4.3)]
128 (Found,302, FOUND, "Found");
129 /// 303 See Other
130 /// [[RFC7231, Section 6.4.4](https://tools.ietf.org/html/rfc7231#section-6.4.4)]
131 (SeeOther,303, SEE_OTHER, "See Other");
132 /// 304 Not Modified
133 /// [[RFC7232, Section 4.1](https://tools.ietf.org/html/rfc7232#section-4.1)]
134 (NotModified,304, NOT_MODIFIED, "Not Modified");
135 /// 305 Use Proxy
136 /// [[RFC7231, Section 6.4.5](https://tools.ietf.org/html/rfc7231#section-6.4.5)]
137 (UseProxy,305, USE_PROXY, "Use Proxy");
138 /// 307 Temporary Redirect
139 /// [[RFC7231, Section 6.4.7](https://tools.ietf.org/html/rfc7231#section-6.4.7)]
140 (TemporaryRedirect, 307, TEMPORARY_REDIRECT, "Temporary Redirect");
141 /// 308 Permanent Redirect
142 /// [[RFC7238](https://tools.ietf.org/html/rfc7238)]
143 (PermanentRedirect,308, PERMANENT_REDIRECT, "Permanent Redirect");
144
145 /// 400 Bad Request
146 /// [[RFC7231, Section 6.5.1](https://tools.ietf.org/html/rfc7231#section-6.5.1)]
147 (BadRequest,400, BAD_REQUEST, "Bad Request");
148 /// 401 Unauthorized
149 /// [[RFC7235, Section 3.1](https://tools.ietf.org/html/rfc7235#section-3.1)]
150 (Unauthorized,401, UNAUTHORIZED, "Unauthorized");
151 /// 402 Payment Required
152 /// [[RFC7231, Section 6.5.2](https://tools.ietf.org/html/rfc7231#section-6.5.2)]
153 (PaymentRequired,402, PAYMENT_REQUIRED, "Payment Required");
154 /// 403 Forbidden
155 /// [[RFC7231, Section 6.5.3](https://tools.ietf.org/html/rfc7231#section-6.5.3)]
156 (Forbidden,403, FORBIDDEN, "Forbidden");
157 /// 404 Not Found
158 /// [[RFC7231, Section 6.5.4](https://tools.ietf.org/html/rfc7231#section-6.5.4)]
159 (NotFound,404, NOT_FOUND, "Not Found");
160 /// 405 Method Not Allowed
161 /// [[RFC7231, Section 6.5.5](https://tools.ietf.org/html/rfc7231#section-6.5.5)]
162 (MethodNotAllowed,405, METHOD_NOT_ALLOWED, "Method Not Allowed");
163 /// 406 Not Acceptable
164 /// [[RFC7231, Section 6.5.6](https://tools.ietf.org/html/rfc7231#section-6.5.6)]
165 (NotAcceptable,406, NOT_ACCEPTABLE, "Not Acceptable");
166 /// 407 Proxy Authentication Required
167 /// [[RFC7235, Section 3.2](https://tools.ietf.org/html/rfc7235#section-3.2)]
168 (ProxyAuthenticationRequired,407, PROXY_AUTHENTICATION_REQUIRED, "Proxy Authentication Required");
169 /// 408 Request Timeout
170 /// [[RFC7231, Section 6.5.7](https://tools.ietf.org/html/rfc7231#section-6.5.7)]
171 (RequestTimeout,408, REQUEST_TIMEOUT, "Request Timeout");
172 /// 409 Conflict
173 /// [[RFC7231, Section 6.5.8](https://tools.ietf.org/html/rfc7231#section-6.5.8)]
174 (Conflict,409, CONFLICT, "Conflict");
175 /// 410 Gone
176 /// [[RFC7231, Section 6.5.9](https://tools.ietf.org/html/rfc7231#section-6.5.9)]
177 (Gone,410, GONE, "Gone");
178 /// 411 Length Required
179 /// [[RFC7231, Section 6.5.10](https://tools.ietf.org/html/rfc7231#section-6.5.10)]
180 (LengthRequired,411, LENGTH_REQUIRED, "Length Required");
181 /// 412 Precondition Failed
182 /// [[RFC7232, Section 4.2](https://tools.ietf.org/html/rfc7232#section-4.2)]
183 (PreconditionFailed,412, PRECONDITION_FAILED, "Precondition Failed");
184 /// 413 Payload Too Large
185 /// [[RFC7231, Section 6.5.11](https://tools.ietf.org/html/rfc7231#section-6.5.11)]
186 (PayloadTooLarge,413, PAYLOAD_TOO_LARGE, "Payload Too Large");
187 /// 414 URI Too Long
188 /// [[RFC7231, Section 6.5.12](https://tools.ietf.org/html/rfc7231#section-6.5.12)]
189 (URITooLong,414, URI_TOO_LONG, "URI Too Long");
190 /// 415 Unsupported Media Type
191 /// [[RFC7231, Section 6.5.13](https://tools.ietf.org/html/rfc7231#section-6.5.13)]
192 (UnsupportedMediaType,415, UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type");
193 /// 416 Range Not Satisfiable
194 /// [[RFC7233, Section 4.4](https://tools.ietf.org/html/rfc7233#section-4.4)]
195 (RangeNotSatisfiable,416, RANGE_NOT_SATISFIABLE, "Range Not Satisfiable");
196 /// 417 Expectation Failed
197 /// [[RFC7231, Section 6.5.14](https://tools.ietf.org/html/rfc7231#section-6.5.14)]
198 (ExpectationFailed,417, EXPECTATION_FAILED, "Expectation Failed");
199 /// 418 I'm a teapot
200 /// [curiously not registered by IANA but [RFC2324](https://tools.ietf.org/html/rfc2324)]
201 (ImATeapot,418, IM_A_TEAPOT, "I'm a teapot");
202
203 /// 421 Misdirected Request
204 /// [RFC7540, Section 9.1.2](http://tools.ietf.org/html/rfc7540#section-9.1.2)
205 (MisdirectedRequest,421, MISDIRECTED_REQUEST, "Misdirected Request");
206 /// 422 Unprocessable Entity
207 /// [[RFC4918](https://tools.ietf.org/html/rfc4918)]
208 (UnprocessableEntity,422, UNPROCESSABLE_ENTITY, "Unprocessable Entity");
209 /// 423 Locked
210 /// [[RFC4918](https://tools.ietf.org/html/rfc4918)]
211 (Locked,423, LOCKED, "Locked");
212 /// 424 Failed Dependency
213 /// [[RFC4918](https://tools.ietf.org/html/rfc4918)]
214 (FailedDependency,424, FAILED_DEPENDENCY, "Failed Dependency");
215
216 /// 426 Upgrade Required
217 /// [[RFC7231, Section 6.5.15](https://tools.ietf.org/html/rfc7231#section-6.5.15)]
218 (UpgradeRequired,426, UPGRADE_REQUIRED, "Upgrade Required");
219
220 /// 428 Precondition Required
221 /// [[RFC6585](https://tools.ietf.org/html/rfc6585)]
222 (PreconditionRequired,428, PRECONDITION_REQUIRED, "Precondition Required");
223 /// 429 Too Many Requests
224 /// [[RFC6585](https://tools.ietf.org/html/rfc6585)]
225 (TooManyRequests,429, TOO_MANY_REQUESTS, "Too Many Requests");
226
227 /// 431 Request Header Fields Too Large
228 /// [[RFC6585](https://tools.ietf.org/html/rfc6585)]
229 (RequestHeaderFieldsTooLarge,431, REQUEST_HEADER_FIELDS_TOO_LARGE, "Request Header Fields Too Large");
230
231 /// 451 Unavailable For Legal Reasons
232 /// [[RFC7725](http://tools.ietf.org/html/rfc7725)]
233 (UnavailableForLegalReasons,451, UNAVAILABLE_FOR_LEGAL_REASONS, "Unavailable For Legal Reasons");
234
235 /// 500 Internal Server Error
236 /// [[RFC7231, Section 6.6.1](https://tools.ietf.org/html/rfc7231#section-6.6.1)]
237 (InternalServerError,500, INTERNAL_SERVER_ERROR, "Internal Server Error");
238 /// 501 Not Implemented
239 /// [[RFC7231, Section 6.6.2](https://tools.ietf.org/html/rfc7231#section-6.6.2)]
240 (NotImplemented,501, NOT_IMPLEMENTED, "Not Implemented");
241 /// 502 Bad Gateway
242 /// [[RFC7231, Section 6.6.3](https://tools.ietf.org/html/rfc7231#section-6.6.3)]
243 (BadGateway,502, BAD_GATEWAY, "Bad Gateway");
244 /// 503 Service Unavailable
245 /// [[RFC7231, Section 6.6.4](https://tools.ietf.org/html/rfc7231#section-6.6.4)]
246 (ServiceUnavailable,503, SERVICE_UNAVAILABLE, "Service Unavailable");
247 /// 504 Gateway Timeout
248 /// [[RFC7231, Section 6.6.5](https://tools.ietf.org/html/rfc7231#section-6.6.5)]
249 (GatewayTimeout,504, GATEWAY_TIMEOUT, "Gateway Timeout");
250 /// 505 HTTP Version Not Supported
251 /// [[RFC7231, Section 6.6.6](https://tools.ietf.org/html/rfc7231#section-6.6.6)]
252 (HttpVersionNotSupported,505, HTTP_VERSION_NOT_SUPPORTED, "HTTP Version Not Supported");
253 /// 506 Variant Also Negotiates
254 /// [[RFC2295](https://tools.ietf.org/html/rfc2295)]
255 (VariantAlsoNegotiates,506, VARIANT_ALSO_NEGOTIATES, "Variant Also Negotiates");
256 /// 507 Insufficient Storage
257 /// [[RFC4918](https://tools.ietf.org/html/rfc4918)]
258 (InsufficientStorage,507, INSUFFICIENT_STORAGE, "Insufficient Storage");
259 /// 508 Loop Detected
260 /// [[RFC5842](https://tools.ietf.org/html/rfc5842)]
261 (LoopDetected,508, LOOP_DETECTED, "Loop Detected");
262
263 /// 510 Not Extended
264 /// [[RFC2774](https://tools.ietf.org/html/rfc2774)]
265 (NotExtended,510, NOT_EXTENDED, "Not Extended");
266 /// 511 Network Authentication Required
267 /// [[RFC6585](https://tools.ietf.org/html/rfc6585)]
268 (NetworkAuthenticationRequired,511, NETWORK_AUTHENTICATION_REQUIRED, "Network Authentication Required");
269}