oxide_framework_core/
response.rs1use axum::{
2 Json,
3 http::StatusCode,
4 response::{IntoResponse, Response},
5};
6use serde::Serialize;
7
8#[derive(Debug, Serialize)]
14pub struct SuccessBody<T: Serialize> {
15 pub status: u16,
16 pub data: T,
17}
18
19#[derive(Debug, Serialize)]
25pub struct ErrorBody {
26 pub status: u16,
27 pub error: String,
28}
29
30pub enum ApiResponse<T: Serialize> {
48 Success(StatusCode, T),
49 Error(StatusCode, String),
50}
51
52impl<T: Serialize> ApiResponse<T> {
53 pub fn ok(data: T) -> Self {
55 Self::Success(StatusCode::OK, data)
56 }
57
58 pub fn created(data: T) -> Self {
60 Self::Success(StatusCode::CREATED, data)
61 }
62
63 pub fn success(status: StatusCode, data: T) -> Self {
65 Self::Success(status, data)
66 }
67
68 pub fn error(status: StatusCode, message: impl Into<String>) -> Self {
70 Self::Error(status, message.into())
71 }
72
73 pub fn bad_request(message: impl Into<String>) -> Self {
75 Self::error(StatusCode::BAD_REQUEST, message)
76 }
77
78 pub fn not_found(message: impl Into<String>) -> Self {
80 Self::error(StatusCode::NOT_FOUND, message)
81 }
82
83 pub fn unauthorized(message: impl Into<String>) -> Self {
85 Self::error(StatusCode::UNAUTHORIZED, message)
86 }
87
88 pub fn forbidden(message: impl Into<String>) -> Self {
90 Self::error(StatusCode::FORBIDDEN, message)
91 }
92
93 pub fn internal_error(message: impl Into<String>) -> Self {
95 Self::error(StatusCode::INTERNAL_SERVER_ERROR, message)
96 }
97}
98
99impl<T: Serialize> IntoResponse for ApiResponse<T> {
100 fn into_response(self) -> Response {
101 match self {
102 ApiResponse::Success(status, data) => {
103 let body = SuccessBody {
104 status: status.as_u16(),
105 data,
106 };
107 (status, Json(body)).into_response()
108 }
109 ApiResponse::Error(status, message) => {
110 let body = ErrorBody {
111 status: status.as_u16(),
112 error: message,
113 };
114 (status, Json(body)).into_response()
115 }
116 }
117 }
118}
119