Skip to content
Clone
b7cd2b1
131 lines 3.4 KB Rust
use actix_web::body::BoxBody;
use actix_web::http::StatusCode;
use actix_web::{HttpRequest, HttpResponse, Responder};
use serde::{Deserialize, Serialize};
use std::fmt;
use utoipa::ToSchema;
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct NoData;
#[derive(Serialize, Deserialize, Debug, Clone, ToSchema)]
pub struct AppResponseData<T> {
pub code: i32,
pub message: String,
pub data: Option<T>,
pub error: Option<String>,
pub error_code: Option<String>,
pub request_id: String,
pub log_id: String,
}
impl<T> AppResponseData<T>
where
T: Serialize,
{
pub fn ok(data: T) -> Self {
AppResponseData {
code: 200,
message: "success".to_string(),
data: Some(data),
error: None,
error_code: None,
request_id: String::new(),
log_id: String::new(),
}
}
pub fn err(code: i32, message: impl Into<String>) -> Self {
AppResponseData {
code,
message: message.into(),
data: None,
error: None,
error_code: None,
request_id: String::new(),
log_id: String::new(),
}
}
pub fn err_with_detail(
code: i32,
message: impl Into<String>,
detail: impl Into<String>,
) -> Self {
AppResponseData {
code,
message: message.into(),
data: None,
error: Some(detail.into()),
error_code: None,
request_id: String::new(),
log_id: String::new(),
}
}
pub fn with_code(mut self, code: i32) -> Self {
self.code = code;
self
}
pub fn with_message(mut self, message: impl Into<String>) -> Self {
self.message = message.into();
self
}
pub fn with_error(mut self, error: impl Into<String>) -> Self {
self.error = Some(error.into());
self
}
pub fn with_error_code(mut self, code: impl Into<String>) -> Self {
self.error_code = Some(code.into());
self
}
pub fn with_request_id(mut self, request_id: impl Into<String>) -> Self {
self.request_id = request_id.into();
self
}
pub fn with_log_id(mut self, log_id: impl Into<String>) -> Self {
self.log_id = log_id.into();
self
}
}
impl AppResponseData<NoData> {
pub fn empty() -> Self {
AppResponseData {
code: 200,
message: "success".to_string(),
data: None,
error: None,
error_code: None,
request_id: String::new(),
log_id: String::new(),
}
}
}
impl fmt::Display for AppResponseData<()> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "API error: code={}, message={}", self.code, self.message)
}
}
impl<T: Serialize> Responder for AppResponseData<T> {
type Body = BoxBody;
fn respond_to(mut self, _request: &HttpRequest) -> HttpResponse<Self::Body> {
let status =
StatusCode::from_u16(self.code as u16).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
if self.request_id.is_empty() {
self.request_id = crate::middleware::request_id().unwrap_or_default();
}
if self.log_id.is_empty() {
self.log_id = crate::middleware::log_id().unwrap_or_default();
}
HttpResponse::build(status).json(self)
}
}