Skip to main content

hirust_resp/
lib.rs

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
9///
10/// Examples
11///```text
12/// async fn test(req: actix_web::HttpRequest) -> impl Responder {
13///     success(&req, Some(String::from("Hey test!"))).respond_to(req)
14/// }
15///```
16///
17pub 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
25///
26/// Examples
27///```text
28/// async fn test(req: actix_web::HttpRequest) -> impl Responder {
29///     success_respond_to(&req, Some(String::from("Hey test!")))
30/// }
31///```
32///
33pub 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
40///
41/// Examples
42///```text
43/// async fn test(req: actix_web::HttpRequest) -> impl Responder {
44///     error(&req, Some(String::from("Hey test!"))).respond_to(req)
45/// }
46///```
47///
48pub 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
56///
57/// Examples
58///```text
59/// async fn test(req: actix_web::HttpRequest) -> impl Responder {
60///     error_respond_to(&req, Some(String::from("Hey test!")))
61/// }
62///```
63///
64pub 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
71///
72/// Examples
73///```text
74/// async fn test(req: actix_web::HttpRequest) -> impl Responder {
75///     return throw(&req, errcode::VALID_CODE_ERROR);
76/// }
77///```
78///
79pub 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
91///
92/// Examples
93///```text
94/// async fn test(req: actix_web::HttpRequest) -> impl Responder {
95///     return throw_tips(&req, errcode::NOT_EXIST, "tips msg");
96/// }
97///```
98///
99pub 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
112///
113/// Examples
114///```text
115/// async fn test(req: actix_web::HttpRequest) -> impl Responder {
116///     return unauthorized::<String>(&req);
117/// }
118///```
119///
120pub 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
141// Responder
142impl<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        // Create response and set content type
152        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        // match *self {
190        //     ErrorCode::InternalError => StatusCode::INTERNAL_SERVER_ERROR,
191        //     ErrorCode::BadClientData => StatusCode::BAD_REQUEST,
192        //     ErrorCode::Timeout => StatusCode::GATEWAY_TIMEOUT,
193        // }
194        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    ///
226    /// Examples
227    ///```text
228    /// async fn test(req: actix_web::HttpRequest) -> impl Responder {
229    ///     let tips = errcode::NOT_EXIST.tips("gg");
230    ///     return ...;
231    /// }
232    ///```
233    ///
234    #[allow(dead_code)]
235    pub fn tips(&self, tips: &'static str) -> String {
236        self.message().replace("%s", tips).parse().unwrap()
237    }
238
239    ///
240    /// Examples
241    ///```text
242    /// async fn test(req: actix_web::HttpRequest) -> impl Responder {
243    ///     return errcode::NOT_EXIST.throw_tips(&req, "gg");
244    /// }
245    ///```
246    ///
247    #[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    ///
262    /// Examples
263    ///```text
264    /// async fn test(req: actix_web::HttpRequest) -> impl Responder {
265    ///     return errcode::VALID_CODE_ERROR.throw(&req);
266    /// }
267    ///```
268    ///
269    #[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        // match *self {
298        //     ErrorCode::InternalError => StatusCode::INTERNAL_SERVER_ERROR,
299        //     ErrorCode::BadClientData => StatusCode::BAD_REQUEST,
300        //     ErrorCode::Timeout => StatusCode::GATEWAY_TIMEOUT,
301        // }
302        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// 拦截器
313#[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    ///
333    /// Examples:
334    /// Registration middleware
335    ///```text
336    /// App::new().wrap(ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, internal_server::handler))
337    ///```
338    ///
339    /// Define middleware handler
340    ///```text
341    /// pub fn handler<B>(mut res: dev::ServiceResponse<B>) -> actix_web::Result<ErrorHandlerResponse<B>> {
342    ///     println!("{}", "add_internal_server_error_header");
343    ///     Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
344    /// }
345    ///```
346    ///
347    /// Return an error
348    ///```text
349    /// #[get(path = "/index")]
350    /// #[allow(unused)]
351    /// async fn index(req: HttpRequest) -> Result<impl Responder, Error> {
352    ///     if true {
353    ///         let message = String::from("测试");
354    ///         Err::<HttpResponse, Error>(Error::new(file!(), line!(), message))
355    ///     } else {
356    ///         Ok(success_respond_to(&req, Some("测试")))
357    ///     }
358    /// }
359    ///```
360    ///
361    #[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
371// Use default implementation for `error_response()` method
372impl error::ResponseError for Error {}