use actix_web::HttpResponse;
use actix_web::http::StatusCode;
use serde::Serialize;
use serde_json::{Value, json};
use crate::api::headers::response_headers::set_response_trace_id;
use crate::error::ProcessedError;
#[derive(Serialize)]
pub struct ApiSuccessResponse<T: Serialize> {
pub status: &'static str,
pub message: String,
pub data: T,
}
#[derive(Serialize)]
pub struct ApiErrorResponse {
pub status: &'static str,
#[serde(skip_serializing_if = "Option::is_none")]
pub code: Option<String>,
pub message: String,
pub error: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<Value>,
}
fn build_error_response(
status: StatusCode,
message: impl Into<String>,
error: impl Into<String>,
code: Option<String>,
data: Option<Value>,
) -> HttpResponse {
HttpResponse::build(status).json(ApiErrorResponse {
status: "error",
code,
message: message.into(),
error: error.into(),
data,
})
}
pub fn api_success<T: Serialize>(message: impl Into<String>, data: T) -> HttpResponse {
HttpResponse::Ok().json(ApiSuccessResponse {
status: "success",
message: message.into(),
data,
})
}
pub fn api_ok<T: Serialize>(data: T) -> HttpResponse {
HttpResponse::Ok().json(data)
}
pub fn api_created<T: Serialize>(message: impl Into<String>, data: T) -> HttpResponse {
HttpResponse::Created().json(ApiSuccessResponse {
status: "success",
message: message.into(),
data,
})
}
pub fn api_accepted<T: Serialize>(message: impl Into<String>, data: T) -> HttpResponse {
HttpResponse::Accepted().json(ApiSuccessResponse {
status: "success",
message: message.into(),
data,
})
}
pub fn bad_request(message: impl Into<String>, error: impl Into<String>) -> HttpResponse {
build_error_response(StatusCode::BAD_REQUEST, message, error, None, None)
}
pub fn postgres_client_not_configured(client_name: &str) -> HttpResponse {
bad_request(
format!("Client '{client_name}' is not available in the registry"),
format!("Postgres client '{client_name}' is not configured"),
)
}
pub fn unauthorized(message: impl Into<String>, error: impl Into<String>) -> HttpResponse {
build_error_response(StatusCode::UNAUTHORIZED, message, error, None, None)
}
pub fn forbidden(message: impl Into<String>, error: impl Into<String>) -> HttpResponse {
build_error_response(StatusCode::FORBIDDEN, message, error, None, None)
}
pub fn not_found(message: impl Into<String>, error: impl Into<String>) -> HttpResponse {
build_error_response(StatusCode::NOT_FOUND, message, error, None, None)
}
pub fn conflict(message: impl Into<String>, error: impl Into<String>) -> HttpResponse {
build_error_response(StatusCode::CONFLICT, message, error, None, None)
}
pub fn too_many_requests(message: impl Into<String>, error: impl Into<String>) -> HttpResponse {
build_error_response(StatusCode::TOO_MANY_REQUESTS, message, error, None, None)
}
pub fn internal_error(message: impl Into<String>, error: impl Into<String>) -> HttpResponse {
build_error_response(
StatusCode::INTERNAL_SERVER_ERROR,
message,
error,
None,
None,
)
}
pub fn service_unavailable(message: impl Into<String>, error: impl Into<String>) -> HttpResponse {
build_error_response(StatusCode::SERVICE_UNAVAILABLE, message, error, None, None)
}
pub fn bad_gateway(message: impl Into<String>, error: impl Into<String>) -> HttpResponse {
build_error_response(StatusCode::BAD_GATEWAY, message, error, None, None)
}
pub fn error_response_with_code(
status: StatusCode,
message: impl Into<String>,
error: impl Into<String>,
code: impl Into<String>,
data: Option<Value>,
) -> HttpResponse {
build_error_response(status, message, error, Some(code.into()), data)
}
pub fn api_success_value(message: impl Into<String>, data: Value) -> HttpResponse {
HttpResponse::Ok().json(json!({
"status": "success",
"message": message.into(),
"data": data
}))
}
pub fn api_error(message: impl Into<String>) -> HttpResponse {
let msg: String = message.into();
internal_error(&msg, &msg)
}
pub fn processed_error(error: ProcessedError) -> HttpResponse {
let status: StatusCode = error.status_code;
let json: Value = error.to_json();
let mut response = HttpResponse::build(status).json(json);
set_response_trace_id(response.headers_mut(), &error.trace_id);
response
}