1pub mod error;
2pub mod handlers;
3pub mod models;
4pub mod routes;
5pub mod server;
6
7use axum::{
8 http::StatusCode,
9 response::{IntoResponse, Response},
10 Json,
11};
12use serde_json::json;
13
14pub use error::ApiError;
16
17pub struct ApiResponse<T> {
19 pub data: Option<T>,
20 pub message: Option<String>,
21 pub status: StatusCode,
22}
23
24impl<T> ApiResponse<T>
25where
26 T: serde::Serialize,
27{
28 pub fn success(data: T) -> Self {
29 Self {
30 data: Some(data),
31 message: None,
32 status: StatusCode::OK,
33 }
34 }
35
36 pub fn success_with_message(data: T, message: &str) -> Self {
37 Self {
38 data: Some(data),
39 message: Some(message.to_string()),
40 status: StatusCode::OK,
41 }
42 }
43
44 pub fn error(status: StatusCode, message: &str) -> ApiResponse<T> {
45 Self {
46 data: None,
47 message: Some(message.to_string()),
48 status,
49 }
50 }
51}
52
53impl<T> IntoResponse for ApiResponse<T>
54where
55 T: serde::Serialize,
56{
57 fn into_response(self) -> Response {
58 let body = match self.data {
59 Some(data) => {
60 if let Some(message) = self.message {
61 json!({
62 "success": self.status.is_success(),
63 "message": message,
64 "data": data
65 })
66 } else {
67 json!({
68 "success": self.status.is_success(),
69 "data": data
70 })
71 }
72 }
73 None => {
74 if let Some(message) = self.message {
75 json!({
76 "success": self.status.is_success(),
77 "message": message
78 })
79 } else {
80 json!({
81 "success": self.status.is_success()
82 })
83 }
84 }
85 };
86
87 (self.status, Json(body)).into_response()
88 }
89}