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>;