mycommon-utils 0.2.1

Common utilities library for database operations, Redis caching and system utilities
Documentation
use std::fmt::Debug;

use axum::{http::{header, HeaderValue, StatusCode}, response::{IntoResponse, Response}, Json};
use serde::{Deserialize, Serialize};
use crate::error::Error;

static RES_CODE_SUCCESS: i32 = 0;

#[derive(Debug, Serialize, Clone,Deserialize)]
/// 查 数据返回
pub struct ListData<T> {
    pub data: Vec<T>,
    pub total: u64,
    #[serde(rename(serialize = "totalPages"))]
    pub total_pages: u64,
    #[serde(rename(serialize = "current"))]
    pub page_num: u64,
    #[serde(rename(serialize = "pageSize"))]
    pub page_size: u64,
}

/// 分页参数
#[derive(Deserialize, Clone, Debug, Serialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct PageParams {
    #[serde(rename(deserialize = "current"))]
    pub page_num: Option<u64>,
    pub page_size: Option<u64>,
}

/// 数据统一返回格式
#[derive(Debug, Serialize, Deserialize, Default)]
pub struct Res<T> {
    #[serde(rename(serialize = "errorCode"))]
    pub code: Option<i32>,
    pub data: Option<T>,
    #[serde(rename(serialize = "errorMsg"))]
    pub msg: Option<String>,
}

/// 填入到extensions中的数据
#[derive(Debug, Clone)] // 添加 Clone 派生
pub struct ResJsonString(pub String);

#[allow(unconditional_recursion)]
impl<T> IntoResponse for Res<T>
where
    T: Serialize + Send + Sync + Debug + 'static,
{
    fn into_response(self) -> Response {
        let data = Self {
            code: self.code,
            data: self.data,
            msg: self.msg,
        };
        let json_string = match serde_json::to_string(&data) {
            Ok(v) => v,
            Err(e) => {
                return Response::builder()
                    .status(StatusCode::INTERNAL_SERVER_ERROR)
                    .header(header::CONTENT_TYPE, HeaderValue::from_static(mime::TEXT_PLAIN_UTF_8.as_ref()))
                    .body(e.to_string().into())
                    .unwrap();
            }
        };
        let res_json_string = ResJsonString(json_string.clone());
        let mut response = json_string.into_response();
        response.headers_mut().insert(
            header::CONTENT_TYPE,
            HeaderValue::from_static("application/json"),
        );
        response.extensions_mut().insert(res_json_string); // 直接插入 ResJsonString 类型
        response
    }
}

impl<T: Serialize> Res<T> {

    pub fn result(arg: Result<T, Error>) -> Self {
        match arg {
            Ok(data) =>  Self::with_data(data),
            Err(e) => Self {
                code: Some(e.error_code),
                msg: Some(e.error_msg.clone()),
                data: None,
            },
        }
    }

    pub fn with_data(data: T) -> Self {
        Self {
            code: Some(RES_CODE_SUCCESS),
            data: Some(data),
            msg: Some("success".to_string()),
        }
    }
    pub fn with_err(err: &str) -> Self {
        Self {
            code: Some(500),
            data: None,
            msg: Some(err.to_string()),
        }
    }

    pub fn with_warn(err: &str) -> Self {
        Self {
            code: Some(601),
            data: None,
            msg: Some(err.to_string()),
        }
    }
    pub fn with_msg(msg: &str) -> Self {
        Self {
            code: Some(RES_CODE_SUCCESS),
            data: None,
            msg: Some(msg.to_string()),
        }
    }
    #[allow(dead_code)]
    pub fn with_data_msg(data: T, msg: &str) -> Self {
        Self {
            code: Some(RES_CODE_SUCCESS),
            data: Some(data),
            msg: Some(msg.to_string()),
        }
    }
    // 将 Res 转换为 JSON 格式的响应
    pub fn resp_json(self) -> Json<Self> {
        Json(self)  // 使用 Axum 的 Json 类型将 Res 包装成 JSON 响应
    }
}