app_core/
lib.rs

1use actix_web::{HttpResponse, Responder};
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4
5#[derive(Debug, Serialize, Deserialize)]
6pub struct Any {}
7
8#[derive(Debug, Serialize, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct ResultPagination {
11    total: i64,
12    page: i64,
13    page_size: i64,
14    current_page: i64,
15}
16
17#[derive(Debug, Serialize, Deserialize)]
18pub struct ApiResult<T> {
19    success: bool,
20    #[serde(skip_serializing_if = "Option::is_none")]
21    data: Option<T>,
22    #[serde(skip_serializing_if = "Option::is_none")]
23    list: Option<Vec<T>>,
24    #[serde(skip_serializing_if = "Option::is_none")]
25    message: Option<String>,
26    #[serde(skip_serializing_if = "Option::is_none")]
27    code: Option<i32>,
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pagination: Option<ResultPagination>,
30    #[serde(skip_serializing_if = "Option::is_none")]
31    extra: Option<Value>,
32}
33impl<T> ApiResult<T> {
34    pub fn value(v: T) -> Self {
35        ApiResult {
36            success: true,
37            data: Some(v),
38            list: None,
39            message: None,
40            code: None,
41            pagination: None,
42            extra: None,
43        }
44    }
45
46    pub fn list(v: Vec<T>) -> Self {
47        ApiResult {
48            success: true,
49            data: None,
50            list: Some(v),
51            message: None,
52            code: None,
53            pagination: None,
54            extra: None,
55        }
56    }
57    pub fn fail(message: &str) -> Self {
58        Self::failure(message)
59    }
60
61    pub fn failure(message: &str) -> Self {
62        ApiResult {
63            success: false,
64            data: None,
65            list: None,
66            message: Some(message.to_string()),
67            code: None,
68            pagination: None,
69            extra: None,
70        }
71    }
72
73    pub fn success() -> Self {
74        ApiResult {
75            success: true,
76            data: None,
77            list: None,
78            message: None,
79            code: None,
80            pagination: None,
81            extra: None,
82        }
83    }
84
85    pub fn extra(&mut self, key: &str, value: Value) -> &mut Self {
86        match self.extra {
87            Some(ref mut v) => {
88                v[key] = value;
89            }
90            None => {
91                let mut v = serde_json::Map::new();
92                v.insert(key.to_string(), value);
93                self.extra = Some(v.into());
94            }
95        }
96        self
97    }
98}
99
100impl<T: Serialize> Responder for ApiResult<T> {
101    type Body = actix_web::body::BoxBody;
102
103    fn respond_to(self, _req: &actix_web::HttpRequest) -> actix_web::HttpResponse<Self::Body> {
104        HttpResponse::Ok().json(self)
105    }
106}
107
108impl<T, E> Into<Result<ApiResult<T>, E>> for ApiResult<T> {
109    fn into(self) -> Result<ApiResult<T>, E> {
110        Ok(self)
111    }
112}
113
114pub type DefaultResult<T> = Result<T, Box<dyn std::error::Error>>;
115pub type AnyhowResult<T> = Result<T, anyhow::Error>;
116pub type AnyResult = ApiResult<Any>;