1use actix_web::body::BoxBody;
2use actix_web::http::StatusCode;
3use actix_web::http::header::ContentType;
4use actix_web::{HttpRequest, HttpResponse, Responder, error};
5use derive_more::derive::{Display, Error};
6use serde::Serialize;
7use std::fmt::{Debug, Display, Formatter};
8
9pub fn success<T: Sized + Serialize + Default>(data: Option<T>) -> Response<T> {
18 Response {
19 data,
20 msg: String::from("成功"),
21 code: 200,
22 }
23}
24
25pub fn success_respond_to<T: Sized + Serialize + Default>(
34 req: &HttpRequest,
35 data: Option<T>,
36) -> HttpResponse<<Response<T> as Responder>::Body> {
37 success(data).respond_to(req)
38}
39
40pub fn error<T: Sized + Serialize + Default>(data: Option<T>) -> Response<T> {
49 Response {
50 data,
51 msg: String::from("失败"),
52 ..Default::default()
53 }
54}
55
56pub fn error_respond_to<T: Sized + Serialize + Default>(
65 req: &HttpRequest,
66 data: Option<T>,
67) -> HttpResponse<<Response<T> as Responder>::Body> {
68 error(data).respond_to(req)
69}
70
71pub fn throw(
80 req: &HttpRequest,
81 ec: ErrorCode,
82) -> HttpResponse<<Response<ErrorCode> as Responder>::Body> {
83 Response::<ErrorCode> {
84 data: None,
85 msg: ec.message().parse().unwrap(),
86 code: ec.code() as i32,
87 }
88 .respond_to(req)
89}
90
91pub fn throw_tips(
100 req: &HttpRequest,
101 ec: ErrorCode,
102 tips: &'static str,
103) -> HttpResponse<<Response<ErrorCode> as Responder>::Body> {
104 Response::<ErrorCode> {
105 data: None,
106 msg: ec.message().replace("%s", tips).parse().unwrap(),
107 code: ec.code() as i32,
108 }
109 .respond_to(req)
110}
111
112pub fn unauthorized<T: Sized + Serialize + Default>(
121 req: &HttpRequest,
122) -> HttpResponse<<Response<T> as Responder>::Body> {
123 let r: Response<String> = Response {
124 data: None,
125 msg: String::from("无权限访问"),
126 ..Default::default()
127 };
128 r.respond_to(req)
129}
130
131#[derive(Serialize, Default)]
132pub struct Response<T>
133where
134 T: Sized + Serialize,
135{
136 pub code: i32,
137 pub data: Option<T>,
138 pub msg: String,
139}
140
141impl<T> Responder for Response<T>
143where
144 T: Sized + Serialize,
145{
146 type Body = BoxBody;
147
148 fn respond_to(self, _req: &HttpRequest) -> HttpResponse<Self::Body> {
149 let body = serde_json::to_string(&self).unwrap();
150
151 HttpResponse::Ok()
153 .content_type(ContentType::json())
154 .body(body)
155 }
156}
157
158impl<T> Response<T>
159where
160 T: Sized + Serialize,
161{
162 pub fn body_json(self) -> String {
163 serde_json::to_string(&self).unwrap()
164 }
165}
166
167impl<T: Serialize> Display for Response<T> {
168 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
169 let serialized = serde_json::to_string(&self).unwrap();
170 write!(f, "{}", serialized)
171 }
172}
173
174impl<T: Serialize> Debug for Response<T> {
175 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
176 let serialized = serde_json::to_string(&self).unwrap();
177 write!(f, "{}", serialized)
178 }
179}
180
181impl<T: Serialize> error::ResponseError for Response<T> {
182 fn error_response(&self) -> HttpResponse {
183 HttpResponse::build(self.status_code())
184 .insert_header(ContentType::json())
185 .body(self.to_string())
186 }
187
188 fn status_code(&self) -> StatusCode {
189 StatusCode::OK
195 }
196}
197
198#[derive(Serialize, Default, Debug, Clone)]
199pub struct ErrorCode {
200 pub code: i64,
201 pub message: &'static str,
202}
203
204impl ErrorCode {
205 #[allow(dead_code)]
206 pub fn new(code: i64, message: &'static str) -> ErrorCode {
207 ErrorCode { code, message }
208 }
209
210 #[allow(dead_code)]
211 pub fn code(&self) -> i64 {
212 self.code
213 }
214
215 #[allow(dead_code)]
216 pub fn code_string(&self) -> Option<String> {
217 Some(format!("{}", self.code))
218 }
219
220 #[allow(dead_code)]
221 pub fn message(&self) -> &'static str {
222 &self.message
223 }
224
225 #[allow(dead_code)]
235 pub fn tips(&self, tips: &'static str) -> String {
236 self.message().replace("%s", tips).parse().unwrap()
237 }
238
239 #[allow(dead_code)]
248 pub fn throw_tips(
249 &self,
250 req: &HttpRequest,
251 tips: &'static str,
252 ) -> HttpResponse<<Response<ErrorCode> as Responder>::Body> {
253 Response::<ErrorCode> {
254 data: None,
255 msg: self.message().replace("%s", tips).parse().unwrap(),
256 code: self.code() as i32,
257 }
258 .respond_to(req)
259 }
260
261 #[allow(dead_code)]
270 pub fn throw(
271 &self,
272 req: &HttpRequest,
273 ) -> HttpResponse<<Response<ErrorCode> as Responder>::Body> {
274 Response::<ErrorCode> {
275 data: None,
276 msg: self.message().parse().unwrap(),
277 code: self.code() as i32,
278 }
279 .respond_to(req)
280 }
281}
282
283impl Display for ErrorCode {
284 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
285 write!(f, "({}, {})", self.code, self.message)
286 }
287}
288
289impl error::ResponseError for ErrorCode {
290 fn error_response(&self) -> HttpResponse {
291 HttpResponse::build(self.status_code())
292 .insert_header(ContentType::html())
293 .body(self.to_string())
294 }
295
296 fn status_code(&self) -> StatusCode {
297 StatusCode::BAD_REQUEST
303 }
304}
305
306#[allow(dead_code)]
307pub trait Auth {
308 fn response(&self) -> Response<Vec<i32>>;
309 fn ok(&self) -> bool;
310}
311
312#[allow(dead_code)]
314#[deprecated]
315pub fn interceptor<A: Auth>(a: A) -> Option<Response<Vec<i32>>> {
316 if !a.ok() {
317 return Some(a.response());
318 }
319 None
320}
321
322#[derive(Debug, Display, Error)]
323#[display("{file}:{line} {message}")]
324#[allow(unused)]
325pub struct Error {
326 pub file: &'static str,
327 pub line: u32,
328 pub message: String,
329}
330
331impl Error {
332 #[allow(unused)]
362 pub fn new(file: &'static str, line: u32, message: String) -> Self {
363 Self {
364 file,
365 line,
366 message,
367 }
368 }
369}
370
371impl error::ResponseError for Error {}